I have this code in my view.
After my database adding the message is showing perfectly but my Grid is not showing the updated result. If I keep
return true;
when I click Submit button I am getting popup window immediately and then adding to the database? This showing my updated result in the grid.
If you have return true at the end of your submit function, then the browser will go to the url in the action attribute of the form. I think you should always return false if you have taken care of the form data in the ajax call. You need to get the updated grid as part of the ajax success method.
You can't have the ajax popup and still let the form submit the normal way.
$(function () {
$('#form4').submit(function () {
...
$.ajax({
...
success: function (result) {
...
// update grid
grid_container = $("#grid").html('');
$("<table>").appendTo(grid_container);
for (ii = 0; ii < result.grid.length; ++ii) {
tr = $("<tr>").appendTo(table);
for (jj=0; jj < result.grid[ii].length; ++ii) {
td = $("<td>").text(result.grid[ii][jj]).appendTo(tr);
}
}
// show success message
alert('Saved NewServiceTypeCategory Successfully. Thank you!');
}
});
return false;
});
});
Now all you have to do is make your server side post handler return the XML with the grid data.
The AJAX request is asynchronous, so it finishes the form submit routine before the callback finishes, which might explain the result you are getting. I think there may be an async setting you can turn off so that the operation/callback must complete first.
Basing on your code and as far as i'm aware of, you have no way on loading the new data.
The reason why when you return true; the new data is being loaded is because the submit event successfully perform it's default operation which is submitting to the server and refreshing the page.
On the other hand, return false; prevents this operation (including the refresh page) and instead just run the XHR.
What you could do is:
Return the new data as a result of the
XHR and parse it accordingly.
Related
In my javascript code when someone change option and click on Go. it's change property for multiple items. I see the save button and edit button for every item.
so I manually clicked the button after change the select and on the click of Go.
for (var i = 0; i < checked.length; i++) {
var cur = checked[i];
$(cur).parents('tr').find('.transaction-category-wrapper .select2').val(catId);
$(cur).parents('tr').find('.transaction-verify-wrapper .btn-save').click();
}
Now problem is I want to refresh the page, but after making sure that response has been come to the page. How I can achieve it.
I am thinking to implement the setTimeout but it wouldn't be good option in case of server doesn't has executed and timeout just refresh the page.
Is jQuery have some property which let me know that javascript request has been complete and response has been received.
$(document).on('click', '.btn-save', function () {
// val logic
$.post("/Entries/AddEntries", val, function (r) {
enableTooltip();
});
});
Since every click generates a post request. You need to keep track of all those requests in an array and then wait for them to resolve. So, your code should look like:
var requests = [];
$(document).on('click', '.btn-save', function () {
// val logic
requests.push($.post("/Entries/AddEntries"));
});
Promise.all(requests).then((data) => {do something});
You can use .then to handle success and failure cases of your AJAX requests:
$.post("your_url", { ... })
.then(function() {
// If succeeded
}, function() {
// If failed
});
.post returns a jQuery deferred object, which can be responded with a .then() handler. The first argument of .then is considered as a success handler, and the second one is a failure handler.
In case of multiple AJAX calls, you can use $.when to take action when all the AJAX calls are done.
$.when($.post( ... ), $.post( ... ))
.then(function() {
// If all AJAX calls succeed
}, function() {
// If any of the call fails
});
When I press the Form Submit button, I want to action some validation (via an Ajax call), and change a screen value, before the Form is actually submitted.
My issue is that when I try this, and I manually action the Submit button, the screen value is not actually updated until the Form has been submitted. Too late!
Is there any way around this issue? I've tried to comment in the code exactly what I mean.
$("form").submit(function (event) {
// we prevent teh default action of the udpate button
event.preventDefault();
alert('In Jquery/JS.. button pressed / Prevented default');
// variables for "self" so we can access the form
// nativley using javascript and not jquery
var self = this,
root = 'https://jsonplaceholder.typicode.com';
// Now call Ajax, get results, and if good, manually call the
// submit button.
$.ajax({
url: root + '/posts/1',
method: 'GET',
success: function (data) {
alert('in ajax success');
}
}).done(function (data) {
alert('in ajax done - Title data = : ' + data.title);
if (data.title !== "") {
// We assign our Input Text field some data
$('#textfield').val(data.title);
// The on screen value actually hasn't updated :o(
alert('about to self submit');
// We go to submit... but our form isn't actually
// updated with the Ajax text yet...
// is that possible before we action the submit???
self.submit();
}
}).fail(function () {
alert('error');
});
});
See JSFiddle : https://jsfiddle.net/dave_pace/890zmj1f/
It is not what you think. JavaScript is single-threaded. Therefore, an alert statement is executed just after its previous statement. It doesn't wait for the previous statement to finish.
Adding to that, alert is quicker than setting the value in the textbox, and it actually blocks the thread until it is dismissed. That's why you cannot see the value set in the textbox, but can see the submit alert first.
Your fiddle is fine, and works as it should. If you want to test this, try to remove all the alert statements from your code, and try to submit your form to an actual URL, for example https://www.google.com.
Though submitting to Google will result in an error, you can actually see that the textbox is being populated before the submit happens.
I have a function that queries a database for info, when a button is clicked. This info gets written to innerHTML of a label. When this function returns, I read the innerHTML of this label. Problem is, it always returns the old value, not the new value that was pulled from the database. The label on the scree is displaying the correct value, though. When I click the button again, the value that I was expecting on the previous click, is now given. Seems like a timing issue but can't seem to figure it out.
example:
SQL Data - cost = 10
I expect to see 10 alerted to me when I click the button. I get a blank alerted to me, even though 10 is now in the label. When I click the button again, 10 is alerted, but 20 is now in the label.
function getInfo() {
var ctlMonthly = document.getElementById("cellMonthlyCost")
getSQLData(ctlMonthly);
alert(ctlMonthly.innerHTML);
}
function getSQLData(ctlCell){
...
var my_ctlCell = document.getElementById(ctlCell);
$.each(objData.items, function() {
my_ctlCell.innerHTML = this.Param1
});
...
}
Thanks.
you need to add the alert after the data is received from the database. I am assuming that you're sending an ajax request to fetch data. You will be able to get the new value in the callback of you're ajax request function.
Currently what is happening in your code is that
1. getSQLData(ctlMonthly);
// This sends a request to the data base to fetch data
2. alert(ctlMonthly.innerHTML);
// This shows the current value in an alert
3. data is received and shown in the label
This process happens so fast that you don't notice the difference between step 2 and 3.
Is this what you want?
I used a callback function
function getInfo() {
var ctlMonthly = document.getElementById("cellMonthlyCost")
getSQLData(ctlMonthly,alertInfo);
}
function alertInfo(info){
alert(info);
}
function getSQLDate(ctlCell,callbackFn){
...
var my_ctlCell = document.getElementById(ctlCell);
$.each(objData.items, function() {
my_ctlCell.innerHTML = this.Param1;
callbackFn(this.Param1);
});
...
}
to piggyback on Himanshu's answer, your request to your server is async. Meaning javascript will execute the GET request and continue on with the script, when the requests comes back from the server it will run whatever callback you give it. ( i.e. update label tag )
assuming getSQLData is a ajax call or something promised based, something like:
function getSQLData(ctlCell){
return $.get('/sql/data').done(function () {
var my_ctlCell = document.getElementById(ctlCell);
$.each(objData.items, function() {
my_ctlCell.innerHTML = this.Param1
});
});
}
you can change your code to:
function getInfo() {
var ctlMonthly = document.getElementById("cellMonthlyCost")
getSQLData(ctlMonthly)
.done(function () {
alert(ctlMonthly.innerHTML);
});
}
Basically the difference is your telling javascript to alert the innerHTML after the requests comes back from the server.
The more correct answer would be to alert the data straight from the response instead of reading from the DOM.
I use a jQuery.get() request to send a form data. But often the page reloads/redirects too fast, before my JavaScript/jQuery code catches and sends the form data to where i need. I use alert() to get the ajax request done while the user clicks ok on alert. Now i need the form working as usual (with PHP post and redirect) and to send the form data using jQuery or JavaScript BEFORE the page reloads and NO alerts. Is there any elegant way to make the page wait until jQuery is done with the request (without using alert)?
jQuery('#form').live('submit', function() {
var inputValue = jQuery(this).find('#theInput').val();
jQuery.get('http://someurl.com/order?var=' + inputValue);
//alert('an unwanted alert');
});
UPD: I embed jQuery code through Google Tag Manager's iframe. So I can't change the way the form works. And I shouldn't prevent the form from submitting.
jQuery('#form').live('submit', function(e){
e.preventDefault(); // prevent default behaviour
var inputValue = jQuery(this).find( '#theInput' ).val();
jQuery.get('http://someurl.com/order?var=' + inputValue, function(){
// redirect
});
//alert('an unwanted alert');
});
I would take a look at [done][http://api.jquery.com/deferred.done/] which could probably do what you want it to do. .done() will wait for the entire ajax to finish, and then run whatever function you call within done.
You can bind callback to do redirect and return false; to prevent default redirect shown as below:
jQuery('#form').on('submit', function() {
var inputValue = jQuery(this).find( '#theInput' ).val();
jQuery.get('http://someurl.com/order?var=' + inputValue,
function(data){
//write redirect code here. In case if you want to check response, you can get it in data variable.
});
return false; //prevent default redirect action
});
When the city input field is blurred I get somnething via an ajax request and set that as the value of a hidden field in the same form that the city field resides in.
$('input#city').on('blur', function() {
$.ajax({
url: 'get/something?param=val',
success: function(response) {
$('input:hidden[name="something"]').val(response);
}
});
});
If the user submits the form immediately after blurring off the city field sometimes due to latency the hidden field is not populated because the SQL on the other end is taking too long.
The form that both these fields are in is also submitted via ajax:
$('form#find-users').on('submit', function() {
if(NO_AJAX_CURRENTLY_RUNNING_ON_PAGE) {
// do stuff
}
});
How to detect if no ajax is running on the page? This will ensure that the city ajax was completed and the hidden field populated before the form is processed.
EDIT
Actually it won't, it will only prevent the form from being submitted. But if I can detect that then I can use a setInterval and keep trying to run that code until it runs because ajax is complete. Ideally there will be something in jQuery that waits until other ajax is complete and then submits.
Use jQuery's Ajax Events. As long as all of your Ajax calls are generated using jQuery, you have a way of knowing if any Ajax calls are outstanding.
$(document).ready(function() {
var ajaxBusy = false;
$(document).ajaxStart( function() {
ajaxBusy = true;
}).ajaxStop( function() {
ajaxBusy = false;
});
});
Edit:
So that answers your direct question about "How do I know if there is any Ajax call running."
Alternatively, you could disable the form's submit buttons when run your blur handler, and then re-enable it when you're done.
$('input#city').on('blur', function() {
var submit = $(this).closest('form').find(':submit:enabled');
submit.prop('disabled', true);
$.ajax('get/something?param=val').done(function(response) {
$('input:hidden[name="something"]').val(response);
}).always(function() {
submit.prop('disabled', false);
});
});
Edit 2:
So now we're at the point where we would like to delay the form submission until all current Ajax calls have completed. We let people click on the submit button, but if there are pending Ajax calls we don't do anything right away.
We can use a Deferred object to help us with this.
$(document).ready(function() {
var ajaxDefer = $.Deferred().resolve();
$(document).ajaxStart( function() {
ajaxDefer = $.Deferred();
}).ajaxStop( function() {
ajaxDefer.resolve();
});
$('form#find-users').on('submit', function() {
ajaxDefer.always(function() {
// Code here will always be executed as soon as there are no
// Ajax calls running.
// this points to the deferred object (ajaxDefer), so use the closure
// to carry over any variables you need.
});
});
});
When we're just starting out, we set up our ajaxDefer object in a resolved state. That means any functions attached using .always() will execute immediately.
When the first Ajax call starts, we replace the old ajaxDefer object with a new one that has not been resolved. Any new functions attached using ajaxDefer.always() will be deferred until later.
When the last Ajax call completes, we call ajaxDefer.resolve(), which causes any unexecuted deferred functions to execute. Now we're back to our initial state, where any newly-attached functions will execute immediately.
When somebody tries to submit the form, create an anonymous function that does the work and attach it to ajaxDefer. It will get executed when appropriate, depending on if there are any outstanding Ajax requests or not. Be mindful of your closures.
Use this to check if AJAX calls are currently in-progress using JQuery:
if ($.active == 0) {
...
}
you can put a variable in the global namespace, perhaps named ajaxLock and toggle it on when AJAX starts and off when the response comes. Then check it before allowing submit.
something like
var ajaxLock = 1;
$('input#city').on('blur', function() {
$.ajax({
url: 'get/something?param=val',
success: function(response) {
$('input:hidden[name="something"]').val(response);
ajaxLock = 0;
}
});
});
Use a lock variable like you suggested:
$('input#city').on('blur', function() {
window.AJAX_CURRENTLY_RUNNING_ON_PAGE = true;
$.ajax({
url: 'get/something?param=val',
success: function(response) {
$('input:hidden[name="something"]').val(response);
},
complete: function() { window.AJAX_CURRENTLY_RUNNING_ON_PAGE = false; }
});
});
$('form#find-users').on('submit', function() {
if(window.AJAX_CURRENTLY_RUNNING_ON_PAGE) {
return;
}
//dostuff
});
What i could have done on this circumstances is to use plugin like block ui or disable the form submit button,the reason is you need to be interactive in your design,you may well able to lock the form submission,but its better to give a message or have a modal gray out