Form submit inside each loop not working after triggering button being dynamically created

Viewed 103

I have a couple of forms that each contain a submit button.

Html example:

<span id="orderlines">
    <div class="productblock">
        <span class="orderlineloop">
            <input type="hidden" class="order_id_input" value="33.1159" />
            <input type="hidden" class="orderline_id_input" value="606467ae09534" />
            <span class="refreshform" id="606467ae09534">
                <form class="editorform" action="https://burrito.a2test.com/print" method="post" target="_blank">
                    <input
                        type="hidden"
                        name="json"
                        value='{"customer_id":"33","order_id":"33.1159","quantity":"1","canvas_size":"0x0","bleed":"10","safety_margin":"","dpi":"100","procheck":"n","multiple_pages":"1","product_name":"Zitzak","product_thumbnail":"https:\/\/printzelf.nl\/new\/cms\/images\/producten\/Textiel\/zitzak\/549_22ed819692c7b8fe_3.jpg","orderline":"606467ae09534"}'
                    />
                </form>
            </span>

            <div class="productblockbottom">
                <span>
                    <b>Hoe lever je jouw ontwerp aan?</b>
                    <span class="tooltippy_nostyle">
                        <img class="infosvg" src="assets/images/custom/icon_info.svg" />
                        <div class="tooltipcontent darktext tooltipcontentnone">Test</div>
                    </span>
                </span>
                <div class="productblockbtns">
                    <a href="javascript:void(0);">
                        <button class="btnstyle uploadbtn" type="button" name="button">Lever je bestanden aan <i class="icon-upload"></i></button>
                    </a>
                    <span>of</span>
                    <a href="javascript:void(0);">
                        <button class="btnstyle" type="button" name="button">Maak een ontwerp <i class="icon-design"></i></button>
                    </a>
                </div>
            </div>
            <span class="unfinished editstatuscheck"></span>
        </span>
    </div>
    <div class="productblock">
        <span class="orderlineloop">
            <input type="hidden" class="order_id_input" value="33.1159" />
            <input type="hidden" class="orderline_id_input" value="606467c357d7e" />
            <span class="refreshform" id="606467c357d7e">
                <form class="editorform" action="https://burrito.a2test.com/print" method="post" target="_blank">
                    <input
                        type="hidden"
                        name="json"
                        value='{"customer_id":"33","order_id":"33.1159","quantity":"1","canvas_size":"900x900","bleed":"10","safety_margin":"","dpi":"100","procheck":"y","multiple_pages":"1","product_name":"Textielframe","product_thumbnail":"https:\/\/printzelf.nl\/new\/cms\/images\/producten\/textiel_producten\/textielwand\/1288_9936468fbe050be8_1.jpg","orderline":"606467c357d7e"}'
                    />
                </form>
            </span>

            <div class="productblockbottom">
                <span>
                    <b>Hoe lever je jouw ontwerp aan?</b>
                    <span class="tooltippy_nostyle">
                        <img class="infosvg" src="assets/images/custom/icon_info.svg" />
                        <div class="tooltipcontent darktext tooltipcontentnone">Test</div>
                    </span>
                </span>
                <div class="productblockbtns">
                    <a href="javascript:void(0);">
                        <button class="btnstyle uploadbtn" type="button" name="button">Lever je bestanden aan <i class="icon-upload"></i></button>
                    </a>
                    <span>of</span>
                    <a href="javascript:void(0);">
                        <button class="btnstyle" type="button" name="button">Maak een ontwerp <i class="icon-design"></i></button>
                    </a>
                </div>
            </div>
            <span class="unfinished editstatuscheck"></span>
        </span>
    </div>
</span>

I submit every form like this:

$( ".uploadbtn" ).each(function() {
    var form = $(this).closest('.productblock').find('.editorform');
    $(this).click(function() {
        form.submit();
    });
});

This used to work, but now I changed it so that the button that triggers the form submit is generated dynamically (at the moment every 2 seconds). And now the button won't submit anymore.

This is the code that "refreshes" all submit buttons:

