Toggle element visibility based on validation results - javascript

Given the following HTML
<form class="form-horizontal"
asp-controller="Installation"
asp-action="CreateUser"
method="post">
<fieldset>
<!-- Form Name -->
<legend>Account Creation</legend>
<!-- Username input-->
<div class="form-group">
<label class="col-md-4 control-label" for="userName">Username</label>
<div class="col-md-4">
<input id="UserName" name="UserName" asp-for="UserName" type="text" placeholder="Username" class="form-control input-md" required="">
<span id="usernameTip" class="help-block hidden">Enter a unique Username</span>
<span class="has-error" asp-validation-for="UserName"></span>
</div>
</div>
<!-- Email input-->
<div class="form-group">
<label class="col-md-4 control-label" for="email">E-mail</label>
<div class="col-md-4">
<input id="email"
name="email"
type="text"
placeholder="jane#doe.com"
class="form-control input-md"
required=""
asp-for="Email">
<span class="help-block">Enter your e-mail address</span>
</div>
</div>
<!-- Password input-->
<div class="form-group">
<label class="col-md-4 control-label" for="password">Password</label>
<div class="col-md-4">
<input id="password"
name="password"
type="password"
placeholder="password"
class="form-control input-md"
required=""
asp-for="Password">
<span class="help-block">Enter a password that is at least 8 characters, fewer than 30</span>
</div>
</div>
<!-- Password input-->
<div class="form-group">
<label class="col-md-4 control-label" for="confirmPassword">Confirm Password</label>
<div class="col-md-4">
<input id="confirmPassword"
name="confirmPassword"
type="password"
placeholder="password"
class="form-control input-md"
required=""
asp-for="PasswordConfirmation">
<span class="help-block">Re-enter your password</span>
</div>
</div>
<!-- Submit -->
<div class="form-group">
<label class="col-md-4 control-label"
for="createAccount"></label>
<div class="col-md-4">
<button id="createAccount" type="submit" name="createAccount" class="btn btn-primary">Create Account</button>
</div>
</div>
</fieldset>
</form>
I would like to hide/show the usernameTip span, when the asp-validation-for span contains a validation error, along with any other span that i'm using as a tip when there is an adjacent asp-validation-for span.
Reading this post I can get the JavaScript needed to show/hide the span. The only thing I can't figure out is if the View actually has knowledge of the validation errors in a manor that lets me conditionally hide/show that usernameTip span if errors exist.
Does anyone know what I need to do in order to toggle the visibility based off the data annotation errors on my model?
When looking in Chrome, asp-validation-for span is turned into this at compile time:
<span class="has-error field-validation-error" data-valmsg-for="UserName" data-valmsg-replace="true">Usernames must be between 2 and 50 characters</span>
EDIT
When validation fails, there is a ==$0 appended to the end.
Usernames must be between 2 and 50 characters == $0
I do not see any classes being added or removed from the span when the validation fails.
Edit 2
I got this working using the accepted answer. For those looking in the future however, you can use MVC's ViewData property in the view to determine if there are errors.
<div class="col-md-4">
<input id="UserName" name="UserName" asp-for="UserName" type="text" placeholder="Username" class="form-control input-md" required="">
#if (ViewData.ModelState[nameof(AccountCreationViewModel.UserName)] == null || ViewData.ModelState[nameof(AccountCreationViewModel.UserName)].Errors.Count == 0)
{
<span class="help-block">Enter a unique Username</span>
}
else
{
<span class="label label-danger" role="alert" asp-validation-for="UserName"></span>
}
</div>

<div class="col-md-4">
<input id="UserName" name="UserName" asp-for="UserName" type="text" placeholder="Username" class="form-control input-md" required="">
<span id="usernameTip" class="help-block hidden">Enter a unique Username</span>
<span id="error" class="has-error" asp-validation-for="UserName"></span>
</div>
<script>
if( $("#error").text().length>0){
//show usernameTip
}
</script>

Related

How can I disable a specific input field form bootstrap 5 validation script

