Background:
I want to submit my HTML form asynchronously using jQuery, except if the ajax call fails. If the ajax call fails, I want to re-submit my HTML form normally.
I cannot get the "submit normally on fail" to work. What happens is if the submit button is pressed again after a fail, it submits normally, but I want the form to be resubmitted automatically on fail.
I am using namespaces because I need the generic .on('submit', ...) to always populate the hidden field.
Question:
How do I need to redesign my code so that I can achieve the functionality I desire?
Code:
$('#form).on('submit', function(event){
$(this).find('#hidden_field').val('value');
});
$('#form').on('submit.as_ajax', function(event){
event.preventDefault();
var $this = $(this);
var post = $.post({
data: $this.serialize(),
url: $this.attr('action')
});
post.done(function(response, status, xhr){
$('#container').html(response);
});
post.fail(function(xhr, status, error){
$this.off('submit.as_ajax').submit();
});
});
I think this will work for you
function submitFormNormally($this) {
$this.submit();
}
function submitFormAsAjax($this) {
var post = $.post({
data: $this.serialize(),
url: $this.attr('action')
});
post.done(function(response, status, xhr){
$('#container').html(response);
});
post.fail(function(xhr, status, error){
submitFormNormally($this);
});
}
$('#submit-button').on('click', function(event){
event.preventDefault();
var $this = $('#form');
submitFormAsAjax($this);
});
Now, what you have to do is bind the submit button like this.
Related
I have a page that uses ajax to render partial views for two forms (student, teacher). When I switch between the two forms (with nav links) and they are fetched and rendered with Ajax I loose my validation. So I tried adding some "reparsing" method to my code that gets called after I fetch the partial view. (links to SO threads SO link So link) This I think works because if I try and submit I see my validation errors showing, but now my Jquery submit events don't fire.
I have 3 events that submit the 2 different forms. Note - I'm loading the student partial view first so I need to have 2 events to catch this submission shown below.
$("#studentSubmit").submit(function(event) {
event.preventDefault();
submitStudentForm();
});
$(document).on('submit', '#studentSubmit', function(event) {
event.preventDefault();
submitStudentForm();
});
$(document).on('submit', '#teacherSubmit', function(event) {
event.preventDefault();
submitTeacherForm();
});
Here are the two calls to fetch the partial views and the method that reparses the form. When I add reparseForm() my 'studentSubmit' and 'teacherSubmit' submit events stop working.
$('#studentProfileLink').on('click', function(event) {
//load student profile
var options = {
url: '/Profile/LoadStudentProfile',
type: "post",
data: {}
};
$.ajax(options).done(function(data) {
$("#profileSection").html(data);
reparseform();
}).fail(function(jqXHR, textStatus) {
$('#errorHomePage').show().fadeOut(8000).text('Error Calling Server -' + textStatus);
});
});
$('#teacherProfileLink').on('click', function() {
//load teacher profile
var options = {
url: '/Profile/LoadTeacherProfile',
type: "post",
data: {}
};
$.ajax(options).done(function(data) {
$("#profileSection").html(data);
//reparseTeacherForm();
reparseform();
}).fail(function(jqXHR, textStatus) {
$('#errorHomePage').show().fadeOut(8000).text('Error Calling Server -' + textStatus);
});
});
var reparseform = function() {
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");
};
It looks like by putting some of the submit events inside my ajax call, they now fire when I hit submit.
Here is what I did. I moved them from the $(document).ready(function () {}
to inside the ajax return call like this. Can anyone explain why they won't work if they are in $(document).ready?
$('#teacherProfileLink').on('click', function() {
//load teacher profile
var options = {
url: '/Profile/LoadTeacherProfile',
type: "post",
data: {}
};
$.ajax(options).done(function(data) {
$("#profileSection").html(data);
reparseform();
$("#teacherSubmit").submit(function(event) {
event.preventDefault();
submitTeacherForm();
});
$(document).on('submit', '#teacherSubmit', function(event) {
event.preventDefault();
submitTeacherForm();
});
}).fail(function(jqXHR, textStatus) {
$('#errorHomePage').show().fadeOut(8000).text('Error Calling Server -' + textStatus);
});
I had this JavaScript running on a testing host page(http://www.000webhost.com/), then I moved the form/site to another hosting page(https://www.one.com/). Suddenly the form is posted twice! I have been trying to add the following line e.stopPropagation(); to the code, right after e.preventDefault();, then noting is posted. If I only use e.stopPropagation(); - nothing is posted either.
$(document).ready(function() {
$('form').on('success.form.bv', function(e) {
var thisForm = $(this);
//Prevent the default form action
e.preventDefault();
//Hide the form
$(this).fadeOut(function() {
//Display the "loading" message
$(".loading").fadeIn(function() {
//Post the form to the send script
$.ajax({
type: 'POST',
url: thisForm.attr("action"),
data: thisForm.serialize(),
//Wait for a successful response
success: function(data) {
//Hide the "loading" message
$(".loading").fadeOut(function() {
//Display the "success" message
$(".success").text(data).fadeIn();
});
}
});
});
});
});
});
I am using 'success.form.bv', because I am using bootstrapvalidator in order to validate the form. I have not been able to combine the "Form is submitted twice" example code on the bootstrapvalidator with my code in order to only submit the form once.
What should I do in order to submit the form only once?
So I have this chat,
http://codepen.io/anon/pen/Frmez
$(function() {
$('.textarea-chat').on('keyup', function(e) {
if (e.which == 13 && ! e.shiftKey) {
$(this.form).submit()
return false;
}
});
});
Updated code ^
But one problem with it is that if you input a text to send away to the chat and press enter, the chat window closes, it should stay open but I can't figure out how
$(this.form).submit()
This actually submits the <form>. You're probably getting the error "Please use POST request" because by default it uses GET. It doesn't like being sent a query string, so it gives that error. You can POST stuff to it, but nothing will happen.
In order to POST stuff to it, you need to use Ajax. See docs.
For example:
$("#myForm").submit(function () {
var url = "path/to/your/script.php"; //handle form input by your script
$.ajax({
type: "POST",
url: url,
data: $("#myForm").serialize(), //serializes the forms elements
success: function (data) {
alert(data); //show response
}
});
return false; //avoid executing actual submit of the form
});
I created a form on /contact-us and having action="/contact-us". Now, when I added Ajax to it, it is sending the request three times, i cannot find the reason.
Ajax:
define(['jquery', 'foundation.alert'], function($) {
return {
init: function() {
$("#success-alert").hide();
$("#error-alert").hide();
$('button').click(function(e){
$('input').map(function() {
if(!$(this).val()) {
$("#error-alert").show();
$("#success-alert").hide();
return false;
} else {
$('document').ready(function() {
var form = $('#contact_us'); // contact form
var submit = $('button'); // submit button
var status = $('#form-status'); // alert div for show alert message
// form submit event
form.on('submit', function(e) {
e.preventDefault(); // prevent default form submit
$.ajax({
url: '/contact-us', // form action url
type: 'POST', // form submit method get/post
dataType: 'html', // request type html/json/xml
data: form.serialize(), // serialize form data
beforeSend: function() {
submit.html('Sending....'); // change submit button text
},
success: function(data) {
form.trigger('reset'); // reset form
$("#success-alert").show();
$("#error-alert").hide();
submit.html('Send'); // reset submit button text
},
error: function(e) {
console.log(e);
}
});
});
});
}
});
});
}
}
});
You are looping through all the inputs and applying on submit for every input in your form. So if it is submitting 3 times, you must have three inputs. Each time you click the button, you will be adding even more submit handlers! The whole design of this is wrong.
You should not be attaching the submit handler inside of the click event, it should be outside and have it done one time. Do your validation inside of the submit handler to make sure that it is valid before making the Ajax call.
try this solution.
var wait = false;
wait variable for global scope
if (!wait) {
wait = true;
$.ajax({
url: '/contact-us', // form action url
type: 'POST', // form submit method get/post
dataType: 'html', // request type html/json/xml
data: form.serialize(), // serialize form data
beforeSend: function () {
submit.html('Sending....'); // change submit button text
},
success: function (data) {
wait = false;
form.trigger('reset'); // reset form
$("#success-alert").show();
$("#error-alert").hide();
submit.html('Send'); // reset submit button text
},
error: function (e) {
console.log(e)
}
});
}
After going through my code i realized what mistakes i have been doing and also realized that reading code is more important than writing it.
This is how i rewrite the code and its working fine but i am still not sure if it is the best approach.
define(['jquery', 'foundation.alert'], function($) {
return {
init: function() {
$("#success-alert").hide();
$("#error-alert").hide();
$(function () {
$('#contact_us').on('submit', function (e) {
$.ajax({
type: 'post',
url: '/contact-us',
data: $('#contact_us').serialize(),
success: function () {
$("#success-alert").show();
$("#error-alert").hide();
}
});
e.preventDefault();
});
});
$('button').click(function(e){
$('input').map(function() {
if(!$(this).val()) {
$("#error-alert").show();
$("#success-alert").hide();
return false;
}
});
});
}
}
});
Note: Never take writing code as a burden.
I am trying to update the database and send the users browser to a different page with one click.
The Html looks like this:
<a id='updateLiveProgress' style='width:118px;' href='~link~'>Click here</a>
The Javascript looks like this:
$("#updateLiveProgress").live("click", function(e){
var ajaxlink = "~ajaxlink~"
$.post(ajaxlink, function(data, e){
return true;
});
});
When the user clicks the link, it's supposed to update the database through the ajax link and then the page that is returned will be dependent on the ajax database updates. The problem is that it seems that the page loads before the ajax finishes updating the database. I'm trying to pass the click event throught to the ajax using e to prevent the link from executing until after the ajax call finishes, but it doesn't seem to be working.
Is there a better way for me to accomplsh this?
Try doing this:
$("#updateLiveProgress").live("click", function(e){
e.preventDefault();
var href = this.href;
var ajaxlink = "~ajaxlink~"
$.post(ajaxlink, function(data, e){
window.location = href;
});
return false;
});
As of jQuery 1.7 do this (using .on instead of .live):
$("#updateLiveProgress").on("click", function(e){
e.preventDefault();
var href = this.href;
var ajaxlink = "~ajaxlink~"
$.post(ajaxlink, function(data, e){
window.location = href;
});
return false;
});
This is the inherent behavior of Ajax, in fact its what the A stands for: asynchronous. The ajax call is fired, and the click function returns before the ajax request has come back. You have 2 options:
Make the ajax call synchronous. I would not recommend this.
Manually follow the link when the ajax call returns:
$("#updateLiveProgress").live("click", function(e){
var ajaxlink = "~ajaxlink~"
$.post(ajaxlink, function(data, e){
window.location.href = ajaxlink; // or something similar
});
return false; // this keeps the link from being followed
});
Depending on how you have your AJAX configured your most likely going to use a callback. In this case, the callback is the where the success function is specified. Here's some example code:
//assuming button is an anchor link
$('#button').click(function(){
//do ajax request
$.ajax{
url: 'http://someurl.com/getuser?id=69',
success: function(data, status){
//assuming page to load is in data, redirect
window.location = "http://mysite.com/newuser.aspx";
}
}
//import to stop the anchor link request
return false;
});
2 ways to do this
First
$("#updateLiveProgress").live("click", function(e){
var ajaxlink = "~ajaxlink~"
$.post(ajaxlink, function(data, e){
return true;
});
return false;
});
Second
$.ajax({
type: 'POST',
url: "~ajaxlink~",
data: data,
async: false
});