I have a problem validating my form. It is a form to change the password of a register user, the profile picture, and the biography of him. In that form the password is not required firstly, but when someone write the old password, the form requires the new password and the confirm password. I show it by an example.
Right now is not required, but if I write something in the input of old password I need that the new password and the confirm password become red. The code I have is it:
<div class="form-group">
<label for="oldpassword" class="cols-sm-2 control-label">Old Password</label>
<div class="cols-sm-10">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-lock fa-lg" aria-hidden="true"></i></span>
<input type="password" class="form-control" name="oldpassword" id="oldpassword"
placeholder="Enter your actual password" ng-model="oldPassword"/>
</div>
</div>
</div>
<div class="form-group">
<label for="password" class="cols-sm-2 control-label">New Password</label>
<div class="cols-sm-10">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-lock fa-lg" aria-hidden="true"></i></span>
<input type="password" class="form-control" name="password" id="password"
placeholder="Enter your new password"
ng-model="newPassword" pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" require-pass/>
</div>
</div>
</div>
<div class="form-group">
<label for="confirm" class="cols-sm-2 control-label">Confirm Password</label>
<div class="cols-sm-10">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-lock fa-lg" aria-hidden="true"></i></span>
<input type="password" class="form-control" name="confirm" id="confirm"
placeholder="Confirm your new password" ng-model="confirm" require-pass confirm-directive
/>
</div>
</div>
</div>
The require-pass directive works but only when the user write something in the input of new password or confirm password. The confirm-directive is a directive to check if both password are equals (that directive works).
The require-pass directive is:
app.directive('requirePass', function () {
return {
require: 'ngModel',
link: function (scope, element, attr, mCtrl) {
function myValidation(value) {
var oldPass = $('#oldpassword').val();
console.log(oldPass);
if (oldPass!="") {
mCtrl.$setValidity('charE', false);
} else {
mCtrl.$setValidity('charE', true);
}
return value;
}
mCtrl.$parsers.push(myValidation);
}
}});
Thank you for the help!!
You don't need another custom directive for this. You can just use ng-required. Docs here: https://docs.angularjs.org/api/ng/directive/ngRequired
<input id="newPass" ng-required="oldPass" type="text" ng-model=... />
<input id="newPassConfirm" ng-required="oldPass" type="text" ng-model=... />
ng-required="oldPass" basically says "I require this field to be filled out if oldPass is not blank."
Related
I am currently working on a website and this particular section requires the user to enter their details in a form. What I am trying to achieve is the following;
If the user hits the submit button and any fields are empty, I want a span element, which is initially set to CSS display none, to show up for each respective input field which has not been filled.
However, nothing seems to be happening when I click on the button. When I go to the console, it does not display any error message.
Can someone please assist? Many thanks.
HTML:
<!-- START OF 'YOUR DETAILS' FORM-->
<section>
<div class="container">
<h3>Step 3: Your Details</h3>
<!-- SLIDE-IN DIV TO REPRESENT DAY PASS -->
<div class="row chosenmembership">
<div class="col-md-12 text-center" id="yourdetails">
<form action="" method="">
<div class="form-group">
<label for="email">Email:</label>
<input type="email" placeholder="Email Address" id="email" class="form-control your-details">
<span class="warning"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
Email is required!</span>
</div>
<div class="form-group">
<label for="name">Name:</label>
<input type="text" placeholder="Full Name" id="name" class="form-control your-details">
<span class="warning"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
Name is required!</span>
</div>
<div class="form-group">
<label for="number">Contact Number:</label>
<input type="tel" placeholder="Contact Number" id="number" class="form-control your-details">
<span class="warning"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
Contact Number is required!</span>
</div>
<div class="form-group">
<label for="postcode">Post Code:</label>
<input type="text" placeholder="Post Code" id="postcode" class="form-control your-details">
<span class="warning"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
Post Code is required!</span>
</div>
<div class="form-group">
<label for="dob">Date of Birth:</label>
<input type="tel" placeholder="DD/MM/YYYY" id="dob" class="form-control your-details">
<span class="warning"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
DOB is required!</span>
</div>
</form>
<div class="form-group">
<input type="submit" id="submit" value="CONTINUE">
</div>
</div>
</div>
</div>
</section>
<!-- END OF YOUR DETAILS FORM -->
JS / JQUERY:
$("#submit").click(function(){
var $formValues = $(".your-details");
var $warning = $(".warnings");
$($formValues).each(function(index){
if ($(this).val("")){
$($warning[index]).css("display","block");
}
})
})
When your running this code $($formValues).each(function(index){if ($(this).val("")){ console.log(this) and see in which context your function is running, the issue is that every time you write a function declaration it creates a new this context and thus the previous this is lost.
Your selectors are kind of redundant, keep the form from submission and show the warnings when any are empty seems to be your intent.
$("#submit").click(function(e) {
$(".your-details").each(function(index) {
if ($(this).val() =="") {
e.preventDefault();// no submit if not filled out
$(this).next('.warning').css("display", "block");// next sibling show
}
});
});
Thought about this for a bit and believe you might handle the form submit instead
$("form").on('submit', function(e) {
$(this).find('.warning').css("display", "none");// hide in case they fix input values
$(this).find(".your-details").each(function(index) {
if ($(this).val() =="") {
$(this).next('.warning').css("display", "block");// next sibling show
}
});
});
Alternately you might use a filter.
$("form").on('submit', function(e) {
$(this).find('.warning').css("display", "none");// hide in case they fix input values
var emptyInputs = $(this).find(".your-details")
.filter(function() {
return ($(this).val() =="");
});
if(!!emptyInputs) {
e.preventDefault();
emptyInputs.next('.warning').css("display", "block");
}
});
Except typo, there was one problem more, you are actually setting value, instead of checking it: if ($(this).val("")) If you change it, and fix typo, something like this should work. Simplified, your code could look like this:
$("#submit").click(function(){
var $formValues = $(".your-details");
$($formValues).each(function(index){
if ($(this).val()==''){
$(".warning").eq(index).css("display","block");
}
else {
$(".warning").eq(index).css("display","none");
}
})
})
Demo:
$("#submit").click(function(){
var $formValues = $(".your-details");
$($formValues).each(function(index){
if ($(this).val()==''){
$(".warning").eq(index).css("display","block");
}
else {
$(".warning").eq(index).css("display","none");
}
})
})
.warning {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- START OF 'YOUR DETAILS' FORM-->
<section>
<div class="container">
<h3>Step 3: Your Details</h3>
<!-- SLIDE-IN DIV TO REPRESENT DAY PASS -->
<div class="row chosenmembership">
<div class="col-md-12 text-center" id="yourdetails">
<form action="" method="">
<div class="form-group">
<label for="email">Email:</label>
<input type="email" placeholder="Email Address" id="email" class="form-control your-details">
<span class="warning"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
Email is required!</span>
</div>
<div class="form-group">
<label for="name">Name:</label>
<input type="text" placeholder="Full Name" id="name" class="form-control your-details">
<span class="warning"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
Name is required!</span>
</div>
<div class="form-group">
<label for="number">Contact Number:</label>
<input type="tel" placeholder="Contact Number" id="number" class="form-control your-details">
<span class="warning"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
Contact Number is required!</span>
</div>
<div class="form-group">
<label for="postcode">Post Code:</label>
<input type="text" placeholder="Post Code" id="postcode" class="form-control your-details">
<span class="warning"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
Post Code is required!</span>
</div>
<div class="form-group">
<label for="dob">Date of Birth:</label>
<input type="tel" placeholder="DD/MM/YYYY" id="dob" class="form-control your-details">
<span class="warning"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
DOB is required!</span>
</div>
</form>
<div class="form-group">
<input type="submit" id="submit" value="CONTINUE">
</div>
</div>
</div>
</div>
</section>
<!-- END OF YOUR DETAILS FORM -->
P.S. You can keep your: $($warning[index]) vars, but you should hide warnings, anyway (else block), if field is not empty.
I have a validation in my form for email. If the user is already registered, it shows the alert and resets the form with null value. I need the alert message as well as data should retain in the form.
Thanks in advance.
https://plnkr.co/edit/WhdRmJmLs69yaf6Q2uYI?p=preview
<div class="form-group">
<label class="control-label col-sm-2" for="firstName">First Name:</label>
<div class="col-xs-4">
<input type="text" class="form-control" id="firstName" ng-disabled="!edit" name="firstName" ng-model="user.firstName" ng-required="true">
<span style="color:red" ng-show="userForm.myName.$touched && userForm.myName.$invalid">Please enter a First Name</span>
</div>
<label class="control-label col-sm-2">Email:</label>
<div class="col-xs-4"><input type="email" id="email" class="form-control" ng-disabled="!edit" name="email" ng-model="user.email" ng-required="true">
<span style="color:red" ng-show="userForm.email.$touched && userForm.email.$invalid">Please enter valid email ID</span>
</div>
</div>
<div class="panel-footer">
<button type="button" ng-click='edit=!edit'id="Edit" ng-show="!edit" class="btn btn-default" >Edit</button>
<button ng-show="edit" id="save" type="submit" ng-click='addOrModifyUser(user)' class="btn btn-default"
ng-disabled="userForm.$invalid">Save
</button>
<a ng-if="user.accountId" ui-sref="account.locations.contacts({accountId: user.accountId})">
<button type="type" class="btn btn-default">Cancel</button>
</a>
</div>
I?p=preview
Don't know exactly what your problem is here but this is how I would have solved a custom email validation check in angular 1.x.
Html:
<form ng-submit="submit()">
<input type="email" class="form-control" id="email" name="email" placeholder="email" ng-model="formModel.email" />
<span ng-show="formModel.$submitted && formModel.teamName.$error.exists">Email already exists</span>
</form>
Js: (in your angular controller) where "EmailService" would be your http service of choice that checks if email exists against your backend:
myApp.controller('mainController', function($scope, EmailService) {
$scope.submit = function() {
$scope.formModel.email.$setValidity("exists", true);
EmailService.emailExist($scope.formModel.email, { // check if email exists
success: function(exists) {
$scope.$apply(function(){
$scope.formModel.email.$setValidity("exists", !exists); // set validation flag
});
if($scope.formModel.$valid) {
// submit if valid
}
}
}
}
}
Good luck!
I have one issue in my password field and user name field using Angular.js.I have a login page.Suppose user clicked on remember me option of browser after the login.These saved user name and password is displaying on my username field and password field.I am explaining my code below.
<div class="input-group bmargindiv1 col-md-12">
<span class="input-group-addon ndrftextwidth text-right" style="width:180px">User Name :</span>
<div ng-class="{ 'myError': billdata.uname.$touched && billdata.uname.$invalid }">
<input type="text" name="uname" id="uname" class="form-control" placeholder="add user Name" ng-model="login_name" ng-minlength="6" ng-keypress="clearField('uname');" tabindex="6" >
</div>
</div>
<div class="help-block" ng-messages="billdata.uname.$error" ng-if="billdata.uname.$touched">
<p ng-message="minlength" style="color:#F00;">This field is too short.The min length of your user name should be 6.</p>
</div>
<div class="input-group bmargindiv1 col-md-12" ng-hide="showpass">
<span style="position:absolute; right:5px; margin-top:6px; top:0px;"><button class="btn btn-xs btn-success"ng-mousedown="hideShowPassword();" ng-mouseup="hideShowPassword();" ng-mouseleave="hidePassAfterLeave();" ><i class="fa fa-eye"></i></button></span>
<span class="input-group-addon ndrftextwidth text-right" style="width:180px">Password :</span>
<div ng-class="{ 'myError': billdata.pass.$touched && billdata.pass.$invalid }">
<input type="{{inputType}}" name="pass" id="passno" class="form-control" placeholder="password" ng-model="password" ng-minlength="8" ng-pattern="/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[_!##\$%\^&\*])(?=.{8,})/" ng-keypress="clearField('passno');" tabindex="7" >
</div>
The Login credentials used by user at the time of login is available where ever the username and password filed is found which i dont need.Here I need blank user name and password field even the user clicked remember me option of browser.Please help me to resolve this issue .
Try to add 2 hidden inputs to start of your form:
<form autocomplete="off">
<div style="display: none;">
<input type="text" id="PreventChromeAutocomplete"
name="PreventChromeAutocomplete" autocomplete="username" />
<input type="password" id="PreventChromePasswordAutocomplete"
name="PreventChromePasswordAutocomplete" autocomplete="password" />
</div>
<!-- Rest form -->
</form>
you can try this
<input type="password" autocomplete="off" />
try adding autocomplete="off" on your form also
<form autocomplete="off" ...></form>
Try using javascript as :
$('#passno').attr("autocomplete", "off");
or add (autocomplete="off") attribute in html input tag :
For more info, refer http://www.w3schools.com/tags/att_input_autocomplete.asp
Try same for username field as well. :)
I have the following in my handlebars tag:
{{#editmode mode}}
<div class="form-group login-input">
<i class="fa fa-key overlay"></i>
<input type="password" class="form-control text-input" name="password" placeholder="Password" value="{{password}}">
</div>
<div class="form-group login-input">
<i class="fa fa-key overlay"></i>
<input type="password" class="form-control text-input" name="password_confirmation" value="{{password}}">
</div>
{{/editmode}}
and I have the following registered as my helper function:
Handlebars.registerHelper('editmode', function(mode){
return mode == 'edit' ? true : false;
});
The object passed to the handlebars template looks something like this:
{
firstname: 'Test',
lastname: 'Test lastname',
mode: 'new
}
So basically, whenever the 'mode' variable is 'new', I want to show the password fields, otherwise hide them, but right now they are always hidden. Any ideas?
I figured it out. This did the trick:
Handlebars.registerHelper('editmode', function(mode, options){
return mode == 'edit' ? '' : options.fn();
});
You can use if statement.
<div class="form-group login-input">
<i class="fa fa-key overlay"></i>
<input type="password" class="form-control text-input" name="password" placeholder="Password" value="{{password}}">
</div>
{{#if mode}}
<div class="form-group login-input">
<i class="fa fa-key overlay"></i>
<input type="password" class="form-control text-input" name="password_confirmation" value="{{password}}">
</div>
{{/if}}
I'm trying to write a registration form with the help of AngularJS and using Bootstrap for the styling. I've got something working, but I'm pretty sure if I had more knowledge with Angular this could be greatly improved. So far I've got...
User-name field:
<div class="container" ng-controller="validateCtrl">
<form name="myForm">
<div class="form-group has-feedback" ng-class="{true: 'has-success'}[myForm.email.$dirty]" ng-class="{true: 'has-error'}[myForm.email.$invalid]">
<label for="email">Email</label>
<input class="form-control" type="email" name="email" ng-model="email" ng-maxlength="254" placeholder="Enter Email" required>
<span class="glyphicon glyphicon-remove form-control-feedback" ng-show="myForm.email.$dirty && myForm.email.$invalid"></span>
<span style="color:red" ng-show="myForm.email.$dirty && myForm.email.$invalid">
<span ng-show="myForm.email.$error.required">Email is required!</span>
<span ng-show="myForm.email.$error.email">Invalid email address!</span>
<span ng-show="myForm.email.$error.maxlength">Email is too long!</span>
</span>
<span class="glyphicon glyphicon-ok form-control-feedback" ng-show="myForm.email.$dirty && !myForm.email.$invalid"></span>
</div>
Password Field:
<div class="form-group has-feedback" ng-class="{true: 'has-success'}[myForm.password.$dirty]" ng-class="{true: 'has-error'}[myForm.password.$invalid]">
<label for="password">Password</label>
<input class="form-control" type="password" name="password" ng-model="password" ng-minlength="5" ng-maxlength="255" placeholder="Enter Password" required>
<span class="glyphicon glyphicon-remove form-control-feedback" ng-show="myForm.password.$dirty && myForm.password.$invalid"></span>
<span style="color:red" ng-show="myForm.password.$dirty && myForm.password.$invalid">
<span ng-show="myForm.password.$error.required">Password is Required!</span>
<span ng-show="myForm.password.$error.minlength">Password is too short! </span>
<span ng-show="myForm.password.$error.maxlength">Password is too long!</span>
</span>
<span class="glyphicon glyphicon-ok form-control-feedback" ng-show="myForm.password.$dirty && !myForm.password.$invalid"></span>
</div>
Password Confirm:
<div class="form-group has-feedback" ng-class="{true: 'has-success'}[myForm.passwordrepeat.$dirty]" ng-class="{true: 'has-error'}[myForm.passwordrepeat.$invalid]">
<label for="passwordrepeat">Confirm Password</label>
<input class="form-control" type="password" name="passwordrepeat" ng-model="passwordrepeat" placeholder="Confirm Password" required compare-to="password">
<span class="glyphicon glyphicon-remove form-control-feedback" ng-show="myForm.passwordrepeat.$dirty && myForm.passwordrepeat.$invalid"></span>
<span style="color:red" ng-show="myForm.passwordrepeat.$dirty && myForm.passwordrepeat.$invalid">
<span ng-show="myForm.passwordrepeat.$error.required">Second Password is Required!</span>
<span ng-show="myForm.passwordrepeat.$error">Passwords do not match!</span>
</span>
<span class="glyphicon glyphicon-ok form-control-feedback" ng-show="myForm.passwordrepeat.$dirty && !myForm.passwordrepeat.$invalid"></span>
</div>
Submit Button:
<button
class="btn btn-primary"
ng-disabled=
"myForm.email.$invalid ||
myForm.password.$invalid ||
myForm.passwordrepeat.$invalid">
Register
</button>
</form>
</div>
Can anyone advise on how I can make this code more concise? For starters, can this conditional ng-class expression be improved...
<div class="form-group has-feedback" ng-class="{true: 'has-success'}[myForm.passwordrepeat.$dirty]" ng-class="{true: 'has-error'}[myForm.passwordrepeat.$invalid]">
...this basically says, if the field is dirty, then if it's valid add the 'has-success' element else add 'has-error'. Is there a cleaner way of achieving this...
<span ng-show="myForm.email.$error.required">Email is required!</span>
<span ng-show="myForm.email.$error.email">Invalid email address!</span>
<span ng-show="myForm.email.$error.maxlength">Email is too long!</span>
Rather than listing every error? Finally, is there a preferred way of writing long expressions like this in the html template...
"myForm.email.$dirty && !myForm.email.$invalid"
I've tried to get my head around directives and I'm using one for the password confirm but I don't think they would make a big difference here (but I'm probably wrong).
Any help/advise on best practices greatly appreciated!
Your question is sort of vague, however here are some great articles that will help in your quest for better Angular based forms :)
Submitting AJAX Forms: The AngularJS Way
https://scotch.io/tutorials/submitting-ajax-forms-the-angularjs-way
AngularJS Form Validation
https://scotch.io/tutorials/angularjs-form-validation
And since you're using Bootstrap and Angular:
How to Correctly Use BootstrapJS and AngularJS Together
https://scotch.io/tutorials/how-to-correctly-use-bootstrapjs-and-angularjs-together
<!-- FORM -->
<!-- pass in the variable if our form is valid or invalid -->
<form name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate> <!-- novalidate prevents HTML5 validation since we will be validating ourselves -->
<!-- NAME -->
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" ng-model="name" required>
</div>
<!-- USERNAME -->
<div class="form-group">
<label>Username</label>
<input type="text" name="username" class="form-control" ng-model="user.username" ng-minlength="3" ng-maxlength="8">
</div>
<!-- EMAIL -->
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control" ng-model="email">
</div>
<!-- SUBMIT BUTTON -->
<button type="submit" class="btn btn-primary">Submit</button>
</form>
// create angular controller
validationApp.controller('mainController', function($scope) {
// function to submit the form after all validation has occurred
$scope.submitForm = function(isValid) {
// check to make sure the form is completely valid
if (isValid) {
alert('our form is amazing');
}
};
});