I have a button in my form. I need my form to be processed after the first click (or pressing Enter) on the button, and after that, if some conditions would be true, I do something like submitting the form by the second click or pressing Enter key on the button.
What do you think I have to do?
Create a (boolean) variable that saves your state, which is set to true when the first click (or action) has happened and your condition is true. Then submit on the second action when the variable is true.
If the condition has to be matched on both clicks (I guess so) consider the following:
$(function() {
var first = false;
$("form").submit(function() {
if(first && checkCondition())
submit();
if(!first && checkCondition())
first = true;
e.preventDefault();
});
});
so in basic code:
var answered = false;
$(function() {
$("form").submit(function() {
if(answered == false) {
answered = true;
return false;
}
});
});
If I've understood what you're trying to do correctly, you could bind an event handler to the submit event. That event handler will handle your validation, but if you use the jQuery one method, it will only be executed once. The next time the submit event is triggered, the form will submit as usual:
$("yourForm").one("submit", function(e) {
e.preventDefault(); //Stop the form from being submitted
//Do stuff
});
The result is effectively the same as #Manuel van Rijn's answer, but using jQuery's one just makes it a bit shorter and cleaner in my opinion. However, this could also add a slight performance benefit, as the event handler is unbound after it's execution and won't be called again.
Related
I have a button similar to below
<button id="uniqueId" onclick="runMethod(this)">Submit</button>
What I'm trying to do is stop the runMethod from running, until after I've done a check of my own. I've tried using the stopImmediatePropagation function, but this doesn't seem to have worked. Here's my jQuery:
$j(document).on('click', '#uniqueId', function(event) {
event.stopImmediatePropagation();
if(condition == true) {
// continue...
} else {
return false;
}
return false;
});
Note: runMethod basically validates the form, then triggers a submit.
What you want to do, especially in the way that you want to do it, requires a some sort of workaround that will always be a bit fiddly. It is a better idea to change the way the button behaves (e.g. handle the whole of the click event on the inside of the jQuery click() function or something along those lines). However I have found sort of a solution for your problem, based on the assumption that your user will first hover over the button. I am sure you can extend that functionality to the keyboard's Tab event, but maybe it will not work perfectly for mobile devices' touch input. So, bear in mind the following solution is a semi-complete workaround for your problem:
$(document).ready(function(){
var methodToRun = "runMethod(this)"; // Store the value of the onclick attribute of your button.
var condition = false; // Suppose it is enabled at first.
$('#uniqueId').attr('onclick',null);
$('#uniqueId').hover(function(){
// Check your stuff here
condition = !condition; // This will change to both true and false as your hover in and out of the button.
console.log(condition); // Log the condition's value.
if(condition == true){
$('#uniqueId').attr('onclick',methodToRun); // Enable the button's event before the click.
}
},
function(){
console.log('inactive'); // When you stop hovering over the button, it will log this.
$('#uniqueId').attr('onclick',null); // Disable the on click event.
});
});
What this does is it uses the hover event to trigger your checking logic and when the user finally clicks on the button, the button is enabled if the logic was correct, otherwise it does not do anything. Try it live on this fiddle.
P.S.: Convert $ to $j as necessary to adapt this.
P.S.2: Use the Javascript console to check how the fiddle works as it will not change anything on the page by itself.
Your problem is the submit event, just make :
$('form').on('submit', function(e) {
e.preventDefault();
});
and it works. Don't bind the button click, only the submit form. By this way, you prevent to submit the form and the button needs to be type button:
<button type="button" .....>Submit</button>
Assuming there's a form that is submitted when button is clicked.
Try adding
event.cancelBubble();
Hence your code becomes:
$j(document).on('click', '#uniqueId', function(event) {
// Don't propogate the event to the document
if (event.stopPropagation) {
event.stopPropagation(); // W3C model
} else {
event.cancelBubble = true; // IE model
}
if(condition == true) {
// continue...
} else {
return false;
}
return false;
});
Your code is mostly correct but you need to remove J:
$(document).on('click', '#uniqueId', function(event) {...
You also need to remove the onClick event from the inline code - there's no need to have it there when you're assigning it via jQuery.
<button id="uniqueId">Submit</button>
I have a form that I don't want to be submitted the first time submit is clicked, but the second time it should work like a normal submit. So I added a not-submittable class to the form on load, then after the first click remove that class... which should (I think) make it submit normally. But, this doesn't happen. The first click works as expected, removes the class and changes the button text. The second click, however, does the exact same thing. So, what am I missing here?
jQuery:
$('form#survey_7042 #ACTION_SUBMIT_SURVEY_RESPONSE').addClass('not-submittable');
$('form#survey_7042 #ACTION_SUBMIT_SURVEY_RESPONSE.not-submittable').click(function(event) {
$('form#survey_7042 #ACTION_SUBMIT_SURVEY_RESPONSE').removeClass('not-submittable');
$('form#survey_7042 #ACTION_SUBMIT_SURVEY_RESPONSE').val('Continue');
$('form#survey_7042 #ACTION_SUBMIT_SURVEY_RESPONSE').removeAttr('disabled');
return false;
});
Pre-javascript button:
<input type="submit" class="Button" value="Submit Survey" id="ACTION_SUBMIT_SURVEY_RESPONSE" name="ACTION_SUBMIT_SURVEY_RESPONSE">
Quote OP: "I have a form that I don't want to be submitted the first
time submit is clicked, but the second time it should work like a
normal submit."
Use jQuery .one() to block the submit on first click only.
http://api.jquery.com/one/
$('#ACTION_SUBMIT_SURVEY_RESPONSE').one('submit', function(e) {
e.preventDefault();
// do what you need to do on first click
}
Alternatively...
$('#ACTION_SUBMIT_SURVEY_RESPONSE').one('submit', function(e) {
e.preventDefault();
// do what you need to do on first click
if ( some-condition ) { // under certain conditions allow submit on first click
$(this).submit();
}
}
Instead of using .click(), try using the .on() and .off() methods to bind and unbind the event. In your case:
$('form#survey_7042 #ACTION_SUBMIT_SURVEY_RESPONSE.not-submittable').on("click.stopSubmit", function(event) {
$('form#survey_7042 #ACTION_SUBMIT_SURVEY_RESPONSE').removeClass('not-submittable');
$('form#survey_7042 #ACTION_SUBMIT_SURVEY_RESPONSE').val('Continue');
$('form#survey_7042 #ACTION_SUBMIT_SURVEY_RESPONSE').removeAttr('disabled');
if (...conditions are met.....) {
$('form#survey_7042 #ACTION_SUBMIT_SURVEY_RESPONSE.not-submittable').off("click.stopSubmit");
}
return false;
});
You may notice that the first parameter of the .on() method is the string representation of the handler, but that I appended the namespace ".stopSubmit". Namespacing your handlers allows you to unbind one specific click handler, rather than all click handlers. The best part about this is that if there is code in your original handler that you still want to use you can make a separate click handler to run that code, and it will not be unbound when you unbind the ".stopSubmit" handler.
Please note that .on() and .off() are the recommended bind/unbind methods - jQuery no longer recommends .bind() and .unbind().
UPDATE
After reading your comment about not unbinding until after certain conditions are met, I would would like to point out that you can insert the .off() call in a conditional. I have updated the code to reflect this.
You can do something like this
$(document).ready(function () {
$('#ACTION_SUBMIT_SURVEY_RESPONSE').click(function (event) {
if (!$('#ACTION_SUBMIT_SURVEY_RESPONSE').hasClass(".not-submittable")) {
//do all conditions you wish on first click
//if condidition meets add this class to button
$('#ACTION_SUBMIT_SURVEY_RESPONSE').addClass(".not-submittable");
//stop form submit
event.preventDefault();
}
else {
//calls when button have .not-submittable class may be second or any no of clicks
$('#ACTION_SUBMIT_SURVEY_RESPONSE').removeClass('not-submittable');
$('#ACTION_SUBMIT_SURVEY_RESPONSE').val('Continue');
$('#ACTION_SUBMIT_SURVEY_RESPONSE').removeAttr('disabled');
//commented return false so form submits normally
}
});
});
If there are certain criteria that must match use this where submitable contains your logic what makes it possible to send the form:
var submit = $('form#survey_7042 #ACTION_SUBMIT_SURVEY_RESPONSE');
submit.addClass('not-submittable');
submit.click(function(event) {
if (true == submitable) {
submit.removeClass('not-submittable').val('Continue').removeAttr('disabled');
submit.unbind();
event.preventDefault();
}
});
This question already has answers here:
How to disable beforeunload action when user is submitting a form?
(7 answers)
Closed 7 years ago.
I am using window.onbeforeunload to prevent the user from navigating away after changing values on a form. This is working fine, except it also shows the warning when the user submits the form (not desired).
How can I do this without showing the warning when the form submits?
Current code:
var formHasChanged = false;
$(document).on('change', 'form.confirm-navigation-form input, form.confirm-navigation-form select, form.confirm-navigation-form textarea', function (e) {
formHasChanged = true;
});
$(document).ready(function () {
window.onbeforeunload = function (e) {
if (formHasChanged) {
var message = "You have not saved your changes.", e = e || window.event;
if (e) {
e.returnValue = message;
}
return message;
}
}
});
Using the form's submit event to set a flag might work for you.
var formHasChanged = false;
var submitted = false;
$(document).on('change', 'form.confirm-navigation-form input, form.confirm-navigation-form select, form.confirm-navigation-form textarea', function (e) {
formHasChanged = true;
});
$(document).ready(function () {
window.onbeforeunload = function (e) {
if (formHasChanged && !submitted) {
var message = "You have not saved your changes.", e = e || window.event;
if (e) {
e.returnValue = message;
}
return message;
}
}
$("form").submit(function() {
submitted = true;
});
});
you could use .on() to bind onbeforeunload and then use .off() to unbind it in form submission
$(document).ready(function () {
// Warning
$(window).on('beforeunload', function(){
return "Any changes will be lost";
});
// Form Submit
$(document).on("submit", "form", function(event){
// disable warning
$(window).off('beforeunload');
});
}
You can handle the submit() event, which will occur only for your form submission.
Within that event, set your flag variable formHasChanged to false to allow the unload to proceed. Also, just a suggestion, but since the purpose of that flag variable will have changed, so you may want to rename it something like 'warnBeforeUnload'
$(document).submit(function(){
warnBeforeUnload = false;
});
I was looking for a better solution to this. What we want is simply exclude one or more triggers from creating our "Are you sure?" dialog box. So we shouldn't create more and more workarounds for more and more side effects. What if the form is submitted without a click event of the submit button? What if our click-handler removes the isDirty status but then the form-submit is otherwise blocked afterwards? Sure we can change the behaviour of our triggers, but the right place would be the logic handling the dialog. Binding to the form's submit event instead of binding to the submit button's click event is an advantage of the answers in this thread above some others i saw before, but this IMHO just fixes the wrong approach.
After some digging in the event object of the onbeforeunload event I found the .target.activeElement property, which holds the element, which triggered the event originally. So, yay, it is the button or link or whatever we clicked (or nothing at all, if the browser itself navigated away). Our "Are you sure?" dialog logic then reduces itself to the following two components:
The isDirty handling of the form:
$('form.pleaseSave').on('change', function() {
$(this).addClass('isDirty');
});
The "Are you sure?" dialog logic:
$(window).on('beforeunload', function(event) {
// if form is dirty and trigger doesn't have a ignorePleaseSave class
if ($('form.pleaseSave').hasClass('isDirty')
&& !$(event.target.activeElement).hasClass('ignorePleaseSave')) {
return "Are you sure?"
}
// special hint: returning nothing doesn't summon a dialog box
});
It's simply as that. No workarounds needed. Just give the triggers (submit and other action buttons) an ignorePleaseSave class and the form we want to get the dialog applied to a pleaseSave class. All other reasons for unloading the page then summons our "Are you sure?" dialog.
P.S. I am using jQuery here, but I think the .target.activeElement property is also available in plain JavaScript.
I have no idea if this is even possible, but I thought I would ask since it would be awesome if it is possible.
So basically I have a link with an onclick and in the onclick there are two calls. one to a function and another to _doPostBack.
The first function that is called is a simple function:
function CheckTerms() {
if (!document.Form.agreetoterms.checked) {
alert("Please check the terms and conditions.");
return false;
}
return true;
}
So basically if the check box isnt checked the alert happens and the page doesn't submit. If it is checked it submits. Right now even if it isn't checked, it shows the alert and executes the doPostBack and submits the page. The doPostBack is put into the link dynamically and I don't have access to it, which has made it harder for me. So any ideas or ways to abort it so it doesn't submit?
Thanks!
I'm assuming the _doPostback function handles the posting of the form, and that you don't want the anchor to move the page to the location of its href when clicked. preventDefault does this by preventing the anchor's default action from being taken when clicked.
var a = document.getElementById("yourAnchorId");
a.onclick = function(e){
e.preventDefault();
if (CheckTerms())
_doPostBack();
}
why can't you do the following:
function CheckTerms() {
if (!document.Form.agreetoterms.checked) {
alert("Please check the terms and conditions.");
return false;
}
else{
<<< call you function here >>>
}
return true;
}
**Update: I have pasted working code in order to erase any ambiguity about what is going on. I have also tried to remove the preventDefault on both handlers, does not help*
I have a form where upon the button click, a JS event needs to happen, and the form needs to submit.
As per the code below, what I thought would happen is: alert(button), then alert(form), or vice versa. I do not care about sequence.
If i run it however, the alert(button) will show up, but the alert(form) will not.
If i comment out the code for the button, the form alert comes up.
Do i have some fundamental misunderstanding of how this is supposed to work?
jQuery(document).ready(function(){
$("form.example").submit(function(event){
event.preventDefault();
alert("form submitted");
});
$("form.example button").click(function(event){
event.preventDefault();
alert("button clicked");
});
)};
<form class="example" action="/v4test">
<button type="submit">Meow!</button>
</form>
After edit of OP
You do not need to preventDefault of the click.... only the submit... here is you working code:
jsFiddle example
jQuery(document).ready(function(){
$('form.example').submit(function(event){
event.preventDefault();
alert("form submitted");
// stop submission so we don't leave this page
});
$('form.example button').click(function() {
alert("button clicked");
});
});
old answer
You can simply put your .click() and .submit() handlers in series, and they should not cancel out. You have some syntax errors in your pseudo code.... maybe those are causing problems?
Another potential problem is that $("form button") targets the HTML <button> tags. If you use <input type="button" /> you should use $("form:button") and note that <input type="submit" /> is not a button. Anyway, I'll assume you are in fact using the <button> tags.
Usually return false is used inside .submit(function() { ... });. This stops the form from being submited through HTML. s**[topPropagation][6]** is very different. It deals with stopping events "bubbling up" to the parents of elements....... But I don't see how this would effect your case.
If you are doing a true HTML submission, make sure to put your .click() handler first, since a true HTML submission will cause you to leave the page.
If you use return false inside .submit(), the form will not be submitted through the HTML, and you'll have to handle the submission with jQuery / Javascript / AJAX.
Anyway, here is a demonstration of both the .click() and .submit() events firing in series... the code is below:
jsFiddle Example
$(function() {
$('form button').click(function() {
// Do click button stuff here.
});
$('form').submit(function(){
// Do for submission stuff here
// ...
// stop submission so we don't leave this page
// Leave this line out, if you do want to leave
// the page and submit the form, but then the results of your
// click event will probably be hard for the user to see.
return false;
});
});
The above will trigger both handlers with the following HTML:
<button type="submit">Submit</button>
As a note, I suppose you were using pseudo code, but even then, it's much easier to read, and one is sure you're not writing syntax errors, if you use:
$('form').submit(function() { /*submits form*/ });
$('form button').click(function() { /*does some action*/ });
If you put a return false on the click, it should cancel the default behavior. If you want to execute one then the other, call $('form').submit() within the click function. e.g.
$('form').submit { //submits form}
$('form button').click {
// does some action
$('form').submit();
}
There seems to be a bit of confusion about propagation here. Event propagation (which can be disabled by stopPropagation) means that events "bubble up" to parent elements; in this case, the click event would register on the form, because it is a parent of the submit button. But of course the submit handler on the form will not catch the click event.
What you are interested in is the default action, which in the case of clicking a submit button is to submit the form. The default action can be prevented by either calling preventDefault or returning false. You are probably doing the latter.
Note that in Javascript functions which do not end with an explicit return do still return a value, which is the result of the last command in the function. You should end your click handler with return; or return true;. I have no idea where I got that from. Javascript functions actually return undefined when there is no explicit return statement.
Does clicking the button submit the form? If so:
// Disable the submit action
$("form").submit(function(){
return false;
});
$("form button").click(function(){
// Do some action here
$("form").unbind("submit").submit();
});
If you don't unbind the submit event when you click the button, the submit will just do nothing.