Custom password validation directive not applying - javascript

I'm working with AngularJS and I want to make a password confirmation field to check if both entries match. In order to do that, I'm using a custom directive from this tutorial: http://odetocode.com/blogs/scott/archive/2014/10/13/confirm-password-validation-in-angularjs.aspx.
For some reason, the matching checking doesn't give any result. When I enter different passwords, it still sees the fields as valid. I think I'm missing something about the usage of custom directives in AngularJS, but it's a bit confusing because I'm litterally taking the exact same code as in the tutorial.
I also checked related questions here on SO, but no luck either.
HTML:
<div ng-app="myApp">
<h1>Register!</h1>
<form name="registrationForm" novalidate>
<div class="form-group">
<label>User Name</label>
<input type="text" name="username" class="form-control" ng-model="registration.user.username" required />
<p ng-show="registrationForm.username.$error.required">Required<br/><br/></p>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" class="form-control" ng-model="registration.user.password" required />
<p ng-show="registrationForm.password.$error.required">Required<br/><br/></p>
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" name="confirmPassword" class="form-control" ng-model="registration.user.confirmPassword" required compare-to="registration.user.password" />
<p ng-show="registrationForm.confirmPassword.$error.required">Required<br/><br/></p>
<p ng-show="registrationForm.confirmPassword.$error.compareTo">Passwords must match !</p>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Register!</button>
</div>
</form>
</div>
JS:
angular.module('myApp', [])
.directive('compareTo', function(){
return {
require: "ngModel",
scope: {
otherModelValue: "=compareTo"
},
link: function(scope, element, attributes, ngModel) {
ngModel.$validators.compareTo = function(modelValue) {
return modelValue == scope.otherModelValue;
};
scope.$watch("otherModelValue", function() {
ngModel.$validate();
});
}
};
})
JSFiddle showing the problem: http://jsfiddle.net/ptb01eak/
Working Plunkr from the tutorial: http://plnkr.co/edit/FipgiTUaaymm5Mk6HIfn?p=preview
Thank you for your help!

The problem comes from your AngularJS version, I updated it in the jsfiddle to : AngularJS 1.5.6 (CDN link) and it works (new jsfiddle).

Related

Ng-If only working when refreshing the page

