Hi all, would like to convert this javaScript code versatile so it will be able to extend various inputs of a form.

var instance = 0;

function moreFields() {

    // Check if there isn't more than 3 fields
    if(instance != 3) {
        instance++;

        // Create a child
        var clone = document.getElementById('water_src').cloneNode(true);

        // Make child unique 
        clone.id += instance;
        clone.name += instance;

        clone.style.display = 'block';

        // Locate clone's home 
        var insertHere = document.getElementById('water_drop');
        // Place clone in home
        insertHere.parentNode.insertBefore(clone,insertHere);
    }
}

window.onload = moreFields;

I do this by adding the parentHome & cloneHome parameters to the function and changing the 'water_src' & 'water_drop' to the corresponding ones.

var instance = 0;

function moreFields(parentHome, cloneHome) {

    // Check if there isn't more than 3 fields
    if(instance != 3) {
        instance++;

        // Create a child
        var clone = document.getElementById(parentHome).cloneNode(true);

        // Make child unique 
        clone.id += instance;
        clone.name += instance;

        clone.style.display = 'block';

        // Locate clone's home 
        var insertHere = document.getElementById(cloneHome);
        // Place clone in home
        insertHere.parentNode.insertBefore(clone,insertHere);
    }
}

window.onload = moreFields;

Unfortunetaly when I do this change not even the parent field appears. HTML code bellow

        <div id="water_src" name="water_src" style="display: none">
            <select>
                <option></option>
                <?php
                    while($row=mysql_fetch_array($result)) {
                        echo "\n\t\t\t\t<option value=".$row['water_ID'].">".$row['water_name']."</option>";
                    }
                    echo "\n";
                ?>
            </select>

                <input type="button" value="-"
                    onclick="if(instance > 1) { instance--; this.parentNode.parentNode.removeChild(this.parentNode);}" />
                <input type="button" value="+"
                    onclick="moreFields('water_src', 'water_drop');" />
                <br />
        </div>

        <form method="post" action="package_builder.php">

                <span id="water_drop"></span>
                <input type="submit" value="Send form" />
        </form>

Is there any errors with my syntax or logic?

Recommended Answers

All 8 Replies

If moreFields() is modified to work with arguments, then you can't simply attach the function as the onload handler. You have to create an event handler from which the function is called in the right way.

For example :

window.onload = function(event) {
    moreFields('water_src', 'water_drop');
}

would I need to specify the event type or is putting event in the function() sufficient?
Or does this go on the html when I do the moreFields() call?

Forget about the event, it's not relevant in this case and can be safely removed from the function definition.

For reference, javascript event handlers accept one parameter - an object describing the event that caused the handler to fire. This aspect is not standard across browsers. The expression event = event || window.event standardizes it. Alternatively, javascript libraries such as jQuery provide an opaque mechanism for event standardization/augmentation.

I'm not sure if I understand you, but do you mean something like this for event handler?

function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}
addLoadEvent(nameOfSomeFunctionToRunOnPageLoad);
addLoadEvent(function() {
  /* more code to run on page load */
});

No, you're reading something into my answer that isn't there.

All I mean is that event can be omitted, leaving :

window.onload = function() {
    moreFields('water_src', 'water_drop');
}

So the fragmented code you posted would go where the window.onload = moreFields; line is on the original javascript? Also, could I replace the water_src with parentHome, and water_drop with cloneHome?

End Result

var instance = 0;
function moreFields(parentHome, cloneHome) {
    // Check if there isn't more than 3 fields
    if(instance != 3) {
        instance++;
        // Create a child
        var clone = document.getElementById(parentHome).cloneNode(true);
        // Make child unique 
        clone.id += instance;
        clone.name += instance;
        clone.style.display = 'block';
        // Locate clone's home 
        var insertHere = document.getElementById(cloneHome);
        // Place clone in home
        insertHere.parentNode.insertBefore(clone,insertHere);
    }
}
window.onload = function() {
    moreFields(parentHome, cloneHome) {
}

Also I would like to apologize ahead of time if you're start to loose patiance. I'm new to javascript.

So the fragmented code you posted would go where the window.onload = moreFields; line is on the original javascript?

Yes, exactly so.

Also, could I replace the water_src with parentHome, and water_drop with cloneHome?

As written, the function uses parentHome and cloneHome internally, as names (arguments) referring to the actual values (parameters) passed to it. Thus, the function (like millions upon millions of functions in software the world over), can be called with different parameters at each call. Every function is coded to provide a particular action, the detailed behaviour of which is determined, to a greater or lesser extent, by any parameters passed to it.

This concept is absolutely central to programming!!!

For example, you might want to call moreFields twice with different parameters :

window.onload = function() {
    moreFields('water_src', 'water_drop');
    moreFields('oil_src', 'oil_drop');
}

So, just to make sure I understand you. If I am using this function on other fields (which I am), I will need to specify the parameters to be passed on the window.onload line?

I just tried the code like this

    var instance = 0;
    function moreFields(parentHome, cloneHome) {
        // Check if there isn't more than 3 fields
        if(instance != 3) {
            instance++;
            // Create a child
            var clone = document.getElementById(parentHome).cloneNode(true);
            // Make child unique 
            clone.id += instance;
            clone.name += instance;
            clone.style.display = 'block';
            // Locate clone's home 
            var insertHere = document.getElementById(cloneHome);
            // Place clone in home
            insertHere.parentNode.insertBefore(clone,insertHere);
        }
    }
    window.onload = function() {
        moreFields(parentHome, cloneHome);
    }

But that gave me issues. so I changed the bottom part to moreFields('water_src', 'water_drop');. This worked. Now when I went to add another field such as moreFields('dfood', 'plate'); the code worked to an extent. Both the select drop downs were giving more fields when I clicked the button. But, the same value of the instance seemed to be used for both fields, instead of resetting the value as I called it for another select drop down (giving it its own instance). Is this issue because I don't have the variable instance localized within the function? Also, if I am to re-use this code for other fields I will need to maintain a "list" of them on the window.onload = function(){?

for example

window.onload = function() {
    moreFields('water_src', 'water_drop");
    moreFields('dfood', 'plate');
    moreFields('drink', 'cup');
                .
                .
                .
                .
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.