AngularJS form validations with submit and reset buttons - angularjs

I have a simple form where I have applied AngularJS validation on a input box containing number value. On submit, it works fine but when I click on Reset button, it gives the input box validation error message. Looks like it is calling ng-submit after ng-click of Reset button. I have tried resetting the value of input field in ng-click, removed type='Reset' and also used $setPristine() on the form. But nothing helps. Below is the code.
<form name="myForm" novalidate ng-submit="submitFilter()">
Enter Age:
<div>
<input name="age" ng-class="{errorinput: submitted && myForm.age.$invalid }" class="form-control" ng-pattern="/^[0-9]+$/" placeholder="Age" type="text" ng-model="age" required>
</div>
<span class="error" ng-style="{color:'red'}" ng-show="submitted && myForm.age.$invalid">Please enter a valid Age</span>
<button type="submit">
Submit
</button>
<button ng-click="reset(myForm)">
Reset
</button>
</form>
Controller:
var original = $scope.age;
$scope.submitFilter = function () {
if ($scope.filterForm.$valid) {
} else {
$scope.submitted = true;
}
};
$scope.reset = function (myForm) {
$scope.age = angular.copy(original);
$scope.myForm.$setPristine();
};
Kindly help in getting rid of this error.
Thanks in Advance.

Setting the reset button's type as 'button' should work. Following code works perfectly on my machine.
// Code goes here
app.controller('mainController', function($scope) {
$scope.age = 123;
var original = $scope.age;
$scope.submitFilter = function () {
$scope.submitted = true;
};
$scope.reset = function (myForm) {
$scope.age = angular.copy(original);
$scope.myForm.$setPristine();
};
});
<form name="myForm" novalidate ng-submit="submitFilter()">
Enter Age:
<div>
<input name="age" ng-class="{errorinput: submitted && myForm.age.$invalid }" class="form-control" ng-pattern="/^[0-9]+$/" placeholder="Age" type="text" ng-model="age" required>
</div>
<span class="error" ng-style="{color:'red'}" ng-show="submitted && myForm.age.$invalid">Please enter a valid Age</span>
<button type="submit">
Submit
</button>
<button type="button" ng-click="reset(myForm)">
Reset
</button>
</form>

Related

unexpected behavior when add $setPristine()

