3

I have the following table.

<table class="table invoice-items-table">
    <thead>
        <tr>
            <th>Item</th>
            <th>Quantity</th>
            <th>Price</th>
            <th>Amount</th>
        </tr>
    </thead>
    <tbody>
        <tr class="invoice-item-row">
            <td>
                <select class="selectpicker invoice-item-select" title="Select an Item">
                    <option value="1">PHP Development</option>
                </select>
            </td>
            <td class="text-right">
                <input class="form-control invoice-item-quantity" value="1" type="text">
            </td>
            <td class="text-right">
                <input class="form-control invoice-item-price" value="0.00" type="text">
            </td>
            <td class="text-right" style="padding-top:18px!important;">
                <span class="invoice-item-amount">0 </span>
                <span class="invoice-currency">₹</span>
            </td>
        </tr>
        <tr class="invoice-item-add-row">
            <td colspan="7">
                <a href="#" class="link invoice-item-add text-center">
                    <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
                    Add an Item
                </a>
            </td>
        </tr>
    </tbody>
</table>

For on-click event of a.invoice-item-add I append more table rows tr to the table, here is the code for that.

$('.invoice-item-add').on('click', function() {
    var itemRowClone = $('.invoice-item-row').last().clone();
    itemRowClone.find('input, textarea').val('');
    itemRowClone.find('.bootstrap-select').replaceWith(function() { return $('select', this); });
    itemRowClone.find('.selectpicker').selectpicker();
    $('.invoice-item-add-row').before(itemRowClone);
    return false;
});

This works perfectly fine, until I want to trigger select.invoice-item-select, here is how I trigger it.

$(document).on('change', '.invoice-item-select', function() {
    // Code here...
});

my problem is, this on-change gets fired multiple times based on the number of elements added dynamically, if there is one tr.invoice-item-row it gets fired twice, if there are two tr.invoice-item-row it gets fired four times, basically it fires times two.

I understand that the tr.invoice-item-row are added dynamically and we are using $(document).on('change', '.invoice-item-select', function()... to listen to the trigger.

How do I make sure this on-change event is fired only once?

Thanks.

1
  • That’s to be expected. Every time you add something to the DOM, the document is changing. Do you mean only once per row or once per event? Commented Mar 30, 2017 at 9:14

4 Answers 4

7

I ended up using this solution

$(document).on('change', '.invoice-item-select', function(e) {
    if (e.handled !== true) {
        e.handled = true;
        return;
    }
    // Code here
});

Although this does not stop from multiple firing of events, I can at-least stop the code execution for subsequent triggers.

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

Comments

6

$(document).on('change') event should called once on page load. No need to add document change on row add.

OR

You can first unbind event then bind again like

$(document).off('change','.invoice-item-select').on('change', '.invoice-item-select', function() {
    // Code here...
});

1 Comment

Tried this, it still gets fired multiple times.
5

Below code save my time. Your code should run inside the 'if' function and element's 'click' event. Then you can avoid the item duplication.

$(document).on('click', '.selectpicker', function(e) {
        if (e.handled !== true) 
        {
            e.handled = true;

            // Your code here

            return;
        }
    });

Comments

1

You can try in alternative way like this,

$('.invoice-item-select.bootstrap-select').on('changed.bs.select', function(){
// your code
});

bootstrap-select class should be applied after loading DOM into the browser.

I hope this will solve your problem.

2 Comments

can you create jsfiddle to workaround the issue you are facing and update the question ?
when you will create elements dynamically, bind selectpicker to it also

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.