angularjs form hide unhide triggers validation - angularjs

I've an angularjs form with validations set. I want to unhide it on click of show button and hide it on click of hide button.
If I play with the input fields and hide and then again unhide, I still see the validation messages which I don't want. Please help me in solving this issue.
Code is as below:
Index.html
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<!-- CSS ===================== -->
<!-- load bootstrap -->
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<style>
body { padding-top:30px; }
</style>
<!-- JS ===================== -->
<!-- load angular -->
<script src="http://code.angularjs.org/1.2.6/angular.js"></script>
<script src="script.js"></script>
</head>
<!-- apply angular app and controller to our body -->
<body ng-app="validationApp" ng-controller="mainController">
<div class="container">
<div class="col-sm-8 col-sm-offset-2">
<!-- PAGE HEADER -->
<div class="page-header"><h1>AngularJS Form Validation</h1></div>
<!-- FORM -->
<!-- pass in the variable if our form is valid or invalid -->
<button type="button" ng-click="unhide()" class="btn btn-primary">Show</button>
<form ng-show="showForm" name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate> <!-- novalidate prevents HTML5 validation since we will be validating ourselves -->
<!-- NAME -->
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" ng-model="name" required>
<p ng-show="userForm.name.$invalid && !userForm.name.$pristine" class="help-block">You name is required.</p>
</div>
<!-- USERNAME -->
<div class="form-group">
<label>Username</label>
<input type="text" name="username" class="form-control" ng-model="user.username" ng-minlength="3" ng-maxlength="8">
<p ng-show="userForm.username.$error.minlength" class="help-block">Username is too short.</p>
<p ng-show="userForm.username.$error.maxlength" class="help-block">Username is too long.</p>
</div>
<!-- EMAIL -->
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control" ng-model="email">
<p ng-show="userForm.email.$invalid && !userForm.email.$pristine" class="help-block">Enter a valid email.</p>
</div>
<!-- SUBMIT BUTTON -->
<button type="submit" class="btn btn-primary">Submit</button>
<button type="button" ng-click="hide()" class="btn btn-primary">Hide</button>
</form>
</div><!-- col-sm-8 -->
</div><!-- /container -->
</body>
</html>
script.js:
// app.js
// create angular app
var validationApp = angular.module('validationApp', []);
// create angular controller
validationApp.controller('mainController', function($scope) {
// function to submit the form after all validation has occurred
$scope.submitForm = function(isValid) {
alert(isValid);
// check to make sure the form is completely valid
if (isValid) {
alert('our form is amazing');
}
};
$scope.hide = function(){
$scope.showForm = false;
}
$scope.unhide = function(){
$scope.showForm = true;
$scope.userForm.$setUntouched();
}
});
Below is the plunker link:
http://plnkr.co/49k8P0

To achieving the behaviour what expect, you need to do several changes in your code.
All the form field should belong to one object, like create one object which would $scope.user = {} and then place all user related fields inside your user object like user.username, user.name and user.email so that while clearing form you could directly do user = {}
While hiding for you need to clear a form object, Here the form object would be the name of the form which userForm.
OR
More simpler solution would be use ng-if instead of ng-show. Which will add and remove DOM on basis of showForm value.
Demo Here

If you still want to keep the previously entered data in the fields but only clear the messages then add a variable to scope that is set to true when the form is submitted. The validation messages are only shown when the variable is true. You can then set it to false when you hide. This means that when the form is shown again the messages are hidden.
$scope.hide = function(){
$scope.showForm = false;
$scope.submitted = false;
}
Plunker: http://plnkr.co/edit/dnBu0mD9RLvLdVJJKBGe

Related

Cancel button click doesn't complete

