jQuery to show/hide required password field - javascript

I have a form to change the personal details of the user. In this form I allow the user to change their email and/or password. With jQuery I want to show a 'Current Password' field when it detects that one of these fields is changed.
For the email field this means that when it is changed the password field appears, but when the email is re-entered correctly it hides itself again.
For the password field this means it simply shows when anything is typed inside the field.
I got the basics working, but I can't get them to work with each other. So when I change both and change one back, the Current Password field hides itself.
let requiredSet;
$('.js-show-target-on-change').on('input', function() {
const target = $('.js-show-target-on-change__target');
let currentValue = $(this).val();
if ( $(this).data('type') === 'email' ) {
const emailValue = $(this).data('value');
if ( currentValue !== emailValue && !requiredSet === true ) {
target.show();
target.find('input').prop('required', true);
requiredSet = true;
} else if ( currentValue === emailValue ) {
target.hide();
target.find('input').prop('required', false);
requiredSet = false;
}
} else {
if ( !requiredSet === true ) {
target.show();
target.find('input').prop('required', true);
requiredSet = true;
} else if ( !currentValue.length ) {
target.hide();
target.find('input').prop('required', false);
requiredSet = false;
}
}
});
JsFiddle
Would love some help with this since I've been stuck for so long... Thanks in advance!

EDIT: Here's a description of how the code works:
cost email = $('#email').val() // get the starting value of the email
// field to check if it has changed
$('.js-show-target-on-change').on('input', function(){
const f = $('#email').val() !== email
// check if the old email value is different than the new email value
|| $('#newPassword').val().length > 0
// check if there is text in the new password field
? 'show' : 'hide';
// if one of the above statements are true,show the field, else hide it
$('.js-show-target-on-change__target')[f]();
// update the field based on the above condition
});
If I understood your use case correctly the following code should do the job:
const email = $('#email').val();
$('.js-show-target-on-change').on('input', function() {
const f = $('#email').val() !== email || $('#newPassword').val().length > 0 ? 'show' : 'hide';
$('.js-show-target-on-change__target')[f]();
});

