0

Is there a way where i could bind the events from the newly created elements via jquery.

Heres an example.

HTML:

    <div id="meta_inner" class="gallery">
    <div id="medias">
        <label for="test_meta_boxes1" ><input id="test_meta_boxes1" type="text" size="100" name="ad_image" value="http://" /><input id="test_meta_boxes_button" class="button" type="button" value="Upload Image" data-int="test_meta_boxes1"/></label>
    </div>
    <input class="button tagadd add" type="button" value="Add Image Field">
</div>

jQuery

    jQuery(document).ready(function($){
    var count = $("#medias").children('label').length;
    $(".tagadd").on('click', function() {
        count = count + 1;

        $('#medias').append('<label for="test_meta_boxes'+count+'" ><input id="test_meta_boxes'+count+'" type="text" size="100" name="ad_image" value="http://" /><input id="test_meta_boxes_button" class="button" type="button" value="Upload Image" data-int="test_meta_boxes'+count+'"/></label>' );

        return false;
    });

    $('label').find('#test_meta_boxes_button').on('click', function(e) {

        metabox = $(this).data('int');

        console.log(metabox);

    });
});

When you runs this. The first label will work and print on the console window when the 'Upload Image' button is clicked.

but when i add another label by clicking the 'Add Image Field' button. the 'Upload Image' button will not work.

Am i missing something? any help is appreciated.

perEights
  • 3
  • 3

3 Answers3

2

If, rather than just appending the HTML, you append some of it and then insert the button as a new jQuery object, it appears to work.

$(".tagadd").click(function () {
    count++;
    $('#medias').append('<label for="test_meta_boxes' + count + '" ><input id="test_meta_boxes' + count + '" type="text" size="100" name="ad_image" value="http://" /></label>');
    $('#test_meta_boxes' + count).after(
        $("<input />")
            .attr('id', "test_meta_boxes_button" + count)
            .attr('type', 'button')
            .attr('value', 'Upload Image')
            .attr('data-int', 'test_meta_boxes' + count)
            .addClass('button')
            .click(function (e) {
                metabox = $(this).data('int');
                console.log(metabox);
            })
    );
    return false;
});

Here is a working fiddle.

This is because your .on() method is currently targeting an id, if you were to bind the method as per the documentation (see below) it should work as expected.

var count = $("#medias").children('label').length;
$(".tagadd").click(function () {
    count++;
    $('#medias').append('<label for="test_meta_boxes' + count + '" ><input id="test_meta_boxes' + count + '" type="text" size="100" name="ad_image" value="http://" /></label>');
    $('#test_meta_boxes' + count).after(
        $("<input />")
            .attr({
                type: 'button',
                value: 'Upload Image',
                'data-int': 'test_meta_boxes' + count 
            })
            .addClass('button test_meta_boxes_button')
    );
    return false;
});

$(document).on('click', 'label .test_meta_boxes_button', function(e) {
    metabox = $(this).data('int');
    console.log(metabox);
});

Please also note that you're currently assigning the same id to every button that is created, this is bad practice and so you should include your count variable in the id for the button, and a class to target all the buttons by.

With the duplicate id issue removed and a class in it's place as above, and with the revised .on() method everything works, see the fiddle here

Pete Uh
  • 630
  • 4
  • 7
  • Thanks for the info, this works too. and thanks for adding the IDs name issue ill change that also. I think this is the best answer... – perEights Mar 07 '13 at 15:55
  • you should not have multiple elements with the same id. use classes instead. You also still don't need to manually attach event listeners when you use `.on` – Andbdrew Mar 07 '13 at 16:01
  • I was adding the second part to explain why this works when you commented, please also read the bottom part of my answer that explains about the id. I will update my code now to remove confusion. – Pete Uh Mar 07 '13 at 16:05
  • updated the answer with all of the code snippets, old and new fiddles and explanations. – Pete Uh Mar 07 '13 at 16:14
  • Thanks guys! Big help from all of you! now it works. thank you all pete cort3z and andbdrew – perEights Mar 07 '13 at 16:17
1

you are only binding click events to label #test_meta_boxes_button elements that exist when document.ready happens.

[EDIT]

instead of

$('label').find('#test_meta_boxes_button').on('click', function(e) {
    metabox = $(this).data('int');
    console.log(metabox);
});

try doing

$(document).on('click', 'label .test_meta_boxes_button', function(e) {
    metabox = $(this).data('int');
    console.log(metabox);
});

check out the jQuery docs for .on at http://api.jquery.com/on/

Please note the .test_meta_boxes_button as well. you should not have multiple elements on a page with the same id.

change <input id="test_meta_boxes_button" class="button" type="button" ... to <input class="button test_meta_boxes_button" type="button"...

Andbdrew
  • 11,788
  • 4
  • 33
  • 37
0

You are not adding the on click event to the newly created element. After creating the new element you need to reapply the on click event, so it is active on that new element as well.

So basicly:

function ReapplyOnClickEvents()
{
      //Your on click events go here
      $(selector).on('click', function(){ /*do whatever*/});
}

... //JS that makes a new button (pseudocode):
$(whatever).AddButton(function(){
  //This is callback after add button is run:
  ReapplyOnClickEvents();
}
Automatico
  • 12,420
  • 9
  • 82
  • 110
  • `.on` is like delegate. You don't have to manually attach event listeners if you use it in the form `$('item-container').on('event', 'selector', eventHandler)`. – Andbdrew Mar 07 '13 at 15:42
  • Wow thanks, it works what i did is put the newly created label in the new function and call it after the document ready and after the addbutton. Thanks a lot! – perEights Mar 07 '13 at 15:50
  • You can potentially improve your performance by applying the listeners to only your newly created object/element, and not to every single element of your selector. – Automatico Mar 07 '13 at 15:52
  • You have a point about improving performance by using this technique. What i did is combined your answer and @pete answer. – perEights Mar 07 '13 at 16:09