I will try to make it short as possible. I have built a signup form for my project using bootstrap 5 validators and I'm facing a problem with the retype password input, if the user writes a password that didn't match the password he wrote earlier the green border of the input keep showing and the red border not showing not red and the jquery script of password comparison is actually working. here is my code I hope you understood my issue :
<div class="tab-pane fade" id="nav-signup" role="tabpanel" aria-labelledby="nav-signup-tab">
<form class="row row m-auto p-5 g-2 needs-validation" method="post" action="../public/include/signup.inc.php" id="reg-form" novalidate>
<div class="col-md-3">
<input type="text" class="form-control" id="Fname" minlength="3" maxlength="12" placeholder="First Name..." onclick="validate()" autofocus required>
<div class="valid-feedback" id="fnvt">
Looks good !
</div>
<div class="invalid-feedback" id="fnvf">
</div>
</div>
<div class="col-md-3">
<input type="text" class="form-control" id="LName" placeholder="Last Name..." required>
<div class="valid-feedback" id="lnvt">
Looks good!
</div>
<div class="invalid-feedback" id="lnvf">
</div>
</div>
<div class="col-md-3">
<input type="email" class="form-control" id="email" maxlength="50" placeholder="Enter your email..." required>
<div class="valid-feedback" id="emvt">
Looks good!
</div>
<div class="invalid-feedback" id="emvf">Email not correct !</div>
</div>
<div class="col-md-3">
<input type="password" class="form-control no-validate" name="pw1" minlength="6" maxlength="24" id="pw1" placeholder="Enter a password..." required >
<div class="valid-feedback" id="pwvt1">
Looks good!
</div>
<div class="invalid-feedback" id="pwvf1">Enter a password !</div>
</div>
<div class="col-md-3">
<input type="password" class="form-control" name="pw2" id="pw2" placeholder="Retype your password..." minlength="6" required>
<div class="valid-feedback" id="cpvt"></div>
<div class="invalid-feedback" id="cpvf">Password not match</div>
</div>
<div class="col-md-3">
<input type="tel" value="05" maxlength="10" minlength="10" aria-describedby="inputGroupPrepend" placeholder="Phone number..." class="form-control" id="phone" onkeypress="validate(event)" aria-describedby="inputGroupPrepend" required>
<div class="invalid-feedback">
Write a correct phone number.
</div>
<div class="valid-feedback">
</div>
<div class="col-15 mt-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
<label class="form-check-label" style="font-family: Tajawal; color: #fff;" for="invalidCheck">
By signing up, I agree to the terms and coniditons of the platform !
</label>
<div class="invalid-feedback">
You must agree before submitting.
</div>
</div>
<div class="justify-content-center mt-4" action="?" method="POST">
<div class="mt-2 g-recaptcha" data-sitekey="your_site_key">
<div class="invalid-feedback"></div>
</div>
<br/>
<div class="col-12 mt-3">
<button class="btn btn-primary" name="submitup" type="submit">Register</button>
</div>
</div>
</form>
Bootstrap 5 validation script :
'use strict'
var forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
jquery password compare :
$(document).ready(function(e){
$("#reg-form").submit(function(event){
let $pw1 = $("#pw1");
let $pw2 = $("#pw2");
let $error = $("#cpvf");
let $true = $("#cpvt");
if ($pw1.val() === $pw2.val()) {
return true;
}if ($pw1.val() !== $pw2.val()) {
$error.text("Password not Match");
event.preventDefault();
}
});
})
here is an example of the problem, the code is working but the retype border is green and it is supposed to show a red border.
best regards.

Unable to get the value of hidden field via jquery using serialize() function

