issue with custom directive for checking unique email id - angularjs

I am working on Angularjs form where i need to validate whether input value is on database or not.
my html is as below
<div class="form-group mg-btm0" show-errors>
<label class="control-label col-sm-4 fw-norm txt-right">Email ID:</label>
<div class="col-sm-8">
<input type="email" class="form-control" placeholder="Email ID" name="emailAddress" ng-required="true" autocomplete="Off" ng-model="User.emailId"
ng-maxlength="100" emailid-available-validator>
<span class="help-block" ng-if="RegisterUser.emailAddress.$error.email">A valid email is required.</span>
<span class="help-block" ng-if="RegisterUser.emailAddress.$error.maxlength">Max length is 100.</span>
<span class="help-block" ng-if="RegisterUser.emailAddress.$pending"> Checking emailId...</span>
<span class="help-block" ng-if="RegisterUser.emailAddress.emailidAvailable">EmailId entered has already been registered</span>
</div>
</div>
Directive is as below
angularFormsApp.directive('emailidAvailableValidator', ['$http', function ($http) {
var baseurl = window.location.protocol + "//" + window.location.host + "/";
return {
require: 'ngModel',
link: function ($scope, element, attrs, ngModel) {
ngModel.$asyncValidators.emailidAvailable = function (value) {
//var emailid = { 'emailid': emailaddress };
return $http.get(baseurl + "Users/CheckExternalUserExists/", { emailid: value });
};
}
}
}])
and controller is as below
[HttpGet]
public ActionResult CheckExternalUserExists(string emailid)
{
if (AccountExecutor.UserExists(emailid))
{
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError, "Exists");
}
return new HttpStatusCodeResult(HttpStatusCode.OK, "Not Exists");
}
Now problem I am having are.
1 . Email id being pass as null to controller.
2 . I want to show two message
a) If email id is unique , then message should say its unique something
b) if email id exists then It should show message that it exists ,
currently message is not being display only red border is showing.

try below in your code
ngModel.$asyncValidators.emailidAvailable = function (ngModel.$modelValue) {
//var emailid = { 'emailid': emailaddress };
return $http.get(baseurl + "Users/CheckExternalUserExists/", { emailid: value });
};
check out below link for more information...
[asyncValidators][1]

Related

How can I return the required message without the distinct message?

I have a small password form that returns different messages depending on what has been entered, if nothing has been entered the message should just be "please enter a password" if the password entered is like the username then the only error message back should be "Your password can not be like your username". And finally when the pattern doesnt match the user should get a message about the pattern. When I enter nothing and click submit I am getting both the distinct and required messages back, how can I fix this to only show the required message until data has been entered that matches the username?
HTML:
<div ng-controller="NewPasswordCtrl" ng-init="init()">
<form name="npForm" class="col-md-12" role="form" style="padding-top:15px" ng-submit="SubmitPasswordReset(npForm, NewPasswordModel)" novalidate>
<div class="form-group">
<div class="input-group">
<input id="newPassword" name="newPassword" type="password" placeholder="Password" class="form-control" ng-model="NewPasswordModel.Password" ng-model-options="{ allowInvalid: true}" override-password user="{{NewPasswordModel.Username}}" ng-style="npForm.newPassword.$error.pattern && {'border':'1px solid red'}"
required>
<small id="newPasswordHelpBlock0" class="form-text text-danger" ng-if="npForm.newPassword.$error.required && npForm.$submitted">
Please enter a password.
</small>
<small id="newPasswordHelpBlock1" class="form-text text-danger" ng-if="npForm.newPassword.$error.pattern && npForm.$submitted">
Password is not valid. Password must be at least 8 characters, upper and lower case text, contain at least one number and contain at least one special character.
</small>
<small id="newPasswordHelpBlock2" class="form-text text-danger" ng-if="npForm.newPassword.$error.distinct && npForm.$submitted">
Your password can not be like your username.
</small>
</div>
</div>
<div class="form-group">
<div class="ml-5">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
<hr /> model = {{NewPasswordModel}}
</form>
</div>
AngularJS
var app = angular.module('app', []);
app.controller('NewPasswordCtrl', ['$scope', function($scope) {
$scope.NewPasswordModel = {};
$scope.NewPasswordModel.Password = "";
$scope.init = function() {
$scope.NewPasswordModel.Username = 'Tester'
};
$scope.SubmitPasswordReset = function (form, model) {
if (form.$valid) {};
};
}]);
app.directive('overridePassword', function() {
var PASSWORD_REGEXP = /(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[$#$!%*?&])[A-Za-z\d$#$!%*?&].{7,}/;
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
var usr = attrs.user;
//For DOM -> model validation
ctrl.$parsers.unshift(function(modelValue) {
var valid = modelValue.includes(usr);
ctrl.$setValidity('distinct', valid);
return valid ? modelValue : undefined;
});
//For model -> DOM validation
ctrl.$formatters.unshift(function(modelValue) {
ctrl.$setValidity('distinct', modelValue.includes(usr));
return modelValue;
});
}
};
});
https://jsfiddle.net/devnsyde/q8v1b4Lj/
You can add another && condition to your ngIf directive that checks the length of your password input.
ng-if="npForm.newPassword.$error.distinct && npForm.$submitted && NewPasswordModel.Password.length > 0"
Demo

