Background:
I have followed this guide and struggle quite a long time to make a custom tag to perform validation (matching of 2 passwords), but the form validation ($error) queue does not contains my custom error (isMatch), and thus does not work as expected :(
Controller
insiderApp.directive('isMatch',function(){
return{
require: "ngModel",
link: function(scope,elt,attr,ngModel){
var firstPwd = attr.isMatch;
//format text from the user (view to model)
ngModel.$parsers.unshift(function(value){
var valid = firstPwd === value;
ngModel.$setValidity('isMatch',valid);
return valid;
});
//format text going to user (model to view)
ngModel.$formatters.unshift(function(value){
ngModel.$setValidity('isMatch',firstPwd === value);
return value;
});
}
};
});
HTML (view)
<form role="form" name="wifiForm" novalidate>
</br>
<div class="form-group">
<label for="ssid">SSID:</label>
<input name="ssid" type="text" class="form-control" id="ssid" placeholder="Enter the SSID" ng-model="wifiConf.ssid" required>
</div>
<div class="form-group" ng-class="{'has-error':wifiConf.key.length<8 || wifiConf.key.length>64 && wifiForm.$dirty}">
<label for="secret">WPA2 Pre-Shared Key:</label>
<input name="secret" type="password" class="form-control" id="secret" ng-model="wifiConf.key" placeholder="Enter the WPA2 Pre-Shared Key" required>
<span class="text-danger" ng-show="wifiConf.key.length<8 || wifiConf.key.length>64 && wifiForm.$dirty"><b>Secret length should be within 8 to 64 characters.</b></span>
</div>
<div class="form-group" ng-class="{'has-error': wifiConf.key != wifiConf.keyRepeat && wifiForm.$dirty}">
<label for="secretRepeat">WPA2 Pre-Shared Key (Repeat):</label>
<input name="secretRepeat" type="password" class="form-control" id="secretRepeat" ng-model="wifiConf.keyRepeat" isMatch="wifiConf.key" required placeholder="Confirm WPA2 Pre-Shared Key">
<span class="text-danger" ng-show="wifiForm.secretRepeat.$error"><b>Two secrets are not match to each other.</b></span>
</div>
<button type="submit" class="btn btn-default wifiSubmit" ng-disabled="wifiForm.$invalid" ng-click="wifiProceed(wifiConf,'/configure/done')">Next</button>
</form>
The problem is even when 2 passwords are incorrect, users still able to press Next.
Any help will be appreciated
Maybe you can try another simpler way :
<form role="form" name="wifiForm" novalidate>
</br>
<div class="form-group">
<label for="ssid">SSID:</label>
<input name="ssid" type="text" class="form-control" id="ssid" placeholder="Enter the SSID" ng-model="wifiConf.ssid" required>
</div>
<div class="form-group" ng-class="{'has-error':wifiConf.key.length<8 || wifiConf.key.length>64 && wifiForm.$dirty}">
<label for="secret">WPA2 Pre-Shared Key:</label>
<input name="secret" type="password" class="form-control" id="secret" ng-model="wifiConf.key" placeholder="Enter the WPA2 Pre-Shared Key" required>
<span class="text-danger" ng-show="wifiConf.key.length<8 || wifiConf.key.length>64 && wifiForm.$dirty"><b>Secret length should be within 8 to 64 characters.</b></span>
</div>
<div class="form-group" ng-class="{'has-error': wifiConf.key != wifiConf.keyRepeat && wifiForm.$dirty}">
<label for="secretRepeat">WPA2 Pre-Shared Key (Repeat):</label>
<input name="secretRepeat" type="password" class="form-control" id="secretRepeat" ng-model="wifiConf.keyRepeat" isMatch="wifiConf.key" required placeholder="Confirm WPA2 Pre-Shared Key">
<span class="text-danger" ng-show="wifiForm.secretRepeat.$dirty && (wifiConf.keyRepeat != wifiConf.key)"><b>Two secrets are not match to each other.</b></span>
</div>
<button type="submit" class="btn btn-default wifiSubmit" ng-disabled="wifiForm.$invalid || (wifiConf.keyRepeat != wifiConf.key)" ng-click="wifiProceed(wifiConf,'/configure/done')">Next</button>
</form>
Related
i'm working on a school project. My project has some forms that need to be validated. Login and register form validation work well but the other form used to upload item is not validated. I have tried to figure out the error but get no result.
Note that the function works ok, just the validation get error
I'm using AngularJS 1.4.5 along with Google Firebase
This is my registration HTML code:
<form name="registerform" ng-submit="register()" novalidate>
<div class="form-group">
<p ng-show="message">{{message}}</p>
<label>First name</label>
<input type="text" name="firstname" class="form-control" placeholder="First name" ng-model="user.firstname" ng-required="true">
<p class="text-danger" ng-show="registerform.firstname.$invalid && registerform.firstname.$touched">This field is required</p>
</div>
<div class="form-group">
<label>Last name</label>
<input type="text" name="lastname" class="form-control" placeholder="Last name" ng-model="user.lastname" ng-required="true">
<p class="text-danger" ng-show="registerform.lastname.$invalid && registerform.lastname.$touched">This field is required</p>
</div>
<div class="form-group">
<label>Email address</label>
<input type="email" name="email" class="form-control" placeholder="Enter email" ng-model="user.email" ng-required="true">
<p class="text-danger" ng-show="registerform.email.$invalid && registerform.email.$touched">Invalid email</p>
<small class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" class="form-control" placeholder="Password" ng-model="user.password" ng-minlength="6" ng-required="true">
<p class="text-danger" ng-show="registerform.password.$invalid && registerform.password.$touched">Password must have at least 6 characters</p>
</div>
<button type="submit" class="btn btn-success btn-block" ng-disabled="registerform.$invalid">Register</button><br>
Already have an account? Login
</form>
And this is my item upload form:
<p ng-show="message">{{message}}</p>
<form name="uploadItem" ng-submit="uploadItem()" novalidate>
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" placeholder="Food name" ng-model="foodname" ng-required="true">
<p class="text-danger" ng-show="uploadItem.name.$invalid && uploadItem.name.$touched">This field is required</p>
</div>
<div class="form-group">
<label>Category</label>
<select class="form-control" name="category" ng-model="foodcategory" ng-required="true">
<option value="">---Please select---</option>
<option value="appetizer">Appetizer</option>
<option value="maincourse">Main Course</option>
<option value="dessert">Dessert</option>
<option value="drinks">Drinks</option>
<option value="bakery">Bakery</option>
</select>
<p class="text-danger" ng-show="uploadItem.category.$invalid && uploadItem.category.$touched">This field is required</p>
</div>
<div class="form-group">
<label>Image</label>
<input type="text" name="image" class="form-control" placeholder="Food image" ng-model="foodimage" ng-required="true">
<p class="text-danger" ng-show="uploadItem.image.$invalid && uploadItem.image.$touched">This field is required</p>
</div>
<div class="form-group">
<label>How to cook</label>
<textarea class="form-control" rows="3" name="howtocook" placeholder="How to cook" ng-model="foodhowtocook" ng-required="true"></textarea>
<p class="text-danger" ng-show="uploadItem.howtocook.$invalid && uploadItem.howtocook.$touched">This field is required</p>
</div>
<div class="form-group">
<label>Video</label>
<input type="text" name="video" class="form-control" placeholder="Youtube embed link" ng-model="foodvideo" ng-required="true">
<p class="text-danger" ng-show="uploadItem.video.$invalid && uploadItem.video.$touched">This field is required</p>
</div>
<button type="submit" class="btn btn-primary btn-block" ng-disabled="uploadItem.$invalid">Submit</button><br>
</form>
The novalidate attribute is a boolean attribute.
When present, it specifies that the form-data (input) should not be validated when submitted
Hye,
I tried to reproduce your scenario, and I am able to validate upload form.
Please have a look.
<div ng-app="angularjs-starter" ng-controller="MainCtrl">
<p ng-show="message">{{message}}</p>
<form name="uploadItem" ng-submit="uploadItem()" novalidate>
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" placeholder="Food name" ng-model="foodname" ng-required="true">
<p class="text-danger" ng-show="uploadItem.name.$invalid && uploadItem.name.$touched">This field is required</p>
</div>
<div class="form-group">
<label>Category</label>
<select class="form-control" name="category" ng-model="foodcategory" ng-required="true">
<option value="">---Please select---</option>
<option value="appetizer">Appetizer</option>
<option value="maincourse">Main Course</option>
<option value="dessert">Dessert</option>
<option value="drinks">Drinks</option>
<option value="bakery">Bakery</option>
</select>
<p class="text-danger" ng-show="uploadItem.category.$invalid && uploadItem.category.$touched">This field is required</p>
</div>
<div class="form-group">
<label>Image</label>
<input type="text" name="image" class="form-control" placeholder="Food image" ng-model="foodimage" ng-required="true">
<p class="text-danger" ng-show="uploadItem.image.$invalid && uploadItem.image.$touched">This field is required</p>
</div>
<div class="form-group">
<label>How to cook</label>
<textarea class="form-control" rows="3" name="howtocook" placeholder="How to cook" ng-model="foodhowtocook" ng-required="true"></textarea>
<p class="text-danger" ng-show="uploadItem.howtocook.$invalid && uploadItem.howtocook.$touched">This field is required</p>
</div>
<div class="form-group">
<label>Video</label>
<input type="text" name="video" class="form-control" placeholder="Youtube embed link" ng-model="foodvideo" ng-required="true">
<p class="text-danger" ng-show="uploadItem.video.$invalid && uploadItem.video.$touched">This field is required</p>
</div>
<button type="submit" class="btn btn-primary btn-block" ng-disabled="uploadItem.$invalid">Submit</button><br>
</form>
</div>
Thanks for trying to help me. I figure out the way to fix this issue but it's weird.
To get the form validation work I just need to change the form name
from
<form name="uploadItem" ng-submit="uploadItem()" novalidate>
to
<form name="uploadForm" ng-submit="uploadItem()" novalidate>
and correct the following in other input tags like:
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" placeholder="Food name" ng-model="foodname" ng-required="true">
<p class="text-danger" ng-show="uploadForm.name.$invalid && uploadForm.name.$touched">This field is required</p>
</div>
However, it now get to other error.
This is my angular code:
$scope.uploadItem = function(){
recipesInfo.$add({
name: $scope.foodname,
category: $scope.foodcategory,
image: $scope.foodimage,
howtocook:$scope.foodhowtocook,
video:$scope.foodvideo,
date: firebase.database.ServerValue.TIMESTAMP
}).then(function(){
$scope.foodname = '';
$scope.foodimage = '';
$scope.foodcategory = '';
$scope.foodhowtocook = '';
$scope.foodvideo = '';
$scope.message = 'Success!';
});//promise
}//uploadItem
I push all of the data into Firebase then reset the input fields into blank with
.then(function(){
$scope.foodname = '';
$scope.foodimage = '';
$scope.foodcategory = '';
$scope.foodhowtocook = '';
$scope.foodvideo = '';
$scope.message = 'Success!';
});//promise
But after hitting the submit button, although data is being pushed into Firebase and input fields reset to blank, this one show up
<p class="text-danger" ng-show="uploadForm.name.$invalid && uploadForm.name.$touched">This field is required</p>
I want after hitting the submit button, the form will be reset without any error message
When I am clicking login button, error messages are not showing.
<form name="loginform" ng-submit="loginform.$valid && login()" novalidate >
<div class="form-group" ng-class="{ 'has-error' : loginform.username.$invalid && !loginform.username.$pristine }">
<input type="email" name="username" class="form-control" ng-model="user.username" placeholder="Email" required>
<p ng-show="loginform.username.$touched && loginform.username.$invalid" class="help-block">The name is required.</p>
<p ng-show="loginform.username.$touched && loginform.username.$error.email" class="help-block">Please enter valid email id.</p>
</div>
<input type="password" ng-model="user.password" placeholder="Password" class="form-control"> <br>
<button type="submit" value="Log in" class="btn btn-primary" >Log In</button>
</form>
Here is my registration form and I want all the form fields to be stored in a json string variable using angular and then post that json string to a certain url. When the user is registered it must show "successfully registered" message but if email_id or username already exist server should send back form data in with error. Below is registration form.
<form name="myForm" class="register--form" ng-submit="register()" novalidate>
<fieldset>
<input class="register--first-input" type="text" name="firstname" placeholder="First Name" ng-model="user.firstname" ng-required="true">
<p class="error validationerror" ng-show="myForm.firstname.$invalid && myForm.firstname.$touched">You must enter your first name.</p>
<input class="register--last-input" type="text" name="lastname" placeholder="Last Name" ng-model="user.lastname" ng-required="true">
<p class="error validationerror" ng-show="myForm.lastname.$invalid && myForm.lastname.$touched">You must enter your last name.</p>
<input class="register--email-input" type="email" name="email" placeholder="Email" ng-model="user.email" ng-required="true">
<p class="error validationerror" ng-show="myForm.email.$invalid && myForm.email.$touched">Must be a valid email.</p>
<input class="register--password-input" type="password" name="password" placeholder="Password" ng-model="user.password" ng-required="true">
<p class="error validationerror" ng-show="myForm.password.$invalid && myForm.password.$touched">You must enter a password.</p>
</fieldset>
<button type="submit" class="register--submit" ng-disabled="myForm.$invalid">Register</button>
<span>or</span>
<a class="login--register" ng-href="#/login">Login</a>
</form>
Below is login form
<form name="form" ng-submit="vm.login()" role="form">
<div class="form-group" ng-class="{ 'has-error': form.username.$dirty && form.username.$error.required }">
<label for="username">Username</label>
<input type="text" name="username" id="username" class="form-control" ng-model="vm.username" required />
<span ng-show="form.username.$dirty && form.username.$error.required" class="help-block">Username is required</span>
</div>
<div class="form-group" ng-class="{ 'has-error': form.password.$dirty && form.password.$error.required }">
<label for="password">Password</label>
<input type="password" name="password" id="password" class="form-control" ng-model="vm.password" required />
<span ng-show="form.password.$dirty && form.password.$error.required" class="help-block">Password is required</span>
</div>
<div class="form-actions">
<button type="submit" ng-disabled="form.$invalid" class="btn btn-primary">Login</button>
Register
</div>
</form>
In the controller where you have the button clicked method create a variable like and it will have the values in the key named same as the ng modle
$scope.show={};
I have a form
<form role="form" name="signup" novalidate>
<div class="form-group" ng-class="{ 'has-error' : signup.firstname.$invalid && !signup.firstname.$pristine }">
<label>First Name</label>
<input type="text" name="firstname" class="form-control" ng-model="firstname" required>
<p ng-show="signup.firstname.$invalid && !signup.firstname.$pristine" class="help-block">You name is required.</p>
</div><div class="form-group"">
<label>Last Name</label>
<input type="text" name="lastname" class="form-control" ng-model="lastname">
</div>
<div class="form-group" ng-class="{ 'has-error' : signup.phone.$invalid && !signup.phone.$pristine }">
<label>Phone</label>
<input type="text" name="phone" class="form-control" ng-model="phone" ng-minlength="10">
<p ng-show="signup.phone.$invalid && !signup.phone.$pristine" class="help-block">Number is too short!!</p>
</div>
<div class="form-group" ng-class="{ 'has-error' : signup.email.$invalid && !signup.email.$pristine }">
<label>Email</label>
<input type="email" name="email" class="form-control" ng-model="email">
<p ng-show="signup.email.$invalid && !signup.email.$pristine" class="help-block">Enter a valid email.</p>
</div>
<div class="form-group" ng-class="{ 'has-error' : signup.password.$invalid && !signup.password.$pristine }">
<label>Password</label>
<input type="password" name="password" class="form-control" ng-model="password" ng-minlength="6">
<p ng-show="signup.password.$invalid && !signup.password.$pristine" class="help-block">Password is too short</p>
</div>
<div class="form-group" ng-class="{ 'has-error' : signup.passwordRepeat.$invalid && !signup.passwordRepeat.$pristine }">
<label>Password Repeat</label>
<input type="password" name="passwordRepeat" class="form-control" ng-model="passwordRepeat" ng-minlength="6">
<p ng-show="signup.passwordRepeat.$invalid && !signup.passwordRepeat.$pristine" class="help-block">Password repeat is too short</p>
</div>
<button type="submit" class="btn btn-primary btn-success" ng-disabled="signup.$invalid" ng-click="signing()">Create New Account</button>
</form>
it calls a controller function signing()
$scope.signing = function () { $scope.signup($scope.firstname, $scope.lastname, $scope.email, $scope.telephone, $scope.password, $scope.$passwordRepeat); }
which in turn calls
$scope.signup = function ($firstname, $lastname, $email, $phone, $password, $passwordRepeat) {....}
but the console is saying
"Error: $scope.signup is not a function"
the thing is, both functions are defined in the same controller, and it was working fine, before, i can't seem to wrap my head around what could be wrong.
It started saying there was an error, wen i tried to do form validation.
Any help will be highly appreciated.
The problem is that you are using the same name for the form: name="signup". This is also creating a signup property in the $scope, overriding the signup function you defined in the controller. Change one of them at it should work.
I'm missing something simple I am sure of it, but my form validation messages never appear in the following code.
<form name="loginform" ng-controller="controllers.LoginController" ng-submit="loginUser(loginform.$valid)" novalidate>
<fieldset>
<br/>
<legend><h3>Account Login</h3></legend>
<div class="{ 'has-error' : loginform.username.$invalid && !loginform.username.$pristine }">
<label>Username:</label>
<input type="text" ng-model="username" name="username" placeholder="username" class="form-control" required><span ng-show="loginform.username.$invalid && !loginform.username.$pristine" class="help-block">Required!</span>
</div>
<br/>
<div class="{ 'has-error' : loginform.password.$invalid && !loginform.password.$pristine }">
<label>Password:</label>
<input type="password" name="password" ng-model="password" placeholder="password" class="form-control" required><span ng-show="loginform.password.$invalid && !loginform.password.$pristine" class="help-block">Required!</span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary" >Submit</button>
Login
</div>
</fieldset>
</form>
controllers.LoginController = function ($scope, $location, AuthFactory, Page) {
'use strict';
$scope.username = null;
$scope.password = null;
$scope.loginUser = function (isValid) {
The $pristine check was the problem... Here are the corrections...
<form name="loginform" ng-submit="loginUser(loginform.$valid)" novalidate>
<fieldset>
<br/>
<legend><h3>Account Login</h3></legend>
<div class="form-group" ng-class="{ 'has-error' : loginform.password.$invalid && submitted }">
<label>Username:</label>
<input type="text" ng-model="username" name="username" placeholder="username" class="form-control" ng-required="true" required><span ng-show="loginform.username.$invalid && submitted" class="help-block">Required!</span>
</div>
<br/>
<div class="form-group" ng-class="{ 'has-error' : loginform.password.$invalid && submitted }">
<label>Password:</label>
<input type="password" name="password" ng-model="password" placeholder="password" class="form-control" required><span ng-show="loginform.password.$invalid && submitted" class="help-block">Required!</span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary" >Submit</button>
Login
</div>
</fieldset>
</form>
If your application is form heavy, consider using this thirdparty ngValidate module.
<input name="demo-field-1" ng-model="user.name" ng-validate="custom-strategy">
The directive will add a span to hold your error messages. You can define custom validation strategies and individual error messages.
demo plnkr