How can I run onclick event from the assigned variable? - javascript

I've got a different scenario of a submit button - submit the info if the response is correct, and throw an error if the response is incorrect.
First, I store the submit button onclick event in a variable and make it null, so it will not submit the info if the response is incorrect.
Here is my code:
(function() {
var submitBtn = jQuery('#submitConfigBtn')[0]
var submitBtnOnclick = submitBtn.onclick
submitBtn.onclick = null
jQuery('#submitConfigBtn').click(function() {
var btn = jQuery(this);
...ajax call,
success: function(response) {
if (response === 'badresponse') {
console.log('Bad response')
} else {
console.log('Response is ok')
btn.onclick = submitBtnOnclick
btn.click();
}
},
err: function(err) {
console.log(err)
}
});
})
})()
How I can retrieve the event from the variable and run it inside the onclick function?

From what I understood, you want to submit the form if the response is okay. No need to store the onclick event just to stop the form from submitting, you can either use: event.preventDefault(), or use type="button" instead in your button
I used the latter here, so instead of invoking the click event of the button, you need to use .submit() to the form, like this:
$(function() {
$('.submitConfigBtn').on('click', function() {
//ajax part here
//sample response result
let response = 'badresponse';
if (response === 'badresponse') {
console.log('Bad response')
} else {
console.log('Response is ok')
$('.sampleForm').submit();
}
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="sampleForm" action="" method="POST">
<button type="button" class="submitConfigBtn">Submit Config Button</button>
</form>

I would suggest you do some tricky logic.
Step 1.
Use two button
1. Submit type
2. Button type
Step 2.
Hide the submit button always.
Step 3.
if(response == true){
$("submitbtnid").trigger('click');
}
else {
console.log('write your custom logic');
}

If you want to avoid the "standard action" to happen you can call event.preventDefault() inside your click-handler function. There is no need to delete and re-install the on-click function itself.
Furthermore the jquery element btn will not know what to do with the property "onclick". This would be a property of a DOM object.
You are not the first person to come up with this problem ;-)
See here https://stackoverflow.com/a/14154017/2610061 for a possible solution.
(It looks like you have to know which action you want to defer, as there is no standard way of belatedly triggering any action that was initially prevented from happening. You can only trigger specific actions like .submit() of a form.)
I prepared a scenario that would work for your requirements. Please note that I do not capture the "click" event on the actual button but instead I listen for the "submit" event on the surrounding form. The form can be submitted by either clicking the button or by hitting the return key after filling out the input field. The current event handler will be executed in either case!
At first the default action is prevented from happening, then an asynchronous Ajax call is sent. Its success function in .done() carries out some "meaningful" test on the response and - depending on its outcome - will then trigger the form's submission or not. Should the Ajax call itself fail the .fail() function jumps into action and will do whatever is required ...
$(function() {
$('.validatedForm').on('submit', function(ev) {
ev.preventDefault(); // prevent submission before AJAX call
$.getJSON('http://jsonplaceholder.typicode.com/users/'+$('#q').val())
.done(function(da){
console.log(da);
if (da.address.city!=="Howemouth") { // some meaningful test on the result ...
setTimeout(()=>ev.target.submit(), 3000); // belated form submission!
console.log('Hey, the input was changed, in 3 seconds I will go to google!')
}})
.fail(function(da){console.log(da.status, da.statusText,'- Only user-IDs 1 ... 10 are allowed.');});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="http://google.com" class="validatedForm">
<input name="q" id="q" value="7">
<button>submit</button>
</form>

Related

Why doesn't my statement to disable form submission work?

I have a checkout form on my website that uses a custom validation method implemented with Bootstrap. It has a JavaScript function to prevent the form from being submitted multiple times if it is filled out correctly. I'm using a technique commonly suggested on SO to disable the submission, albeit with vanilla JavaScript instead of JQuery. This is the function:
function submitForm() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(thisForm) {
event.preventDefault();
if (thisForm.checkValidity() === false) {
event.stopPropagation();
}
thisForm.classList.add('was-validated');
<?php if(isset($shipping)){
echo "stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the user if there was an error
} else {
thisForm.addEventListener('submit', function(event){
event.preventDefault();
return false;
});
// Send the token to the server
console.log('Sending token ' + result.token + '.');
}
});";
}?>
});
};
The form is created like this:
<form id="payment-form" onsubmit="return submitForm()" class="needs-validation" novalidate>
When I test the page with the form filled out correctly, double clicking the submit button prints the "Sending token" message to the console twice when it should only happen once. I thought maybe it was because it was taking too long to get to the part of the function where the form is disabled, but the message prints again no matter how many times the button is clicked.
Using inline event handlers is bad practice and results in poorly factored, hard-to-manage code. Seriously consider attaching your events with JavaScript, instead, eg: https://developer.mozilla.org/en/DOM/element.addEventListener
You're not calling the validation function with the event of when the form was clicked - and then you reference event.preventDefault();, but event is not defined.
Try something like this instead. Remove the onsubmit attribute, and do:
[...document.querySelectorAll('.needs-validation')].forEach((thisForm) => {
thisForm.addEventListener('submit', (event) => { // add the event argument here
event.preventDefault();
if (thisForm.checkValidity() === false) {
// rest of your code
(though, I don't see why you're using .filter in the first place it doesn't make sense here - did you mean to use forEach? And if there's only one #payment-form, couldn't you have selected that by itself?)
To stop a form from submitting you should call event.preventDefault() or return false;
<form onsubmit="handleSubmit"></form>
handlesubmit(event) {
event.preventDefault();
// or return false;
}

Submit based on ajax response causes loop, how to properly call native submit?

I have a form where continuation of submit depends on ajax response.
$('#restaurant_form').on('submit', function(e) {
e.preventDefault();
fetchRestaurant(); // Checks if restaurant is already registered
});
In fetchRestaurant(), when restaurant does not exist yet I call this to proceed:
$('#restaurant_form').submit();
but I'm having a loop where the event handler for submit seems to be triggered. How do I properly call the native submit?
Do not use preventDefault method, you end in non submittable loop. Use return.
<form onsubmit="return validateRestaurant(this)">
...
</form>
<script src="https://unpkg.com/jquery#3.2.1/dist/jquery.min.js"></script>
<script>
function validateRestaurant (form) {
$.get('fetchRestaurant.php')
.then(function (restaurant) {
if (restaurant.exists) form.submit()
})
return false
}
</script>

Reactjs firing AJAX call multiple times a button is clicked (only want 1 per click!)

I have a simple React app that has a form in it and upon the user clicking submit, post the form to a server. Simple enough.
But React is firing the AJAX call multiple times (4-5 usually) in immediate succession, creating all sorts of issues. I don't know why - I assume it has something to do so React's lifecycle, but I am not sure.
I am using axios as a AJAX library, so perhaps the problem is with that library (I think not though).
Here is the method that fires the code:
submitEvent(event) {
event.preventDefault();
const apiQueryString = `api/event?${qs.stringify(this.state)}`;
if (this.state.event_title === undefined) {
alert('Event title is required!');
} else {
axios.post(apiQueryString)
.then((result) => {
this.state.id = result.data[0];
store.dispatch({
type: 'ADD_SINGLE_EVENT',
event: this.state,
});
alert('Success creating event!');
this.setState({}); // clear out old values
browserHistory.push('/');
})
.catch((error) => {
console.log(error);
alert('Error with database! See console for output.');
});
}
And this is the button that fires this function:
<button onClick={this.submitEvent} className="btn btn-primary">Submit</button>
The entire file's source code is here, and the working page is here.
Thanks for any help you can offer.
The problem was with the middleware. In the method that handled this AJAX request on the backend, a new item was being inserted into the database on the successful callback of req.getValidationResult(). This success callback was being called twice, resulting in multiple database inserts.
I would move the submission from the button to the form. Any button inside a form will trigger the form to submit on click, unless that button has type=button attribute. In your case the button click would cause the form to submit, which would then submit a form GET request to your current page.
Your submitEvent method is already preventing the default event, which should stop the native form submit from happening.
<form onSubmit={submitEvent}>
// this button is inside form so clicking it will trigger form submit
<button className="btn btn-primary">Submit</button>
</form>
If you have only one button in your form and you don't specify it's type (button/submit) by default it will be a submit button.
So it is better to use onSubmit instead of onClick here.

Why won't this form submit with AJAX?

I'm trying to submit a form to Campaign Monitor. They offer this code example to POST via Ajax.
This is my code for my multi-step modal.
var next_step = false;
var final_step = false;
$('.next').on('click', function(e){
e.preventDefault();
if (next_step) {
$('#step-1').slideUp(function(){
$('#step-2').slideDown();
$('.next').html('Submit');// Change button text to submit
final_step = true;
});
}
next_step = true;
if (final_step) {
$('#myform').submit(function (e){
alert('submit started'); //This never fires unless I remove the preventDefault();
e.preventDefault();//But if I remove this, the page will refresh
$.getJSON(
this.action + "?callback=?",
$(this).serialize(),
function (data) {
if (data.Status === 400) {
alert('error');
} else {
alert('success');
}
})
});
}
});
On the last step of the form, I check whether final_step is true, if so, go ahead and submit the form via ajax.
The problem is that it just doesn't do anything? But if I remove the e.preventDefault(); from the $('#myform') it will post the form as normal and re-direct you to the form URL.
How can I fix this?
What you are doing currently is wiring up an onsubmit handler. Not invoking submit.
$('#myform').submit(function (e){ });
...is the same thing as...
<form action="#" method="post" onsubmit="return someFunction()">
... which is the same as ...
$('#myForm').on('submit', function(e){});
You are never submitting the form.
What you are looking for is to use Ajax to post the data to the server and not submit the form.
You can do that like this:
$.ajax({
type: "POST",
url: "SomeUrl.aspx",
data: dataString,
success: function() {
//display message back to user here
}
});
dataString would be replaced with the values you posting.
$('#myform').submit(function (e){
just registers an event handler and attaches it to the "submit" event of "myform", it doesn't actually cause a submit. It means you're saying you'd like this function to be run every time the form is submitted. This handler function should be outside your $('.next').on('click', function(e){ block. Just below it will do.
If, within the $('.next').on('click', function(e){ block you wish to cause the form to be submitted, write:
$('#myform').submit();
This will actually trigger the form submission.
See https://api.jquery.com/submit/ for more info on what the different method signatures of "submit" actually do.
This line: $('#myform').submit(function (e) { registers the function you pass as an argument as a handler to the submit event of the form, and does not invoke a submit action. I'm not sure whether or not this is the problem, though I would recommend preventDefault() outside of the wizard flow
(e.g.
$(document).ready(function() {
$("#form").submit(function(e) {
e.preventDefault();
}
});
)
Then inside the if(final_step) just do the post without worrying about the form.
Also, you'd do good in not setting a submit button inside the form if you do not wish to use it's functionality. Just create an element with a click event that sends the data rather than registering to the submit event of the form.
I'm not sure but I always do $('#form').submit() after click in element and catch this event (e.g. by $('#form').on('submit', function () { .. });) in other place.

Calling Javascript on a form post to update UI via jQuery

I have an Input element that submits a form:
<input type="submit" value="Download" id="downloadButton" class="btn-download" />
I need the button to call a javascript function, and then post the form normally.
How would that be done in jQuery?
$('#downloadButton').on('click', function (e) {
e.preventDefault();
//call your function here
$(this).parents('form').submit();
});
the preventDefault() call is important because it stops the submission of the form so you can call your function before the form submit is called at the end.
You can do:
<form onsubmit="return doSomething();">
</form>
function doSomething() {
// do something
return true;
}
If in the doSomething function you don't like what you're seeing, then return false instead of true.
EDIT
The jQuery equivalent (to satisfy both commenters): remove the onsubmit from the HTML and replace with:
jQuery(document).ready(function () {
jQuery("form#myFormId").submit(doSomething);
});
Take a look at this jsfiddle
It changes the case of textbox content to to upper case before submitting the form
$('#formID').on('submit', function () {
//var form = $(this),
//input = form.find('input[type="text"]');
//input.val(input.val().toUpperCase());
//alert(input.val());
// call your function here!
});
this is what you request:
1.- click a button (adding event handler)
2.- call a function
3.- submit form
myfunction(){
//do wathever you want
$('#formid').submit();
}
$(document).on("click", "#downloadButton", myfunction);
you can do also:
$(document).on("click", "#downloadButton", function(event){
$('#formid').submit();
});
without having an extra function
but the solution of #Paritosh is the more accurate.
jsFiddle here
Change input type to type="button" and use:
$('#downloadButton').click(function() {
//Do any javascript stuff here
//And here, etc. Then, when ready...
$('#yourFormID').submit();
});
I recommend assigning an ID attribute to your form as it is good practice.
<form id="yourFormID" action="" method="POST">
Perhaps you have only one form on this page, in that case $('form').submit() is fine. But in future (or perhaps even on this page, you haven't said) you may have multiple forms on a page and therefore the ID is necessary to specify the exact form to be submitted.
Note that if you do NOT change the submit button element's <input type="submit" to <input type="button", then you must use e.preventDefault() to prevent the button's default action. Why bother with that? Just change type="button" and use less code and less future confusion.
add a submit event on form.
$('form').submit(function(event){
event.preventDefault();
var formObj = $(this);
var formData = formObj.serialize();
$.ajax({
type: 'post',
data: formData
}).done(function(response){
console.info(response);
// update UI here accordingly.
});
});

Categories