I have created this function in JQuery:
function CheckRequired() {
var ret = true;
$(".required").each( function() {
var check = $(this).val();
if(check == '') {
//alert($(this).attr("id"));
ret = false;
}
});
if(!ret) {
alert("One or more fields cannot be blank");
return false;
}
}
on my forms submit buttons, i run this onClick
<input type="submit" onClick="CheckRequired();" />
if any fields in the form with a class of required have a blank value the error will alert to the user and the form should not submit.
the alert is showing, however the form still seems to be submitting
use preventDefault. This method makes sure the default action of the event will not be triggered.
function CheckRequired(event) {
var ret = true;
$(".required").each( function() {
var check = $(this).val();
if(check == '') {
//alert($(this).attr("id"));
event.preventDefault();
}
});
if(!ret) {
alert("One or more fields cannot be blank");
event.preventDefault();
}
}
To prevent form from submission you should bind event to form's onsubmit, and return function result
<form onsubmit="return CheckRequired()" />
Also, as you already use jquery it would be much more convenient to bind events in javascript:
$('#form_id').submit(function(){
//your form submit code
})
I think you have to prevent the default submission action by using event.preventDefault(); as noted here:
Prevent submit button with onclick event from submitting
I have a form with some fields on. I am still learning Javascript. When my is submitted it triggers my JS which checks if the fields was submitted and then displays the errors in a which is done through innerhtml. Problem is it only display's the div for a few seconds and then finishes reloading the page and the div is not displayed anymore.
function checkradio() {
chosen = ""
len = document.cv.Radio1.length
for (i = 0; (i<2); i++) {
if (document.cv.Radio1[i].checked) {
chosen = document.cv.Radio1[i].value
}
}
if (chosen == "") {
document.getElementById('error-1').innerHTML = "Please choose a type";
document.getElementById("Radio1").focus();
}
}
You need to add
e.preventDefault();
for avoiding the default behavior.
Hence, if validation fails, the form won't be submitted.
please check whether your using normal HTML input element or ASP.NET server element. If your using Server element like then page will send back to server(reloaded) when click on button. the details you gave above is not enough.
you need to prevent the default behaviour if validation fails
you most likely do the validation on submit sth like:
$('form').submit(function(e){
check = checkradio() // let your function return true or false
if(!check){
e.preventDefault(); // add this to not submit the form
}
});
so the form will not submit if the validation fails
your tweaked validate function could look like this :
function checkradio() {
chosen = ""
len = document.cv.Radio1.length
for (i = 0; (i<2); i++) {
if (document.cv.Radio1[i].checked) {
chosen = document.cv.Radio1[i].value
}
}
if (chosen == "") {
document.getElementById('error-1').innerHTML = "Please choose a type";
document.getElementById("Radio1").focus();
return false;
}else {
return true;
}
}
I have form that calls the function GenerateWords when it is submitted and returns false.
<form id="3Form" onsubmit="GenerateWords(this); return false;">
This is causing problems with Google Tag Manager implementation as it does not bubble up to the form submit listener.
I understand event.preventDefault(); needs to be used and return false removed but don't know how to implement this. The current javascript I have is:
function GenerateWords(F) {
var strWords = F.words.value;
if ... condition is false
return false;
}
if ... condition is false
return false;
}
vars declared
for (var i = 0; i < ctLines; i++) {
var strLine = arrLines[i];
strLine = Trim(strLine.replace(/[\r]/g,""));
if successful condition
}
}
F.result.value = oResult.join("");
F.result.focus();
}
Any help would be appreciated. Thanks.
Try this in javascript:
function GenerateWords(F,ev) { // event object
...
if(someCondition) // condition when the form should not be submitted.
ev.preventDefault();
}
and you may remove return false; from the form tag and pass the event reference
<form id="3Form" onsubmit="GenerateWords(this,event);">
A couple of questions here:
I was wondering what event do I use to execute some Javascript on form submission (to do some validation)?
Once I have done my validation, how do I then submit the form in Javascript ?
Let's say you have a form named myForm:
var form = document.getElementById('myForm');
To catch submission:
try {
form.addEventListener("submit", someFunction, false);
} catch(e) {
form.attachEvent("onsubmit", someFunction); //Internet Explorer 8-
}
Note: If you want to stop the form from submitting, you make someFunction return false.
To submit the form:
form.submit();
You can use addEventListener(event, callback) but it's never been properly supported by Internet Explorer.
IE uses attachEvent(event, callback) instead.
I strongly recommend using a prebuilt addEvent function (lots available out there) or a library like jQuery, Prototype, Mootools, etc. since they all have excellent event handling functions built-in.
If you use jquery, it has a nice built-in form submission event hook that can make life very easy. Check out the following:
http://docs.jquery.com/Events/submit
1) Are you looking for OnSubmit event?
2) You can call a function like validate() on onsubmit event and return false if validation fails. If false returned return false from the onsubmit function.
may be like,
<form name="test" OnSubmit = "return Submit()">
function Submit()
{
return Validate()
}
function Validate()
{
//Validation code goes here
}
I took a look at the comments by Serhiy on Sasha's post. The JsFiddle example Serhiy provided was interesting, and I wanted to write an answer that describes the behavior that Serhiy mentioned:
Let's say you have a form named myForm:
var form = document.getElementById('myForm');
To catch submission when using a submit button (<input type='submit' >):
try {
form.addEventListener("submit", validationFunction, false);
} catch(e) {
form.attachEvent("onsubmit", validationFunction); //Internet Explorer 8-
}
Note: If you want to stop the form from submitting, you make validationFunction return false.
To submit the form via javascript:
form.submit();
NOTE: If you use an <input type="button" onclick="form.submit()" />, the onsubmit event handlers added with the attachEvent will not be called. Therefore, you should use something like:
<input type="button" onclick="if (validationfunction()) form.submit();" />
or alternatively if you have a button:
You can add javascript to attach to the button's click event.
var btnValidateAndSubmit = document.getElementById("btnValidateAndSubmit");
try {
btnValidateAndSubmit .addEventListener("click", validationAndSubmitFunction, false);
} catch(e) {
btnValidateAndSubmit .attachEvent("onclick", validationAndSubmitFunction); //Internet Explorer 8-
}
Finally, let's say you are working off a SharePoint web form for editing a list item, and you want to add custom validation to the web form. You can add the following javascript to the web form to add custom validation to the onclick for the OK buttons.
var oElements = document.getElementsByTagName("input");
for (var i=0; i< oElements.length; i++)
{
var elementName = oElements[i].getAttribute("Title");
var elementType = oElements[i].getAttribute("type");
var elementValue = oElements[i].value;
if (elementType=="button" && elementValue=="OK")
{
var okbutton = oElements[i];
// alert("typeof okbutton.onclick = "+typeof okbutton.onclick);
if (typeof okbutton.onclick == "function")
{
var previousfunction = okbutton.onclick;
okbutton.onclick = function()
{
if (validateForm())
{
previousfunction();
}
};
}
else
{
var aspnetForm = document.getElementById("aspnetForm");
aspnetForm.attachEvent("onsubmit",validateForm);
okbutton.onclick = function()
{
if (validateForm())
{
aspnetForm.submit();
}
};
}
}
}
I'd like to track changes in inputs in a form via javascript. My intent is (but not limited) to
enable "save" button only when something has changed
alert if the user wants to close the page and something is not saved
Ideas?
Loop through all the input elements, and put an onchange handler on each. When that fires, set a flag which lets you know the form has changed. A basic version of that would be very easy to set up, but wouldn't be smart enough to recognize if someone changed an input from "a" to "b" and then back to "a". If it were important to catch that case, then it'd still be possible, but would take a bit more work.
Here's a basic example in jQuery:
$("#myForm")
.on("input", function() {
// do whatever you need to do when something's changed.
// perhaps set up an onExit function on the window
$('#saveButton').show();
})
;
Text form elements in JS expose a .value property and a .defaultValue property, so you can easily implement something like:
function formChanged(form) {
for (var i = 0; i < form.elements.length; i++) {
if(form.elements[i].value != form.elements[i].defaultValue) return(true);
}
return(false);
}
For checkboxes and radio buttons see whether element.checked != element.defaultChecked, and for HTML <select /> elements you'll need to loop over the select.options array and check for each option whether selected == defaultSelected.
You might want to look at using a framework like jQuery to attach handlers to the onchange event of each individual form element. These handlers can call your formChanged() code and modify the enabled property of your "save" button, and/or attach/detach an event handler for the document body's beforeunload event.
Here's a javascript & jquery method for detecting form changes that is simple. It disables the submit button until changes are made. It detects attempts to leave the page by means other than submitting the form. It accounts for "undos" by the user, it is encapsulated within a function for ease of application, and it doesn't misfire on submit. Just call the function and pass the ID of your form.
This function serializes the form once when the page is loaded, and again before the user leaves the page. If the two form states are different, the prompt is shown.
Try it out: http://jsfiddle.net/skibulk/ev5rE/
function formUnloadPrompt(formSelector) {
var formA = $(formSelector).serialize(), formB, formSubmit = false;
// Detect Form Submit
$(formSelector).submit( function(){
formSubmit = true;
});
// Handle Form Unload
window.onbeforeunload = function(){
if (formSubmit) return;
formB = $(formSelector).serialize();
if (formA != formB) return "Your changes have not been saved.";
};
// Enable & Disable Submit Button
var formToggleSubmit = function(){
formB = $(formSelector).serialize();
$(formSelector+' [type="submit"]').attr( "disabled", formA == formB);
};
formToggleSubmit();
$(formSelector).change(formToggleSubmit);
$(formSelector).keyup(formToggleSubmit);
}
// Call function on DOM Ready:
$(function(){
formUnloadPrompt('form');
});
Try
function isModifiedForm(form){
var __clone = $(form).clone();
__clone[0].reset();
return $(form).serialize() == $(__clone).serialize();
}
Hope its helps ))
If your using a web app framework (rails, ASP.NET, Cake, symfony), there should be packages for ajax validation,
http://webtecker.com/2008/03/17/list-of-ajax-form-validators/
and some wrapper on onbeforeunload() to warn users taht are about to close the form:
http://pragmatig.wordpress.com/2008/03/03/protecting-userdata-from-beeing-lost-with-jquery/
Detecting Unsaved Changes
I answered a question like this on Ars Technica, but the question was framed such that the changes needed to be detected even if the user does not blur a text field (in which case the change event never fires). I came up with a comprehensive script which:
enables submit and reset buttons if field values change
disables submit and reset buttons if the form is reset
interrupts leaving the page if form data has changed and not been submitted
supports IE 6+, Firefox 2+, Safari 3+ (and presumably Opera but I did not test)
This script depends on Prototype but could be easily adapted to another library or to stand alone.
$(document).observe('dom:loaded', function(e) {
var browser = {
trident: !!document.all && !window.opera,
webkit: (!(!!document.all && !window.opera) && !document.doctype) ||
(!!window.devicePixelRatio && !!window.getMatchedCSSRules)
};
// Select form elements that won't bubble up delegated events (eg. onchange)
var inputs = $('form_id').select('select, input[type="radio"], input[type="checkbox"]');
$('form_id').observe('submit', function(e) {
// Don't bother submitting if form not modified
if(!$('form_id').hasClassName('modified')) {
e.stop();
return false;
}
$('form_id').addClassName('saving');
});
var change = function(e) {
// Paste event fires before content has been pasted
if(e && e.type && e.type == 'paste') {
arguments.callee.defer();
return false;
}
// Check if event actually results in changed data
if(!e || e.type != 'change') {
var modified = false;
$('form_id').getElements().each(function(element) {
if(element.tagName.match(/^textarea$/i)) {
if($F(element) != element.defaultValue) {
modified = true;
}
return;
} else if(element.tagName.match(/^input$/i)) {
if(element.type.match(/^(text|hidden)$/i) && $F(element) != element.defaultValue) {
modified = true;
} else if(element.type.match(/^(checkbox|radio)$/i) && element.checked != element.defaultChecked) {
modified = true;
}
}
});
if(!modified) {
return false;
}
}
// Mark form as modified
$('form_id').addClassName('modified');
// Enable submit/reset buttons
$('reset_button_id').removeAttribute('disabled');
$('submit_button_id').removeAttribute('disabled');
// Remove event handlers as they're no longer needed
if(browser.trident) {
$('form_id').stopObserving('keyup', change);
$('form_id').stopObserving('paste', change);
} else {
$('form_id').stopObserving('input', change);
}
if(browser.webkit) {
$$('#form_id textarea').invoke('stopObserving', 'keyup', change);
$$('#form_id textarea').invoke('stopObserving', 'paste', change);
}
inputs.invoke('stopObserving', 'change', arguments.callee);
};
$('form_id').observe('reset', function(e) {
// Unset form modified, restart modified check...
$('reset_button_id').writeAttribute('disabled', true);
$('submit_button_id').writeAttribute('disabled', true);
$('form_id').removeClassName('modified');
startObservers();
});
var startObservers = (function(e) {
if(browser.trident) {
$('form_id').observe('keyup', change);
$('form_id').observe('paste', change);
} else {
$('form_id').observe('input', change);
}
// Webkit apparently doesn't fire oninput in textareas
if(browser.webkit) {
$$('#form_id textarea').invoke('observe', 'keyup', change);
$$('#form_id textarea').invoke('observe', 'paste', change);
}
inputs.invoke('observe', 'change', change);
return arguments.callee;
})();
window.onbeforeunload = function(e) {
if($('form_id').hasClassName('modified') && !$('form_id').hasClassName('saving')) {
return 'You have unsaved content, would you really like to leave the page? All your changes will be lost.';
}
};
});
I would store each fields value in a variable when the page loads, then compare those values when the user unloads the page. If any differences are detected you will know what to save and better yet, be able to specifically tell the user what data will not be saved if they exit.
// this example uses the prototype library
// also, it's not very efficient, I just threw it together
var valuesAtLoad = [];
var valuesOnCheck = [];
var isDirty = false;
var names = [];
Event.observe(window, 'load', function() {
$$('.field').each(function(i) {
valuesAtLoad.push($F(i));
});
});
var checkValues = function() {
var changes = [];
valuesOnCheck = [];
$$('.field').each(function(i) {
valuesOnCheck.push($F(i));
});
for(var i = 0; i <= valuesOnCheck.length - 1; i++ ) {
var source = valuesOnCheck[i];
var compare = valuesAtLoad[i];
if( source !== compare ) {
changes.push($$('.field')[i]);
}
}
return changes.length > 0 ? changes : [];
};
setInterval(function() { names = checkValues().pluck('id'); isDirty = names.length > 0; }, 100);
// notify the user when they exit
Event.observe(window, 'beforeunload', function(e) {
e.returnValue = isDirty ? "you have changed the following fields: \r\n" + names + "\r\n these changes will be lost if you exit. Are you sure you want to continue?" : true;
});
I've used dirtyforms.js. Works well for me.
http://mal.co.nz/code/jquery-dirty-forms/
To alert the user before closing, use unbeforeunload:
window.onbeforeunload = function() {
return "You are about to lose your form data.";
};
I did some Cross Browser Testing.
On Chrome and Safari this is nice:
<form onchange="validate()">
...
</form>
For Firefox + Chrome/Safari I go with this:
<form onkeydown="validate()">
...
<input type="checkbox" onchange="validate()">
</form>
Items like checkboxes or radiobuttons need an own onchange event listener.
Attach an event handler to each form input/select/textarea's onchange event. Setting a variable to tell you if you should enable the "save" button. Create an onunload hander that checks for a dirty form too, and when the form is submitted reset the variable:
window.onunload = checkUnsavedPage;
var isDirty = false;
var formElements = //Get a reference to all form elements
for(var i = 0; len = formElements.length; i++) {
//Add onchange event to each element to call formChanged()
}
function formChanged(event) {
isDirty = false;
document.getElementById("savebtn").disabled = "";
}
function checkUnsavedPage() {
if (isDirty) {
var isSure = confirm("you sure?");
if (!isSure) {
event.preventDefault();
}
}
}
Here's a full implementation of Dylan Beattie's suggestion:
Client/JS Framework for "Unsaved Data" Protection?
You shouldn't need to store initial values to determine if the form has changed, unless you're populating it dynamically on the client side (although, even then, you could still set up the default properties on the form elements).
You can also check out this jQuery plugin I built at jQuery track changes in forms plugin
See the demo here and download the JS here
If you are open to using jQuery, see my answer a similar question:
Disable submit button unless original form data has changed.
I had the same challenge and i was thinking of a common solution. The code below is not perfect, its from initial r&d. Following are the steps I used:
1) Move the following JS to a another file (say changeFramework.js)
2) Include it in your project by importing it
3) In your html page, whichever control needs monitoring, add the class "monitorChange"
4) The global variable 'hasChanged' will tell, if there is any change in the page you working on.
<script type="text/javascript" id="MonitorChangeFramework">
// MONITOR CHANGE FRAMEWORK
// ALL ELEMENTS WITH CLASS ".monitorChange" WILL BE REGISTERED FOR CHANGE
// ON CHANGE IT WILL RAISE A FLAG
var hasChanged;
function MonitorChange() {
hasChanged = false;
$(".monitorChange").change(function () {
hasChanged = true;
});
}
Following are the controls where I used this framework:
<textarea class="monitorChange" rows="5" cols="10" id="testArea"></textarea></br>
<div id="divDrinks">
<input type="checkbox" class="chb monitorChange" value="Tea" />Tea </br>
<input type="checkbox" class="chb monitorChange" value="Milk" checked='checked' />Milk</br>
<input type="checkbox" class="chb monitorChange" value="Coffee" />Coffee </br>
</div>
<select id="comboCar" class="monitorChange">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<button id="testButton">
test</button><a onclick="NavigateTo()">next >>> </a>
I believe there can be huge improvement in this framework. Comment/Changes/feedbacks are welcome. :)