Im currently trying to do a form that requires the user to enter valid information.
For instance Here's a classic form: jsfiddle
I want the user to put name and address. But I want the button to be unclickable until the user inputs his Name and his Email(in a correct form).
Is there any property that lets me access if a button is unclickable? Something like:
function validateButtonSubmit {
if (validateEmail(email)) {
if (validateName(name)) {
document.getElementById("submitButton").clickable = true;
}
}
}
Whats the best way to accomplish this, am I going in the right direction?
You could probably shorten this up without the nesting if you wanted:
function validateButtonSubmit() {
var btnSubmit = document.getElementById("submitButton");
btnSubmit.disabled = !(validateEmail(email) && validateName(name));
}
Use disabled:
document.getElementById("submitButton").disabled = true;
You could call removeAttribute() on the element and then call setAttribute after you've validated the form:
var button = document.getElementById('submitButton');
button.removeAttribute('click');
// validation stuff
button.setAttribute('click', submitForm());
Related
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);
});
I want to use form serialization but exclude a button and a label from the serialization.
This is a version of the javascript I have:
var saveBtn = document.getElementById("btnSaveButton");
var saveLbl = document.getElementById("lblSaveLabel");
var originalFormData = $("#MasterForm").not(saveBtn, saveLbl).serialize();
$("form :input").on('change keyup paste mouseup', function () {
var newFormData = $("#MasterForm").serialize();
if (originalFormData != newFormData) {
//some code
} else {
//some other code
}
});
See: .not(saveBtn, saveLbl)
That is not excluding the button or the label.
Can someone please help me and let me know how I can exclude the button and the label from the serialization?
What essentially happens is I switch the display from the button to the label and back depending on whether the user has made any change to the form.
UPDATE UPDATE
Thank you for the responses ... appears something is amiss ...
There might be too much html to post here ...
Using vb.net. I have a master page, within it is a page called Admin.aspx, and within that is a usercontrol called Bundles.ascx.
In the code of Bundles.ascx I have this javascript:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(prmRequest);
prm.add_endRequest(prmRequest);
function prmRequest(sender, args) {
setupFormChangeCheck("btnSaveBundle", langId);
}
In a master javascript file I have the function setupFormChangeCheck, which looks like this:
function setupFormChangeCheck(txtName, langId) {
try {
savebtnFnctn('dis', txtName, langId)
var originalFormData = $("#MasterForm").serialize();
$("form :input").on('change keyup paste mouseup', function () {
var newFormData = $("#MasterForm").serialize();
if (originalFormData != newFormData) {
savebtnFnctn('en', txtName, langId)
} else {
savebtnFnctn('dis', txtName, langId)
}
});
} catch (err) { }
}
On the same master javascript file I have the function savebtnFunction, which looks like this:
function savebtnFnctn(event, txtName, langId) {
var saveBtn = document.getElementById(txtName);
var saveLbl = document.getElementById(txtName.replace("btn", "lbl"));
if (event == 'en') {
saveBtn.style.display = "inline";
saveLbl.style.display = "none";
} else if (event == 'dis') {
saveBtn.style.display = "none";
saveLbl.style.display = "inline";
}
}
The user control is loaded dynamically, because the same page has multiple use controls and unless I load the one control dynamically, all load ... slows things down incredibly.
Loading a user control dynamically leads to serious postback challenges. So, the vast majority of the user control interactions are handled client side with jquery. For Bundle.ascx this is done in Bundle.js
SOOOOO ....
When the user control is loaded, setupFormChangeCheck fires, which runs the 'dis' (disable) event in function savebtnFnctn.
Here is the problem I noticed today as I tried the code from suggestions above.
When I interact in the Bundle uc, setupFormChangeCheck does not fire from the beginning. What first fires is this line $("form :input").on('change keyup paste mouseup', function ()
And no matter what I do, click in a textbox even without changing anything, leads this: originalFormData != newFormData to be true and the Save button remains enabled ...
I should add that all the controls in the Bundle user control are inside an updatepanel:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
Long explanation I know, sorry ... if anyone has any idea to solve this, I would be eternally grateful.
Thank you. Erik
The jQuery's .not() method takes selector, not elements.
Also, you are matching the form itself, not the inputs of it.
Since you do know the IDs of the elements to exclude, use this instead:
var data = $("#MasterForm").find("input, textarea, select").not("#btnSaveButton, #lblSaveLabel").serialize();
You select the form.
Then you select the form elements underneath.
Then you exclude the concrete elements from the collection.
Lastly you serialize the results.
NOTE: You should use strict comparison !== instead of !=.
Friends i am new to javascript, I am trying to write a script to validate the entire form whenever any input field value is changed of input fiels with the data attribute of required.
HTML
<form>
<input type="text" name="FirstName" class="inputField" data-required="true"></input>
<input type="text" name="MiddleName" class="inputField"></input>
<input type="text" name="LastName" class="inputField" data-required="true"></input>
</form>
SCRIPT
var field, required, isValid, fieldVal;
function validatedForm() {
field = document.querySelectorAll('.inputField');
document.getElementById("submitButton").disabled = true;
var isValid = true;
for(var i=0; i < field.length; i++){
required = field[i].dataset.required;
if(required){
field[i].addEventListener('blur', function(e){
fieldVal = this.value;
if(fieldVal == ''){
isValid = false;
}
checkSubmitBtn();
}, true);
}
}
function checkSubmitBtn() {
if(isValid = true) {
console.log(isValid);
document.getElementById("submitButton").disabled = false;
}
}
}
window.addEventListener("load", validatedForm);
PROBLEM 1:
The isValid is not updating hence even an empty blur on the input field makes the button disable to be false.
PROBLEM 2:
In case there are multiple forms on the page then how to validate only the desired forms .. just like in jQuery we add a script tag in the end to initialize the script according to it.
PROBLEM 3:
Is there a way to change the disable state of the button without the GetElementID ... I mean if that can be managed depending on the submit button of that particular form on the page where the script is suppose to work.
Any help will be highly appreciated. Thanks in advance.
I think you need something like the following form validation..
<script type="text/javascript">
var field, fieldVal, required = false;
function validatedForm() {
field = document.querySelectorAll('.inputField');
document.getElementById("submitButton").disabled = true;
field.forEach(function(elem) {
required = elem.dataset.required;
if(required){
elem.addEventListener('blur', function(e) {
checkSubmitBtn(field);
});
}
});
}
function checkSubmitBtn(field) {
var isDisabled = false;
field.forEach(function(elem) {
fieldVal = elem.value.trim();
if(fieldVal == ''){
isDisabled = true;
return false;
}
});
document.getElementById("submitButton").disabled = isDisabled;
}
window.addEventListener("load", validatedForm);
</script>
I hope it helps...
There are quite a few things going on here. First, your checkSubmitBtn function used a single = operator in the if statement. This won't actually check the variable, it instead will set the variable to that value. Here is the fixed function:
function checkSubmitBtn() {
if (isValid == true) {
document.getElementById("submitButton").disabled = false;
}
}
You mentioned not wanting to use getElementById. There are a few ways around this. One way would be to call the function once and store it in a variable to use later, like so:
var button = document.getElementById("submitButton");
...
function checkSubmitBtn() {
button.disabled = !isValid;
}
Another way would be to use jQuery. It still is technically calling getElementById in the backend, but the code is much simpler. If you wanted to avoid that, you also can still combine this with the technique I described above.
$("#submitButton").attr("disabled", !isValid);
I'd also like to point out that your code doesn't account for a situation where a form goes from invalid (starting point) to valid and back to invalid again. Say a user types in all of the fields but then backspaces everything. Your code will fall apart.
Lastly, your <input> HTML tags should not be closed. There are certain tags that are considered "self-closing", i.e. you don't have to write the closing tag, </input>.
I'm having issues trying to get my form to reset without the required fields error messages appearing. On submit, if the form is valid I call the following function.
$scope.reset = function() {
$scope.createUser.$submitted = false;
$scope.createUser.$dirty = false;
$scope.createUser.$pristine = true;
$scope.user = angular.copy($scope.master);
$scope.createUser.$setPristine(true);
}
This resets the form but prompts the following messages.
Ive been looking for a way of reseting the form to prestine without any luck, im not sure if its because of the way I'm adding the has-error class.
ng-class="{'has-error': (createUser.name.$dirty || submitted) && createUser.name.$error.required}"
I would be grateful for any help with this, I have a plunker to go with it.
Im not sure if this is what you wanted but does this plunker solve your issue?
first of all like Mathew stated you had an issue with the submitted variable, $submitted is not defined anywhere you wanted to use submitted.
and you want to check your form and only if correct then set it as false.
also I would do validations like so
ng-class="{'has-error': (createUser.name.$dirty &&
createUser.name.$invalid && submitted)}"
but you dont have to, for the controller:
$scope.reset = function() {
$scope.submitted = true;
if($scope.createUser.$valid){
$scope.submitted = false;
$scope.createUser.$dirty = false;
$scope.createUser.$pristine = true;
$scope.user = angular.copy($scope.master);
$scope.createUser.$setPristine(true);
}
}
It doesn't look like you're resetting your submitted variable that you're using in has-error. You're resetting $submitted
Edit your reset function:
$scope.reset = function() {
$scope.createUser.$submitted = false;
}
you need nothing else.. good luck :)
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.