I have the following setup:
A document can have multiple forms.
When the input on an input field changes, jQuery will fire an ajax event. And input.data("checking", true) is called.
When the ajax event has been finished, input.data("checking", false) is called.
Now I want to make a custom form submit that waits for all input in this form to be on input.data("checking") === true.
My code so far, without the question applied:
$(document).on("submit", "form", function(event) {
event.target.checkValidity();
event.preventDefault();
event.stopPropagation();
//TODO: prevent this when not everything is checked
var dataSerialized = $(this).serialize();
var service = $(this).attr("action");
$.ajax({
url: "services/" + service + ".php",
data: dataSerialized,
type: "POST",
cache: false,
success: function(html) {
if (html == "1") {
//TODO: load page from json callback
//loadPage(onsuccess);
}
else {
loadPage("error");
}
},
error: function(html, message) {
finalError(message);
}
});
});
How could I make this function wait (non-blocking!) until all ajax events are finished?
Suppose to create a function checkDone which returns true when input.data("checking") == false for all input in the form, you could do:
$(document).on("submit", "form", function(event) {
event.target.checkValidity();
event.preventDefault();
event.stopPropagation();
var that = $(this);
var interval = setInterval(function() {
if(checkDone(that)) {
clearInterval(interval);
var dataSerialized = that.serialize();
var service = that.attr("action");
$.ajax({
url: "services/" + service + ".php",
data: dataSerialized,
type: "POST",
cache: false,
success: function(html) {
if (html == "1") {
//TODO: load page from json callback
//loadPage(onsuccess);
}
else {
loadPage("error");
}
},
error: function(html, message) {
finalError(message);
}
});
}
}, 500);
});
In this way you check every 0.5 seconds if you can submit the form after all inputs are validated, and if so the interval is cleared and the form submitted.
However I would recommend not to remove standard server side validation on post submit.
Related
I just want one click to equal one submit in my jQuery code.
I've read quite a few posts on this same topic but I think mine is different. I do have a mouseleave and focusout event that I'm using to find errors in user input. Those functions feed down into the function that is submitting multiple times. The more times I hit mouseleave and focusout the more times my Ajax request is submitted. But I need mouseleave and focusout to continue to work and check the users input, that's why I'm not using one. Please see my code below, the function that I think is submitting multiple times is handleButtonClicksAfterError
function getCreditAmountToSend(modal){
console.log("getCreditAmountToSend");
var checkBox = $(modal).contents().find("#fresh-credit-checkbox");
checkBox.change(function(){
if($(checkBox).is(":checked")) {
var creditAmount = +(sessionStorage.getItem("creditAmount"));
sessionStorage.setItem('amountToSend', creditAmount);
}
});
var pendingCreditAmount = $(modal).contents().find("#pending_credit_amount");
pendingCreditAmount.on({
mouseleave: function(){
if(pendingCreditAmount.val() != ""){
adminForGetPendingCredit(modal);
}
},
focusout: function(){
if(pendingCreditAmount.val() != ""){
adminForGetPendingCredit(modal);
}
}
});
}
function adminForGetPendingCredit(modal){
console.log("adminForGetPendingCredit");
var checkBox = $(modal).contents().find("#fresh-credit-checkbox");
if(!$(checkBox).is(":checked")) {
var enteredAmount = +($(modal).contents().find("#pending_credit_amount").val());
var creditAmount = +(sessionStorage.getItem("creditAmount"));
sessionStorage.setItem('enteredAmount', enteredAmount);
doWeDisplayError(modal,creditAmount, enteredAmount);
}
}
function doWeDisplayError(modal,creditAmount, enteredAmount){
console.log("doWeDisplayError");
$(modal).contents().find("#fresh-credit-continue-shopping").prop("disabled", false);
$(modal).contents().find("#fresh-credit-checkout").prop("disabled", false);
if(creditAmount < enteredAmount){
$(modal).contents().find("#pending_credit_amount").val("");
$(modal).contents().find("#fresh-credit-continue-shopping").prop("disabled", true);
$(modal).contents().find("#fresh-credit-checkout").prop("disabled", true);
displayError();
}
else{
handleButtonClicksAfterError(modal, enteredAmount);
}
}
function handleButtonClicksAfterError(modal, enteredAmount){
// this is the problem!!!!!!!!!!!!!
console.log("handleButtonClicksAfterError");
sessionStorage.setItem('amountToSend', enteredAmount);
var continueButton = $(modal).contents().find("#fresh-credit-continue-shopping");
continueButton.click(function() {
modal.hide();
});
var checkoutButton = $(modal).contents().find("#fresh-credit-checkout");
checkoutButton.click(function() {
console.log("handleButtonClicksAfterError");
sendData();
});
}
function displayError(){
console.log("displayError");
$(function(){
$("#fresh-credit-iframe").contents().find("#pending_credit_amount").attr("placeholder", "Whoops, that was too much");
$("#fresh-credit-iframe").contents().find("#pending_credit_amount").attr({
class: "form-control form-control-red"
});
sessionStorage.removeItem('enteredAmount');
});
}
This is the function that actually POSTs the data
function sendData(){
var amountToSend = sessionStorage.getItem("amountToSend");
var products = $.parseJSON(sessionStorage.getItem("products"));
console.log("sendData");
console.log("This is the amount to send " + amountToSend);
$.ajax({
url: "/apps/proxy/return_draft_order",
data: {amountToSend, products},
type: "POST",
dataType: "json",
complete: function(data) {
window.location.href = data.responseText;
console.log("This is the URL from poll " + data.responseText );
return false;
},
});
}
It ended up being super simple.. I just needed the jQuery off method.. I attached it to the button before click and everything is peachy.. Looks like this:
checkoutButton.off().click(function(){});
off clears all the previous event handlers and then just proceeds with Click
Pretty cool, to read more check it out here
use async:false to prevent multiple request
$(document).off('click').on('click', function(){
$.ajax({
type:'POST',
url: ,
async:false,
cache: false,
data:{}
,
success: function(data){
},
error:function(data){
}
});
});
$("#destination1" + countVar).autocomplete({
minLength : 3,
source : function(request, response) {
var url = configOptions.icaocodeUrl;
var term = request.term;
url=url+term;
console.log(url);
$.ajax({
url : url,
type : "GET",
data : request,
dataType : "json",
success : function(data) {
response(data.slice(0, 10));
//alert(data);
},error: function(xhr, textStatus) {
alert('error');
}
});
},
change:function(event,ui){
console.log("fired in dest2");
},close:function(event,ui){
console.log("close in dest2"+'#dof1'+countVar);
console.log(countVar);
$(this).parents('form').find('#dof1'+countVar)
.filter(function () { return $(this).val() === ''; })
.first().focus();
}
});
above is my code for autocomplete and autotab(autofocus) to next field for dynamically created elements.autotab(autofocus ) is working fine for normal html but it is not working for dynamically created elements only.
Are you trying to focus() on a tab that is being dynamically added? If so, you might be triggering focus() to soon and the DOM element might not be there.
Try wrapping the focus function into a setTimeout() function to test it out.
setTimeout(function () {
$(this).parents('form').find('#dof1'+countVar)
.filter(function () { return $(this).val() === ''; })
.first().focus();
}, 2000); // 2 seconds
I have a form that is submitted via jquery for an instant image upload. When the image starts to upload via the form, i show a cancel upload button via jquery. Now is there a way using jquery, i can stop/cancel the form submission on the click property of the cancel upload button? What i do currently is that i delete the current upload from the databse using ajax and then refresh the page. this will not upload the image but i am trying to find something that will not let the page refresh.
$('.deleteimage').live("click", function () {
var ID = $(this).attr("id");
var IPString = $(".ipvaluetable").val();
var dataString = 'msg_id=' + IPString;
document.getElementById("preview").style.visibility = "hidden";
$(".preview").slideUp('slow', function () {
$(this).remove();
});
document.getElementById("deleteimage").style.visibility = "hidden";
$.ajax({
type: "POST",
url: "http://schoolspam.com/delete_image.php",
data: dataString,
cache: false,
success: function (html) {}
});
location.reload();
return false;
});
Well on cancel you can do event.preventDefault(); and then return false.
Example
$('.cancel').on('click', function(e){
e.preventDefault();
return false;
});
Please use below code and also see my comments :
$('.deleteimage').live("click", function (e) {
e.preventDefault();//Stops default behaviour
var ID = $(this).attr("id");
var IPString = $(".ipvaluetable").val();
var dataString = 'msg_id=' + IPString;
document.getElementById("preview").style.visibility = "hidden";
$(".preview").slideUp('slow', function () {
$(this).remove();
});
document.getElementById("deleteimage").style.visibility = "hidden";
$.ajax({
type: "POST",
url: "http://schoolspam.com/delete_image.php",
data: dataString,
cache: false,
success: function (html) {}
});
//location.reload();//This one needs to be removed so as to stop the reload
return false;
});
I have an application running with jquery-1.5.2.min.js. It works fine in IE9, 8, 7, FF and Chrome.
But there's this problem. I have a JavaScript function in a custom .js file using jQuery that rules the behaviour of a hidden field. Whenever a button is clicked, the hidden field is turned into a jQuery Autocomplete control, and loads the Autocomplete information through an Ajax call. The function is like this:
$.ajax({
type: "POST",
url: action,
dataType: "json",
data: "{type: '" + control + "', param:" + params + "}",
contentType: "application/json; charset=utf-8",
success: function (data) {
var dataTable = data;
$(selector).autocomplete({
minLength: 2,
source: dataTable,
open: function (e, ui) {
var options = $(this).data('autocomplete');
options.menu.element.find('a').each(function () {
var this_ = $(this);
var regex = new RegExp(options.term, "gi");
this_.html(this_.text().replace(regex, function (matched) {
return autocompleteTemplate.replace('%s', matched);
}));
});
},
focus: function (event, ui) {
$(selector).val(ui.item.label);
return false;
},
change: function (event, ui) {
if (!ui.item) {
var options = $(this).data('autocomplete');
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i"),
valid = false;
options.menu.element.find('a').each(function () {
if ($(this).text().match(matcher)) {
valid = true;
return false;
}
});
if (!valid) {
if (control == "ProjectType") {
$('#selector').val("...");
$('#selector').attr('disabled', 'disabled');
$('#another.selector').val("");
}
// Remueve los valores inválidos.
$(this).val("");
$(selector).val("");
$(selector).data("autocomplete").term = "";
return false;
}
}
if (control == "ProjectType") {
$('#selector').val("");
}
},
select: function (event, ui) {
$(selector).val(ui.item.label);
$(hidden).val(ui.item.value);
if (control == "ProjectType") {
Autocomplete("ProjectSubType", action, ui.item.value);
// This is a function that changes the CSS for another HTML control
ProjectSubType(false);
}
return false;
}
});
}
});
So, whenever I change the browser type from IE8 to IE7 or IE9, or from IE7 to IE8 or IE9, after activating this field, the following exception is thrown from jquery-1.5.2.min.js
Runtime error from Microsoft JScript: Cannot get value of property
'type': the object is null or undefined
FYI:
The AJAX calls work. The autocomplete works properly and fires the events it has to fire when completed, in the order they have to be fired.
There is another control that fires another AJAX event (filling a jqGrid) which produces no mistake.
The conditional clause that you see in the code, "if (control == "ProjectType")", is meant to allow another control to turn into an Autocomplete if this control being used has an Autocomplete option filled in. Otherwise, it is disabled, as you can see (I changed its name to '#selector'). This also works properly: if you fill in a value in that Autocomplete, the other control is filled with the options needed.
Thanks
UDP
The function that calls the AJAX function is the following:
function SetSearchMenu(url, local) {
$('#advancedSearch').hide();
$('#advSearch').click(function () {
if ($('#advancedSearch').css("display") == "none") {
$('#advancedSearch').show();
$('#generalSearch').val("...");
$('#generalSearch').attr('disabled', 'disabled');
ProjectSubType(true);
}
else {
$('#dAdvancedSearch').hide();
$('#General').val("");
$('#General').removeAttr('disabled');
}
if (alreadyOpen == false) {
Autocomplete("SelectorOne", url, null);
Autocomplete("ProjectType", url, null);
Autocomplete("Selector", url, local);
alreadyOpen = true;
}
});
}
The parameters url and local are sent from the $(document).ready() function, and are filled with an #Url.Action() in string format and another variable hardcoded to one.
When you click, "Add to Bag" on this page, it freezes IE6 every time. How can I figure out why it is freezing? Does anyone have a more direct answer?
totallytrollbeads {dot} com {slash} Safety0.html
function update() {
$.ajax({
dataType: 'json',
type: 'POST',
url: '/cgi-bin/ajax_cart_count.cgi',
timeout: 2000,
success: function (data) {
// If bag is empty, it's see through.
if (data.cart_count == 0) {
$(".shopping_bag").css("opacity", ".2");
}
// If bag is not empty, it's not see through.
else {
$(".shopping_bag").css("opacity", "1");
}
$("#bag_total").html(data.grand_total);
$("#bag_count").html(data.cart_count);
window.setTimeout(update, 15000);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
$("#bag_total").html('Timeout contacting server..');
window.setTimeout(update, 60000);
}
})
}
$(document).ready(update);
// preparethe form when the DOM is ready
$(document).ready(function () {
// bind form using ajaxForm
$('.add_to_cart_form').ajaxForm({
beforeSubmit: loading,
success: myBox
});
});
// preparethe form when the DOM is ready
$(document).ready(function () {
// bind form using ajaxForm
$('.add_to_cart_form').ajaxForm({
beforeSubmit: loading,
success: myBox
});
});
// $(".add_to_cart_form").click(function () {
// $('.bypass_add_to_cart_form').ajaxForm({ success: myBox });
// });
function loading() {
$("#loadingContent").show();
}
function myBox(resptext, statustext) {
$("#loadingContent").hide();
Boxy.ask(resptext, ["View Bag", "Continue Shopping"], function (val) {
if (val == "View Bag") {
document.location.href = "/cgi-bin/store.cgi?action=view_cart";
}
if (val == "Continue Shopping" && product_detail == 1) {
history.go(-1);
}
}, {
title: "Add to Bag"
});
$('.bypass_add_to_cart_form').ajaxForm({
beforeSubmit: loading,
success: myBox
});
update();
return false;
}
/*
This tells the ajax-style add to cart that
it's on a product detail page so if the
user clicks "Continue Shopping" it takes
them back on step in their history.
*/
$('.search_view').click(function () {
product_detail = 0;
});
$('.product_view').click(function () {
product_detail = 1;
});
It's not easy to debug a thing that freezes immediately from the outside. But it's always a good idea to cleanup the whole, remove things that are not essential, check the functionality and then do the next step.
For example this:
// preparethe form when the DOM is ready
$(document).ready(function () {
// bind form using ajaxForm
$('.add_to_cart_form').ajaxForm({
beforeSubmit: loading,
success: myBox
});
});
// preparethe form when the DOM is ready
$(document).ready(function () {
// bind form using ajaxForm
$('.add_to_cart_form').ajaxForm({
beforeSubmit: loading,
success: myBox
});
});
It's not hard to see that have this part twice there.
Put a little more accuracy into your application instead of copy&paste.