I'm using the Tag Manager plugin to create tags for my form and passing values to php using the serialize() function in jquery. When I retrieve the value I get an empty string but without the serialize() function, the tag creator works fine.
<input type="text" name="tags" placeholder="Tags" class="tm-input form-control tm-input-info" id="collaborationsSoughtInput" name="collaborationsSoughtInput" />
And this is my jquery function
function adduser() {
$.post("functions/add-user.php", $("#registerForm").serialize()).done(function(data) {
var result = $.trim(data);
if (result == "OK") {
window.location.href = "login";
} else {
console.log("Register error :" + result);
}
});
}
And the php code
$collaborationsSoughtInput = $con->real_escape_string($_POST['hidden-tags']);
And here is the working example
Here if the complete form
<form action="" id="registerForm" class="mb-4" style="margin-bottom: 50px" method="post" enctype="multipart/form-data">
<div class="form-group has-feedback row">
<label for="fullnameInput" class="col-sm-3 col-form-label" required>Full Name *</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="fullname" name="fullname" required>
</div>
<span id="fullNameError" class="color-red hide-me">Full Name Error</span>
</div>
<div class="form-group has-feedback row">
<label for="usernameInput" class="col-sm-3 col-form-label">Username *</label>
<div class="col-sm-8">
<input minlength="4" type="text" class="form-control" id="username" name="username">
</div>
<span id="usernameError" class="color-red hide-me">Userame Error</span>
</div>
<div class="form-group has-feedback row">
<label for="passwordInput" class="col-sm-3 col-form-label" required>Password *</label>
<div class="col-sm-8">
<input class="form-control" type="password" value="hunter2" id="password" name="password">
</div>
<span id="passwordError" class="color-red hide-me">Password Error</span>
</div>
<div class="form-group has-feedback row">
<label class="col-sm-3 col-form-label" for="collaborationsSoughtInput">Collaborations Sought *</label><br/>
<div class="col-sm-8">
<input type="text" name="tags" placeholder="Tags" class="tm-input form-control tm-input-info" id="collaborationsSoughtInput" name="collaborationsSoughtInput" />
</div>
<span id="collaborationsError" class="color-red hide-me">Collaborations Error</span>
</div>
</form>
And in the console, I get this
<b>Notice</b>: Undefined index: hidden-tags in ...
Your whole output of .serialize() is empty? Seems like your form selector could be wrong then.

The entity name must immediately follow the '&' in the entity reference AngularJs Validation

Hey everyone am trying to make a validation for a form with AngularJS in Thymeleaf
<form name="registerForm" novalidate="">
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
<div class="form-group">
<label>Lastname *</label>
<input id="lastname" type="text" ng-model="lastname" class="form-control" required="required" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Firstname *</label>
<input id="firstname" type="text" ng-model="firstname" class="form-control" required="required" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Date of birth *</label>
<input id="birth" type="date" ng-model="brith" class="form-control" required="required" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>email *</label>
<input id="email" type="text" ng-model="email" class="form-control" required="required" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Username *</label>
<input id="user" type="text" ng-model="user" class="form-control" required="required" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Acount Type *</label>
<select ng-model="accout" class="form-control" required="required" >
<option selected="">StartUp</option>
<option>Entreprise</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="form-group" ng-class="{'has-error': registerForm.$dirty && registerForm.pass.$invalid, 'has-success': registerForm.pass.$valid}">
<label>Password *</label>
<input id="pass" name="pass" type="text" ng-model="pass" ng-minlength="6" class="form-control" required="required" />
<span class="text-danger" ng-show="registerForm.pass.$error.minlength">Password Too Short</span>
</div>
</div>
<div class="col-md-6">
<div class="form-group" ng-class="{'has-error': registerForm.$dirty && registerForm.confpass.$invalid, 'has-success': registerForm.confpass.$valid}">
<label>Confirm Password *</label>
<input id="confpass" name="confpass" type="text" ng-model="confpass" class="form-control" equals-to="registerForm.pass" required="required" />
<span ng-show="!registerForm.confpass.$error.required && registerForm.confpass.$error.equalsTo">Vérifiez votre mot de passe</span>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-danger pull-right" >Sign Up</button>
</div>
</div>
</div>
</form>
This actually work in a simple HTML Page in Thymeleafi get this kind of error
The entity name must immediately follow the '&' in the entity reference
i've tried replacing the && with &&
the form validation wont work , am not having any errors but i don't think that the conditions are correct.
Thymeleaf Doesn't Support &&.
You use 'and' instead of '&&'.
For Example :
<span ng-show="!registerForm.confpass.$error.required and registerForm.confpass.$error.equalsTo">Vérifiez votre mot de passe</span>

