I've followed this answer to run custom server side validation for unique email constraint.
This is my submit function on controller:
function submit(form){
CompanyUser.save(vm.model)
.success(function(data) {
vm.closeModal();
toastSucess(data);
})
.error(function(data) {
if(data.code == 'error_duplicated_email')
form['email'].$setValidity("uniqueEmail", false);
});
}
and here my email piece of HTML code:
<form name="form" novalidate ng-click="form.$valid && vm.submit(form)">
<div class="form-group" ng-class="{ 'has-error': form.$submitted && form.email.$error.uniqueEmail }">
<label>E-mail</label>
<input type="email" class="form-control" name="email" ng-model="vm.model.email" required>
<span ng-show="form.$submitted && form.email.$error.uniqueEmail" class="help-block">Duplicated e-mail</span>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white" ng-click="vm.closeModal()">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
And works fine once that server returns the error. But, then I change the email and try to submit, but I cannot do it anymore. I think that is because I've set the validity to false. So how can I set to true to try to submit the form again?
You can try to use the $setPristine(); method.
From angular documentation:
$setPristine(); Sets the form to its pristine state.
This method sets the form's $pristine state to true, the $dirty state
to false, removes the ng-dirty class and adds the ng-pristine class.
Additionally, it sets the $submitted state to false.
This method will also propagate to all the controls contained in this
form.
Setting a form back to a pristine state is often useful when we want
to 'reuse' a form after saving or resetting it.
Here is the solution from #code90:
I needed to add a ng-change="form.$valid=true" to the <input type="email"..
and it works fine!
Related
Using angularjs 1.3 and Bootstrap 3 here.
I am trying to validate my form for required field. I added html5 "required" attribute. I also added ng-class to highlight the error but the issue is when the form loads my input field ie texbox is already highlighted. What I am looking for is to hightlight the texbox on button click. Do I have to manually check for this and show error?
I use the below code:
<div class="m-grid-col-lg-10"
ng-class="{ 'has-error': nameForm.userName.$invalid }">
<input type="text" name="userName" required ng-model="userName"
class="form-control input-lg input-small" />
</div>
Button click:
<button class="btn btn-primary" type="button"
ng-click="done(nameForm.$valid)">
Done
</button>
JSController code:
$scope.done = function (isValid) {
if (isValid) {
$modalInstance.close();
}
else {
return false;
}
};
Here is a jsfiddle:
http://jsfiddle.net/aman1981/a0cLtnpr/7/
'has-error': nameForm.userName.$invalid && nameForm.userName.$touched
This way the has-error only hapepns if invalid and touched, you can also do or form.$submitted if you want to trigger on submit incase they didn't even touch it.
Updated:
'has-error': nameForm.userName.$invalid && (nameForm.userName.$touched || nameForm.$submitted)
I need to disable the submit button after clicking on the button to prevent multiple submissions but before the it has to ensure that the required fields are filled.
I tried
<body ng-app="ngToggle">
<div ng-controller="AppCtrl">
<form name="newUserForm">
<input type="text" required>
<input type="text" required>
<input type="text">
<button ng-click="disableClick()" ng-disabled="isDisabled"
ng-model="isDisabled">Disable ng-click</button>
</form>
</div>
</body>
angular.module('ngToggle', [])
.controller('AppCtrl',['$scope', function($scope){
$scope.isDisabled = false;
$scope.disableClick = function() {
alert("Clicked!");
$scope.isDisabled = true;
return false;
}
}]);
but this will only disable the button without any validation
Ok, I get what you mean/want so I'll try to help and come up with some code - which is obviously missing but if it wasn't missing the necessary code, you'd have the solution :)
First, you'll have to properly write your form:
<form name="newUserForm" ng-submit="disableClick(newUserForm.$valid)" novalidate>
<input type="text" name="input1" ng-model="form.input1" required>
<input type="text" name="input2" ng-model="form.input2" required>
<input type="text" name="input3" ng-model="form.input3"> //not required
<button type="submit" ng-disabled="isDisabled">Disable ng-click</button>
</form>
so what we've got here, which you're missing:
You did name your form, but you're missing a submit, in the form as ng-submit or the button with type="submit", which will submit the form and that's when the validation happens
In order for Angular to validate your inputs, they need to have ng-model, otherwise it will not validate (HTML5 validation would, but read on)
I've added novalidate so we tell the browser "Hey, we need this validated but not by you, so do nothing", and Angular takes over
And last but not least, Angular adds a couple of properties to the form (see more here: Angular form Docs), $valid being one of them, which is set to true when all validated inputs are valid.
So this sums up the changes you needed to do to your form.
As for the Javascript part, there is just one small change:
$scope.disableClick = function(valid) {
if(valid && !$scope.isDisabled) {
$scope.isDisabled = true;
}
return false;
}
I guess the change is obvious, but I'll explain anyway - check that newUserForm.$valid (boolean) and if it's true (meaning form has passed validation) disable this button.
Of course, you'll have to add checks not to run the code on any type of submits and not just disabling the button (which can easily be re-enabled via Dev Tools), so that's why I added !$scope.isDisabled to the if statement.
Hope this answers your question :)
P.S. Here's a running demo in Plunker
I have a form which I'm in the process of changing my phone fields from using a regex to the intl-tel-input module. I'm running into problems & confusion in checking for valid #s.
I have a form with several of these fields...
<div class="row">
<div class="col-xs-2">
<label for="cellPhone"
translate>CONTACT.CELL</label>
</div>
<div class="col-xs-6"
ng-class="{'has-error': !cellPhoneFocus && forms.contactForm.cellPhone.$invalid && forms.contactForm.cellPhone.$touched }">
<input type="text" class="form-control intlPhoneInput"
id="cellPhone" name="cellPhone"
ng-model="contact.cellPhone.display"
ng-focus="cellPhoneFocus = true"
ng-blur="cellPhoneFocus = false; validatePhone($event)">
<div ng-messages="forms.contactForm.cellPhone.$error"
ng-show="!cellPhoneFocus && forms.contactForm.cellPhone.$touched"
class="errorMessages">
<p ng-message="pattern" translate>
CRUD.VALID_PHONE</p>
</div>
</div>
and the submit...
<button type="submit" class="btn btn-primary" ng-disabled="forms.contactForm.$invalid" id="saveContactLink" translate>CRUD.SAVE</button>
Then in my controller (Typescript)...
//In Constructor
$scope.validatePhone = this.validatePhone.bind(this);
//Outside constructor
private validatePhone(eventObject: any) {
let thePhoneField = $('#' + eventObject.target.id);
let phoneIsValid = thePhoneField.intlTelInput("isValidNumber");
this.$scope.forms.contactForm[eventObject.target.id].$invalid = !phoneIsValid;
this.$scope.forms.contactForm[eventObject.target.id].$error = {"pattern": !phoneIsValid};
}
This properly sets my has-error class and error message, but it doesn't set the FORM to invalid. I've tried $setValidity...
this.$scope.forms.contactForm[eventObject.target.id].$setValidity('pattern', !phoneIsValid);
...but it doesn't seem to do anything at all.
How do I set the field to invalid, show the correct ng-message(if there's more than one), and make sure the form $errors gets updated so the submit is disabled?
Turns out $setValidity WAS working, but having setValidity along with .$invalid and $error caused some crossed wires. Commenting out the last two enabled/disabled my submit button correctly when invalidating a field.
You should just be able to set the form to invalid like so:
forms.contactForm.$invalid = true
I am working with Angular2 with two way binding concept [(ngModel)].I have form with my page and I have to validate the pristine state of the element. So for validation I have used ngIf to check the pristine state of the element. But the condition is not working. I need to check the pristine state for every model change. Below is my app.component.html page:
<form (ngSubmit)="angular2form(myAngular2Form.employeeDob)" [ngFormModel]="myAngular2Form">
<input type="text" class="form-control" id="employee" name="employee" [(ngModel)]="employeeDob" required />
<div *ngIf="employeeDob.pristine">
<p>Please enter the date</p>
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
This is my component:
export class AppComponent {
employeeDob: String;
constructor(private myform: FormBuilder) {
this.employeeDob = '';
}
angular2form(date) {
alert("date submitted successfully");
}
}
Thanks for any suggestion
<input type="text" class="form-control" id="employee" name="employee" [(ngModel)]="employeeDob" #date="ngModel" required />
<div [hidden]="date.valid || date.pristine">
<p>Please enter the date</p>
</div>
straight outta documentation
https://angular.io/docs/ts/latest/guide/forms.html
pristine is a property of the Control not of the value.
You might want to use
<input #employeeDobCtrl="ngForm" type="text" class="form-control" id="employee" name="employee" [(ngModel)]="employeeDob" required />
<div *ngIf="employeeDobCtrl.pristine">
(for the old forms module)
pristine is true if the user has not interacted with the form yet. You probably want to check for dirty instead? You can also use the hidden tag and replace
<div *ngIf="employeeDob.pristine">
with:
<div [hidden]="employeeDob.pristine">
I have the html below where I have a form that I want to submit to the AngularJS Controller.
<div class="newsletter color-1" id="subscribe" data-ng-controller="RegisterController">
<form name="registerForm">
<div class="col-md-6">
<input type="email" placeholder="your#e-mail.com" data-ng-model="userEmail" required class="subscribe">
</div>
<div class="col-md-2">
<button data-ng-click="register()" class="btn btn-primary pull-right btn-block">Subsbcribe</button>
</div>
</form>
</div>
And the controller is below
app.controller('RegisterController', function ($scope,dataFactory) {
$scope.users = dataFactory.getUsers();
$scope.register = function () {
var userEmail = $scope.userEmail;
dataFactory.insertUser(userEmail);
$scope.userEmail = null;
$scope.ThankYou = "Thank You!";
}
});
The problem is that no validation is taking place when I click the button. It is always routed to the controller although I do not supply a correct email. So every time I click the button I get the {{ThankYou}} variable displayed. Maybe I do not understand something.
AngularJS does not disable enable any functionality for form validations. What is does is, it makes the state of the form and its control in terms of validation available on the current scope. You are required to implement the behaviour yourself.
In your case if you need to check user email is valid your html input should have a name attribute like
<input type="email" placeholder="your#e-mail.com" data-ng-model="userEmail" required class="subscribe" name='userEmail'>
Then on your controller you can check
$scope.registerForm.userEmail.$invalid property.
You can use the same property to disable the button on the form using ng-disabled
<button data-ng-click="register()" class="btn btn-primary pull-right btn-block" ng-disabled='registerForm.userEmail.$invalid'>Subsbcribe</button>
Basically the registerForm object is a ngFormController and userEmail is ngModelController. Please read the developer guide for forms
You are missing some part to achieve what you want. Normally you will need to add some code to enable disable the submit button base on the state of the form i.e valid/invalid. In your case this can be done like that :
<button data-ng-click="register()" class="btn btn-primary pull-right btn-block" ng-disabled="registerForm.$invalid">Subsbcribe</button>
Notice the ng-disabled="registerForm.$invalid".
You can as well provided inline feedback to the user with something like :
<input type="email" placeholder="your#e-mail.com" data-ng-model="userEmail" required="" class="subscribe" name="userName"/>
<span ng-show="registerForm.userName.$error.required">Please enter a name</span>
Or with CSS like that :
input.ng-invalid-required {
background-color: #FA787E;
}
You have a working plunker here