Form won't submit once error checking breaks it - javascript

I'm working on a project where I have some error checking. However, the form wanted to submit each time so I had to break the submit. Here is what I did.
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "order-form" }))
{
...
<input type="submit" name="btnSaveOpv#(item.Id)" value="#T("Admin.Common.Save")" id="btnSaveOpv#(item.Id)" class="adminButton" style="display: none;" onclick="SaveBtn(#item.Id);" />
...
var originalIssuedQty = 0;
function SaveBtn(id) {
var quantity = parseInt($("#pvQuantity" + id).val());
var issuedQty = parseInt($("#pvIssuedQty" + id).val());
var stockQty = parseInt($("#hfStockQty" + id).val());
var availableStockQty = stockQty + parseInt(originalIssuedQty);
//Issued Quantity cannot exceed Quantity (you can't issue more than requested)
if (issuedQty > quantity) {
alert("Issued Quantity cannot exceed Quantity.");
$("#order-form").submit(function (e) { e.preventDefault(); });
return false;
}
//Make sure Issued Quantity is within Available Stock Quantity
if (issuedQty > availableStockQty) {
alert("There is not enough Products in Stock to issue this amount.");
$("#order-form").submit(function (e) { e.preventDefault(); });
return false;
}
//Present confirmation
var result = confirm('#T("Admin.Common.AreYouSure")');
if (!result) {
$("#order-form").submit(function (e) { e.preventDefault(); });
return false;
}
else {
$("#order-form").submit(function (e) { this.submit(); });
//$("#order-form").submit(function (e) { return true; });
}
}
...
}
Here is the problem. Whenever I try to submit the first time without triggering any of my error checking, things work. When I trigger the error checking, things work. However, if I fix the error and try to submit again, the page merely refreshes. Any ideas on this would be very helpful. Thanks.

You are making things too complicated.
This is a basic template on how you do validation and how you stop the form from submitting when it's not valid:
$(function() {
$("#order-form").submit(function (e) {
var isValid = false;
// Do your validation here and put the result in the variable isValid
if ( !isValid ) {
e.preventDefault(); // If the form is invalid stop the submit, otherwise proceed
}
});
});

Every time you call $("#order-form").submit(function (e) { whatever });, you add an additional handler function. It doesn't remove the handlers you've already added. This is probably why it breaks.
Repeatedly changing the submit event handler is a messy way to do it. Instead, you should have a single function which handles the submit event, and that function should do (or call) the error checking, and preventDefault() if necessary (like ZippyV is suggesting).

Related

jQuery and livequery error on javascript code not executing?

I have some very old javascript code on an existing site and I wanted to update it, but I'm running into errors and I'm not sure what to replace it with. The code is just part of a section where it does a .submit() call to the form. Then the code reaches the try condition, it throws the error that livequery is not a function. Code is also below the screenshot.
Also I'm not sure if the "var form" is outside the scope of the try for form to work or not. What could I have wrong here?
var submit = false;
var form = $("#webform-client-form-2")[0];
try {
if (repair) {
console.log('repair is true - line 317');
$(".simple-dialog").click();
$(".ui-dialog, .ui-widget-overlay").hide();
$(".form-actions").livequery(function() {
console.log('livequery - line 321');
$("#edit-submitted-name").val(subject_field);
$("#edit-submitted-phone").val(phone);
$("#edit-submitted-email").val(email);
$("#edit-submitted-details-of-issue").val(problem);
var find = $(".form-actions")[0]; //get the 1st form actions on the page. if more than 2 forms on page, this might submit wrong form.
if (!submit && find) {
console.log('repair is true - line 328');
submit = true;
$("#webform-client-form-2").submit();
$(".form-actions").expire();
return false;
}
});
} else if (contact) {
console.log('yyy');
console.log(form);
$("#edit-submitted-phone-number").val(phone);
$("#edit-submitted-message").val(problem);
$(form).submit();
} else {
console.log('zzz');
$(form).submit();
}
} catch (error) {
console.log(error);
console.log("no form - line 346");
}

Event handler preventing submit

