Tural
Tural

Reputation: 1128

Element lost event when inserting clone after this element

I have one drop-down list (<select> <option>) on page with id="coclevel1". If current selected option has child items then I have to add new drop-down list and fill it with child items. Next drop-down lists should named like "coclevel2", "coclevel3", etc. I've to do this event for every added drop-down list. In $(document).ready I placed:

$('[id^=coclevel]').live('change', function() {
    var currElement = $(this).attr('id');
    alert(currElement); //for debug
    cleanUpCocOptionsAfter(currElement);
    renderSubItemsOf(currElement);
});

renderSubItemsOf(currElement); make query to DB, and if data is not empty add new drop-down list and fill it.

function cleanUpCocOptionsAfter(currElement) {
    var num = $('.cocItems').length;
    var currNum = parseInt(currElement.substring(8, currElement.length));
    for (var i = currNum + 1; i <= num; i++) {
        $('#coclevel' + i).remove();
        $('#cocBr' + i).remove();
    }
}

function renderSubItemsOf(currElement) {
    var parentId = $('#' + currElement + ' option:selected').val();
    $.getJSON('getchildrenof/' + parentId,
            function() {

            }).success(function(data) {
                var len = data.length;
                if (len > 0) {
                    var newElemSelector = '#' + addCocOptionAfter(currElement);
                    for (var i = 0; i < len; i++) {
                        $(newElemSelector).append($("<option></option>").attr("value", data[i].id).text(data[i].description));
                    }
                } else {
                    //not developed yet
                }
            });
}

function addCocOptionAfter(currElement) {
    // how many "duplicatable" input fields we currently have
    var num = $('.cocItems').length;
    var currNum = parseInt(currElement.substring(8, currElement.length));
    var currElemSelector = '#' + currElement;
    // the numeric ID of the new input field being added
    var newNum = new Number(num + 1);

    // create the new element via clone(),
    //and manipulate it's ID using newNum value
    var newElemId = 'coclevel' + newNum;

    var newElem = $(currElemSelector).clone().attr('id', newElemId).empty();
    $(newElem).append($("<option></option>").attr("value", -1).text('-- Select one --'));

    // insert the new element after the last "duplicatable" input field
    $(currElemSelector).after(newElem);
    $(currElemSelector).after('<br/>').attr('id', 'cocBr' + newNum);

    return newElemId;
}

Adding new drop-down box and filling works fine, but thereafter previous drop-down box lost event, and when I try to change selected option nothing appears (browser don't show alert(currElement); //for debug). Please help to solve this issue.

Upvotes: 1

Views: 1561

Answers (2)

Eric
Eric

Reputation: 97641

You don't need to be using numeric ids here. You should be able to do this more efficiently by passing around the DOM objects themselves:

$('.cocItems').live('change', function() {
    cleanUpCocOptionsAfter(this);
    renderSubItemsOf(this);
});

function cleanUpCocOptionsAfter(currElement) {
    $(currElement).nextAll('.cocItems').remove();
}

function renderSubItemsOf(currElement) {
    var parentId = $(currElement).val();
    $.getJSON('getchildrenof/' + parentId, function(data) {
        var len = data.length;
        if (len > 0) {
            addCocOptionAfter(currElement, data)
        } else {
            //not developed yet
        }
    });
}

function addCocOptionAfter(currElement, data) {
    var newElem = $('<select />').addClass('cocItems');
    $('<option />')
        .attr('value', -1)
        .text('-- Select one --')
        .appendTo(newElem);

    $.each(data, function() {
         $('<option />')
             .attr('value', this.id)
             .text(this.description)
             .appendTo(newElem);
    });
    newElem.insertAfter(currElement);
    return newElem;
}

Upvotes: 1

jfriend00
jfriend00

Reputation: 707836

I'm not sure I understand what you're asking, but if you want jQuery event handlers to be cloned with an element, then you need to use .clone(true) rather than just clone(). See here for more info.

Upvotes: 2

Related Questions