angular validating match password using view - angularjs

I'm trying to implement a form validation using only the view - i'm trying to avoid creating a new directive for this.
Question - is possible to validate matching password only using the partial/view e.g:
div(ng-class="{true: 'no-match'}[password != password2]")
any tip will be gladly appreciated :)

Yes it is possible ,
<input name="password" ng-class = "{valid: (password1 == password2),
invalid: (password1 != password2) }" ng-pattern="/[0-9]/">
where, valid and invalid are css classes,
to display an error message regarding that, use
<div id="invalidEmail" class="mismatch"
ng-show="testForm.password.$error.pattern && !testForm.password.$pristine">
Please enter atleast a number
</div>
where testForm is your form name like
<form name="testForm"> </form>
For more reference you can see the link http://www.ng-newsletter.com/posts/validations.html

Related

“Agree on Terms”-checkbox change error message

I use this question "Agree on Terms"-checkbox code to add "Agree on Terms" on my PHP Wordpress Page but i need change error messagge if user not accept the checkbox.
Is possibile?
This is my code use
<form action="#" onsubmit="if(document.getElementById('agree').checked) { return true; } else { alert('Please indicate that you have read and agree to the Terms and Conditions and Privacy Policy'); return false; }">
<input type="checkbox" required name="checkbox" value="check" id="agree" /> I have read and agree to the Terms and Conditions and Privacy Policy
<button type="submit" class="btn" name="reg_user">Register</button>
</form>
Just change this string in your code:
'Please indicate that you have read and agree to the Terms and Conditions and Privacy Policy'
Make sure you don't use ' in your error msg itself - it defines the end of the string.
Edit:
if you remove required name="checkbox" it should work
because if you do have the required name in your code the form itself will check if the checkbox is checked. This would lead to your js code not being executed. Also you should consider puting your js code into a seperate file.

issue with ngPattern

I am trying to design a nifty expiration date input on a credit card checkout form that will automatically insert a " / " between expiration month and year while the user is typing. The model no longer picks up the input value since I have introduced ngPattern validation to the input. Angular only allows a model to pick up the input value once the validation has succeeded. This basically makes my nifty feature not work due to my code. Can someone find a way around this. below is my code.
html
<input ng-keyup="checkout.updateExp()" class="form-control" type="text" maxlength="7" placeholder="mm / yy" required autocomplete="off" name="exp" ng-pattern="/\d{2}\s\/\s\d{2}/" ng-model="checkout.cf.exp">
controller function
vm.updateExp = function(){
var separator=" / ";
//add separator
if(vm.cf.exp.length==2){//-----> cannot process since ngPattern makes exp undefined till pattern is met
vm.cf.exp = vm.cf.exp.substring(0,2) + separator;
}
//remove separator
if(vm.cf.exp.length==4){
vm.cf.exp = vm.cf.exp.substring(0,1);;
}
};
Why not validate it manually using a regular expression instead of having it done using ng-pattern? You can set the $validity of the field manually just like angular would do it using ng-pattern.
In the html add
ng-keyup="checkout.updateExp(form.exp)" name="exp"
form.exp is the form and then the name of the input field. I do not know what the form name is so you will have to replace it accordingly.
vm.updateExp = function(formModel){
/* existing code omitted */
var expression = /\d{2}\s\/\s\d{2}/; // create RegEx
formModel.$setValidity("pattern", expression.test(vm.cf.exp)); // set validity to whatever name you want, I used the name pattern
};

Chaining an element using css containing text and accessing an associated field