When I open a modal dialog and without making a change, I click on cancel button, I expect the dialog to close.
But in case I have a validation on the textbox currently in focus, the validation text still appears when the focus moves out of the text box. The mentioned behavior can be seen in the following plunker -
https://plnkr.co/edit/5VsL59iCh7smS1wfEwFZ
<input type="text" autofocus ng-model="$ctrl.textValue" ng-blur="$ctrl.validate()">
Also, as reproducible in the above link, if I click on the cancel button near the top of the button, the click never completes (though the focus is shifted to the button) and the modal dialog does not close.
Any suggestion on how I can make sure that the click on the button completes or if the blur event can be avoided in case the dialog is being cancelled.
You can call $ctrl.validate() inside $ctrl.ok() function. So ng-blur can also be removed.
$ctrl.ok = function () {
$ctrl.validate ();
if(!$ctrl.textValue) {
$ctrl.invalidControl = true;
}
else
$uibModalInstance.close($ctrl.selected.item);
};
Hope it helps :)
Working Plunker: https://plnkr.co/edit/70vdDsbFrSehaHR9TXNp?p=preview
The below code snippet demonstrates how form validation can be done. So since you have many fields you can validate each field with your desired validations.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<h2>Validation Example</h2>
<form ng-app="myApp" ng-controller="validateCtrl"
name="myForm" novalidate>
<p>Username:<br>
<input type="text" name="user" ng-model="user" required>
<span style="color:red" ng-show="myForm.user.$dirty && myForm.user.$invalid">
<span ng-show="myForm.user.$error.required">Username is required.</span>
</span>
</p>
<p>Email:<br>
<input type="email" name="email" ng-model="email" required>
<span style="color:red" ng-show="myForm.email.$dirty && myForm.email.$invalid">
<span ng-show="myForm.email.$error.required">Email is required.</span>
<span ng-show="myForm.email.$error.email">Invalid email address.</span>
</span>
</p>
<p>
<input type="submit"
ng-disabled="myForm.user.$dirty && myForm.user.$invalid ||
myForm.email.$dirty && myForm.email.$invalid">
</p>
</form>
<script>
var app = angular.module('myApp', []);
app.controller('validateCtrl', function($scope) {
$scope.user = 'John Doe';
$scope.email = 'john.doe#gmail.com';
});
</script>
</body>
</html>
Move the validate function into the $ctrl.ok() and remove it form the view.
$ctrl.ok = function () {
if(!$ctrl.validate())
$uibModalInstance.close($ctrl.selected.item);
else
return
};
Here it is the working example: link

Angularjs 1 - Show/update validation messages on submit click button only (does not change on user input)

