jquery form validation, and submit-on-change - javascript

I want to make all my settings forms across my site confirm that changes are saved, kinda like facebook does if you make changes in a form and then try to navigate away without saving. So I'm disabling the submit button on the forms only enabling if the values change. I then prompt the user to hit save before they leave the page in the case that they do have changes pending.
var form = $('form.edit');
if(form.length > 0) {
var orig_str = form.serialize();
$(':submit',form).attr('disabled','disabled');
form.on('change keyup', function(){
if(form.serialize() == orig_str) {
setConfirmUnload(false);
$(':submit',form).attr('disabled','disabled');
} else {
setConfirmUnload(true);
$(':submit',form).removeAttr('disabled')
}
});
$('input[type=submit]').click(function(){ setConfirmUnload(false); });
}
function setConfirmUnload(on) {
window.onbeforeunload = (on) ? unloadMessage : null;
}
function unloadMessage() {
return 'If you navigate away from this page without saving your changes, they will be lost.';
}
One of these forms needs some additional validation which I do using jQuery.validate library. e.g. if i wanted to ensure the user can't double submit the form on accident by double clicking on submit or somesuch (the actual validation in question is for a credit-card form and not this simple):
$('form').validate({
submitHandler: function(form) {
$(':submit', form).attr('disabled','disabled');
form.submit();
}
});
Unfortunately both bits are trying to bind to submit button and they're interfering with each other such that the submit button remains disabled no matter what I do and it is impossible to submit the form at all.
Is there some way to chain the validations together or something? Or some other way to avoid re-writing the validation code to repeat the "did you change anything in the form" business?

Not sure what's wrong with your solution, but here's one that seems to work:
<!doctype html><!-- HTML5 ROCKS -->
<html>
<head>
<title>Usable Forms</title>
</head>
<body>
<form id="my_form" action="http://www.google.com/search">
<input type="text" name="query">
<input type="submit" disabled>
</form>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js">
</script>
<script>
var my_form = $('#my_form');
var original_form_values = my_form.serialize();
// Returns true if the contents of #my_form have changed since the page was
// loaded.
function MyFormChanged() {
return my_form.serialize() != original_form_values;
}
var submitting = false;
// Warn of unsaved changes if the user tries to navigate away.
window.onbeforeunload = function() {
// Don't stop the submission.
if (submitting) {
return;
}
if (MyFormChanged()) {
return 'You have unsaved changes.';
}
// Not submitting, nor has form changed;
// therefore, it is safe for the user to navigate away.
}
$('#my_form').on('submit', function() {
// Just in case submit button isn't disabled for some reason.
$('#my_form input[type=submit]').attr('disabled', '');
if (!MyFormChanged()) {
return false;
}
if (submitting) {
return false;
}
submitting = true;
return true;
});
// Toggle submit button, depending on whether there are any changes to submit.
$('#my_form input').on('change keyup', function() {
if (!submitting && MyFormChanged()) {
// Enable submit button.
$('#my_form input[type=submit]').removeAttr('disabled');
} else {
// Disable submit button.
$('#my_form input[type=submit]').attr('disabled', '');
}
});
</script>
</body>
</html>

Related

Prevent submit form when focus is on input [duplicate]

