How to wait for processing before new ajax load
How to wait for processing before new ajax load
Question:
How do I wait for editor to finish it's business before overwriting it's content with an ajax call?
It does seem to wait with a regular reload. For example a refresh of entire page, or clicking a completely different url leaving the page. But I don't know how to get that result when I'm updating a div with an ajax call.
I'm using a partial page with a datatable and editor that I load dynamicly with a $.ajax call based on a user's selection.
The problem arrises when I have an inline form input open and then make a different selection that starts loading the new page into the div element. It tries to submit (and triggering any preceeding events) after the new partial page is loaded.
It works fine when I reload the entire page when the form input is open (and the value has changed), it will then execute the submit before it starts loading.
Current result: After the new partial page (with new datatable and editor) is loaded into the div the initial editor triggers all events that happen onBlur. The initial datatable and data don't exist anymore, so any logic raises errors and I'm unable to correctly submit the changed data.
Desired result: Finish editor event chain before loading new page into div.
I tried making a testcase, but I couldn't figure out (maybe not possible at all) how to use the editor urls used in the examples in a testcase. I will post a simplified use case below.
Steps to reproduce in use case:
- Select a department
- Open inline form input for salary
- Change salary
- Select different department while inline form input is still open
Simplified use case:
A page with a selectlist (id="departmentselect") that triggers function update() on change. An empty div (id="overview") that will hold the partial page loaded with ajax.
update function like this:
function update() {
var dept = $('#departmentselect').val();
$.ajax({
url: '<get partial page based on dept>',
cache: false,
async: false,
type: 'GET',
datatype: 'json',
data: { dept : dept },
success: function (data) {
$('#overview').html(data);
},
error: function (jqXHR, textStatus, errorThrown) {
alert(errorThrown);
}
});
}
Partial page loaded with above ajax function:
<table id="overviewtable" class="table">
<thead>
<tr>
<th>Name</th>
<th>Salary</th>
</tr>
</thead>
</table>
<script type="text/javascript">
//Constants
var TABLENAME = '#overviewtable';
$(document).ready(function () {
var editor = new $.fn.dataTable.Editor({
ajax: {
url: '<CRUd-url>',
},
table: TABLENAME,
idSrc: 'empid',
fields: [
{
label: 'Salary',
name: 'Salary',
},
]
});
editor.on('preSubmit', function( e, submitdata, action ){
//Some logic here comparing against other rows
$(TABLENAME).DataTable().rows().every(function (rowIdx, tableLoop, rowLoop)
{
//Errors in use case
console.log(this.data());
});
return true;
});
$(TABLENAME).on('click', 'tbody td.editable', function () {
editor.inline(this, {
onBlur: 'submit',
submit: 'allIfChanged'
});
});
$(TABLENAME).DataTable({
ajax: {
url: '<CRUD-url>',
type: 'POST',
data: {
action: 'read',
},
},
dom: 'tB',
buttons: [
{ extend: 'create', editor: editor },
],
retrieve: true,
stateSave: false,
pageLength: -1, //All
initComplete: null,
rowId: 'empid',
order: [[0, "asc"]],
columns: [
{
data: 'Name',
},
{
data: 'Salary',
className: 'editable',
},
],
});
});
</script>
This question has an accepted answers - jump to answer
Answers
I've changed my update function to check if editor and required properties exist and destroying them before loading the new content.
At least this doesn't give errors, but it does discard the changes. Ideally I would like to process the changed data before loading the new content.
What I think you could do is use the
display()
method to determine if the Editor form is displayed or not in yourupdate()
function. If it is, then add an event listener forsubmitComplete
and in that handler callupdate()
again (by which time the form will have finished processing).You want to avoid using the properties in the
s
object of Editor - it is considered to be private and is not documented. The properties can, will and do change between versions.Allan
Thank you for your suggestion.
There's still a bit of a problem with this solution. It is logic that has to be repeated for every page that loads the partial page, and it gets a little complex when there's fielderrors to be handled and submitSuccess doesn't trigger.
The suggestion about not using the s object makes sense.
I've updated the code and now have it placed on the partial page, so I don't have to repeat it and got rid of the s object.
It now submits the data and ignores the outcome. So if it had field errors it will never submit to server, and if it didn't it will submit to server.
Snippet:
This feels like a dirty solution, but it works for my use case. Any suggestions about my approach are welcome.
Yeah, its a little bit messy using global variables like that - but I'm not sure that there is really a better way. DataTables has a
$.fn.dataTable.isDataTable()
static method which could be used instead of the global DataTable variable, but there isn't any such method for Editor.Allan