Keep value after submit form - javascript

I have this category checkbox where if I select certain values it will display div size but also in the same time when I select the checkbox it will submit the form. The problem is if I add this.form.submit() , the code below won't work and the form won't submit the value, but if I don't add it, the code will work.
How do I display div size and submit the form at the same time?
function getIds(checkboxName) {
let checkBoxes = document.getElementsByName(checkboxName);
let ids = Array.prototype.slice.call(checkBoxes)
.filter(ch => ch.checked==true)
.map(ch => ch.value);
return ids;
}
$(".category").on('change', function() {
this.form.submit();
let catIds = getIds("category[]");
$.each(catIds, function(index, value){
if (value == '1' || value == '2') {
$("#size").show();
} else if (value == '3') {
$("#size").hide();
}
});
});

This sounds like a racing problem. The form gets put into a different thread by the browser and gets handled first before the rest of the javascript is able to finish.
A quick (but dirty) hotfix for me is usually to use the setTimeout() method.
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
That way the javascript can work it's magic and afterwards the form gets submitted.

Related

Jquery issue with val not working as expected

I have a couple of forms on a site. On the first form I used the code below to add a border color if the input field is not blank and remove it if it is blank. This works just fine no issues. But I've found that when I try to use the same method on other forms, to do something else using the same logic, it does not work.
I have read through many forums and what I'm seeing is that the code is only read on page load. But I have forms that run the function after the page is far past loading. Can someone give some light to this? I'm really trying to understand the way this works fully.
Code that works on form:
var checkErrorIn;
jQuery(document).ready(function ($) {
checkErrorIn = setInterval(CheckErrorInput, 0);
});
function CheckErrorInput() {
if (jQuery('body').is('.page-id-6334')) {
// First Name, Last Name validation colors
var pasdFName = jQuery('#first_name').val();
var pasdLName = jQuery('#last_name').val();
if (pasdFName != '') {
jQuery('#first_name').addClass('formConfirm_cc');
} else {
jQuery('#first_name').removeClass('formConfirm_cc');
}
if (pasdLName != '') {
jQuery('#last_name').addClass('formConfirm_cc');
} else {
jQuery('#last_name').removeClass('formConfirm_cc');
}
if (pasdFName != '' & pasdLName == '') {
jQuery('#last_name').addClass('formError_cc');
} else {
jQuery('#last_name').removeClass('formError_cc');
}
if (pasdFName == '' & pasdLName != '') {
jQuery('#first_name').addClass('formError_cc');
} else {
jQuery('#first_name').removeClass('formError_cc');
}
}
}
Code that is not working:
if (jQuery('body').is('.woocommerce-page')) {
var checkActiveName = jQuery('.woo_login_form > form > #username').val();
jQuery('.woo_login_form').on('input', function(){
jQuery('.woo_login_form').addClass('cdc_keep_active');
});
if (checkActiveName =='') {
jQuery('.woo_login_form').removeClass('cdc_keep_active');
}
}
What I am trying to do is fix an issue with a form becoming hidden if not hovered over even when the input has characters. Based on my research I figured I'd do the .on to get the class added when the input got characters. That works but the removal of the characters isn't removing the class. The logic looks right to me. What am I missing?
Thank you in advance for your help and insight.
Update:
Ok so I ended up doing this:
jQuery('.woo_login_form').on('click', function () {
jQuery('.woo_login_form').addClass('cdc_keep_active');
});
jQuery('.custom-login-box > a').on('click', function () {
jQuery('.woo_login_form').toggle();
});
For some reason my class would not add with any of the methods suggested individually so I combined the logic. The first part adds the class that makes the form visible but then the form won't close if clicked out of regardless of the 'removeClass'. So I added a toggle (thank you commenters) method to the "hovered link" to allow users to close the box if not needed.
Would still like to understand why the first method worked in one instance but not the other. Any and all insight appreciated. Thank you.
In your current code example you immediately check for the value of the username field.
var checkActiveName = jQuery('.woo_login_form > form > #username').val();
The thing with this is that checkActiveName will never change, unless it is reassigned elsewhere in the code.
What you need to do is to check the current value after every input of the user. That means moving that line of reading the value of the input inside the input event listener.
if (jQuery('body').is('.woocommerce-page')) {
var $wooLoginForm = jQuery('.woo_login_form');
var $userName = jQuery('#username'); // This ID should only exist once, so no need for complex selectors.
$wooLoginForm.on('input', function() {
var checkActiveName = $userName.val();
if (checkActiveName =='') {
$wooLoginForm.removeClass('cdc_keep_active');
} else {
$wooLoginForm.addClass('cdc_keep_active');
}
});
}
On a sidenote: using setInterval to validate your form is a bad practice. This would basically run infinitely. It doesn't have to. You only have to check if a form is valid after the user enters a value.
Apply the same technique with the event listener like in your second code snippet.
var $document = jQuery(document);
$document.ready(function ($) {
/**
* It might even be better to listen for the input event on the form
* that has to be validated, but I didn't see it in your code.
* Right now it listens for input on the entire page.
*/
$document.on('input', CheckErrorInput);
});

