I have a registration form where the user adds their postcode and by sending a GET request to an API, I receive and show the address in the fields below.
My problem is that I am currently using onchange: "getAddress(this.value)" in the form_tag itself however I would like to implement it using a jQuery event handler. This is how my code within the <script> tag at the bottom of the page looks like:
var getAddress = function(postcode) {
$.ajax({
url: '<%= get_address_url %>',
dataType: 'script',
type: "GET",
data: { postcode: postcode }
});
};
$(document).ready(function() {
dooo();
$(this).on("change", "input", dooo);
var p = $("input#jobseeker_postcode");
$(this).on("change", "input#jobseeker_postcode", getAddress(p.val()));
});
The doo() function is declared in my .js files and the event handler managing it works like a charm. However I don't manage to get the postcode thing(second event handler in the code) to run. What I have figured out is that the value of the field is not properly retreived, as no matter what I fill in, I get a failed response from the API => the value that I am passing is "".
FYI the doo() function implements a jQuery UI progress bar which loads based on how many fields are filled in.
You should set the change event handler to a function. Since you need to pass a parameter into the handler function, it should be defined within a closure.
This should work:
var getAddress = function(postcode) {
return function() {
$.ajax({
url: '<%= get_address_url %>',
dataType: 'script',
type: "GET",
data: { postcode: postcode }
});
};
};
Related
I have a jQuery script, in which I need to load data from a CSV from an external URL.
At the same time, I need to combine the data from the CSV with data provided by a frontend user through an input field. My expected result would be that I'd be able to call the jQuery code for fetching the value from the user's entry into the input field. However, while this works when the code is placed outside the ajax call, it does not work inside.
At the same time, I can't place the code for fetching the user's input outside the ajax call, as I need to be able to utilize information from the loaded CSV together with the user input to perform a dynamic calculation.
My code is as below:
HTML:
<input type="text" id="my_input" value="12" maxlength="2">
Javascript:
$.ajax({
url: csv_url,
async: false,
success: function (csvd) {
var csv = $.csv.toObjects(csvd);
// XYZ done with the CSV data to populate various fields
$("#my_input").keyup(function () {
console.log(this.value);
// this does not result in anything being logged
});
},
dataType: "text",
complete: function () {}
});
Of course it will not work. You are telling the compiler to add the keyup event listener to input after the ajax call is successful. Which means it will not work until ajax call is completed successfully.
You need to put the keyup event listener outside and inside the ajax call just get the value like below:
let myInputValue = "";
$("#my_input").keyup(function () {
console.log(this.value);
myInputValue = this.value;
});
$.ajax({
url: csv_url,
async: false,
success: function (csvd) {
var csv = $.csv.toObjects(csvd);
// XYZ done with the CSV data to populate various fields
//And later use the myInputValue here
},
dataType: "text",
complete: function () {}
});
You have not give us enough info. if you only need the current value in the ajax call you can do like below:
$.ajax({
url: csv_url,
async: false,
success: function (csvd) {
var csv = $.csv.toObjects(csvd);
// XYZ done with the CSV data to populate various fields
let myInputValue = $("#my_input").val();//And later use the myInputValue here
},
dataType: "text",
complete: function () {}
});
This question already has answers here:
How to stop form submit during ajax call
(7 answers)
Closed 2 years ago.
I am new to JQuery and ajax in general and I want to disable form submit after I get data from my controller back (I am using Asp.net core MVC). Thing is that even tho I cancel submit it submits anyways as shown bellow:
$("form").submit(function (e) {
var link = '#Url.Action("Action", "Controller")';
var args = {
arg1: Elem1.val(),
arg2: Elem2.val()
};
$.ajax({
type: "GET",
url: link,
data: args,
dataType: "json",
success: function (data) {
alert(data.canacess); //Shows False
if (data.canacess== true) {
AllEnable();
}
else { //Goes here
e.preventDefault(); //Dont do this
alert(data.erromessage); //Do this
}
},
error: function () {
alert("Error. Kontaktujte správce.");
return;
}
});
});
I think it has to do something with ajax because anywhere else in code it works.
Thanks for any help!
e.preventDefault() needs to be invoked within the scope of the submit function handler. Right now you're invoking it in the AJAX callback handler which is far too late to have any effect.
Is there any way that I can stop form from being submitted until I decide whether I submit it or not?
Yes. To do that you need to always call e.preventDefault() in order to stop the form submission so that you give the AJAX request time to execute and return a response. Then, based on that response, you can directly submit the HTMLFormElement object, note not the jQuery object, and send the form data to the specified action. Try this:
$("form").submit(function(e) {
e.preventDefault();
var form = this;
$.ajax({
type: "GET",
url: '#Url.Action("Action", "Controller")',
data: {
arg1: Elem1.val(),
arg2: Elem2.val()
},
dataType: "json",
success: function(data) {
if (data.canacess) {
AllEnable();
form.submit();
}
},
error: function() {
alert("Error. Kontaktujte správce.");
}
});
});
Also note that when using boolean values in conditions it's redundant to compare them to true/false. Similarly, the return in the error handler is redundant as it's the last statement in the function anyway.
I would like to validate a form with an AJAX request to the server and then swap the form html in the web browser with the form html from the server because this would be an easy implementation in theory. It is proving a nightmare though because the change event is triggered without the user interacting further after the first interaction which triggered the first change event. Consequently an infinite loop of AJAX requests to the server is happening.
The html form sits inside a div which has classes 'container mb-4'. This is the JS code -
var _cont = $('.container.mb-4')
var _form = $('.custom-form')
function ajax_validation(form) {
form.on('change', 'input, select, textarea', function() {
form_data = form.serialize()
$.ajax({
url: "/form/6/",
type: "POST",
data: form_data,
success: function(data) {
if(!(data['success'])) {
_cont.empty()
_cont.append(data['form_html'])
form = _cont.find('form')
ajax_validation(form)
}
},
error: function () {
form.find('.error-message').show()
}
});
})
}
ajax_validation(_form)
The change event I am assuming is triggered because the server returns a form input field with a different csrf token as the value to the previous input field - all other fields are the same. So an obvious solution would be to keep the same csrf token. But I want to understand why the JS code isn't working. I thought destroying the form would destroy the change event bound to it. So am at a loss to explain this infinite loop. How do I change this so I can just swap the form and not trigger another change event until the user really does change something?
It's not a good thing to use events in function no need to do that
Also your event here for input , select , textarea for serialize you need to select the closest() form
Try the next code
var _cont = $('.container.mb-4');
var _form = $('.custom-form');
_cont.on('change', 'form input,form select,form textarea', function() {
var ThisForm = $(this).closest('form');
var form_data = ThisForm.serialize();
$.ajax({
url: "/form/6/",
type: "POST",
data: form_data,
success: function(data) {
if(!(data['success'])) {
_cont.html(data['form_html']);
}
},
error: function () {
ThisForm.find('.error-message').show()
}
});
});
And logically if(!(data['success'])) { should be if(data['success']) {
First let's understand the issue that you have. You have a function called ajax_validation that is defining a change event on the form's elements which, on response will call ajax_validation. So, if any change happens on your elements, then a new request is sent to the server. So, if any value is changed, like a token, the request will be sent again. You could use a semaphore, like this:
var semaphore = true;
function ajax_validation(form) {
form.on('change', 'input, select, textarea', function() {
if (!semaphore) return;
semaphore = false;
form_data = form.serialize()
$.ajax({
url: "/form/6/",
type: "POST",
data: form_data,
success: function(data) {
if(!(data['success'])) {
_cont.empty()
_cont.append(data['form_html'])
form = _cont.find('form')
ajax_validation(form)
}
semaphore = true;
},
error: function () {
form.find('.error-message').show()
}
});
})
}
Something like this should solve your issue for the time being, but you should consider refactoring your code, because what you experience is well-known and is called callback hell.
Turns out the password field was coming back blank from the server - this django must do out of the box if the PasswordInput widget is used. So the form is replaced with a new form which lacks the password input from the before. The browser was then applying the autofill password value to the form which was triggering the change event.
This is my code now. It checks that the form_data about to be sent for validation really is different to before minus the csrf token which will be different.
It is based on Mohamed's answer -
var _cont = $('.container.mb-4');
var _form = $('.custom-form');
var prev_data = undefined
_cont.on('change', 'form input,form select,form textarea', function() {
var ThisForm = $(this).closest('form');
var form_data_wo_csrf = ThisForm.find("input, textarea, select").not("input[type='hidden']").serialize()
if(form_data_wo_csrf == prev_data) {
return
}
var form_data = ThisForm.serialize()
$.ajax({
url: "/form/6/",
type: "POST",
data: form_data,
success: function(data) {
if(!(data['success'])) {
_cont.html(data['form_html']);
prev_data = form_data_wo_csrf
}
},
error: function () {
ThisForm.find('.error-message').show()
}
});
});
I'v got a problem with jQuery Validation plugin.
When I defined custom submitHandler, it's stored after first validation run.
I'm using submitHandler to send the Object via AJAX request, but when the object is changed after event trigger, it wont change in submit handler function.
Is there any way to refresh submit handler after each event trigger?
My code
$('.request-telephone-form-submit').click(function(){
var thisForm = $(this).closest('form');
var postVars = new Object();
postVars.name = $('.request-name').val();
postVars.phone = $('.request-phone').val();
thisForm.closest('form').validate({
rules:
{
Name: {
required: true,
},
Telephone: {
required: true,
}
},
submitHandler: function(){
$.ajax({
type: 'POST',
url: '...',
data : postVars,
success : function(response) {
}
});
}
})
});
You've got a couple errors here.
Move your $.validate call out of the click handler, and just do it directly in a $(document).ready block:
$(document).ready(function(){
$('#formID').validate({
//options here
});
});
If your $('.request-telephone-form-submit') is a submit button in the form, it will automatically validate when the button is clicked. If the form validates according to your rules, then it will call the submitHandler function. At that time you can collect your post variables like so:
submitHandler: function(form){
var postVars = new Object();
postVars.name = $('.request-name').val();
postVars.phone = $('.request-phone').val();
$.ajax({
type: 'POST',
url: '...',
data : postVars,
success : function(response) {
}
});
}
Try to handle event on your form tag and use $('form.formClass').on('submit', function(){}) that is better jQuery way
I've got a simple form submission that upon success I've got an alert and a call to clear the form. I do get the alert, the info gets successfully added to the database, but the second call--for the form to clear, is not being carried out. I'm sure it's something simple I'm doing wrong, but I can't figure it out.
$('#contact_submit').click(function(e){
if ($("#submit_form_contact").valid()) {
var post_data = {
"name" : $('#name').val(),
"email" : $('#email').val(),
"inquiry" : $('#inquiry_dropdown option:selected').text(),
"message" : $('#message').val()
};
$.ajax({
type: "POST",
url: "process-contact.php",
data: post_data,
success: function(data) {
alert("Thank you for contacting us.");
$('#submit_form_contact').reset();
}
});
e.preventDefault();
}
Also, the submit button is just a button, not a submit input. Is it necessary to preventDefault()? I'm new at this.
jQuery doesn't have a .reset() method.
Do this instead:
$('#submit_form_contact')[0].reset();
This grabs the first DOM element, and invokes the native .reset(). If there's any chance the form won't be found, then test for the element.
var f = $('#submit_form_contact')[0];
if (f)
f.reset();
And of course you don't really need jQuery to get an element by ID, especially if you're not going to use any jQuery methods.
var f = document.getElementbyId('submit_form_contact');
if (f)
f.reset();
Another alternative would be to set the submit button as the context: of the ajax call, then use its form property.
$.ajax({
context: this,
type: "POST",
url: "process-contact.php",
data: post_data,
success: function(data) {
alert("Thank you for contacting us.");
this.form.reset();
}
});
this line can be used too
$("#submit_form_contact").trigger('reset');