AngularJs password validation watching issue

I have a form with 2 password inputs.
I use a directive to validate that the 2 forms are identical to each other.
It currently works if you fill in the password1 first and the password2 second.
Problem: When you fill in password1 and password2 and they're equal, and after that you change password1, the error messages don't get updated. I would have to type in password2 again for the error messages to appear.
Template
<!-- Password1-->
<div class="form-group"
ng-class="{ 'has-error' : userForm.password.$touched && userForm.password.$invalid,
'has-success' : userForm.password.$valid }">
<div class="col-10">
<input class="form-control" type="password" placeholder="Password"
name="password"
ng-model="home.user.password"
ng-minlength="8"
ng-maxlength="30"
required>
<div class="help-block" ng-messages="userForm.password.$error" ng-if="userForm.password.$touched">
<p ng-message="minlength">Your password is too short.</p>
<p ng-message="maxlength">Your password is too long.</p>
<p ng-message="required">Your password is required.</p>
</div>
</div>
</div>
<!-- Password2-->
<div class="form-group"
ng-class="{ 'has-error' : userForm.password2.$touched && userForm.password2.$invalid,
'has-success' : userForm.password2.$valid }">
<div class="col-10">
<input class="form-control" type="password" placeholder="Confirm your password"
name="password2"
ng-model="home.user.password2"
ng-minlength="8"
ng-maxlength="30"
password-verify="home.user.password"
required>
<div class="help-block" ng-messages="userForm.password2.$error" ng-if="userForm.password2.$touched">
<p ng-message="passwordVerify">Passwords do not match.</p>
</div>
</div>
</div>
passwordVerify directive
.directive('passwordVerify', passwordVerify);
function passwordVerify() {
var directive = {}
directive.require = "ngModel";
directive.scope = { passwordVerify: '=' };
directive.link = verifyPassword;
return directive;
function verifyPassword(scope, element, attrs, ctrl) {
scope.$watch('passwordVerify', WatcherPassword1, callback);
scope.$watch(WatcherPassword2, callback);
function WatcherPassword1() {
var combined;
console.log(scope.passwordVerify);
if (scope.passwordVerify || ctrl.$viewValue) {
combined = scope.passwordVerify + '_' + ctrl.$viewValue;
}
return combined;
}
function WatcherPassword2() {
var combined;
console.log(ctrl.$viewValue);
if (scope.passwordVerify || ctrl.$viewValue) {
combined = scope.passwordVerify + '_' + ctrl.$viewValue;
}
return combined;
}
function callback(value) {
if (value) {
ctrl.$parsers.unshift(function(viewValue) {
var origin = scope.passwordVerify;
if (origin !== viewValue) {
ctrl.$setValidity("passwordVerify", false);
return undefined;
} else {
ctrl.$setValidity("passwordVerify", true);
return viewValue;
}
});
}
}
}
}
I think you need also $watch first input password model in directive
UPDATE
So I found the problem, $watchers areworking good, it was not working because of
ctrl.$parsers.unshift. ctrl.$parsers.unshift executes only if ctrl was modified by user. Check my JSFiddle example
.directive('passwordVerify', passwordVerify);
function passwordVerify() {
return {
require: "ngModel",
scope: {
passwordVerify: '='
},
link: function(scope, element, attrs, ctrl) {
function checkPasswords(){
console.log(viewValue);
var origin = scope.passwordVerify;
if (origin !== ctrl.$viewValue) {
ctrl.$setValidity("passwordVerify", false);
return undefined;
} else {
ctrl.$setValidity("passwordVerify", true);
return ctrl.$viewValue;
}
});
scope.$watch('passwordVerify', function(){
// first input changed
}, function(){
checkPasswords()
})
scope.$watch(function() {
... code here ...
}, function(){
checkPasswords()
})

How do I get multiple input values in the same directive?

EDIT: Below is the working example for anyone looking. I have live validation on the promoCode with the directive that takes in 2 input values.
Hello I'm stuck on a problem. I have 2 inputs, an email and a promo code and one directive that checks if the promo code and associated email are valid. However I am stuck in how to pass in the email value as well. I've got it half way where I am able to check the promo code with a hardcoded email value. Am I going to have to rewrite how I do this check or am I missing something obvious to get the email value? Is this even a right approach? I am new to Angular.
To clarify: The API call happens when the user starts typing in a promo code. Basically how do I grab the email value and send it along to the factory? I've looked and tried scope.$watch and was able to see the values changing for each input but was unable to store it.
I have looked here How to get evaluated attributes inside a custom directive and tried that approach but was getting "undefined" for email and promocode values.
HTML
<input type="text" class="form-control" name="email" id="email" placeholder="Enter Email" maxlength="254" ng-model="registrationData.email" required >
<input type="text" class="form-control" name="promoCode" id="promo-code" placeholder="Parking Program Code" ng-model="registrationData.promo_code" ng-model-options="{ debounce: 500 }" promo-email='registrationData.email' promo-validation>
<div ng-show="validate.promoCode.$touched || validate.promoCode.$dirty">
<div ng-messages="validate.promoCode.$error" style="color:maroon" role="alert">
<div ng-message="promoCode">Code invalid</div>
</div>
<div ng-messages="validate.promoCode.$pending">
<div ng-message="promoCode">Checking promo test...</div>
</div>
Directive
.directive('promoValidation',['isPromoValid', function(isPromoValid)
{
return {
restrict: 'A',
require: 'ngModel',
scope:
{
promoEmail:'='
},
link: function(scope, element, attrs, ngModel) {
element.bind('focus', function() {
ngModel.$asyncValidators.promoCode = function(promoCode) {
return isPromoValid(scope.promoEmail, promoCode);
})
}
}}
]);
Factory
.factory('isPromoValid',['$q', '$http', 'SERVICE_BASE', function($q, $http, SERVICE_BASE) {
var apiUrl = SERVICE_BASE + '/users/ValidatePromoCode';
return function(email, promoCode) {
var deferred = $q.defer();
if(!promoCode)
{
deferred.resolve(); //promoCode is optional so I have this check if the user adds a promoCode then deletes it. It removes the error message
}
else {
$http.get(apiUrl , {params: { promo_code: promoCode, email: email }}).then(function validPromo(data){
var isPromoValid = data.data.data.valid;
if(isPromoValid) {
deferred.resolve();
}
else {
deferred.reject();
}
});
}
return deferred.promise;
};
}]);
You need to change your directive like as-
.directive('promoValidation',['isPromoValid', function(isPromoValid
{
return {
restrict: 'A',
require: 'ngModel',
scope: {
promoEmail:'='
},
link: function(scope, element, attrs, ngModel) {
element.bind('focus', function() {
//console.log(ngModel.email);
//console.log(scope.promoEmail); // pass this email to your validator factory
ngModel.$asyncValidators.promoCode = isPromoValid;
})
}
}}
]);
On html, use this directive only for promocode input field like as-
<input type="text" class="form-control" name="email" id="email" placeholder="Enter Email" maxlength="254" ng-model="registrationData.email" required >
<input type="text" class="form-control" name="promoCode" id="promo-code" placeholder="Parking Program Code" ng-model="registrationData.promo_code" ng-model-options="{ debounce: 500 }" promo-email='registrationData.email' promo-validation>
<div ng-show="validate.promoCode.$touched || validate.promoCode.$dirty">
<div ng-messages="validate.promoCode.$error" style="color:maroon" role="alert">
<div ng-message="promoCode">Code invalid</div>
</div>
<div ng-messages="validate.promoCode.$pending">
<div ng-message="promoCode">Checking promo test...</div>
</div>
you can improve this code as much as you needed.

AngularJS validation directive

We have a validation directive that we use to validate the controls on Blur and viewContentLoaded event.
We persist the form values in local storage to remember the details when we navigate away from the form and come back
The problem is that, even though it remembers the details it doesn't re-validate the Firstname and Lastname when we load that view again.
Following is our original code:
<div>
<form name="form" class="form-horizontal">
<label class="control-label">First name</label>
<div class="controls">
<input id="firstName" name="FirstName" ng-model="order.FirstName" type="text" validate="alphabeticOnly" maxLength="30" required/>
<span class="help-block" ng-show="form.FirstName.$dirty && form.FirstName.$invalid">Please enter valid Firstname</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Last name</label>
<div class="controls">
<input id="lastName" name="LastName" ng-model="order.LastName" type="text" validate="alphabeticOnly" maxLength="30" required/>
<span class="help-block" ng-show="form.LastName.$dirty && form.LastName.$invalid">Please enter valid Lastname</span>
</div>
</div>
</form>
Confirm
The next function just saves the order and redirects to another page.
We have a $watch on $scope.order that saves the data in local storage to remember.
Directive:
.directive('validate', ['validationService', function(validationService) {
function validate(elm) {
var fn = elm.attr("validate");
var value = elm.val();
return validationService[fn](value);
}
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
function triggerValidations(){
checkValidity();
ctrl.$parsers.unshift(function(viewValue) {
checkValidity();
return viewValue;
});
ctrl.$formatters.unshift(function(viewValue) {
checkValidity();
return viewValue;
});
}
function checkValidity(){
if (elm.val().length > 0)
{
var isValid = validate(elm);
ctrl.$setValidity('validate', isValid);
console.log(" here i am - CheckValidity", attrs.id, elm.val(), isValid );
//scope.$apply();
}
}
$rootScope.$on('$viewContentLoaded', triggerValidations);
elm.bind('blur', function(event) {
scope.$apply(function() {
ctrl.$setValidity('validate', validate(elm));
});
});
}
};
}])
If we add $scope.apply it gives an error "$digest already in progress"
At the end, we want to validate the form when someone lands onto the page.

Prevent disabled form fields from being validated

Update
I have created jsfiddles to illustrate my problem since the question was not clear.
First I thought that I can't deactivate validation of form fields but I learned that this can be done with the ng-required directive.
http://jsfiddle.net/charms/YhVfN/23/
My actual problem is that the password fields are not set to the pristine state. All other form fields are cleared but the password fields are not cleared.
To test this behaviour you can:
Click on to the "Add user" button
Add an email address, firstname, lastname, password and a wrong password for the confirmation
Click on to the close button without saving
Click on to the edit button
And then you'll see that the password is still set. It is not cleared by the $setPristine method. All other form fields are cleared.
http://jsfiddle.net/charms/eP7T8/61/
Previous (outdated question)
Does anybody know how I can deactivate validation for disabled fields? I'm using angularjs 1.1.3.
When I'm creating a new user I would like to validate all fields, inclusive password fields. But when I edit a user I would like that the password fields stay inactive and are not validated, unless the user activates the fields over a checkbox.
My current problem is that if I set the password fields to ng-disabled=true the validation is still kicking in. I thought that ng-required=false might help but it doesn't.
I'm setting the password field to ng-disabled=true and ng-required=false.
<input type="password" name="password" ng-model="password" placeholder="Password" ng-disabled="true" ng-required="false" required/>
I'm setting the password confirmation field to ng-disabled=true and ng-required=false.
<input type="password" name="passwordConfirm" ng-model="passwordConfirm" placeholder="Confirm Password" ng-disabled="true" ng-required="false" required field-equal="password"/>
But still the required and field-equal directives are being validated. How can I prevent validation on those deactivated fields?
Below my full code.
HTML:
<div id="user_list" class="listview_list">
<div id="user_row" class="listview_row" ng-repeat="u in users">
<div id="user_username" class="listview_column"><span class="listview_mainfield">{{u.email}}</span></div>
<div id="user_firstname" class="listview_column">{{u.firstName}}</div>
<div id="user_lastname" class="listview_column">{{u.lastName}}</div>
<button class="listview_row_button" ng-click="deleteUser(u.id, $index)">Delete</button>
<button class="listview_row_button" ng-click="showEditScreen(u.id, $index)">Edit</button>
</div>
</div>
<div id="user_new" class="new_user">
<button class="new_user_button" ng-click="showAddScreen()">Add user</button>
</div>
<div id="user_mod" class="user_form" ng-show="userModScreenIsVisible">
<form name="mod_user" novalidate>
<input type="email" name="email" ng-model="user.email" placeholder="E-Mail" ng-disabled="emailFieldDisabled" required email-available/>
<div class="user-help" ng-show="mod_user.email.$dirty && mod_user.email.$invalid">Invalid:
<span ng-show="mod_user.email.$error.required">Please enter your email.</span>
<span ng-show="mod_user.email.$error.email">This is not a valid email.</span>
<span ng-show="mod_user.email.$error.checkingEmail">Checking email...</span>
<span ng-show="mod_user.email.$error.emailAvailable">Email not available</span>
</div>
<br/>
<input name="firstName" ng-model="user.firstName" placeholder="Firstname" required/>
<div class="user-help" ng-show="mod_user.firstName.$dirty && mod_user.firstName.$invalid">Invalid:
<span ng-show="mod_user.firstName.$error.required">Please enter your firstname.</span>
</div>
<br/>
<input name="lastName" ng-model="user.lastName" placeholder="Lastname" required/>
<div class="user-help" ng-show="mod_user.lastName.$dirty && mod_user.lastName.$invalid">Invalid:
<span ng-show="mod_user.lastName.$error.required">Please enter your lastname.</span>
</div>
<br/>
<input type="checkbox" name="setPassword" ng-disabled="passwordCheckboxDisabled" ng-show="passwordCheckboxVisible"/>
<span class="password_checkbox" ng-show="passwordCheckboxVisible">Change password</span>
<br ng-show="passwordCheckboxVisible"/>
<input type="password" name="password" ng-model="password" placeholder="Password" ng-disabled="passwordFieldDisabled" ng-required="passwordFieldRequired" required/>
<div class="user-help" ng-show="mod_user.password.$dirty && mod_user.password.$invalid">Invalid:
<span ng-show="mod_user.password.$error.required">Please enter a password.</span>
</div>
<br/>
<input type="password" name="passwordConfirm" ng-model="passwordConfirm" placeholder="Confirm Password" ng-disabled="passwordFieldDisabled" ng-required="passwordFieldRequired" required field-equal="password"/>
<div class="user-help" ng-show="mod_user.passwordConfirm.$dirty && mod_user.passwordConfirm.$invalid">Invalid:
<span ng-show="mod_user.passwordConfirm.$error.required">Please enter a password.</span>
<span ng-show="mod_user.passwordConfirm.$error.fieldEqual">Passwords do not match.</span>
</div>
<br/>
<button class="button" ng-click="hideUserModScreen()">Close</button>
<button class="button" ng-click="updateUserDetails()" ng-disabled="mod_user.$invalid" ng-show="updateUserDetailsButtonIsVisible">Update</button>
<button class="button" ng-click="saveUserDetails()" ng-disabled="mod_user.$invalid" ng-show="saveUserDetailsButtonIsVisible">Save</button>
</form>
</div>
Controller:
'use strict';
/*
* Controller to display and manipulate users.
*/
function UserCtrl($scope, User) {
// initialize as invisible
$scope.userModScreenIsVisible = false;
$scope.updateUserDetailsButtonIsVisible = false;
$scope.saveUserDetailsButtonIsVisible = false;
$scope.passwordCheckboxVisible = false;
// initialize as disabled or enabled
$scope.emailFieldDisabled = false;
$scope.passwordCheckboxDisabled = false;
$scope.passwordFieldDisabled = false;
// initialize required or not required
$scope.passwordFieldRequired = false;
// gather array index before opening edit
// screen (used in updateUserDetails method)
$scope.editIndex = null;
// display list with users
$scope.getList = function() {
User.query(
{}, //params
function (data) { //success
$scope.users = data.data;
},
function (data) { //failure
console.log("Error occurred while getting list of users");
});
}
// execute getList() when partial is loaded
$scope.getList();
// show edit screen if edit button is clicked
$scope.showEditScreen = function(id, index) {
$scope.user = User.get({userId: id});
$scope.editIndex = index;
$scope.updateUserDetailsButtonIsVisible = true;
$scope.userModScreenIsVisible = true;
$scope.emailFieldDisabled = true;
$scope.passwordCheckboxVisible = true;
$scope.passwordFieldDisabled = true;
$scope.passwordFieldRequired = false;
$scope.passwordCheckboxDisabled = false;
//console.log($scope.mod_user);
}
// show add screen if the add button is clicked
$scope.showAddScreen = function() {
$scope.user = new User();
$scope.saveUserDetailsButtonIsVisible = true;
$scope.passwordCheckboxDisabled = true;
$scope.passwordFieldRequired = true;
$scope.userModScreenIsVisible = true;
console.log($scope.mod_user);
}
// hide edit screen if close button is clicked
$scope.hideUserModScreen = function() {
$scope.updateUserDetailsButtonIsVisible = false;
$scope.saveUserDetailsButtonIsVisible = false;
$scope.userModScreenIsVisible = false;
$scope.emailFieldDisabled = false;
$scope.passwordFieldDisabled = false;
$scope.passwordFieldRequired = false;
$scope.passwordCheckboxVisible = false;
$scope.passwordConfirm = '';
$scope.password = '';
$scope.mod_user.$setPristine();
}
// update a user
$scope.updateUserDetails = function() {
$scope.user.$update();
angular.extend($scope.users[$scope.editIndex], $scope.user);
$scope.editIndex = null;
$scope.updateUserDetailsButtonIsVisible = false;
$scope.userModScreenIsVisible = false;
//console.log($scope.mod_user);
}
// save a new user
$scope.saveUserDetails = function() {
$scope.user.$create();
$scope.users.push($scope.user);
$scope.saveUserDetailsButtonIsVisible = false;
$scope.userModScreenIsVisible = false;
}
// delete a user
$scope.deleteUser = function(id, index) {
User.delete({userId: id});
$scope.users.splice(index, 1);
$scope.userModScreenIsVisible = false;
}
}
Directives:
'use strict';
/* Directives */
angular.module('myApp.directives', []).
directive('appVersion', ['version', function (version) {
return function (scope, elm, attrs) {
elm.text(version);
};
}]).
/*
* Validate if the email address is available.
*/
directive('emailAvailable', function($http) { // available
return {
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
// push the validator on so it runs last.
ctrl.$parsers.push(function(viewValue) {
// set it to true here, otherwise it will not
// clear out when previous validators fail.
ctrl.$setValidity('emailAvailable', true);
if(ctrl.$valid) {
// set it to false here, because if we need to check
// the validity of the email, it's invalid until the
// AJAX responds.
ctrl.$setValidity('checkingEmail', false);
// check if email is available or used
if(viewValue !== "" && typeof viewValue !== "undefined") {
$http.get('/api/user/email/' + viewValue + '/available')
.success(function(data, status, headers, config) {
ctrl.$setValidity('emailAvailable', true);
ctrl.$setValidity('checkingEmail', true);
})
.error(function(data, status, headers, config) {
ctrl.$setValidity('emailAvailable', false);
ctrl.$setValidity('checkingEmail', true);
});
} else {
ctrl.$setValidity('emailAvailable', false);
ctrl.$setValidity('checkingEmail', true);
}
}
return viewValue;
});
}
};
}).
/*
* Validate if two fields are equal (such as passwords match for example
*/
directive('fieldEqual', [function() {
return {
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
ctrl.$parsers.push(function(viewValue) {
ctrl.$setValidity('fieldEqual', true);
if(ctrl.$valid) {
scope.$watch(attr.fieldEqual, function() {
var compareValue = this.last;
if (viewValue !== compareValue) {
ctrl.$setValidity('fieldEqual', false);
return undefined;
} else {
ctrl.$setValidity('fieldEqual', true);
return viewValue;
}
});
}
});
}
};
}]);
It seems that I have confused myself with what $setPristine does.
I have expected that $setPristine will not only set the $pristine state to true, but will also recursively clear my form fields. This doesn't seem to be the case. $setPristine does only set the state of $pristine to true globally and in all the controls.
I have been looking at the advancedForm example on the Angularjs page and have seen that they create a master to pre-fill the fields:
http://docs.angularjs.org/cookbook/advancedform
So as solution I have just created an empty master:
http://jsfiddle.net/charms/AhGDC/24/
Controller
var $scope;
var app = angular.module('myapp', []);
function UserCtrl($scope) {
$scope.showField = true;
$scope.reset = function() {
var master = { name: '' };
$scope.temp = angular.copy(master);
$scope.user_form.$setPristine();
}
}
HTML
<div ng-app="myapp">
<div ng-controller="UserCtrl">
<form name="user_form" novalidate>
<input name="name" ng-model="temp.name" ng-show="showField" placeholder="Name" required/>
<button class="button" ng-click="reset()">Reset</button>
</form>
<p>
Pristine: {{user_form.$pristine}}
</p>
<p>
<pre>Errors: {{user_form.$error | json}}</pre>
</p>
</div>
</div>
So I guess this is the way to go. If somebody has a better solution to reset form fields it would be great to hear about it.
I thought Angularjs might have a more elegant solution. Also looking at the setPristine source did not reveal anything else.

Resources