0

Accordingly to this question I built a clone script, which creates a selectbox together with an inline text field. All works fine, but the select box will not deliver any value, when submitting the form. The value of the text field instead will be submitted.

I tried to cach the onChange event of this box:

$("#item-1-deposit").change(function(){
    alert($("#item-1-deposit").val());
});

but nothing happens. This works, if I refer to "#item-0-deposit", which is my base element what I've cloned.

My HTML

<div id="items">
     <input type="hidden" id="itemCounter" name="itemCounter" value="0">
     <div class="item">
         <div class="form-group">
             <div class="col-md-2">Nr. <span id="count-0">1</span></div>
             <div class="col-md-4"><f:form.select property="deposits.0.deposit" options="{deposits}" id="item-0-deposit" class="form-control" tabindex="11"/></div>
             <div class="col-md-3"><f:form.textfield property="deposits.0.amount" placeholder="Menge" id="item-0-amount" class="form-control" tabindex="12"/></div>
          </div>
     </div>
 </div>

My jQuery is:

/* 
 * add fields for sub inspections of a main inspection
 */
$(document).ready(function()
{
    // Accepts an element and a function
    function childRecursive(element, func){
        // Applies that function to the given element.
        func(element);
        var children = element.children();
        if (children.length > 0) {
            children.each(function (){
                // Applies that function to all children recursively
                childRecursive($(this), func);
            });
        }
    }

    // Expects format to be xxx-#[-xxxx] (e.g. item-1 or item-1-name)
    function getNewAttr(str, newNum){
        // Split on -
        var arr = str.split('-');
        // Change the 1 to wherever the incremented value is in your id
        arr[1] = newNum;
        // Smash it back together and return
        return arr.join('-');
    }

    // Expects format to be yyyyy[xxx][#][xxxx] (e.g.  depositInspection[deposits][0][deposit])
    function getNewFluidVar(str, newNum){
        // Split on -
        var arr = str.split('][');
        // Change the 1 to wherever the incremented value is in your id
        arr[1] = newNum;
        // Smash it back together and return
        return arr.join('][');
    }

    // Written with Twitter Bootstrap form field structure in mind
    // Checks for id, name, and for attributes.
    function setCloneAttr(element, value){
        // Check to see if the element has an id attribute
        if (element.attr('id') !== undefined){
            // If so, increment it
            element.attr('id', getNewAttr(element.attr('id'),value));
        }
        // so with the name...
        if(element.attr('name') !== undefined){
            element.attr('name', getNewFluidVar(element.attr('name'),value));
        }
        // so with the labels.
        if (element.attr('for') !== undefined){
            element.attr('for', getNewAttr(element.attr('for'),value));
        }
        // so with the count.
        if (element.attr('count') !== undefined){
            element.attr('count', getNewAttr(element.attr('count'),value));
            element.text(Number(element.text()) + 1);
        }
        // so with the tabindex.
        if (element.attr('tabindex') !== undefined){
            element.attr('tabindex', Number(element.attr('tabindex')) + value*2);
        }
    }

    // Sets an element's value to ''
    function clearCloneValues(element){
        if (element.is("select")){
            element.prop('selectedIndex', -1);
        }
        if (element.attr('value') !== undefined){
            element.val('');
        }
    }

    $('#addItem').click(function(){
        var fieldsCount = $('#fieldsCount').val();
        for (var i = 0; i < fieldsCount; i++){
            //increment the value of our counter
            $('#itemCounter').val(Number($('#itemCounter').val()) + 1);
            //clone the first .item element
            var newItem = $('div.item').first().clone();
            //recursively set our id, name, and for attributes properly
            childRecursive(newItem, 
                // Remember, the recursive function expects to be able to pass in
                // one parameter, the element.
                function(e){
                    setCloneAttr(e, $('#itemCounter').val());
            });
            // Clear the values recursively
            childRecursive(newItem, 
                function(e){
                    clearCloneValues(e);
                }
            );
            // Finally, add the new div.item to the end
            newItem.appendTo($('#items'));
        }
        return false;
    });
});

(BTW, I did not get, how to increment the row number within the span element)

Community
  • 1
  • 1
furgo
  • 1
  • 1

1 Answers1

3

For cloned items, you need to use event delegation. Try this:

$(document).on("change", "#item-1-deposit", function(){
    alert($("#item-1-deposit").val());
});
Milan Jaric
  • 5,556
  • 2
  • 26
  • 34
cssyphus
  • 37,875
  • 18
  • 96
  • 111
  • Thank you, but this was only for testing, that the cloned selectbox will be accessible. The actual issue is, that the cloned selectbox will not submit a value, i.e. in the backend the value of the selectbox is empty, while the corresponding inline will do so. – furgo Jan 17 '14 at 18:41
  • Your scipt brings up the alert box, but no value in it. – furgo Jan 17 '14 at 18:44
  • @furgo There was type in jquery selector. It is corrected now. – Milan Jaric Aug 27 '15 at 08:44
  • @MilanJaric Thanks for catching / correcting that error. – cssyphus Aug 27 '15 at 15:22