I have the very simple code below that installs an event handler on confirmPass keystrokes. On registration form submit I want to be able to disable the submit if the passwords do not match. In the 'onClick' event for the registration form if I call confirmPass() it fails to submit, if I comment it out it submits. Why is confirmPass() blocking the programatic form submit?
$( document ).ready(function() {
console.log( "ready!" );
$('#confirmPassword').keyup(function(){
confirmPass();
})
});
function registrationSubmit(){
confirmPass();
$('#registration').submit();
}
function confirmPass() {
var pass = $('#password').val();
var cpass = $('#confirmPassword').val();
if (!(pass == cpass)) {
$('#confirmPassword').addClass('text-danger');
$('#cpassmsg').addClass('text-danger').removeClass('ui-helper-hidden');
$('#cpassmsg').text("Confirm Password Fails")
$('#registration').submit(function (event) {
event.preventDefault();
});
return;
} else {
$('#confirmPassword').addClass('text-success').removeClass('text-danger');
$('#cpassmsg').addClass('text-success').removeClass('text-danger');
$('#cpassmsg').text("Confirm Password Match!")
}
this line adds an event handler.
$('#registration').submit(function (event) {
event.preventDefault();
});
Which means every time the submit event is fired after this line have been hit it will be cancelled. Since you call confirmPass on each keystroke the line will be executed at least once and thus submits events on the form will always be cancelled. Instead you might want to only call submit only if the validations are succesfull and remove the line I mentionned above
Exemple
function registrationSubmit(event){
// Assuming you modify confirmPass to return true/false
if(confirmPass()){
$('#registration').submit();
}
}
You never remove the submit handlers that call preventDefault().
Instead of adding a handler in confirmPass(), check whether the password is valid in registrationSubmit(). Have confirmPass() return a boolean to indicate this.
$(document).ready(function() {
console.log("ready!");
$('#confirmPassword').keyup(function() {
confirmPass();
})
});
function registrationSubmit() {
if (confirmPass())
$('#registration').submit();
}
}
function confirmPass() {
var pass = $('#password').val();
var cpass = $('#confirmPassword').val();
if (pass != cpass) {
$('#confirmPassword').addClass('text-danger');
$('#cpassmsg').addClass('text-danger').removeClass('ui-helper-hidden');
$('#cpassmsg').text("Confirm Password Fails")
return false;
} else {
$('#confirmPassword').addClass('text-success').removeClass('text-danger');
$('#cpassmsg').addClass('text-success').removeClass('text-danger');
$('#cpassmsg').text("Confirm Password Match!");
return true;
}
}

Stop redirect in JavaScript

I have a function which verifies if some fields have been filled out (if length > 0) before submitting. If it fails to submit, I don't want to redirect the client at all. Right now, I have the following:
function onSubmit()
{
if (verify()) //This function will throw alert statements automatically
{
document.getElementById('my_form').submit();
return void(0);
}
else
{
document.getElementById('my_form').action = null;
}
}
However, it doesn't matter if verify() returns true or not, I still redirect the client and wipe her inputted fields. How do I keep the client on the page if a required field is blank? (I don't want to lose her currently filled out form...)
Also, I can't use the slick JQuery libraries, since it's not supported on some older browsers. (I'm trying to capture the most general audience.)
This is how I would try to solve this:
document.getElementById('my_form').onsubmit = function( e ){
var event = e || window.event;
// function payload goes here.
event.returnValue = false;
if ( event.preventDefault ){ event.preventDefault(); }
return false;
}
Can be used with event delegation too.
return false to the form!
<form onsubmit="return onSubmit()">
function onSubmit()
{
if (verify()) //This function will throw alert statements automatically
{
return true;
}
else
{
return false;
}
}
to stop the form from submitting, return false from your onSubmit

Respect regular onsubmit handlers from jQuery.submit

I want a jQuery form submit handler to respect any previous submit handlers, including ones added with onsubmit.
I'm trying to detect the previous handler's return value but can't seem to do it:
<form><input type="submit" /></form>
<script type="text/javascript">
$('form')[0].onsubmit = function() { return false; }; // called first
$('form').submit(function(e) {
console.log(e.result); // undefined
console.log(e.isDefaultPrevented()); // false
console.log(e.isPropagationStopped()); // false
console.log(e.isImmediatePropagationStopped()); // false
});
</script>
Is there a way to do this?
I found one non-jQuery way to do this:
var form = $('form')[0];
var old_onsubmit = form.onsubmit;
form.onsubmit = function() {
if ($.isFunction(old_onsubmit)) {
if (old_onsubmit() === false) {
console.log("false");
return false;
}
}
console.log("true");
return true;
}
But I'd much prefer detecting this from the jQuery-bound submit handler

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