1

I'm totally newbie in javascript/jQuery and i have a little problem :)

I'm using AJAX to get datas to generate and populate form fields. After that, i would like to add and/or remove fields with javascript functions but it doesn't work.

As i'm learning, i make my code step by step, so the following code implement the ajax request (which is working perfectly), and the function which i would like to call with an on click attribute on an + image.

$(document).ready(function(){

var id = $('#subId').val();
var num     = $('.cloneSub').length;
var newNum  = new Number(num + 1);

$.ajax({
    type: 'POST',
    dataType: 'json',
    url: '/admin/popsub2/',
    data: 'id='+id,
    async: false,
    success: function(data){

        $.each(data, function(key, val){

            // Add and populate the input text element
            var newElem = $('#sub' + num).clone().attr('id', 'sub' + newNum);
            newElem.children(':first').attr('id', 'sub' + newNum).attr('name', 'sub' + newNum);

            $('#sub' + num).attr('value', val);

            $('#sub' + num).after(newElem);
            $(newElem).before('<br />');

            // Simply add the select element
            var newSelect = $('#editMenu_article' + num).clone().attr('id', 'editMenu_article' + newNum);
            newSelect.children(':first').attr('id', 'editMenu_article' + newNum).attr('name', 'editMenu_article' + newNum);

            $('#editMenu_article' + num).after(newSelect);
            $(newSelect).before('<br />');
        });
    },

    failure: function(){
        alert('echec !!!');
    }
});


function addField(){

    // Add the input text element
    var newElem = $('#sub' + num).clone().attr('id', 'sub' + newNum);
    newElem.children(':first').attr('id', 'sub' + newNum).attr('name', 'sub' + newNum);

    $('#sub' + num).attr('value', val);

    $('#sub' + num).after(newElem);
    $(newElem).before('<br />');

    // Add the select element
    var newSelect = $('#addMenu_article' + num).clone().attr('id', 'addMenu_article' + newNum);
    newSelect.children(':first').attr('id', 'addMenu_article' + newNum).attr('name', 'addMenu_article' + newNum);

    $('#addMenu_article' + num).after(newSelect);
    $(newSelect).before('<br />');

}

});

The addField() function doesn't work at all, and i don't know why. AJAX seems to keep a hand on the script execution.

Thanx for your help.

UPDATE

My + image is :

<img src="images/plus.png" id="editSub2" />

Following your help i tried those codes :

$('#editSub2').live('click', function(){ ... });

$('#editSub2').bind('click', function(){ ... });

But nothing works.

4
  • I don't see a click handler anywhere in your code... unless I'm missing it. Commented Mar 7, 2012 at 21:58
  • try moving the addField() function outside the $(document).ready(function(){ block Commented Mar 7, 2012 at 21:58
  • also, without seeing your click handler, I can't tell if you're trying to apply it to elements you've cloned. If you are, I'm pretty sure cloned elements don't get the handlers of the element they were cloned from unless you pass true (like $("#id").clone(true)) Commented Mar 7, 2012 at 22:01
  • @colleen My click handler is <img src="images/plus.png" id="editSub2" onclick="addField(); return;" /> Commented Mar 7, 2012 at 22:16

3 Answers 3

1

You've declared addField() inside the scope of your jQuery document ready callback. No one outside that function will be able to know about it. You can declare it as a global function, but you'll be better encapsulating it. You might find something like Javascript Patterns a helpful resource.

Sign up to request clarification or add additional context in comments.

3 Comments

Also, newNum as it is won't work as expected...as a variable nor as a counter for the elements.
@stormdrain That's it, if i put my function outside $(document).ready(... my vars will not work as a counter. Which is necessary for me to dynamically add new elements
@KevOne the first problem you need to rectify is newNum. Right now it's not generating numbers. if you log newNum to console, you will get an object not an int. Try declaring newNum as global (no var, just newNum = num+1); and increment the counter in the each loop.
0

If the image is created dynamically, you should bind the click event after creating it, if not, on the document ready block, you must bind it.

$('img#myimg').bind("click", function(){

// Add the input text element
    var newElem = $('#sub' + num).clone().attr('id', 'sub' + newNum);
    newElem.children(':first').attr('id', 'sub' + newNum).attr('name', 'sub' + newNum);

    $('#sub' + num).attr('value', val);

    $('#sub' + num).after(newElem);
    $(newElem).before('<br />');

    // Add the select element
    var newSelect = $('#addMenu_article' + num).clone().attr('id', 'addMenu_article' + newNum);
    newSelect.children(':first').attr('id', 'addMenu_article' + newNum).attr('name', 'addMenu_article' + newNum);

    $('#addMenu_article' + num).after(newSelect);
    $(newSelect).before('<br />');


});

Comments

0

Sounds like you've run into the DOM event handler trap. This issue makes more sense if you've ever handled events sans jQuery.

Basically, what happens when you do this:

$(".images").click(myFunc);

is that jQuery goes and finds all elements that match the selector and binds the function myFunc to the onclick event, using this (roughly) code:

element.onclick = myFunc;

(It actually does something more complicated, but just assume that thats what it does)

and that happens when you run the above code and only then, any extra elements added to the DOM don't have that event added, jQuery was never told to add them!

However, all is not lost, you can use the brilliant .live() function in jQuery to bind to all matching elements, existing and future. Its simpler and easier to use than having to manually rebind new elements and less error prone. One minor downside is that it interferes with event ordering, and you have to use a .bind()-like interface, so you use .live("click", myfunc) instead.

EDIT

In light of reading more of your question, it seems that the problem is that you have is that you have bound to #editSub2 but are generating #editSub<n> so jQuery has no idea what you are on about. I suggest using classes to push common functionality onto elements, and IDs for unique elements, for one its probably more efficient.

2 Comments

Thanx much for your answer. I've already tried your solution, but nothing works
In fact, #editSub2 is unique. I'm just using one button to add (a + image). That's why i'm using an ID. However, i followed your advise to see what happens ... without any success :(

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.