// Function below executes every 2 seconds
var editorcheck = function() {
    // Post order id to editorcheck.php
    order_id = $('.order_id_input').val();
    $.ajax({
        type:'post',
        url:"payprocess/editorcheck.php",
        data:({order_id: order_id}),
        success:function(data){
            var obj = JSON.parse(data);
            // Loop json result from editorcheck.php
            for (var i = 0; i < obj.length; i++) {
                var status = obj[i].edit_status;
                var orderline = obj[i].orderline;
                // Loop all elements with class .orderlineloop
                $(".orderlineloop").each(function(i) {
                    // If the returned status == finished
                    if(obj[i].edit_status == 'finished'){
                        if($(this).find('.orderline_id_input').val() == obj[i].orderline){
                            $(this).find('.productblockbottom').empty().append('<div class="finishedblock"><span><b>Je ontwerp is ontvangen</b>  <img class="feedbacksvg" src="assets/images/custom/icon_good.svg"></span> <a href="#" title="Verwijderen"><i class="icon-trash deletedesign"></i></a></div>');
                        }
                    }else if(obj[i].edit_status == 'unfinished'){
                        // Else if status == unfinished
                        $(this).find('.productblockbottom').empty().append('<span><b>Hoe lever je jouw ontwerp aan?</b>  <span class="tooltippy_nostyle"><img class="infosvg" src="assets/images/custom/icon_info.svg"><div class="tooltipcontent darktext tooltipcontentnone">Test</div></span></span>'
                        +'<div class="productblockbtns">'
                        +'<a href="javascript:void(0);"><button class="btnstyle uploadbtn" type="button" name="button">Lever je bestanden aan <i class="icon-upload"></i></button></a>'
                        +'<span>of</span>'
                        +'<a href="javascript:void(0);"><button class="btnstyle" type="button" name="button">Maak een ontwerp <i class="icon-design"></i></button></a>'
                        +'</div>');
                    }
                });
            }
        }
    });
};
var interval = 2000;
setInterval(editorcheck, interval);

This is the part where the buttons get replaced:

}else if(obj[i].edit_status == 'unfinished'){
    // Else if status == unfinished
    $(this).find('.productblockbottom').empty().append('<span><b>Hoe lever je jouw ontwerp aan?</b>  <span class="tooltippy_nostyle"><img class="infosvg" src="assets/images/custom/icon_info.svg"><div class="tooltipcontent darktext tooltipcontentnone">Test</div></span></span>'
    +'<div class="productblockbtns">'
    +'<a href="javascript:void(0);"><button class="btnstyle uploadbtn" type="button" name="button">Lever je bestanden aan <i class="icon-upload"></i></button></a>'
    +'<span>of</span>'
    +'<a href="javascript:void(0);"><button class="btnstyle" type="button" name="button">Maak een ontwerp <i class="icon-design"></i></button></a>'
    +'</div>');
}

I was thinking that my each loop can't find the buttons anymore since they have been replaced/dynamically created. So I looked for something like .on() for the each function, but I see that doesn't exist.

So I tried starting from an element higher in the DOM hierarchy, one that doesn't get replaced and from there find the button like this:

$( "body .uploadbtn" ).each(function() {
    var form = $(this).closest('.productblock').find('.editorform');
    $(this).click(function() {
        form.submit();
    });
});

But this also doesn't work. What can I do?

I also tried not putting the trigger on uploadbtn but on an element that never refreshes and from there select the uploadbtn:

$( ".orderlineloop" ).each(function() {
    var submitbutton = $(this).find('.uploadbtn');
    var form = $(this).find('.editorform');
    $(submitbutton).click(function() {
        form.submit();
    });
});

But again this doesn't work. I can only submit the button once if I click fast (before the function replaces the button).

1 Answers

For dynamically added elements you need to use event delegation with the .on() method, so you were on the right track.

This should work for you:

$(document).on('click', '.uploadbtn', function () {                
   var form = $(this).closest('.productblockbottom').siblings('.refreshform').find('.editorform');
   form.submit();
});

Edit: Added OP solution for finding the form element from comment below.

Related