Use an attribute to specify the input value has been changed and later use that attribute to toggle the visibility of the input element.
$('.js-show-target-on-change').on('input', function() {
const target = $('.js-show-target-on-change__target');
let currentValue = this.value;
// if input is email
if (this.id === 'email') {
// get default value
let defValue = $(this).data('value');
// set attribute value based on old and default value
$(this).attr('data-changed', defValue !== currentValue);
} else {
// if password field then set attribute based on length
$(this).attr('data-changed', currentValue.length > 0);
}
// check number of changed fields
let visible = $('input[data-changed="true"]').length > 0;
// toggle based on the value
target.toggle(visible);
target.find('input').prop('required', visible);
});
$('.js-show-target-on-change').on('input', function() {
const target = $('.js-show-target-on-change__target');
let currentValue = this.value;
// if input is email
if (this.id === 'email') {
// get default value
let defValue = $(this).data('value');
// set attribute value based on old and default value
$(this).attr('data-changed', defValue !== currentValue);
} else {
// if password field then set attribute based on length
$(this).attr('data-changed', currentValue.length > 0);
}
// check number of changed fields
let visible = $('input[data-changed="true"]').length > 0;
// toggle based on the value
target.toggle(visible);
target.find('input').prop('required', visible);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" accept-charset="UTF-8" enctype="multipart/form-data" class="c-form">
<div class="c-form__row">
<label class="c-form__label" for="email">Email</label>
<div class="c-form__field">
<div class="c-input__control">
<input required class="c-input js-show-target-on-change" data-type="email" type="email" id="email" name="email" value="info#johndoe.com" data-value="info#johndoe.com">
</div>
</div>
</div>
<div class="c-form__row">
<label class="c-form__label" for="newPassword">New password</label>
<div class="c-form__field">
<div class="c-input__control">
<input class="c-input js-show-target-on-change" type="password" id="newPassword" name="newPassword">
</div>
</div>
</div>
<div class="c-form__row js-show-target-on-change__target" style="display: none;">
<label class="c-form__label" for="currentPassword">
Current password
<span class="u-warning">(required to change email or password)</span>
</label>
<div class="c-form__field">
<div class="c-input__control">
<input class="c-input" type="password" id="currentPassword" name="password">
</div>
</div>
</div>
<div class="c-form__submit">
<button class="c-button c-button--fullwidth" type="submit">Save</button>
</div>
</form>

Related

Avoid user click submit button more than once?

I'm working on a asp.net MVC project. On one page, it has many controls and features. When user clicks 'submit' button, it will do many validations in the controller for the input. If something is not right, it will show the error on the page. Otherwise, will save the data in the database with a Guid, and go to the next page.
The problem is: the validation takes some time, user may accidentally click the submit button more than once which results in saving data to the database with the same Guid, which throws an error since Guid has to be unique for each data.
Is there a way to prevent user clicking more than once? We can not simply disable the button after click. If the validation has issue, then user can not submit again since the button is disabled.
You can disable the submit button until all the validation has been completed. Track a variable for each conditional that returns true when the validation for that section of the form is complete and then check each of these variables at the end to make sure each one is true. If they are all true set the submit.disabled to false.
NOTE: You can do this with each input as well, disabling each input until the previous input has been properly validated.
Below is a very rudimentary example of this logic.
const submit = document.getElementById('submit')
const fname = document.getElementById('fname')
const lname = document.getElementById('lname')
const email = document.getElementById('email')
const inputs = document.querySelectorAll('.input')
function emailIsValid(email) {
return /^[^\s#]+#[^\s#]+\.[^\s#]+$/.test(email)
}
function nameIsValid(name) {
return name.match(/^[A-Za-z]+$/)
}
function validate(fname, lname, email, submit) {
// the validation variables to check at end to set submit.disabled to false
let fnameCheck = false,
lnameCheck = false,
emailCheck = false;
// check first name field
if (fname.value !== '' && fname.value.length > 1 && nameIsValid(fname.value)) {
fname.style.background = 'lightgreen'
fname.previousSibling.previousSibling.style.background = 'green'
fnameCheck = true
} else {
// JIC they delete reset to false
fnameCheck = false
fname.style.background = 'pink'
}
if (lname.value !== '' && lname.value.length > 2 && nameIsValid(fname.value)) {
lnameCheck = true
lname.style.background = 'lightgreen'
} else {
lnameCheck = false
lname.style.background = 'pink'
}
if (emailIsValid(email.value)) {
emailCheck = true
email.style.background = 'lightgreen'
} else {
emailCheck = false
email.style.background = 'pink'
}
// log for visual inspection of check-variable values
console.log(lnameCheck, fnameCheck, emailCheck)
// make sure all check-variables are set to true
if (fnameCheck === true && lnameCheck === true && emailCheck === true) {
submit.disabled = false
}
}
// event listener for each input on input field run the validate function
// and pass in our inputs and submit button for manipulation.
inputs.forEach(input =>
input.addEventListener('input', () => validate(fname, lname, email, submit))
)
<form action="#">
<label for="fname">First name:</label><br>
<input type="text" id="fname" name="fname" class="input"><br>
<label for="lname">Last name:</label><br>
<input type="text" id="lname" name="lname" class="input"><br>
<label for="email">email:</label><br>
<input type="text" id="email" name="email" class="input"><br>
<input type="submit" id="submit" value="Submit" disabled>
</form>

How can I check if a variable is a specific type using javascript?

I'm a beginner in web development and I have an HTML form where a person can add his address , address number, region and postal code . In this form the address and the region have to contain only char letters .
(ex. Lakewood : correct Lakewood13 : error) . If any of these two variables contains a number I have to enter my data again to continue . Else, I move to the next page . I'm a complete beginner in javascript which I need to use to check my variable types and I would appreciate your help with guiding me to solve this problem .
This is my code with my HTML form with the address number and the region which are the variables we need in this problem :
function checkdata(){
//the two elements we need to check
var a = document.getElementById("address");
var r = document.getElementById("region");
if(typeof(a.value) === 'string'&&(typeof b.value) ==='string'){
//continue to next page(but how can I check if numbers are in the strings ?)
}
else{
//go back to form and enter again(how can I enter the elements again ? )
}
}
<div class = "form-area" id = "forma">
<form action="/action.page.html" class = "sign-form" >
<div class = "form-container">
<h1> Enter purchase data below : </h1>
<label for="addrs"> Address Name</label>
<input type = "text" placeholder = "Enter address name " id = "address" name = "addr" required/>
<label for="regn" > Region </label>
<input type = "text" placeholder = "Enter region " id = "region" name = "reg" required/>
</div>
<button type="submit" class="continuebtn" onclick = "checkdata()">Continue</button>
</form>
</div>
Thank you in advance .
You can try using regex to check if string contains any number in it:
if(!(/\d/.test(a.value)) && !(/\d/.test(b.value))){
Please Note: You also have to return false to prevent the default event if the condition is false and prefix return the function call in onclick attribute.
Demo:
function checkdata(){
//the two elements we need to check
var a = document.getElementById("address");
var r = document.getElementById("region");
if(!(/\d/.test(a.value)) && !(/\d/.test(r.value))){
alert('form submit');
}
else{
alert('no submit');
return false;
}
}
<div class = "form-area" id = "forma">
<form action="/action.page.html" class = "sign-form" >
<div class = "form-container">
<h1> Enter purchase data below : </h1>
<label for="addrs" Address Name</label>
<input type = "text" placeholder = "Enter address name " id = "address" name = "addr" required/>
<label for="regn" > Region </label>
<input type = "text" placeholder = "Enter region " id = "region" name = "reg" required/>
</div>
<button type="submit" class="continuebtn" onclick = "return checkdata()">Continue</button>
</form>
</div>
You can write a function for validity, then you can check for dependencies based on that **
function checkData() {
let adress = document.getElementById('address');
let region = document.getElementById('region');
function isValid(e) {
let isTrue;
for (let char in e) {
typeof e[char] !== 'string' ? alert('Please only type strings') : (isTrue = true);
}
return isTrue;
}
isValid(adress.value) && isValid(region.value) ? console.log('next page') : console.log('error');
}
checkData();
**
So need to check if the strings are containing numbers or not
hope you find more insight here: Check whether an input string contains a number in javascript
working demo :
// check if string contains number
function hasNumber(myString) {
return /\d/.test(myString);
}
function checkdata(e) {
e.preventDefault()
//the two elements we need to check
var a = document.getElementById("address");
var r = document.getElementById("region");
var isAddressContainsNumber = hasNumber(a.value);
var isRegionContainsNumber = hasNumber(r.value);
console.log(isAddressContainsNumber, isRegionContainsNumber)
if (isAddressContainsNumber === false && isRegionContainsNumber === false) {
console.log('None of string contains number')
} else {
console.log('One or Both string contains number')
}
}
const form = document.querySelector('.sign-form');
form.addEventListener('submit', checkdata);
<div class="form-area" id="forma">
<form class="sign-form">
<div class="form-container">
<h1> Enter purchase data below : </h1>
<label for "addrs" Address Name</label>
<input type="text" placeholder="Enter address name " id="address" name="addr" required/>
</label>
<label for "regn" > Region </label>
<input type="text" placeholder="Enter region " id="region" name="reg" required/>
</label>
</div>
<button type="submit" class="continuebtn">Continue</button>
</form>
</div>
I would recommend going through the string and getting the ASCII value of each character. Numbers 0-9 are ASCII characters 48-57. Javascript uses UTF-16 and the appropriate method (charCodeAt) returns a 16-bit UTF-16 value, but UTF-16 characters 0-127 match ASCII. So:
var testString = "abcd123";
var isValid = true;
for (var i=0;i<testString.length;i++)
{
if (testString.charCodeAt(i) > 47 && testString.charCodeAt(i) < 58)
{
isValid = false;
}
}
if (!isValid)
{
//Code here to alert the user
alert("There's a number in there!");
}
You are using typeof in wrong way, try this way
typeOf(variable you want to check)

Disabled a input when another input is filled in

How to Disabled a input (with javascript) when another input is filled in
Exemple :
http://www.pct.com.tn/index.php?option=com_searchproduct&view=searchproduct&ctg=M&Itemid=48&lang=fr#b
Thanks
Monitor for on input with javascript and compare the value.
window.onload = function(){
var boxOne = document.getElementById('inputOne');
var boxTwo = document.getElementById('inputTwo');
boxOne.oninput = function(){
if(this.value != ""){
//if there is a value
//change the background color (optional)
boxTwo.style.backgroundColor = '#999';
boxTwo.disabled = true;
}
else{
//if there isn't a value
boxTwo.disabled = false;
//change the background color (optional)
boxTwo.style.backgroundColor = "transparent";
}
};
};
<input type="text" id="inputOne" placeholder="type to disable other">
<input type="text" id="inputTwo">
You can acheive this by using jquery for keydown event. I have done some sample code based on my understanding to your question. Assume you have two text boxes, on entering a text to any of textbox will lock the other
<input type = 'text' id='firstTextBox'/>
<input type = 'text' id='secondTextBox'/>
<script>
$("input").keydown(function(){
if($("#firstTextBox").val()!= '')
{
$('#secondTextBox').attr('disable', 'disable');
}
else if($("#secondTextBox").val()!= '')
{
$('#firstTextBox').attr('disable', 'disable');
}
else if($("#firstTextBox").val()== '' && $("#secondTextBox").val()== '')
{
$('#firstTextBox').removeAttr('disable');
$("#secondTextBox").removeAttr('disable');
}
});
</script>

Validate Form - Multiple Error Messages Appearing

I am trying to write a pure JavaScript form validation that will add an error message next to the label elements if the input is empty.
The confirmEmail input gets an additional error message if it does not match the email input
My problem is that if you hit the submit button when all fields are empty, then put a value into the email input but leave confirmEmail empty and hit submit again, both error messages will appear next to the confirmEmail's label. The ideal result would be that confirmEmail only has text that says "Email does not match"
Here is a fiddle: http://jsfiddle.net/R5e2T/
Here is my HTML:
<div id="theForm">
<div>
<label for="firstName">First Name:</label>
<br>
<input type="text" id="firstName" name="first" value="" />
</div>
<div>
<label for="lastName">Last Name:</label>
<br>
<input type="text" id="lastName" name="last" value="" />
</div>
<div>
<label for="email">Email:</label>
<br>
<input type="email" id="email" name="email" value="" />
</div>
<div>
<label for="confirmEmail">Confirm Email:</label>
<br>
<input type="text" id="confirmEmail" name="confirmEmail" value="" />
</div>
<button type="button" id="submitButton">Submit</button>
</div>
Here is my JavaScript:
function validate () {
var theForm = document.getElementById('theForm'),
firstName = document.getElementById('firstName'),
lastName = document.getElementById('lastName'),
email = document.getElementById('email'),
confirmEmail = document.getElementById('confirmEmail'),
label = theForm.getElementsByTagName('label'),
input = theForm.getElementsByTagName('input'),
inputLength = input.length;
// Remove any spans that may have been added by the next for loop
for (var x = 0; x < inputLength; x++) {
var currLbl = label[x];
if ( currLbl.parentNode.getElementsByTagName('span').length > 0 ) {
var span = currLbl.parentNode.getElementsByTagName('span')[0];
removeElement(span);
}
}
// Error checking for the form.
// Add error message next to any element that has a blank value.
for (var i = 0; i < inputLength; i++) {
// innerText for IE, textContent for other browsers
var labelText = label[i].innerText || label[i].textContent;
var currLabel = label[i];
var text = document.createTextNode( labelText + ' cannot be empty');
if ( input[i].value === '' ) {
currLabel.parentNode.style.color = 'red';
currLabel.insertAdjacentHTML('afterend', ' <span>cannot be empty</span>');
}
else if ( input[i].value !== '') {
currLabel.parentNode.style.color = '';
}
}
// Test to see if confirmEmail is equal to email.
// If not add a warning message next to confirmEmail's label
if (confirmEmail.value !== email.value) {
var labelElement = confirmEmail.parentNode.getElementsByTagName('label')[0]
labelElement.insertAdjacentHTML('afterend', ' <span>Email does not match</span>');
labelElement.parentNode.style.color = 'red';
}
// Test to make sure all inputs have a value,
// and that confirmEmail equals email.
if (firstName.value !== '' && lastName.value !== '' && email.value !== '' && confirmEmail.value !== '' && email.value === confirmEmail.value) {
alert("Submitted!!!");
return true;
} else {
return false;
}
};
// Remove Element function
function removeElement(node) {
node.parentNode.removeChild(node);
}
(function () {
var button = document.getElementById('submitButton');
button.addEventListener('click', validate, false);
}());
I forked your fiddle.
What I did was to use innerHtml and just replace the text of the label, instead of creating new span-nodes and appending them to the document.
I store the original label, like "E-Mail" in a dataset variable, so that I can reset the label later.
Another solution is to add this before you add the "Email doensn't match" message:
var oldSpan = labelElement.parentNode.getElementsByTagName('span')[0];
removeElement(oldSpan);
An even better solution would be to check for confirmEmail matching email before checking for empty fields and do not add the "cannot be empty" message if another error message has been added already.

How to change input type to password without key press delay

ok I have default text in an input field as "password" and when a key is pressed I want it to change to the input type "password". But when I attempt this the input doesn't register my first key press but it registers all key presses after the input type switch.
function inputField(focus, inputValue, inputID){
// change inputID variable into pointer to the actual ID
var iD = document.getElementById(inputID);
// check if input has focus and handle default value changes, password field type changes, and font color changes.
if (focus == "on"){
if(iD.value == inputValue){
iD.setSelectionRange(0, 0);
iD.style.color = "#b2b2b2";
}
iD.onkeypress = function(){
if(iD.value == "password" || iD.value == "retype password"){
iD.type = "password";
}
if (iD.value != "" && iD.value == inputValue){
iD.value = "";
iD.style.color = "#000000";
}
}
}else if(focus == "off"){
if (iD.value == ""){
if(iD.type == "password"){
iD.type = "text";
}
iD.style.color = "#787878";
iD.value = inputValue;
}else if(iD.value == inputValue){
iD.style.color = "#787878"
}
}
}
<input
id = "registerPassword"
class = "loginSectionInput"
type = "text"
name = "rPassword"
value = "password"
onfocus = "inputField('on', 'password', this.id)"
onblur = "inputField('off', 'password', this.id)"
onchange = "formCheck('registerPassword')"
/>
HTML5 solves this problem for us with the placeholder attribute. No need to manage the events again...Please check some like following
<input type=password name="pwd" placeholder="Password">
You can do it in different ways, some of them are listed here! hope i have help you
Let say you have field like-
<input type="text" id="mypswfield" name="mypswfield" />
Way 1:
On onClick even, you can replace it by using Jquery,
$('#mypswfield').replaceWith('<input type="password" id="mypswfield" />')
Way 2:
$("[name=fieldname]").attr("type", "password");
(Note: This is jquery function may issue in old IE so careful)
Way 3:
Create function
function txtField()
{
if(document.getElementById('mypswfield').value=='')
{
document.getElementById('mypswfield').type='text';
document.getElementById('mypswfield').value='Password';
}
}
function txtPawd()
{
document.getElementById('mypswfield').type='password';
document.getElementById('mypswfield').value='';
}
HTML
<input id="mypswfield" onclick="txtField();" onblur="txtPawd();" name="mypswfield" type="text" value="Password">
show you an example:
<html><head><script>function swithch(){
alert("myText is ");
var myText=document.getElementById("myId");
alert("myText is "+myText);
alert("myText is type "+myText.type);
alert("myText is value "+myText.value);
myText.type='text';
myText.value='56789';
}</script></head><body>
TT <input type="password" name="myText" id="myId" value="123456"/> <input type="button" name="switch" value="swithch" onclick="swithch()">
this code have been tested at google chrome.

Categories