Using Blur and Submit events on the same form

I am still confused about this. Started learning JQuery about a week now and this is what I have:
var IsValidUserName = false;
$(document).ready(function () {
$('#txtUserName').blur(function () {
if ($('#txtUserName').val().match(isNumberLetter) &&
($('#txtUserName').val().length >= 8)) {
$('#userNameError').removeClass("error").addClass("default");
$('#txtUserName').removeClass("alert");
$('#txtUserName + label').removeAttr("id", "lblUserName");
IsValidUserName = true;
}
else {
$('#userNameError').removeClass("default").addClass("error");
$('#txtUserName').addClass("alert");
$('#txtUserName + label').attr("id", "lblUserName");
}
});
});
Lets say I have another function like above, lets say FirstName:
How do I call this on the submit event? The code works as I need it to when the user leaves a field. Not sure how I can also call this code and also use the variable above to prevent submit if the data entered is invalid.
I need to call the validation above if the user clicks the submit button and stop the submission if the IsValidUserName variable is false.
Somethings just need a little push.
Thanks my friends.
Guy
You could always extract it into a function instead of an anonymous function and pass the reference to the object you want to check. This would give you the added benefit of reusing it for other elements.
function validate(ele) {
var valid;
if (ele.val().match(isNumberLetter)) && (ele.val().length >= 8)) {
valid = true;
// update user here.
} else {
valid = false;
// update user here.
}
return valid;
}
$(function(){
$('#firstName').blur(function(){ validate($(this)); });
$('#lastName').blur(function(){ validate($(this)); });
$("yourFrom").submit(function(){
var firstNameIsValid = validate($('#firstName'));
var lastNameIsValid = validate($('#lastName'));
if (!nameIsValid) && (!lastNameIsValid) {
return false;
// User has already been updated
}
});
});
Also, since you are already heavily using javascript for your validation (hope this is convenience and not the only security), you can also disable the submit button entirely until the form meets the proper requirements.

How to test if users has made any changes to a form if they haven't saved it