In Angularjs 1 there are many examples of validation on submit OR on user input.
In this project I need to update the validation messages on user clicks submit button only, i.e, the USER INPUT WILL NOT UPDATE THE VALIDATION MESSAGES (client spec).
Example: http://embed.plnkr.co/N0rRBS8AXU3jQJjQidIT/
It seems you only need validation on the controller, so to turn off html validation you need novalidate like this in your html:
<form name="yourForm" ng-controller="YourController as yourCtrl" ng-submit="yourCtrl.yourmethod(data)" novalidate>
then you proceed to do your validations in your controller
Here is my option:
(function(){
'use strict';
var app = angular.module('sample', []);
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="sample">
<form name="userRegister" novalidation>
<div ng-messages="userRegister.name.$error.required"
ng-if="submitted ">
<p ng-message="required">I need your name Sr</p>
</div>
<input type="text" ng-required name="name" ng-model="user.name">
<input value="Send" type="submit" ng-click="submitted=true"/>
</form>
</div>

How to set the action of a form using angularjs controller variable?

I have a form like this:
<form action="http://my-action-url">
...
</form>
How do I include use a variable to set the "action" url to be equivalent to say a variable in my controller:
$scope.actionURL = "http://my-action-url";
?
I am currently doing:
<form action="{{actionURL}}">
...
</form>
However, when I inspect element, i see the action tag is empty.
here is the code available to set action in a form using an angularJs scope variable. i have successfully run this code. please check this.
Here Submit will not work because stackoverflow does not allow to submit. for more detail you can see this error in console
angular.module("test",[]).controller("testAction",testAction);
function testAction($scope) {
$scope.actionURL = "http://www.google.com";
$scope.testD = function() {
location.href = $scope.actionURL;
};
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">
</script>
</head>
<body ng-app="test">
<div ng-controller="testAction">
<form ng-submit="testD();">
<input type="submit" >
<div>{{actionURL}}</div>
</form>
</div>
</body>
</html>
You may write the form with
$sce.trustAsHtml(html);
by yourself
Edit : better use
<form action="{{trustAction(your post url)}}">
and in your scope write
$scope.trustAction = function (actionURL) {
return $sce.trustAsResourceUrl(actionURL);
};
You can see here https://docs.angularjs.org/api/ng/directive/form
Angular prevent action and due to that you have to use
ng-submit or ng-click
as http://dojo.telerik.com/EmEki
I used jquery selector to set the form action.
<form method="post" name="deleteForm" action="#">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token('delete') }}">
<md-button ng-click="closeDialog()" class="md-raised md-primary md-button md-ink-ripple">
Cancel
</md-button>
<md-button type="submit" class="md-raised md-warn md-button md-ink-ripple">
Delete
</md-button>
</form>
And in my controller:
$('form[name="deleteForm"]').attr('action', '/manager/card-design/' + cardDesign.id);

Reset form to pre validation state?

We are new to angular and we wanted to use angular validations with our forms. We are using async ajax calls with a kendo grid to get, create, edit and save data without any submit. I am having a hard time figuring out how to reset the validation state of the form when the user chooses to create a new record.
I made this small exaple, trying anything I could find in sof without any luck so far:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-messages.min.js"></script>
<div ng-app="app">
<div ng-controller="ValidationController">
<form name="myForm" novalidate>
<label>
Name
<input name="nombre"
ng-model="field"
required />
</label>
<div ng-messages="myForm.$error">
<div ng-message="required" ng-if="myForm.nombre.$touched" ng-messages-include="myMessages">
</div>
</div>
<button type="button" ng-click="reset(myForm);" value="Reset">reset validation</button>
</form>
<script type="text/ng-template" id="myMessages">
<div ng-message="required">required field</div>
</script>
</div>
</div>
<script>
angular.module('app', ['ngMessages']).controller("ValidationController", function ($scope, $window) {
$scope.reset = function (form) {
form.$setPristine();
form.$setUntouched();
form.$setValidity();
form.nombre.$setPristine();
form.nombre.$setValidity();
form.nombre.$setUntouched();
}
});
</script>
Here is my fiddle:
https://jsfiddle.net/yh9q1a2j/
Update:
I think this better suits your needs. I've updated the fiddle
https://jsfiddle.net/n7qqn1x6/6/
In your reset method call $setPristine along with clearing the formData object.
$scope.formData = {};
$scope.myForm.$setPristine();
To get the error messages to be removed from the page once added I had to use ng-show instead of ng-if
<div ng-show="myForm.nombre.$error.required&&myForm.nombre.$dirty">required</div>

how to apply validation in AngularJS without form tag?

I have a div in which I am not using the form tag and submit the form on ng-click button but how can I apply the validation of given filed in AngularJS.
<div ng-controller="AddNewvisaController">
<input type="text" class="form-control" ng-model="visa.requirement">
<select ng-model="visa.country">
<option value="1">abc<option>
<option value="2">xyz<option>
<option value="3">pqrs<option>
</select>
<button type="submit" data-ng-click="submitvisa()">Submit</button>
</div>
You can use the "ng-form" directive if you really dont want to add a form tag.
<body ng-controller="MainCtrl">
<div ng-form="myForm">
<input type="text" required ng-model="user.name" placeholder="Username">
<button ng-click="doSomething()" ng-disabled="myForm.$invalid">DO</button>
</div>
</body>
example
You may try something below,
var myValidationModule = angular.module('myApp', []);
myValidationModule.controller('AddNewvisaController', function($scope) {
$scope.visa = {requirement : "", country : "pqrs"}
//initilize to false - it will make sure the disable the submit button
$scope.enableSubmitButton = false;
//Do the watch collection - whenever something changed, this will trigger and then do the validation as per the needs - here i validated as not empty - you can do whatever you wish and if everything is fine, then enable the button
$scope.$watchCollection(['requirement, country'], function(valueArray) {
if(valueArray[0] != "" && valueArray[1] != "") {
$scope.enableSubmitButton = true;
} else {
$scope.enableSubmitButton = false;
}
})
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="AddNewvisaController">
<input type="text" class="form-control" ng-model="visa.requirement">
<select ng-model="visa.country">
<option value="1">abc<option>
<option value="2">xyz<option>
<option value="3">pqrs<option>
</select>
<button type="submit" data-ng-click="submitvisa()" ng-disable="!enableSubmitButton">Submit</button> <!-- introduce the disable directive to make is disable by default and this will acitve if all the required filed had met their validation
</div>
</div>

Resources