How do you prevent an ENTER key press from submitting a form in a web-based application?
[revision 2012, no inline handler, preserve textarea enter handling]
function checkEnter(e){
e = e || event;
var txtArea = /textarea/i.test((e.target || e.srcElement).tagName);
return txtArea || (e.keyCode || e.which || e.charCode || 0) !== 13;
}
Now you can define a keypress handler on the form:
<form [...] onkeypress="return checkEnter(event)">
document.querySelector('form').onkeypress = checkEnter;
Here is a jQuery handler that can be used to stop enter submits, and also stop backspace key -> back. The (keyCode: selectorString) pairs in the "keyStop" object are used to match nodes that shouldn't fire their default action.
Remember that the web should be an accessible place, and this is breaking keyboard users' expectations. That said, in my case the web application I am working on doesn't like the back button anyway, so disabling its key shortcut is OK. The "should enter -> submit" discussion is important, but not related to the actual question asked.
Here is the code, up to you to think about accessibility and why you would actually want to do this!
$(function(){
var keyStop = {
8: ":not(input:text, textarea, input:file, input:password)", // stop backspace = back
13: "input:text, input:password", // stop enter = submit
end: null
};
$(document).bind("keydown", function(event){
var selector = keyStop[event.which];
if(selector !== undefined && $(event.target).is(selector)) {
event.preventDefault(); //stop event
}
return true;
});
});
Simply return false from the onsubmit handler
<form onsubmit="return false;">
or if you want a handler in the middle
<script>
var submitHandler = function() {
// do stuff
return false;
}
</script>
<form onsubmit="return submitHandler()">
//Turn off submit on "Enter" key
$("form").bind("keypress", function (e) {
if (e.keyCode == 13) {
$("#btnSearch").attr('value');
//add more buttons here
return false;
}
});
You will have to call this function whic will just cancel the default submit behaviour of the form. You can attach it to any input field or event.
function doNothing() {
var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
if( keyCode == 13 ) {
if(!e) var e = window.event;
e.cancelBubble = true;
e.returnValue = false;
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
}
The ENTER key merely activates the form's default submit button, which will be the first
<input type="submit" />
the browser finds within the form.
Therefore don't have a submit button, but something like
<input type="button" value="Submit" onclick="submitform()" />
EDIT: In response to discussion in comments:
This doesn't work if you have only one text field - but it may be that is the desired behaviour in that case.
The other issue is that this relies on Javascript to submit the form. This may be a problem from an accessibility point of view. This can be solved by writing the <input type='button'/> with javascript, and then put an <input type='submit' /> within a <noscript> tag. The drawback of this approach is that for javascript-disabled browsers you will then have form submissions on ENTER. It is up to the OP to decide what is the desired behaviour in this case.
I know of no way of doing this without invoking javascript at all.
In short answer in pure Javascript is:
<script type="text/javascript">
window.addEventListener('keydown', function(e) {
if (e.keyIdentifier == 'U+000A' || e.keyIdentifier == 'Enter' || e.keyCode == 13) {
if (e.target.nodeName == 'INPUT' && e.target.type == 'text') {
e.preventDefault();
return false;
}
}
}, true);
</script>
This only disables the "Enter" keypress action for input type='text'. Visitors can still use "Enter" key all over the website.
If you want to disable "Enter" for other actions as well, you can add console.log(e); for your your test purposes, and hit F12 in chrome, go to "console" tab and hit "backspace" on the page and look inside it to see what values are returned, then you can target all of those parameters to further enhance the code above to suit your needs for "e.target.nodeName", "e.target.type" and many more...
See my detailed answer for a similar question here
I've always done it with a keypress handler like the above in the past, but today hit on a simpler solution. The enter key just triggers the first non-disabled submit button on the form, so actually all that's required is to intercept that button trying to submit:
<form>
<div style="display: none;">
<input type="submit" name="prevent-enter-submit" onclick="return false;">
</div>
<!-- rest of your form markup -->
</form>
That's it. Keypresses will be handled as usual by the browser / fields / etc. If the enter-submit logic is triggered, then the browser will find that hidden submit button and trigger it. And the javascript handler will then prevent the submision.
All the answers I found on this subject, here or in other posts has one drawback and that is it prevents the actual change trigger on the form element as well. So if you run these solutions onchange event is not triggered as well. To overcome this problem I modified these codes and developed the following code for myself. I hope this becomes useful for others.
I gave a class to my form "prevent_auto_submit" and added the following JavaScript:
$(document).ready(function()
{
$('form.prevent_auto_submit input,form.prevent_auto_submit select').keypress(function(event)
{
if (event.keyCode == 13)
{
event.preventDefault();
$(this).trigger("change");
}
});
});
I've spent some time making this cross browser for IE8,9,10, Opera 9+, Firefox 23, Safari (PC) and Safari(MAC)
JSFiddle Example: http://jsfiddle.net/greatbigmassive/ZyeHe/
Base code - Call this function via "onkeypress" attached to your form and pass "window.event" into it.
function stopEnterSubmitting(e) {
if (e.keyCode == 13) {
var src = e.srcElement || e.target;
if (src.tagName.toLowerCase() != "textarea") {
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
}
}
}
stopSubmitOnEnter (e) {
var eve = e || window.event;
var keycode = eve.keyCode || eve.which || eve.charCode;
if (keycode == 13) {
eve.cancelBubble = true;
eve.returnValue = false;
if (eve.stopPropagation) {
eve.stopPropagation();
eve.preventDefault();
}
return false;
}
}
Then on your form:
<form id="foo" onkeypress="stopSubmitOnEnter(e);">
Though, it would be better if you didn't use obtrusive JavaScript.
Preventing "ENTER" to submit form may inconvenience some of your users. So it would be better if you follow the procedure below:
Write the 'onSubmit' event in your form tag:
<form name="formname" id="formId" onSubmit="return testSubmit()" ...>
....
....
....
</form>
write Javascript function as follows:
function testSubmit(){
if(jQuery("#formId").valid())
{
return true;
}
return false;
}
(OR)
What ever the reason, if you want to prevent the form submission on pressing Enter key, you can write the following function in javascript:
$(document).ready(function() {
$(window).keydown(function(event){
if(event.keyCode == 13) {
event.preventDefault();
return false;
}
});
});
thanks.
To prevent form submit when pressing enter in a textarea or input field, check the submit event to find what type of element sent the event.
Example 1
HTML
<button type="submit" form="my-form">Submit</button>
<form id="my-form">
...
</form>
jQuery
$(document).on('submit', 'form', function(e) {
if (e.delegateTarget.activeElement.type!=="submit") {
e.preventDefault();
}
});
A better solution is if you don't have a submit button and you fire the event with a normal button. It is better because in the first examlple 2 submit events are fired, but in the second example only 1 submit event is fired.
Example 2
HTML
<button type="button" onclick="$('#my-form').submit();">Submit</button>
<form id="my-form">
...
</form>
jQuery
$(document).on('submit', 'form', function(e) {
if (e.delegateTarget.activeElement.localName!=="button") {
e.preventDefault();
}
});
In my case, this jQuery JavaScript solved the problem
jQuery(function() {
jQuery("form.myform").submit(function(event) {
event.preventDefault();
return false;
});
}
You will find this more simple and useful :D
$(document).on('submit', 'form', function(e){
/* on form submit find the trigger */
if( $(e.delegateTarget.activeElement).not('input, textarea').length == 0 ){
/* if the trigger is not between selectors list, return super false */
e.preventDefault();
return false;
}
});
How about:
<asp:Button ID="button" UseSubmitBehavior="false"/>
Add this tag to your form - onsubmit="return false;"
Then you can only submit your form with some JavaScript function.
Please check this article How to prevent ENTER keypress to submit a web form?
$(“.pc_prevent_submit”).ready(function() {
$(window).keydown(function(event) {
if (event.keyCode == 13) {
event.preventDefault();
return false;
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class=”pc_prevent_submit” action=”” method=”post”>
<input type=”text” name=”username”>
<input type=”password” name=”userpassword”>
<input type=”submit” value=”submit”>
</form>
You can trap the keydown on a form in javascript and prevent the even bubbling, I think. ENTER on a webpage basically just submits the form that the currently selected control is placed in.
This link provides a solution that has worked for me in Chrome, FF, and IE9 plus the emulator for IE7 and 8 that comes with IE9's developer tool (F12).
http://webcheatsheet.com/javascript/disable_enter_key.php
Another approach is to append the submit input button to the form only when it is supposed to be submited and replace it by a simple div during the form filling
Simply add this attribute to your FORM tag:
onsubmit="return gbCanSubmit;"
Then, in your SCRIPT tag, add this:
var gbCanSubmit = false;
Then, when you make a button or for any other reason (like in a function) you finally permit a submit, simply flip the global boolean and do a .submit() call, similar to this example:
function submitClick(){
// error handler code goes here and return false if bad data
// okay, proceed...
gbCanSubmit = true;
$('#myform').submit(); // jQuery example
}
I Have come across this myself because I have multiple submit buttons with different 'name' values, so that when submitted they do different things on the same php file. The enter / return button breaks this as those values aren't submitted.
So I was thinking, does the enter / return button activate the first submit button in the form?
That way you could have a 'vanilla' submit button that is either hidden or has a 'name' value that returns the executing php file back to the page with the form in it.
Or else a default (hidden) 'name' value that the keypress activates, and the submit buttons overwrite with their own 'name' values.
Just a thought.
How about:
<script>
function isok(e) {
var name = e.explicitOriginalTarget.name;
if (name == "button") {
return true
}
return false;
}
</script>
<form onsubmit="return isok(event);">
<input type="text" name="serial"/>
<input type="submit" name="button" value="Create Thing"/>
</form>
And just name your button right and it will still submit, but text fields i.e. the explicitOriginalTarget when you hit return in one, will not have the right name.
If none of those answers are working for you, try this. Add a submit button before the one that actually submits the form and just do nothing with the event.
HTML
<!-- The following button is meant to do nothing. This button will catch the "enter" key press and stop it's propagation. -->
<button type="submit" id="EnterKeyIntercepter" style="cursor: auto; outline: transparent;"></button>
JavaScript
$('#EnterKeyIntercepter').click((event) => {
event.preventDefault(); //The buck stops here.
/*If you don't know what this if statement does, just delete it.*/
if (process.env.NODE_ENV !== 'production') {
console.log("The enter key was pressed and captured by the mighty Enter Key Inceptor (⌐■_■)");
}
});
This worked for me.
onkeydown="return !(event.keyCode==13)"
<form id="form1" runat="server" onkeydown="return !(event.keyCode==13)">
</form>
Here's how I'd do it:
window.addEventListener('keydown', function(event)
{
if (event.key === "Enter" && event.target.tagName !== 'TEXTAREA')
{
if(event.target.type !== 'submit')
{
event.preventDefault();
return false;
}
}
});
put into javascript external file
(function ($) {
$(window).keydown(function (event) {
if (event.keyCode == 13) {
return false;
}
});
})(jQuery);
or somewhere inside body tag
<script>
$(document).ready(function() {
$(window).keydown(function(event) {
alert(1);
if(event.keyCode == 13) {
return false;
}
});
});
</script>
I had the same problem (forms with tons of text fields and unskilled users).
I solved it in this way:
function chkSubmit() {
if (window.confirm('Do you want to store the data?')) {
return true;
} else {
// some code to focus on a specific field
return false;
}
}
using this in the HTML code:
<form
action="go.php"
method="post"
accept-charset="utf-8"
enctype="multipart/form-data"
onsubmit="return chkSubmit()"
>
In this way the ENTER key works as planned, but a confirmation (a second ENTER tap, usually) is required.
I leave to the readers the quest for a script sending the user in the field where he pressed ENTER if he decide to stay on the form.

Prevent beforeunload function from executing if submit button is clicked

I have the following function that gives a warning to the user if they are exiting the page when the $('.article_div textarea') form field is populated.
$(window).on('beforeunload', function(event) {
var unsaved = "Are you sure you want to exit?";
var text = $('.article_div textarea').val();
if (text.length > 0){
return unsaved;
}
});
However, I would like to prevent this popup from executing when they click the submit button to the actual form.
How can I ammend the function to account for this? The element of the submit button is
$('button.submit_post').
You can create a boolean which gets positive when you click on submit Or remove the event of unload when clicked. The code will be as follows:
var isSubmitClicked = false;
$('button .submit_post').on("click",onClick);
function onClick(e){
isSubmitClicked = true;
}
$(window).on('beforeunload', function(event) {
if(isSubmitClicked){
isSubmitClicked = false;
return;
}
// Rest of your method.
}
How about binding a event handler to the submit event instead of the submit button element?
Maybe like this:
var submitted = false;
$('form').on("submit", function() {
submitted = true;
console.log('submitted');
});
$(window).on('beforeunload', function(event) {
if(submitted){
submitted = false;
console.log('aborted because of submit');
return;
}
console.log('rest of code');
// Rest of your method.
});

Javascript confirm Stop page refresh after cancel

I have made a JavaScript function which is attached to the cancel button on of a form. The issue I am finding is that when the cancel button is pressed the page/form reloads losing the data in the text fields.
function cancelConfirm(){
var confirmCancel = confirm("Are you sure you wish to cancel?");
if(confirmCancel==true)
{
alert("byebye");
}
else
{
return false;
}
};
I was just wondering how can you prevent the page from reloading after the cancel button on the confirm has been clicked? Thanks for any help you can give
you can just use a simple way
Delete
function cancelConfirm() {
var confirmCancel = confirm("Are you sure you wish to cancel?");
if (confirmCancel == true) {
alert("byebye");
return false;// to stop postback on ok cick of confirmation popup
}
else {
return false;
}
}
What you can do is to add an onClick event and pass the event object down to it.
{onClick(e) => {
e.preventDefault();
//do something here
}}
A simple e.preventDefault() is what you need.

disabling submit button till input fields are validated

i have disabled the submit button in my guestbook. it has 2 fields[name(textbox)&comment(textarea)].it has 2 other fields ID(primary key) and date.the function is:
function Frmvalidate() {
var nmchk=document.forms["guestform1"]["name"].value;
var cmntchk=document.forms["guestform1"]["comment"].value;
if (nmchk.length==0)
{
var namep = document.getElementById("namep");
namep.innerHTML="name must be filled out";
return false;
}
else if (cmntchk.length==0)
{
var cmntp = document.getElementById("cmntp");
cmntp.innerHTML="comment must be filled out";
return false;
}
else
{
document.getElementById("sbmt").disabled=false;
return true;
}
}
i have called the function in places: body tag's onload,button tag's onclick. still its not working and blank entries are being stored in my database.
You dont need to disable the submit button
you gain noting from it. ( alerting the user , running another script etc...)
instead -- The submit button should stop its regular behaviour by this code :
<input type="submit" onclick="return Frmvalidate();"/>
meaning :
when you press the button , it will execute the function yielding True or False and if it's True (only) it will continue to the server.

Activating OnBeforeUnload ONLY when field values have changed

What I'm trying to achieve is to Warn the user of unsaved changes if he/she tries to close a page or navigate away from it without saving first.
I've managed to get the OnBeforeUnload() dialog to pop-up... but I don't want it to be displayed at all if the user hasn't modified any field values. For this, I'm using this hidden input field called is_modified that starts with a default value of false and flips to true when any field is edited.
I tried to bind the change event to this is_modified field to try and detect for value change... and only then activate OnBeforeUnload.
$( '#is_modified' ).change( function() {
if( $( '#is_modified' ).val() == 'true' )
window.onbeforeunload = function() { return "You have unsaved changes."; }
});
But from what I figure is that the change() event works only after these 3 steps - a field receives focus, a value is changed and the field looses focus. In case of the hidden input field, I'm not sure how this receiving and loosing focus part works! Hence, the onbeforeunload function is never being activated.
Can anyone suggest a way to maintain a trigger over is_modified?
Thanks.
I had a similar requirement so came up with following jQuery script:
$(document).ready(function() {
needToConfirm = false;
window.onbeforeunload = askConfirm;
});
function askConfirm() {
if (needToConfirm) {
// Put your custom message here
return "Your unsaved data will be lost.";
}
}
$("select,input,textarea").change(function() {
needToConfirm = true;
});
The above code checks the needToConfirm variable, if its true then it will display warning message.
Whenever input, select or textarea elements value is changed, needToConfirm variable is set to true.
PS: Firefox > 4 don't allow custom message for onbeforeunload.
Reference: https://bugzilla.mozilla.org/show_bug.cgi?id=588292
UPDATE: If you are a performance freak, you will love #KyleMit's suggestion.
He wrote a jQuery extension only() which will be executed only once for any element.
$.fn.only = function (events, callback) {
//The handler is executed at most once for all elements for all event types.
var $this = $(this).on(events, myCallback);
function myCallback(e) {
$this.off(events, myCallback);
callback.call(this, e);
}
return this
};
$(":input").only('change', function() {
needToConfirm = true;
});
The following works well in jQuery:
var needToConfirm = false;
$("input,textarea").on("input", function() {
needToConfirm = true;
});
$("select").change(function() {
needToConfirm = true;
});
window.onbeforeunload = function(){
if(needToConfirm) {
return "If you exit this page, your unsaved changes will be lost.";
}
}
And if the user is submitting a form to save the changes, you might want to add this (change #mainForm to the ID of the form they're submitting):
$("#mainForm").submit(function() {
needToConfirm = false;
});
We just use Window.onbeforeunload as our "changed" flag. Here's what we're doing, (using lowpro):
Event.addBehavior({
"input[type=radio]:change,input[type=text]:change,input[type=checkbox]:change,select:change": function(ev) {
window.onbeforeunload = confirmLeave;
}
".button.submit-button:click": function(ev) {
window.onbeforeunload = null;
},
});
function confirmLeave(){
return "Changes to this form have not been saved. If you leave, your changes will be lost."
}
$(window).bind('beforeunload',function() {
return "'Are you sure you want to leave the page. All data will be lost!";
});
$('#a_exit').live('click',function() {
$(window).unbind('beforeunload');
});
Above works For me.
Try your logic in a different manner. Meaning, put the logic for checking the value of the input field in your onbeforeunload method.
window.onbeforeunload = function () {
if ($("#is_modified").val() == 'true') {
return "You have unsaved changes.";
} else {
return true; // I think true is the proper value here
}
};
in IE9 you can use simple return statement (re) which will not display any dialogue box. happy coding..
why not have the onbeforeunload call a function that checks if the values have changed, and if so return the "unsaved changes" confirm?

Categories

Resources