sohal07 sohal07 - 2 months ago 17
Javascript Question

jQuery avoid on change to be triggered when done programatically

I have a basic invoicing system, where we can select an item (jquery select 2), which on change fills in the base price, units per ctn etc in the form. We can change this price before saving the invoice.

if I need to edit this (saved) invoice (in the same page and form), I'd get the id with PHP GET and then fetch the invoice saved in mysql with ajax, to get the item and its qty, price etc details to be filled in the form.

Now the problem is, (after ajax) when I programatically select the item in select box (jquery select 2), it triggers the on change function (as stated earlier) and gets the base price etc in the form, instead of the one I want to fill programatically to see and then change it.

//Fetch Items
fetchItems()

function fetchItems() {
$.ajax({
url: 'https://api.myjson.com/bins/4z7se',
dataType: "json",
success: function(items) {
// Create list of items in select tag
var toAppend = '';
$.each(items, function(i, o) {
toAppend += '<option value="' + o.itemId + '">' + o.newName + '</option>';
});

$('#item').append(toAppend);
$('#item').select2({
placeholder: "Select an item",
escapeMarkup: function(markup) {
return markup;
}
})
},
error: function(xhr, ajaxOptions, thrownError) {
alert("ERROR:" + xhr.responseText + " - " + thrownError);
}
});
}



// On item select, get item details and fill in the table
// --->>> Select first item for this demo to get the details filled (usually it requests the values from mysql for the selected item)
$('#item').on('change', function() {
$.ajax({
url: 'https://api.myjson.com/bins/vjfi',
dataType: "json",
success: function(data) {
// Print item details in respective elements
$('#itemId').val(data[0]['itemId'])
$('#size').text(data[0]['size'])
$('#units_per_ctn').text(data[0]['units_per_ctn'])
$('#ctn_price').val(data[0]['ctn_price'])
$('#qty').val('') // Clear qty from previous
$('#total_price').text('') // Clear total price from previous
},
error: function(xhr, ajaxOptions, thrownError) {
alert("ERROR:" + xhr.responseText + " - " + thrownError);
}
});
})


// For update purpose, details to be filled in the form
$('#edit').click(function() {
//var editId = '<?PHP if(isset($_GET['edit '])) { echo $_GET['edit'];}?>';
var editId = 1 // Lets assume it for this demo
if (editId > 0) {
// Get transfer details for this id
$.ajax({
url: 'https://api.myjson.com/bins/1iwha',
dataType: 'json',
success: function(data) {
$('table #item').select2().val(data[0]['item_id']).trigger('change')

// Here is the proble, can't put these values in the input because as soon as select2 change is triggered it fills its own values to the inputs. But I want the following values (returned from mysql in json) to be filled in.
$('table #ctn_price').val(data[0]['ctn_price'])
$('table #qty').val(data[0]['qty'])
$('table #totap_price').val(data[0]['total_price'])
},
error: function(xhr, ajaxOptions, thrownError) {
alert("ERROR:" + xhr.responseText + " - " + thrownError);
}
})
}
})



Here is the Fiddle

Answer

You can use triggerHandler and return the $.ajax object in your event listener. Then you can chain .done() and do your work after ajax request has finished.

// return ajax object
$('#item').on('change', function() {
    return $.ajax({
        /* ... */
    });
});

// chain actions
$('#item').select2().val(val).triggerHandler('change').done(function() {
    // set your values
});

Working example.