Best way to get all required inputs

I have form, where exist few required fields Example
<div class="form-group">
<label class="col-md-3 control-label" for="mpassword">Password<span class="required"> * </span></label>
<div class="col-md-3">
<input type="password" id="mpassword" name="mpassword" class="form-control" placeholder="Enter password"/>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label" for="memail">Email <span class="required">* </span></label>
<div class="col-md-3">
<input type="email" id="memail" name="memail" class="form-control" placeholder="Enter email"/>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label" for="mname">Full name<span class="required">* </span></label>
<div class="col-md-3">
<input type="text" id="mname" name="mname" class="form-control" placeholder="Enter name" value="MyName"/>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label" for="mname">Nick name</label>
<div class="col-md-3">
<input type="text" id="mname" name="mname" class="form-control" placeholder="Enter nickname"/>
</div>
</div>
Problem, i don't know what is correct way to get all required fields as they don't have required attribute or class. Only labels have required class, which means "this input is required"
Just target the labels, and then get the inputs based on the for attribute
$('label:has(.required)').map(function() {
return $('#' + $(this).attr('for'));
});
Note that two of the form elements have the same name ?
$('.required').next().find('input').each(function() {
// handle elements
});

Multiple required fields in angular JS

I have a new profile form that has multiple required fields, email, password and confirm password. The submit button is set to be disabled if the form is in invalid state. I believe that form should remain in invalid state until user has filled in all the required fields. To my surprise, angular checks my first field only. If it is alone in valid state, submit button gets activated, regardless of states of other fields. I am using angular 1.0.7. What is the reason behind this behavior ?
<form name='newProfileForm' ng-submit="formSubmit(newProfileForm.$valid)" novalidate>
<fieldset>
<legend>Login Information</legend>
</fieldset>
<!-- NAME -->
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control" ng-model="user.mail" required>
<p ng-show="newProfileForm.email.$invalid && newProfileForm.email.$dirty">Please enter valid email.</p>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="pass" required/>
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" class="form-control" required/>
</div>
<fieldset>
<legend>Personal Details</legend>
</fieldset>
<div class="form-group">
<label>Title</label>
<select class="span3">
</select>
</div>
<div class="form-group">
<label>First Name</label>
<input type="text" class="form-control"/>
</div>
<div class="form-group">
<label>Last Name</label>
<input type="text" class="form-control"/>
</div>
<div class="form-group">
<label>Contact Number</label>
<input type="text" class="form-control"/>
</div>
<div class="form-group">
<label>Date of Birth</label>
<input type="text" class="form-control"/>
</div>
<div class="form-group">
<label>Address</label>
<textarea rows="3"></textarea>
</div>
<div class="form-group">
<label>Country</label>
<select class="span3">
</select>
</div>
<div class="form-group">
<label>State</label>
<select class="span3">
</select>
</div>
<div class="form-group">
<label>City</label>
<select class="span3">
</select>
</div>
<div class="form-group">
<label>Pin Code</label>
<input type="text" class="form-control"/>
</div>
<div class="form-group">
<label>Gender</label>
<select class="span3">
<option label="Male" value="Male"/>
<option label="Female" value="Female"/>
</select>
</div>
<div class="form-group">
<label>Field of Interest</label>
<input type="text" class="form-control"/>
</div>
<!-- SUBMIT BUTTON -->
<button type="submit" class="btn btn-primary" ng-disabled="newProfileForm.$invalid">Submit</button>
</form>
You forgot to give ng-model to your password and confirm password field. Do it like
<input type="password" class="form-control" name="pass" ng-model="pass" required/>
<input type="password" class="form-control" name="confirmpass" ng-model="confirmpass" required/>

Categories