I need to access the input field in the below html. The way the page is setup I need to chain using the 'Address Line 1' text and then sending text to the input field. The input field id changes and so doesn't the layout of the fields depending on user preference. I am struggling. If you need some more information feel free to ask I did not want to overload with too much information.
<td class="labelCol requiredInput">
<label for="00N36000000xina"><span class="assistiveText">*</span>Address Line 1</label>
</td>
<td class="dataCol col02">
<div class="requiredInput">
<div class="requiredBlock"></div>
<input id="00N36000000xina" maxlength="255" name="00N36000000xina" size="20" tabindex="4" type="text">
</div>
</td>
I have accessed like this:
element(by.css('div.pbSubsection:nth-child(3) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(2) > td:nth-child(2) > input'))
However depending on where the user puts the fields it can move around. So what I was hoping was to be able to access the label\ and use that to pinpoint its input field.
I don't know protractor but I cobbled together some code that hopefully will work or be close and I'll give you the thought process and some info and hopefully you can use it to fix my code, if needed, and solve the problem.
Start by finding an element by XPath, "//label[text()='Address Line 1']". This searches for a LABEL tag that contains "Address Line 1". Once you find that element, get the label attribute. From your HTML, this label is the id for the INPUT element you want. Now use the id to find the element and do with it what you want.
id = element(by.xpath("//label[text()='Address Line 1']")).getAttribute("label")
input = element(by.id(id))
input.sendkeys("some text")
Haven't tested this myself, but you could try something like this:
// $ is shorthand for element(by.css())
$('div.assistiveText').getAttribute('for').then(function (val) {
// locate the <input> by the value of the attribute on <label>
element(by.id(val)).sendKeys('abc'); // replace sendKeys with your intended function
});
Or if that first locator on the label isn't specific enough, swap out $('div.assistiveText') for element(by.cssContainingText('Address Line 1'))
I tried it for other attributes (I don't have a for attribute anywhere in my app) and it seemed to work for me.
Try this:
List<WebElement> elementList = driver.findElements(By.cssSelector("tbody > tr"));
for (WebElement element : elementList) {
if(element.findElement(By.cssSelector("td.labelCol > label")).getText().equalsIgnoreCase("Address Line 1")) {
element.findElement(By.cssSelector("input[type='text']")).sendKeys("textToInput");
}
}

ng-if inside a form tag?

Logic:
if(condition)
Use first `<form ng-submit="action1">`
else
Use second `<form ng-submit="action2">`
Logic in PHP approach:
<?php
if(condition){
echo "<form action='action1.php' >";
}
else{
echo "<form action='action2.php' >";
}
echo "....many many many inputs here...";
echo "</form>";
?>
What I'm trying to write is something like this: (I'm using AngularJs)
<form ng-submit="action1" ng-if="condition1"> ---> First condition
<form ng-submit="action2" ng-if="condition2"> ---> Second condition if first condition fails
....Many many many inputs
</form>
But of course I can simply write something like this: (would be a pain in the ass)
<div ng-if="condition1"> ---> First condition
<form ng-submit="action1" >
....Many many many inputs
</form>
</div>
<div ng-if="condition2"> ---> Second condition if first condition fails
<form ng-submit="action2" >
....Same inputs as in the first div
</form>
</div>
My question is, is it possible to use ng-if (I also tried ng-disabled) inside a <form> tag?
What I'm trying to avoid is to re-code all my inputs inside the form if the only change I will make is the opening <form> tag.
I've searched for an answer and found nothing and the only thing that's left is to confirm and ask.
If the difference is only the function you want to call on submit, you can do the test in the function itself.
<form ng-submit="mySubmit" >
...Many many many inputs
</form>
Controller
$scope.mySubmit = function(){
if($scope.condition1){
// call the function 1
action1();
}else{
// call the function 2
action2();
}
}
Okay after a long try, zcui93 and abimelex codes seems to work without the {} (curly braces):
So the code will be:
ng-submit="condition1 ? action1() : condition2 ? action2() : action3()"
Please confirm if it also works with you. But it really works for me.

Input is invalid even when it's error is empty

I'm trying to create my own validation for password confirm, and putting my error on $error. this is my code:
html:
<input ng-model="user.password2" type="password" name="password2" required
ng-keyup="confirmPassword(user.password, user.password2)">
<div ng-messages="register.password2.$error" ng-if="register.password2.$dirty">
<div ng-message="required">Password is required</div>
<div ng-message="passwordsDontMatch">Passwords don't match</div>
</div>
JS:
$scope.confirmPassword = function (pass1, pass2) {
if (angular.isUndefined(pass1) || angular.isUndefined(pass2) || pass1.trim() != pass2.trim()) {
$scope.register.password2.$error["passwordsDontMatch"] = true;
} else {
delete $scope.register.password2.$error["passwordsDontMatch"];
}
console.log($scope.register.password2.$error);
};
it looks like it's working. when the passwords are the same, the message is not displayed and indeed the $error object is empty. But the input is still invalid: ($scope.register.password2.$invalid == true)
you can see what I'm talking about in this plunkr: http://plnkr.co/edit/ETuVqsdSaEBWARvlt4RR?p=preview
try 2 identical passwords. the message will disappear but when you blur from the input, it's still red because internally it's $invalid
The problem probably comes from the fact that you're not typing a password in the first field that matches your regex pattern. The first password is thus undefined, since it doesn't respect the ng-pattern validation rule.
That said, you shouldn't modify the $error array directly. Instead, you should set the validity of the field using $setValidity(). That will not only set and remove the error automatically, but also deal with the $invalid/$valid properties, add and remove the CSS classes, etc.
var valid = !((angular.isUndefined(pass1) || angular.isUndefined(pass2) || pass1.trim() != pass2.trim()));
$scope.register.password2.$setValidity("passwordsDontMatch", valid);
Here's a working example. But remember to enter a valid password in the first place.
Also, instead of implementing this check with ng-keyup, you should make it a directive, which would add a validator to the validators of the form input. This would make sure the check is made whatever the way the second password is entered (i.e. via copy/paste using the mouse only, or simply by prepopulating the form programmatically.

Resources