I have a problem with ng-if, I am pretty new to angularjs. I want to show/hide a searchbar only on certain views, but it only works after refreshing the page. But it should work, when the view changed.
html:
<div id="searchbarTop" ng-controller="searchbarController">
<form class="col-md-12 py-1" ng-if="!showSearchbarTop">
<div class="input-group">
<input type="text" class="form-control typeahead" id="query"
placeholder="Search for folders or workflows..." data-
provide="typeahead" autocomplete="off" ng-wflist="workflowList" wf-search/>
</div>
</form>
</div>
controller:
ProjectX.controller("searchbarController", function($scope,$http,$location) {
$scope.$root.showSearchbarTop = $location.path() === "/";
...
});
Hope someone can explain me, which mistake I made.
You are using showSearchbarTop as an attribute which is initialized only at the beginning of the page load. That's why, you need to use it as a function.
See the following code
var ProjectX = angular.module('', []);
ProjectX.controller("searchbarController", function($scope, $http, $location) {
$scope.$root.showSearchbarTop = function() {
return $location.path() === "/";
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div id="searchbarTop" ng-controller="searchbarController">
<form class="col-md-12 py-1" ng-if="!showSearchbarTop()">
<div class="input-group">
<input type="text" class="form-control typeahead" id="query" placeholder="Search for folders or workflows..." data- provide="typeahead" autocomplete="off" ng-wflist="workflowList" wf-search/>
</div>
</form>
</div>

AngularJS with ng-pattern in form does not send invalid field to server

I want to validate a text input in form, so the submit of the form could not be done until the input match a regular expression. But when I type a wrong field value and I clik submit the form is submitted but the input value is not sent to the server. I want the same behaviour as with HTML5 required Attribute. This is my code:
<div class="row">
<label class="col-sm-2 label-on-left">APN</label>
<div class="col-sm-7">
<div class="form-group label-floating">
<label class="control-label"></label>
<input class="form-control" type="text" name="apn" ng-model="Configure3gCtrl.configure3g.apn" ng-pattern="/^[a-zA-Z0-9-.]*$/" required/>
</div>
</div>
</div>
As i said in the comment [value not sent because when you pass the input with incorrect pattern the ng-model is undefined].
But we can use the form validation here as sample if our ng-model are invalid the form will disabled.
var app = angular.module("app", []);
app.controller("ctrl", ["$scope", "$filter", function($scope, $filter) {
$scope.submit = function() {
console.log($scope.object)
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<form name="form">
<label class="col-sm-2 label-on-left">APN</label>
<input type="text" name="apn" ng-model="object.apn" ng-pattern="/^[a-zA-Z0-9-.]*$/" required />
<button ng-click="submit()" ng-disabled="form.$invalid">submit</button>
</form>
</div>
Ideally, you should not send the invalid value to server, So you should disable\hide your submit button, but if you really require sending the invalid value as well to server, then from angularjs 1.3+ you have ng-model-options (Read Doc) directive which can help you.
Simply mark your text type input as ng-model-options="{allowInvalid: true }", It will persist the invalid values as well.
See Demo:
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function MyCtrl($scope) {
$scope.submitt = function() {
alert($scope.Configure3gCtrl.configure3g.apn);
}
$scope.Configure3gCtrl = {
configure3g: {
apn: ""
}
}
});
<script src="https://code.angularjs.org/1.3.1/angular.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<form name="frm" ng-submit="submitt()" class="row">
<label class="col-sm-2 label-on-left">APN</label>
<div class="col-sm-7">
<div class="form-group label-floating">
<label class="control-label"></label>
<input class="form-control" type="text" name="apn"
ng-model="Configure3gCtrl.configure3g.apn"
ng-model-options="{allowInvalid: true }"
ng-pattern="/^[a-zA-Z0-9-.]*$/" required/>
</div>
</div>
<input type="submit" value="submit" type="submit" />
</form>
</div>
also, Test with removing ng-model-options="{allowInvalid: '$inherit' }" from above code snippet then ng-model will be undefined, because it is invalid.

I can't access ng-model from a controller [AngularJS]

I'm developing an e-commerce site for learnign purposes.
HTML:
<div class="container">
<form class="log-in-form" ng-controller="ControllerLogin">
<div class="form-group">
<label for="loginEmail">Email address</label>
<input type="email" class="form-control" id="loginEmail" placeholder="Email" ng-model="email">
</div>
<div class="form-group">
<label for="loginPass">Password</label>
<input type="password" class="form-control" id="loginPass" placeholder="Password" ng-model="password">
</div>
<button class="btn btn-default" ng-click="authenticate()">Login</button>
</form>
</div>
Angular javascript
app.controller('ControllerLogin', ['$scope', '$http', 'ServiceLogin', function ($scope, $http, ServiceLogin) {
$scope.authenticate = function () {
console.log($scope.email);
ServiceLogin.auth($scope.email, $scope.password)
.success(function (data) {
alert(data);
});
}
}]);
Every time I console.log the $scope.email, or password. It throws an error of undefined. I'm just starting on angular and I don't know why is not getting the models, I thinks my code is correct. Any help you can give I will be gratefull.
From Angular site:
Note that novalidate is used to disable browser's native form validation.
The value of ngModel won't be set unless it passes validation for the input field. For example: inputs of type email must have a value in the form of user#domain.
Reference: https://docs.angularjs.org/guide/forms
So the reason it may be blank is that it's not a valid email.
You can look at their demo for the email type and see it in action.
I recommend adding:
{{email}}
<br>
{{password}}
somewhere in your html within the controller's HTML scope for your own debugging.
Good luck.

Allow Remember Password to work with AngularJS

Okay, I spent all morning trying to solve this, and despite the fact that it seems to have been a problem for a couple years, I couldn't find a solution that worked. I've seen other people on Stack Overflow ask this question, but none of them had working answers.
My Angular app's login form works fine, but the remember password dialog won't pop up in either Chrome or Opera. It does work in Firefox. I understand WHY it doesn't work, but my users are complaining and I need to fix it. What can I do?
<form name="loginForm" ng-submit="login(user)">
<div class="input-group">
<input type="email" name="email" class="form-control" placeholder="Email" ng-model="user.email">
</div>
<div class="input-group">
<input type="password" name="password" class="form-control" placeholder="Password" ng-model="user.password">
</div>
<button type="submit" class="btn btn-default">Login</button>
</form>
Edit:
Okay, from a couple different answers that didn't work, I was able to piece together something that finally did, which was simply to turn it into an entirely normal HTML form where the button is type="submit" and then simply put a jQuery .click command in my javascript which calls the login function. So basically, just completely ignored the Angular way of doing it, which makes me a sad panda. :-\ Opera still doesn't work, but I don't care a ton about that I guess.
this is the code from Timothy E. Johansson's blog. I do not take credit.
app.directive("ngLoginSubmit", function(){
return {
restrict: "A",
scope: {
onSubmit: "=ngLoginSubmit"
},
link: function(scope, element, attrs) {
$(element)[0].onsubmit = function() {
$("#login-login").val($("#login", element).val());
$("#login-password").val($("#password", element).val());
scope.onSubmit(function() {
$("#login-form")[0].submit();
});
return false;
};
}
};
});
$scope.login = function(submit) {
$scope.user = {
login: $("#login").val(),
password: $("#password").val()
};
function ajaxCallback() {
submit();
}
return false;
};
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<form name="login-form" id="login-form" method="post" action="" style="display: none;">
<input name="login" id="login-login" type="text">
<input name="password" id="login-password" type="password">
</form>
<form name="login-form" autocomplete="on" ng-login-submit="login">
<input id="login" name="login" type="text" autocomplete="on">
<input id="password" name="password" type="password" autocomplete="on">
</form>
The solution with AngularJS and without jQuery:
<form action="/" method="post" onsubmit="return false;">
<input type="text" name="username" autocomplete="on" id="email" ng-model="user.email">
<input type="password" id="password" name="password" autocomplete="on" ng-model="user.password">
<button type="submit" ng-click="login()">Submit</button>
</form>
Explantion
You should have action attribute in your form tag and a button with type=submit attribute. To prevent page from reloading, add onsubmit="return false;" to form tag. Simple :)

Angular custom form validation

I was trying to follow some tutorials, but couldn't figure out what to do.
I would like to add the validation, that at least one of the checkboxes (consumer/vendor) has to be true. If not true show an error message at both fields). What would be the easiest way to accomplish that?
<form role="form" name="addClientForm" ng-submit="submitForm(addClientForm.$valid)" novalidate>
<div class="form-group" ng-class="{ 'has-error' : addClientForm.title.$invalid && !addClientForm.title.$pristine }">
<label>Title</label>
<input type="text" class="form-control" placeholder="Enter a title" ng-model="client.title" required>
</div>
<div class="form-group" ng-class="{ 'has-error' : addClientForm.company.$invalid && !addClientForm.company.$pristine }">
<label>Company</label>
<input type="text" class="form-control" placeholder="Enter a company" ng-model="client.company" required>
</div>
<div class="checkbox">
<label class="i-checks">
<input type="checkbox" ng-model="client.consumer"><i></i> Consumer
</label>
</div>
<div class="checkbox">
<label class="i-checks">
<input type="checkbox" ng-model="client.vendor"><i></i> Vendor
</label>
</div>
</form>
Controller (modal controller)
angular.module('App')
.controller('ModalAddClientCtrl', function ($scope, $modalInstance) {
$scope.client = { title: '', company: '', consumer: true, vendor: false };
$scope.submitForm = function(isValid) {
};
$scope.ok = function () {
$modalInstance.close($scope.client);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
To use angular form validation like you are trying to you have to set name attribute in the input fields. So, if you have a <form name='form'> with <input name='input'> only then you can use form.input.$dirty or form.input.$pristine. Combine that with ng-if like you have the rest is simple.
See this fiddle for example and try editing the values. I have implemented validation in your form. I have left out the controller, conditions and error messages could be simpler but you will get the idea.
See this related post that has an excellent answer on using form validation.

Categories