There is some unexpected behavior occurring in my project when $setPristine() is added to a function.
Here is a working JSFiddle that demonstrates the behavior:
http://jsfiddle.net/knot22/2x4yt0vb/21/
Here is the HTML:
<html ng-app="myApp">
<div ng-controller="formulaCtrlr as vm" >
<form name="vm.formContainer.form" autocomplete="off">
<div class="form-group" ng-class="{'has-error': vm.formContainer.form.FatA.$dirty && vm.formContainer.form.FatA.$invalid}">
<label for="FatA" class="col-sm-2 control-label">Fat A</label>
<input name="FatA" type="text" class="form-control col-sm-10 input-sm" ng-required="true" ng-model-options="{updateOn: 'blur'}" ui-validate="{numberCheck: 'vm.numberCheck($value)', fatRangeCheck: 'vm.fatRangeCheck($value)'}" ng-model="vm.formulaInput.Fats[0]" /><span>%</span>
<span class="error" ng-show="vm.formContainer.form.FatA.$dirty && vm.formContainer.form.FatA.$invalid">Invalid entry.</span>
<span class="error" ng-show="vm.formContainer.form.FatA.$dirty && vm.formContainer.form.FatA.$error.numberCheck">{{vm.errorMessages.numberCheck}}</span>
<span class="error" ng-show="vm.formContainer.form.FatA.$dirty && vm.formContainer.form.FatA.$error.fatRangeCheck">{{vm.errorMessages.fatRangeCheck}}</span>
</div>
<div class="form-group" ng-class="{'has-error': vm.formContainer.form.FatB.$dirty && vm.formContainer.form.FatB.$invalid}">
<label for="FatB" class="col-sm-2 control-label">Fat B</label>
<input name="FatB" type="text" class="form-control col-sm-10 input-sm" ng-required="true" ng-model-options="{updateOn: 'blur'}" ui-validate="{numberCheck: 'vm.numberCheck($value)', fatRangeCheck: 'vm.fatRangeCheck($value)'}" ng-model="vm.formulaInput.Fats[1]" /><span>%</span>
<span class="error" ng-show="vm.formContainer.form.FatB.$dirty && vm.formContainer.form.FatB.$invalid">Invalid entry.</span>
<span class="error" ng-show="vm.formContainer.form.FatB.$dirty && vm.formContainer.form.FatB.$error.numberCheck">{{vm.errorMessages.numberCheck}}</span>
<span class="error" ng-show="vm.formContainer.form.FatB.$dirty && vm.formContainer.form.FatB.$error.fatRangeCheck">{{vm.errorMessages.fatRangeCheck}}</span>
</div>
<div class="col-sm-offset-2">
<input type="reset" value="Clear" class="btn btn-default" ng-click="vm.clear()" ng-disabled="vm.formContainer.form.$pristine" />
</div>
</form>
<div>formula input: {{vm.formulaInput}}</div>
</div>
</html>
Here is the JS/AngularJS:
angular.module('myApp', ['ui.validate'])
.controller("formulaCtrlr", ['$scope', function ($scope) {
var vm = this;
vm.formContainer = {
form: {}
}
vm.formulaInput = {};
vm.formulaInput.Fats = [];
vm.clear = function () {
vm.formulaInput.Fats = [];
//vm.formContainer.form.$setPristine();
}
vm.errorMessages = {
numberCheck: 'Value must be a number.',
fatRangeCheck: 'Number must be between 0 and 100.'
}
vm.numberCheck = function (value) {
var result = !(isNaN(parseFloat(value)));
return result;
//return !(isNaN(parseFloat(value)));
}
vm.fatRangeCheck = function (value) {
var result = (value && value > 0.0 && value < 100.0);
return result;
//return (value && value > 0.0 && value < 100.0);
}
}]);
If the user types abc into the first input box and -20 into the second input box the validation error messages appear, as expected. When the user clicks the Clear button the input box contents are removed but the validation errors are still displayed. The goal is to clear out the input boxes and remove the validation error messages when the user clicks Clear. It seems like adding $setPristine() would achieve this. However...
To demonstrate the unexpected behavior:
enable //vm.formContainer.form.$setPristine();
click Run
type abc into the first input box and -20 into the second input box
click Clear button
The validation errors disappear, which is good, but the input boxes still contain abc and -20; this is the unexpected behavior. Why aren't the input box values being removed?
Here is a link to the JSFiddle that now works using $setPristine():
http://jsfiddle.net/knot22/rxqh8jtc/42/
Here is the pertinent part:
vm.clear = function () {
vm.formulaInput = {};
vm.formulaInput.Fats = [];
vm.formContainer.form.FatA.$setPristine();
vm.formContainer.form.FatB.$setPristine();
}

Save every scope from a Form in a service Angularjs

I would like to save my datas from my form to my service function setData(), but I am not sure how to do it. I have already done the service, the setData() function, and my form.
Form
<form id="eventForm" data-toggle="validator" class="text-left" role="form" name="form.eventForm">
<div class="form-group col-md-12">
<input type="text" ng-model="form.return" name="RT" id="return"> Return
<input type="text" ng-model="form.oneway" name="OW" id="oneway"> One way
</div>
<button name="submit" class="btn btn-default ng-click="form.$valid && submit()">Pay now</button>
</form>
AngularJS submit method
$scope.submit = function() {
FormData.setData($scope.form);
$location.path("/flights");
}
Service setData()
this.data = JSON.parse(sessionStorage.getItem("flights") || '{}');
this.setData = function(data) {
this.data = data;
sessionStorage.setItem("flights", JSON.stringify(data));
}
this.getData = function() {
return this.data;
}
I don't know how should I pass my whole data from my Form to setData() function.
Try changing the submit button to disable on an invalid form, and set the submit action to send the form object. Then, in the controller, set the function to accept an argument (the form data), and use that.
HTML
<form id="eventForm" data-toggle="validator" class="text-left" role="form" name="form.eventForm">
<div class="form-group col-md-12">
<input type="text" ng-model="form.return" name="RT" id="return"> Return
<input type="text" ng-model="form.oneway" name="OW" id="oneway"> One way
</div>
<button name="submit"
class="btn btn-default
ng-disabled="form.$invalid"
ng-click="submit(form)">
Pay no
</button>
</form>
JS
$scope.submit = function(submitData) {
FormData.setData(submitData);
$location.path("/flights");
}

Get rid of pesky borders in ngMessage

