I need to code a function in Javacript that updates the button colour and enables it when all fields are valid.
See picture below to understand the user interaction with the form
When the admin wants to update an user the update button needs to be green only if the following apply
At least one edit button is enabled. (When the edit button is enabled the respective fields is deleted and the user can write something)
The field must be validated in real time
If I uncheck the field the script has to revalidate the other open fields. For Instance if the open field is blank the button should be red but if I close the field and another field was enabled and filled with valid text (lets assume just 1 character means valid) the button from red should turn green
Could you please help me to figure this out. I think a solution is to use the JQuery keyup function but it is restricted only to one field. I need instead something more global.
Is there a way in javascript to create a global button listener than be useful for this scenario
In addition when I turn on the password checkbox two fields are enabled and the button should be valid only if password is valid and it matches with confirmed password
Please see below a brief summary of the jsp page
I have omitted the small icons of the password fields and the bootstrap part of the code
<sf:form class="form-horizontal"
role="form"
id="formsubmit"
method="POST"
action="${pageContext.request.contextPath}/updateprofile"
commandName="user">
<sf:input type="text" class="form-control" value="${user.username}" path="username" readonly="true"></sf:input>
<input type="checkbox" class="form-control" name="email-checkbox" checked />
<sf:input id="emailInput" type="text" class="form-control" path="email" placeholder="Type Email" name="email" disabled="true" />
<input type="checkbox" class="form-control" name="first-name-checkbox" checked />
<sf:input id="nameInput" type="text" class="form-control" placeholder="Type First Name" path="firstName" name="firstName" disabled="true" />
<input type="checkbox" class="form-control" name="last-name-checkbox" checked />
<sf:input id="surnameInput" type="text" class="form-control" placeholder="Type Last Name" path="lastName" name="lastName" disabled="true" />
<input type="checkbox" class="form-control" name="password-checkbox" checked />
<input id="password" type="password" class="form-control" name="password" placeholder="Insert Password" disabled>
<input id="confirmpassword" type="password" class="form-control" name="confirmpassword" placeholder="Confirm Password" disabled>
<button id="updateUserBtn" type="submit" class="btn btn-danger" data-loading-text="Creating User..." disabled>Update User</button>
</sf:form>
My first attemp with javascript is below and it works only for the password fields but it is not connected with the edit button
$("input[type=password]").keyup(
function() {
var ucase = new RegExp("[A-Z]+");
var lcase = new RegExp("[a-z]+");
var num = new RegExp("[0-9]+");
if ($("#password").val().length >= 8) {
$("#8char").removeClass("glyphicon-remove");
$("#8char").addClass("glyphicon-ok");
$("#8char").css("color", "#00A41E");
} else {
$("#8char").removeClass("glyphicon-ok");
$("#8char").addClass("glyphicon-remove");
$("#8char").css("color", "#FF0004");
}
if (ucase.test($("#password").val())) {
$("#ucase").removeClass("glyphicon-remove");
$("#ucase").addClass("glyphicon-ok");
$("#ucase").css("color", "#00A41E");
} else {
$("#ucase").removeClass("glyphicon-ok");
$("#ucase").addClass("glyphicon-remove");
$("#ucase").css("color", "#FF0004");
}
if (lcase.test($("#password").val())) {
$("#lcase").removeClass("glyphicon-remove");
$("#lcase").addClass("glyphicon-ok");
$("#lcase").css("color", "#00A41E");
} else {
$("#lcase").removeClass("glyphicon-ok");
$("#lcase").addClass("glyphicon-remove");
$("#lcase").css("color", "#FF0004");
}
if (num.test($("#password").val())) {
$("#num").removeClass("glyphicon-remove");
$("#num").addClass("glyphicon-ok");
$("#num").css("color", "#00A41E");
} else {
$("#num").removeClass("glyphicon-ok");
$("#num").addClass("glyphicon-remove");
$("#num").css("color", "#FF0004");
}
if ($("#password").val() == $("#confirmpassword").val()
&& ($("#confirmpassword").val() != 0)) {
$("#pwmatch").removeClass("glyphicon-remove");
$("#pwmatch").addClass("glyphicon-ok");
$("#pwmatch").css("color", "#00A41E");
} else {
$("#pwmatch").removeClass("glyphicon-ok");
$("#pwmatch").addClass("glyphicon-remove");
$("#pwmatch").css("color", "#FF0004");
}
if ($("#password").val().length >= 8
&& ucase.test($("#password").val())
&& lcase.test($("#password").val())
&& num.test($("#password").val())
&& $("#password").val() == $("#confirmpassword").val()
&& ($("#confirmpassword").val() != 0)) {
$("#updateUserBtn").removeClass("btn-danger");
$("#updateUserBtn").addClass("btn-success");
$("#updateUserBtn").prop('disabled', false);
} else {
$("#updateUserBtn").removeClass("btn-success");
$("#updateUserBtn").addClass("btn-danger");
$("#updateUserBtn").prop('disabled', true);
}
});
A keyup handler attached to the form element will be called for any field within it having a keyup event. That is because most events bubble up through all their ancestors and can be listened for at any level.
Small example as requested :)
$("form").keyup(
function() {
// your existing code here
});
If you want to target only specific inputs for the changes, you could use a delegated handler instead attached to the form (this one is using the specific form id):
$("#formsubmit").on('keyup', 'input[type=text],input[type=password]',
function() {
// your existing code here
});
This applies the selector at event time so is quite efficient, and also means the this value will be the control that changed (if that is useful to you).
As a general jQuery guideline, only run selectors once and save the element. This is faster & shorter and usually more readable. Also you can chain most jQuery functions together.
e.g.
var $password = $("#password");
var $8char = $("#8char");
if ($password.val().length >= 8) {
$8char.removeClass("glyphicon-remove").addClass("glyphicon-ok").css("color", "#00A41E");
Related
I'm building a demo login form. For the demo, I'd like two things to happen:
When the user clicks the login button for the first time, an error message appears.
When the user clicks the login button for the second time, they are directed to another page.
Here's how my code looks so far:
function toggleError() {
var toggleError = document.querySelector('.message--error');
toggleError.classList.toggle('error-toggled');
}
.message {
display: none;
}
.error-toggled {
display: block;
}
<div class="message message--error">
<span class="message__text">The login details you entered are incorrect.</span>
</div>
<form onsubmit="toggleError(); return false;" action="/" method="get" class="login__form" autocomplete="off">
<label for="email" class="srt">Email</label>
<input type="email" name="email" id="email" required placeholder="Email" class="input input--border-right">
<label for="password" class="srt">Password</label>
<input type="password" name="password" id="password" required placeholder="Password" class="input">
<div class="login__actions">
<button type="submit" class="button">Log In</button>
Lost your password?
</div>
</form>
Using onsubmit="toggleError(); return false;" achieves my first objective of displaying an error message.
How would I extend this function so the user is directed to a page when they click the button for a second time? I'm guessing I would write some type of loop?
Based on first two comments here a possible way:
<script>
var clickCounter=0;
function toggleError() {
//Increase the value by one
clickCounter++;
if (clickCounter == 1) {
//what ever you want to do
return false;
} else if (clickCounter == 2) {
//You need to change the value again
...
var toggleError = document.querySelector('.message--error');
toggleError.classList.toggle('error-toggled');
return false;
}
}
</script>
I am trying to handle some JavaScript work, which I don't have much experience with. I have a 2 part form where a user enters their personal info, and then company info. I am trying to set some of the company fields to what they already entered in their personal info.
I don't want the user to have to retype address, email, etc.
for example, I have...
<div class="form-group">
<label for="email">Email<span>*</span></label>
<input name="email" type="text" class="form-control required" id="email"placeholder="Email" value=".
{{email}}">
<span id="span_email" class="error-msg"></span>
And...
<div class="form-group">
<label for="comp_email">Company Email<span>*</span></label>
<input name="comp_email" type="text" class="form-control required" id="comp_email"placeholder="Email"
value="{{comp_email}}">
<span id="span_email" class="error-msg"></span>
How would I be able to set that second comp_email field to initially have the email info, so the user doesn't have to retype, unless they actually wanted to change the comp_email to another email address?
EDIT
It is all in one form, just separated by divs. Initially, when the page is loaded, the account section div is displayed, when the user hits next, it triggers the display of the business info.
<input type="button" onclick="nextFormPage(); window.scrollTo(0, 100)"
class="btn btn-danger btn-block" value="Next">
The nextFormPage() function just hides the first div and displays the second div.
You have tagged both javascript and jQuery so I'm not sure which you are using. But you can do this with a single line either way:
Javascript::
document.getElementById("comp_email").value = document.getElementById("email").value;
document.getElementById("email").value gets the value from the email input and we set the value of the document.getElementById("comp_email") by setting its value attribute:
jQuery:
$("#comp_email").val( $("#email").val() );
$("#email").val() get the value from the email input and $("#comp_email").val( ... ); sets the text passed in as the input value.
Javascript Working Example
function nextFormPage(){
document.getElementById("comp_email").value = document.getElementById("email").value;
}
<div class="form-group">
<label for="email">Email<span>*</span></label>
<input name="email" type="text" class="form-control required" id="email" placeholder="Email" value="">
<span id="span_email" class="error-msg"></span>
<div class="form-group">
<label for="comp_email">Company Email<span>*</span></label>
<input name="comp_email" type="text" class="form-control required" id="comp_email" placeholder="Email"
value="">
<span id="span_email" class="error-msg"></span>
<input type="button" onclick="nextFormPage(); window.scrollTo(0, 100)"
class="btn btn-danger btn-block" value="Next">
If your user is logged in, you should pass all of their information to the form, including their email. For example:
const logIn = () => {
... some code to get the user ...
... pass the user to the form, probably through an event listener...
let button = document.createElement("button")
button.textContent = "Edit"
button.addEventListener('click', () => {editYourStuff(user)}
}
const editYourStuff = user => {
... grab whatever your form is called ...
editForm.email.value = user.email
}
This should pre populate your form with the email
I am using form twice on same page.
HTML Code
<form action="post.php" method="POST" onsubmit="return checkwebform();">
<input id="codetext" maxlength="5" name="codetext" type="text" value="" placeholder="Enter here" />
<input class="button" type="submit" value="SUMBIT" />
</form>
It's working fine with one form but when i add same form again then it stop working. The second form start showing error popup alert but even i enter text in form field.
JS Code
function checkwebform()
{
var codecheck = jQuery('#codetext').val();
if(codecheck.length != 5)
{
alert('Invalid Entry');
} else {
showhidediv('div-info');
}
return false;
}
How can i make it to validate other forms on page using same function?
As I commented, you can't have more than one element with the same id. It's against HTML specification and jQuery id selector only returns the first one (even if you have multiple).
As if you're using jQuery, I might suggest another approach to accomplish your goal.
First of all, get rid of the codetext id. Then, instead of using inline events (they are considered bad practice, as pointed in the MDN documentation), like you did, you can specify an event handler with jQuery using the .on() method.
Then, in the callback function, you can reference the form itself with $(this) and use the method find() to locate a child with the name codetext.
And, if you call e.preventDefault(), you cancel the form submission.
My suggestion:
HTML form (can repeat as long as you want):
<form action="post.php" method="POST">
<input maxlength="5" name="codetext" type="text" value="" placeholder="Enter here" />
<input class="button" type="submit" value="SUMBIT" />
</form>
JS:
$(document).ready(function() {
//this way, you can create your forms dynamically (don't know if it's the case)
$(document).on("submit", "form", function(e) {
//find the input element of this form with name 'codetext'
var inputCodeText = $(this).find("input[name='codetext']");
if(inputCodeText.val().length != 5) {
alert('Invalid Entry');
e.preventDefault(); //cancel the default behavior (form submit)
return; //exit the function
}
//when reaches here, that's because all validation is fine
showhidediv('div-info');
//the form will be submited here, but if you don't want this never, just move e.preventDefault() from outside that condition to here; return false will do the trick, too
});
});
Working demo: https://jsfiddle.net/mrlew/8kb9rzvv/
Problem, that you will have multiple id codetext.
You need to change your code like that:
<form action="post.php" method="POST">
<input maxlength="5" name="codetext" type="text" value="" placeholder="Enter here" />
<input class="button" type="submit" value="SUMBIT" />
</form>
<form action="post.php" method="POST">
<input maxlength="5" name="codetext" type="text" value="" placeholder="Enter here" />
<input class="button" type="submit" value="SUMBIT" />
</form>
And your JS:
$(document).ready(function(){
$('form').submit(function(){
var codecheck = $(this).find('input[name=codetext]').val();
if(codecheck.length != 5)
{
alert('Invalid Entry');
} else {
showhidediv('div-info');
}
return false;
})
})
I'm fairly new to JavaScript, I've been using tutorials online but they seem to often validate with php and use JavaScript for warnings, the application I'm making users xhr to post the data to the server, but before this I want to have JavaScript complete some validations. Then I'll re validate with the PHP.
Here is the form code
<form id="booking" action="">
<span class="red">*</span>First Name:
<input type="text" name="firstName" id="firstName">
<br>
<span class="red">*</span>Last Name:
<input type="text" name="lastName" id="lastName">
<br>
<span class="red">*</span>Contact Number:
<input type="text" name="number" id="number">
<br>
Unit Number(optional):
<input type="text" name="unit" id="unit">
<br>
<span class="red">*</span>Street Number:
<input type="text" name="streetNumber" id="streetNumber">
<br>
<span class="red">*</span>Street Name:
<input type="text" name="streetName" id="streetName">
<br>
<span class="red">*</span>Suburb:
<input type="text" name="pickupSuburb" id="pickupSuburb">
<br>
Destination Suburb<span class="red">*</span>:
<input type="text" name="destinationSuburb" id="destinationSuburb">
<br>
Pick-Up Date and Time<span class="red">*</span>:
<input type="datetime-local" name="dateTime" id="dateTime">
<br>
<br>
<input type="button" value="Submit"
onclick="getData('bookingprocess.php','message', firstName.value, lastName.value, number.value, unit.value, streetNumber.value, streetName.value, pickupSuburb.value, destinationSuburb.value, dateTime.value)"/>
<input type="reset" value="Reset">
</form>
<div id="message">
</div>
I've created a div for the warning messages.
Here is the JavaScript
// file simpleajax.js
var xhr = createRequest();
function getData(dataSource, divID, firstName, lastName, number, unit, streetNumber, streetName, pickupSuburb, destinationSuburb, dateTime) {
if(xhr) {
var place = document.getElementById(divID);
var requestbody = "firstName="+encodeURIComponent(firstName)+"&lastName="+encodeURIComponent(lastName)+"&number="+encodeURIComponent(number)+"&unit="+encodeURIComponent(unit)+"&streetNumber="+encodeURIComponent(streetNumber)+"&streetName="+encodeURIComponent(streetName)+"&pickupSuburb="+encodeURIComponent(pickupSuburb)+"&destinationSuburb="+encodeURIComponent(destinationSuburb)+"&dateTime="+encodeURIComponent(dateTime);
xhr.open("POST", dataSource, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
place.innerHTML = xhr.responseText;
} // end if
} // end anonymous call-back function
xhr.send(requestbody);
} // end if
} // end function getData()
function checkForm(booking) {
var valid = true;
if(firstName.value.length <= 0) {
window.alert("Name is empty");
booking.firstName.focus();
return valid = false;
}
}
Note there will be more validations, my question is how can I call the validations from the form, or directly from the XHR, which is the best practice? I understand the call to the XHR from the form could be considered bad practice as well as I've hard coded all the values?
Getting this to work has been quite troublesome, so apologies if its a little Hodge podge.
Validating while the form is filled (when the cursor leaves a field) makes more sense since you can add some hints to user. Like, if a user enters an email, you check if it contains # and it doesn't, it's much more user-friendly to notify them that something's wrong with their email input (in contrast, they may send the form, you validate it then and tell them the form is not ok, but then they have to fill the form again, which is sort of frustrating).
Try
<input type="text" onblur="alert('out!');" />
This fires when the input loses focus. Now, you may wonder how to use functions defined elsewhere in such handling. That can be done, for instance, like this:
JS:
window.myHandler = function(input,event) { ... };
HTML:
<input type="text" onblur="window.myHandler(input,event);" />
Note that in HTML onblur attribute event is a "pre-defined" variable that contains the Event object "instance", but for elder versions of IE, you should use
window.myHandler = function(input,event) {
event = event || window.event; // elder IE store the Event object in window.event
// input is your DOM element. You can use input.value to get the value
// or this.classList to add some class which indicates (via CSS) that the input is wrong
...
};
var name = document.getElementById('contact-name'),
email = document.getElementById('contact-email'),
phone = document.getElementById('contact-phone'),
message = document.getElementById('contact-message');
function checkForm() {
if (name.value == '') {
alert('test');
}
}
I was simply trying to make sure everything was working before I began learning actual client-side validation.
Here is the HTML
<form role='form' name='contactForm' action='#' method="POST" id='contact-form'>
<div class="form-group">
<label for="contact-name">First and Last Name</label>
<input type="text" class="form-control" id="contact-name" name="contactName" placeholder="Enter your name.." pattern="[A-Za-z]+\s[A-Za-z]+">
</div>
<div class="form-group">
<label for="contact-email">Email address</label>
<input type="email" class="form-control" id="contactEmail" name="contactEmail" placeholder="Enter Email" required>
</div>
<div class="form-group">
<label for="contact-phone">Phone Number</label>
<input type="number" class="form-control" id="contactPhone" name="contactPhone" placeholder="Enter Phone Number" required'>
</div>
<div class="form-group">
<label for='contactMessage'>Your Message</label>
<textarea class="form-control" rows="5" placeholder="Enter a brief message" name='contactMessage' id='contact-message' required></textarea>
</div>
<input type="submit" class="btn btn-default" value='Submit' onclick='checkForm()'>
</fieldset>
</form>
I took the required attribute off, and if I leave the name field empty it goes right to the other one when i click submit. To check whether javascript was working at all, i did an basic onclick function that worked.
Maybe someone can explain to me what is wrong with the checkForm function. Thanks in advance.
P.S The form-group and form-control classes belong to bootstrap
Change your javascript to this:
var contactName = document.getElementById('contact-name'),
email = document.getElementById('contact-email'),
phone = document.getElementById('contact-phone'),
message = document.getElementById('contact-message');
function checkForm() {
if (contactName.value === '') {
alert('test');
}
}
Okay, Hobbes, thank you for editing your question, now I can understand your problem.
Your code faces three two issues.
Your control flow. If you want to validate your field, you have to obtain its value upon validation. You instead populate variable name when the page loads, but the user will enter the text only after that. Hence you need to add var someVariableName = document.getElementById(...); to the beginning of the checkForm() function.
global variables. Please do not use them like that, it is a good design to avoid global variables as much as possible, otherwise you bring upon yourself the danger of introducing side effects (or suffering their impact, which happens in your situation). The global context window already contains a variable name and you cannot override that. See window.name in your console. You can of course use var name = ... inside the function or a block.
Even if you fix the above, you will still submit the form. You can prevent the form submission if you end your checkForm() function with return false;
For clarity I append the partial javascript that should work for you:
function checkForm() {
var name = document.getElementById('contact-name');
if (name.value == '') {
alert('test');
return false;
}
}
EDIT: As Eman Z pointed out, the part 1 of the problem does not really prevent the code from working as there's being retrieved an address of an object (thanks, Eman Z!),