Question

i have a form and would like to give users the ability to duplicate a group of fields as many times as necessary. With one group it iterates correctly but when I add a second group the "current" variable iterates collectively instead of being unique to each group... i tried changing all of the "current" to "newFieldset.current" but that returns NAN... any ideas?

<script type="text/javascript">
$(document).ready(function() {
var current = 0;
    //Add New Fieldset with Button
    var newFieldset = {
        init: function(groupIndex) {
            current++;
            $newPerson= $("#Template"+groupIndex).clone(true);
            $newPerson.children("p").children("label").each(function(i) {
                var $currentElem= $(this);
                $currentElem.attr("for",$currentElem.attr("for")+current);
            });
            $newPerson.children("p").children("input").each(function(i) {
                var $currentElem= $(this);
                $currentElem.attr("name",$currentElem.attr("name")+current);
                $currentElem.attr("value",$currentElem.attr("value")+groupIndex+current);
                $currentElem.attr("id",$currentElem.attr("id")+current);
            });

            $newPerson.appendTo("#mainField"+groupIndex);
            $newPerson.removeClass("hideElement");
        },
        currentID: null,
        obj: null
    };
    $(".addButton").each(function() {
        $(this).click(function() {
            var groupIndex = $(this).attr("title");
            //newFieldset.obj = this;
            //var fieldIndex = $(this).attr("class");
            newFieldset.init(groupIndex);
        });
    });

    console.log('r');
});
</script>
<style>
.hideElement {display:none;}
</style>

<form name="demoForm" id="demoForm" method="post" action="#">
<div id="groupCtr1">
    <fieldset id="mainField1">
    <div id="Template1" class="hideElement">
    <p>
        <label for="firstname">Name</label> <em>*</em>
        <input id="firstname" name="firstname" size="25" /> <input id="lastname" name="lastname" size="25" />
    </p>
    <p>
        <label for="email">Email</label> <em>*</em><input id="email" name="email" size="25" />
    </p>
    </div>
    <div>
    <p>
        <label for="firstname1">Name</label> 
        <em>*</em> <input id="firstname1" name="firstname1" size="25" /> <input id="lastname1" name="lastname1" size="25" />
    </p>
    <p>
        <label for="email1">Email</label>  
        <em>*</em><input id="email1" name="email1" size="25" />
    </p>
    </div>
    </fieldset>
    <p>
    <input type="button" class="addButton" title="1" value="Add Another Person">
    </p>
</div>
<div id="groupCtr2">
    <fieldset id="mainField2">
    <div id="Template2" class="hideElement">
        <p>
            <label for="coname">Company Name</label> <em>*</em>
            <input id="coname" name="coname" size="25" />
        </p>
        <p>
            <label for="codesc">Description</label> <em>*</em><input id="codesc" name="codesc" size="25" />
        </p>
    </div>
    <div>
        <p>
            <label for="coname1">Company Name</label> 
            <em>*</em> <input id="coname1" name="coname1" size="25" />
        </p>
        <p>
            <label for="codesc1">Description</label>  
            <em>*</em><input id="codesc1" name="codesc1" size="25" />
        </p>
    </div>
    </fieldset>
    <p>
    <input type="button" class="addButton" title="2" value="Add Another Company">
    </p>
</div>
<input type="submit" value="Save">
</form>
Was it helpful?

Solution

Attach the value to the element with the jQuery data method. Increment it on click, and then pass it to the newFieldset.init method as the second param. Voila!

$(document).ready(function() {
    //Add New Fieldset with Button
    var newFieldset = {
        init: function(groupIndex,current) {
                $newPerson= $("#Template"+groupIndex).clone(true);
                $newPerson.children("p").children("label").each(function(i) {
                        var $currentElem= $(this);
                        $currentElem.attr("for",$currentElem.attr("for")+current);
                });
                $newPerson.children("p").children("input").each(function(i) {
                        var $currentElem= $(this);
                        $currentElem.attr("name",$currentElem.attr("name")+current);
                        $currentElem.attr("value",$currentElem.attr("value")+groupIndex+current);
                        $currentElem.attr("id",$currentElem.attr("id")+current);
                });

                $newPerson.appendTo("#mainField"+groupIndex);
                $newPerson.removeClass("hideElement");
        },
        currentID: null,
        obj: null
    };
    $(".addButton").click(function() {
        var groupIndex = $(this).attr("title");
        var current = $(this).data('current');
        $(this).data('current',++current);
        //newFieldset.obj = this;
        //var fieldIndex = $(this).attr("class");
        newFieldset.init(groupIndex,current);
    }).data('current',0);

    console.log('r');
});

Happy jquery-ing to you sir.

OTHER TIPS

if you dont make the current variable global it will should work. try this:

var newFieldset = { 
                  current: 0,
                  init: function() {
                      this.current++; 
                      //rest of init code
                  },
                  //all your other fieldset code here
};
/* all other code */

EDIT: After re-reading the question, I would take a completely different approach to what you're trying to achieve. The above code will still exhibit the same behavior for you. If the question hasn't been successfully answered I'll do a bigger writeup when i get home.

I would do something like that:

...
var currents = {};
var newFieldset = {
    init: function(groupIndex) {
        var current = 0;
        if (currents[groupIndex]) {
            current = currents[groupIndex];
        }
        ++current;
        currents[groupIndex] = current;
...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top