Basically the same functionality as stackoverflow when posting a question, if you start writing a post then try to reload the page. You get a javascript alert box warning message.
I understand how to check if the form has been changed, although how do I do the next step.
I.E: How to I check this when leaving the page, on here you get "This page is asking you to confirm that you want to leave - data you have entered may not be saved."?
EDIT: found correct answer here to another question https://stackoverflow.com/a/2366024/560287
I'm very sure that if you search, 'jQuery detect form change plugin', you will find something much more usable than this semi-pseudo code i'm about to write:
formChanged = function(form) {
form.find('input[type="text"], textarea').each(function(elem) {
if (elem.defaultValue != elem.value) {
return true;
}
});
// repeat for checkbox/radio: .defaultChecked
// repeat for ddl/listbox: .defaultSelected
return false;
}
usage:
if (formChanged($('form')) { // do something }
Note that this is to detect changes against the original rendered value. For instance, if a textbox has a value = "x", and the user changes it to "y", then changes it back to "x"; this will detect it as NO change.
If you do not care about this scenario, you can just do this:
window.formChanged = false;
$(':input').change(function() {
window.formChanged = true;
});
Then you can just check that value.
Yes, it is JavaScript as HTML is just a markup language.
Yes, jQuery can be used for this. It's preferable over vanilla JavaScript as it makes things easier, although it does add some overhead.
There are a number of ways to check if any of a form's controls have changed.
To check for changes from the default, most can be checked against the defaultValue property. For radio buttons, you should always have one checked by default, so check if it's still selected or not. Similarly for selects, set the selected attribute for the default option and see if it's still selected, and so on.
Alternatively, if all your form controls have an ID or unique name, you can collect all their values onload and then check their values when the form is submitted.
Another method is to listen for change events on each form control, but that is a bit over the top.
Here's a POJS version that takes the same approach as rkw's answer:
/*
Check if any control in a form has changed from its default value.
Checks against the default value for inputs and textareas,
defaultChecked for radio buttons and checkboxes, and
default selected for select (option) elements.
*/
function formChanged(form) {
var control, controls = form.elements;
var tagName, type;
for (var i=0, iLen=controls.length; i<iLen; i++) {
control = controls[i];
tagName = control.tagName.toLowerCase();
type = control.type;
// textarea
if (tagName == 'textarea') {
if (control.value != control.defaultValue) {
return true;
}
// input
} else if (tagName == 'input') {
// text
if (type == 'text') {
if (control.value != control.defaultValue) {
return true;
}
// radio and checkbox
} else if (type == 'radio' || type == 'checkbox') {
if (control.checked != control.defaultChecked) {
return true;
}
}
// select multiple and single
} else if (tagName == 'select') {
var option, options = control.options;
for (var j=0, jLen=options.length; j<jLen; j++) {
option = options[j];
if (option.selected != option.defaultSelected) {
return true;
}
}
}
}
// Not really needed, but some like the return value to
// be a consistent Type
return false;
}
Note that you need to be careful with select elements. For a single select, you should always set one option to selected, as if there is no default selected, some browsers will make the first option selected and others wont.

Disabling/enabling a button based on multiple other controls using Javascript/jQuery

I have a bunch of controls:
When a user clicks the Generate button, a function uses all of the values from the other controls to generate a string which is then put in the Tag text box.
All of the other controls can have a value of null or empty string. The requirement is that if ANY of the controls have no user entered value then the Generate button is disabled. Once ALL the controls have a valid value, then the Generate button is enabled.
What is the best way to perform this using Javascript/jQuery?
This can be further optimized, but should get you started:
var pass = true;
$('select, input').each(function(){
if ( ! ( $(this).val() || $(this).find(':selected').val() ) ) {
$(this).focus();
pass = false;
return false;
}
});
if (pass) {
// run your generate function
}
http://jsfiddle.net/ZUg4Z/
Note: Don't use this: if ( ! ( $(this).val() || $(this).find(':selected').val() ) ).
It's just for illustration purposes.
This code assumes that all the form fields have a default value of the empty string.
$('selector_for_the_parent_form')
.bind('focus blur click change', function(e){
var
$generate = $('selector_for_the_generate_button');
$generate.removeAttr('disabled');
$(this)
.find('input[type=text], select')
.each(function(index, elem){
if (!$(elem).val()) {
$generate.attr('disabled', 'disabled');
}
});
});
Basically, whenever an event bubbles up to the form that might have affected whether the generate button ought to be displayed, test whether any inputs have empty values. If any do, then disable the button.
Disclaimer: I have not tested the code above, just wrote it in one pass.
If you want the Generate button to be enabled as soon as the user presses a key, then you probably want to capture the keypress event on each input and the change event on each select box. The handlers could all point to one method that enables/disables the Generate button.
function updateGenerateButton() {
if (isAnyInputEmpty()) {
$("#generateButton").attr("disabled", "disabled");
} else {
$("#generateButton").removeAttr("disabled");
}
}
function isAnyInputEmpty() {
var isEmpty = false;
$("#input1, #input2, #select1, #select2").each(function() {
if ($(this).val().length <= 0) {
isEmpty = true;
}
});
return isEmpty;
}
$("#input1, #input2").keypress(updateGenerateButton);
$("#select1, #select2").change(updateGenerateButton);
The above assumes that your input tags have "id" attributes like input1 and select2.

Onsubmit validate change background requried fields?

Anyone know of a good tutorial/method of using Javascript to, onSubmit, change the background color of all empty fields with class="required" ?
Something like this should do the trick, but it's difficult to know exactly what you're looking for without you posting more details:
document.getElementById("myForm").onsubmit = function() {
var fields = this.getElementsByClassName("required"),
sendForm = true;
for(var i = 0; i < fields.length; i++) {
if(!fields[i].value) {
fields[i].style.backgroundColor = "#ff0000";
sendForm = false;
}
else {
//Else block added due to comments about returning colour to normal
fields[i].style.backgroundColor = "#fff";
}
}
if(!sendForm) {
return false;
}
}
This attaches a listener to the onsubmit event of the form with id "myForm". It then gets all elements within that form with a class of "required" (note that getElementsByClassName is not supported in older versions of IE, so you may want to look into alternatives there), loops through that collection, checks the value of each, and changes the background colour if it finds any empty ones. If there are any empty ones, it prevents the form from being submitted.
Here's a working example.
Perhaps something like this:
$(document).ready(function () {
$('form').submit(function () {
$('input, textarea, select', this).foreach(function () {
if ($(this).val() == '') {
$(this).addClass('required');
}
});
});
});
I quickly became a fan of jQuery. The documentation is amazing.
http://docs.jquery.com/Downloading_jQuery
if You decide to give the library a try, then here is your code:
//on DOM ready event
$(document).ready(
// register a 'submit' event for your form
$("#formId").submit(function(event){
// clear the required fields if this is the second time the user is submitting the form
$('.required', this).removeClass("required");
// snag every field of type 'input'.
// filter them, keeping inputs with a '' value
// add the class 'required' to the blank inputs.
$('input', this).filter( function( index ){
var keepMe = false;
if(this.val() == ''){
keepMe = true;
}
return keepMe;
}).addClass("required");
if($(".required", this).length > 0){
event.preventDefault();
}
});
);

Categories