In this plunk I have a form with two fields, each validated with ngMessage, where the error message appears when the user tabs out of the field, or the form is submitted.
The issue is that if the message is shown and then hidden (because the problem was fixed) the borders are still shown.
Try tabbing out of a field, then entering a value, you will see only borders in the error message.
How to get rid of these borders?
HTML
<body ng-app="ngMessagesExample" ng-controller="ctl">
<form name="myForm" novalidate ng-submit="submitForm()">
<label>
Enter Aaa:
<input type="text"
name="aaa"
ng-model="aaa"
required ng-blur="aaaBlur()" />
</label>
<div ng-show="showAaa || formSubmitted"
ng-messages="myForm.aaa.$error"
style="color:red;background-color:yellow;border:1px solid brown">
<div ng-message="required">You did not enter a field</div>
</div>
<br/>
<label>
Enter Bbb:
<input type="text"
name="bbb"
ng-model="bbb"
ng-minlength="2"
ng-maxlength="5"
required ng-blur="bbbBlur()" />
</label>
<br/><br/>
<div ng-show="showBbb || formSubmitted" ng-messages="myForm.bbb.$error"
style="color:red;background-color:yellow;border:1px solid brown">
<div ng-message="required">You did not enter a field</div>
</div>
<br/>
<button style="float:left" type="submit">Submit</button>
</form>
</body>
Javascript
var app = angular.module('ngMessagesExample', ['ngMessages']);
app.controller('ctl', function ($scope) {
$scope.formSubmitted = false;
$scope.showAaa = false;
$scope.showBbb = false;
$scope.submitForm = function() {
$scope.formSubmitted = true;
};
$scope.aaaBlur = function() {
$scope.showAaa = true;
};
$scope.bbbBlur = function() {
$scope.showBbb = true;
};
});
It's because you show the div (showAaa=true) but there's no content. Solution? Don't show the div. :)
<div ng-show="!myForm.aaa.$valid && (showAaa || formSubmitted)"
In which field do you have the problem ? Both or only the 2nd one ?
I see that in the 2nd field you fixed a min and max length. If they're not right, you don't have any ng-message to handle them, but your field will be in error, so you'll end up with the red border and no message.
By the way : you can use [formName].[fieldName].$touched instead of using your native onblur.

input type range doesn't initialize value

I'm having trouble getting the input to initialize a value
View:
<form ng-submit="changeDistance(form)" id="form">
<input min="1" max="50" ng-model="form.distance" type="range">
<button type="submit" >
Done
</button>
</form>
Controller:
$scope.form = {};
$scope.form.distance = $localStorage.distance;
$scope.changeDistance = function(form){
$localStorage.distance = form.distance;
}
This works but problem is value can't be submitted:
View:
<form ng-submit="changeDistance(form)" id="form">
<input min="1" max="50" ng-model="distance" type="range">
<button type="submit" >
Done
</button>
</form>
Controller:
$scope.distance = $localStorage.distance;
$scope.changeDistance = function(form){
console.log(form.distance)//cannot read
}
Try your above code (where you're using ng-model="form.distance") with angular 1.3.14 and above.
http://codepen.io/zrdesign/pen/jPRjeM
This is a confirmed bug for Angular 1.2. See the Github bug report for more details.

Cannot read property $valid of undefined

I have a form like this -
<form name="myForm" novalidate>
There are some fields in the form which I am validating and then submitting the form like this -
<input type="button" ng-click="Save(data)" value="Save">
In the controller, I want to check if the form is not valid then Save() should show some error on the page. For that, I am setting up a watch like this -
$scope.$watch('myForm.$valid', function(validity) {
if(validity == false)
// show errors
});
But I am always getting this error on running it -
Cannot read property '$valid' of undefined
Can someone explain why?
Thanks
You just misspelled "myForm" in your controller code. In order to remove the error, Write "myform" instead of "myForm".
However I expect what you want is like this.
$scope.Save = function(data){
alert($scope.myform.$valid);
}
I setup jsfiddle.
In my case I was wrapping the form in a modal created in the controller and therefore got the same error. I fixed it with:
HTML
<form name="form.editAddress" ng-submit="save()">
<div class="form-group">
<label for="street">Street</label>
<input name="street" type="text" class="form-control" id="street" placeholder="Street..." ng-model="Address.Street" required ng-minlength="2" />
<div class="error" ng-show="form.editAddress.street.$invalid">
<!-- errors... -->
</div>
</div>
<button type="submit" class="btn btn-primary" >Save address</button>
</form>
JS
angular.module("app").controller("addressController", function ($scope, $uibModal, service) {
$scope.Address = {};
$scope.form = {};
$scope.save = function() {
if (modalInstance !== null) {
if (isValidForm()) {
modalInstance.close($scope.Address);
}
}
};
var isValidForm = function () {
return $scope.form.editAddress.$valid;
}
});

Resources