when user click on submit button i am validating form, using ng-click i am calling function, in this function i am passing form1.$invalid,based on this variable , i am putting condition, if condition true, validate function will call, here problem is mobile is hidden field, this hidden field also checking validation.how can skip or not validate mobile field hidden status, I tried bellow code.
html
----
<form name="form1" novalidate>
<input ng-show="user" type="text" name="user" ng-model="frm1.user" />
<p ng-show="form1.user.$error.required"><span ng-show="errorMsgShow" ng-required="true">{{requiredMsg}}</span></p>
<input ng-show="mobile" type="text" name="mobile" ng-model="frm1.mobile" />
<p ng-show="form1.mobile.$error.required"><span ng-show="errorMsgShow" ng-required="true">{{requiredMsg}}</span></p>
<button ng-click="SubmitForm(regForm.$invalid);">submit</button>
</form>
Script----
$scope.SubmitForm = function(val){
$scope.user= true;
$scope.mobile = false;
if (if(val ===true){
$scope.validation();
}
}
$scope.validation = function(){
$scope.requiredMsg="input fieldis required";
}
I suggest better approach will be taking the mobile input out of the form when it's unnecessary using ng-if rather than just hide it with ng-show.
Ng-if will make sure the input is not rendered in the DOM tree when the condition is false, therefore, there will be no validation triggered.
You can do some research on differences between ng-if and ng-show to have better understanding about these two directives.
Try ng-if to avoid validation.If you want mobile to skip validation then make ng-if as false using expression.
syntax: ng-if="expression"
go to this link for further info
https://docs.angularjs.org/api/ng/directive/ngIf
for difference between ng-if and ng-hide/ng-show refer the below link
what is the difference between ng-if and ng-show/ng-hide
Some observations :
Instead of using ng-show to hide and show the inputs just use <input type="hidden"... > element for mobile field.
No need to use variable $scope.user and $scope.mobile to hide and show the inputs.
Add the required attribute in the user input field not on mobile input field as you don't want to validate mobile field.
Use SubmitForm(form1.$invalid) instead of SubmitForm(regForm.$invalid) as your form name is form1 not regForm.
DEMO
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function($scope) {
$scope.SubmitForm = function(val) {
console.log(val);
if(val === true) {
$scope.validation();
}
}
$scope.validation = function() {
$scope.requiredMsg="input fieldis required";
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<form name="form1" novalidate>
<input type="text" name="user" ng-model="frm1.user" required/>
<p ng-show="form1.user.$error.required">{{requiredMsg}}</p>
<input type="hidden" name="mobile" ng-model="frm1.mobile" />
<button ng-click="SubmitForm(form1.$invalid);">submit</button>
</form>
</div>
Related
<!--Below is the html code-->
<div ng-init="InitializeFields()">
<input type="text" on-click="makeOtherReadOnly('1')"
readonly="show_or_not_first"/>
<input type="text" on-click="makeOtherReadOnly('2')" readonly="show_or_not_second"/>
</div>
// Now inside javascript
$scope.makeOtherReadOnly=function(number){
if(number==='1'){
show_or_not_second=true;
show_or_not_first=false;
show_or_not_second=true;
}else if(number==='2'){
show_or_not_first=true;
show_or_not_second=false;
}
};
$scope.Initializer=function(){
show_or_not_first=false;
show_or_not_second=false;
}
$scope.Initializer();
the problem that I am facing is as I click on the input field, it should turn the other field to readonly after pafe gets loaded and we have either field clicked, but it requires two click...
Every help is appreciated.
Try changing on-click to ng-click.
You need to correct few things ion your code :
change on-click to ng-click, So your function can be called from HTML.
Change readonly to ng-readonly, So you can utilize $scope property
In your ng-init, I guess you need to call Initializer() method to initialize default value.
Further just to make 2 input box readonly, you can chieve this by 1 flag. and no string comparison.
Simple Demo :
angular.module('myApp', []).controller('myCtrl', function($scope) {
$scope.makeOtherReadOnly = function(boolValue) {
console.log(boolValue);
$scope.data.first = boolValue;
};
$scope.Initializer = function() {
$scope.data = {
first: false
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-init="Initializer()">
First: <input type="text" ng-click="makeOtherReadOnly(false)"
ng-readonly="data.first" />
Second: <input type="text" ng-click="makeOtherReadOnly(true)"
ng-readonly="!data.first" />
</div>
</div>
There are two scopes here
javascript and angular
sometimes inside ng-click, javqascript function don't work
so change on-click to ng-click.
This is my first time using AngularJS, and the form validation is making me question my sanity. You would think this would be the easy part, but no matter how many ways I've tried Googling, the only thing that works is if I set a flag inside my controller's submit if the form is invalid to set the error class. I've looked at similar problems here, but none of them helped, so please do not simply dismiss this as a potential duplicate. Everything else has been a fail.
In the example mark up below I have reduced my form down to just one element. Here is what I have observed:
Using only $error.required does work. The ng-class { 'has-error' :registerForm.firstName.$error.required} does outline the text box with the bootstrap has-ertror class, but this is on form load, which I do not want.
The <p> element with the error message will exhibit the same behavior, so I know that the message exists and is not malfored. It will also display if I only use $error.required. But as soon as I add && registerForm.$submitted ( or $isdirty or !notpristine ) the message will not display on form submit. There are no errors (have developers tools open in chrome) and will post to the web API with no problem and return ok 200 or 400 if I send bad params.
I can write validation code inside my controller, checking if the field has a value and setting a flag on $scope such as $scope.firstNameIsRequired and that will work fine setting ng-show="$scope.firstNameIsRequired", but that will remove testability.
So the problem definitely has to be with how I am adding this in the markup. But after a weekend spent googling I am at my wits end. The only other thing different is that I am using a span on a click element to submit the form instead of an input = submit, but the registerForm.$valid function is setting the correct value. Do I somehow need to trigger the form validation in that ng-click directive?
I am using angular.js v 1.4.8.
I do have angular ui which has it's own validate, but that shouldn't interfere with the basic validation.
Here is the simplified markup:
<form name="registerForm" class="form-group form-group-sm"
ng-controller="userAccountController" novalidate>
<div class="form-group"
ng-class="{ 'has-error' : registerForm.firstName.$error.required }">
<div><label>First Name</label> </div>
<input type="text" class="form-control" id="firstName" name="firstName" value=""
ng-model="firstName" placeholder="First Name" maxlength="100" required=""/>
<p ng-show="registerForm.firstName.$error.required && registerForm.$submitted"
class="alert alert-danger">First Name is required</p>
</div>
<div>
<span class="btn btn-default"
ng-click="submit(registerForm.$valid)">Register</span>
</div>
My controller code is
angular.module( "Application" ).controller( "userAccountController", [
"$scope", "userAccountService", function ( $scope, userAccountService)
{
$scope.hasErrors = false;
$scope.errorMessages = "";
$scope.emailExists = true;
$scope.clearErrors = function (){
$scope.hasErrors = false;
}
$scope.onSuccess = function ( response ) {
alert( "succeeded" );
}
$scope.submit = function (isValid) {
if ($scope.registerForm.$invalid)
return;
alert("isvalid");
$scope.clearErrors();
var userProfile = $scope.createUser();
userAccountService.registerUser(userProfile, $scope.onSuccess, $scope.onError);
}
$scope.createUser = function () {
return {
FirstName: $scope.firstName, LastName: $scope.lastName, Email: $scope.email,
Password: $scope.password, SendAlerts: $scope.sendAlerts
};
};
}
]);
Any help will be appreciated. I probably just need a second set of eyes here because I have been dealing with this on and off since late Friday.
in angular you want use the element.$valid to check wheter an model is valid or not - and you use element.$error.{type} to check for a specific validation error.
Keep in mind that the form.$submitted will only be set if the form is actually submitted - and if it has validationerrors it will not be submitted (and thus that flag is still false)
If you want to show errors only on submit you could use a button with type="submit" and bind to ng-click event - and use that to set a flag that the form has been validated. And handling the submit if the form is valid.
A short example with 2 textboxes, having required and minlength validation:
angular.module("myApp", [])
.controller("myFormController", function($scope) {
$scope.isValidated = false;
$scope.submit = function(myForm) {
$scope.isValidated = true;
if(myForm.$valid) {
console.log("SUCCESS!!");
}
};
});
.form-group {
margin: 10px;
padding: 10px;
}
.form-group.has-error {
border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<div ng-app="myApp" ng-controller="myFormController">
<form name="myForm">
<div class="form-group" ng-class="{'has-error': myForm.name.$invalid && isValidated}">
<span>Name:</span>
<input type="text" name="name" minlength="5" ng-model="name" required />
<span ng-if="myForm.name.$error.required && isValidated">Name is required</span>
<span ng-if="myForm.name.$error.minlength && isValidated">Length must be atleast 5 characters</span>
</div>
<div class="form-group" ng-class="{'has-error': myForm.email.$invalid && isValidated}">
<span>Email:</span>
<input type="text" name="email" minlength="5" ng-model="email" required />
<span ng-if="myForm.email.$error.required && isValidated">Email is required</span>
<span ng-if="myForm.email.$error.minlength && isValidated">Length must be atleast 5 characters</span>
</div>
<button type="submit" ng-click="submit(myForm)">Submit</button>
</form>
</div>
Having such form
<div ng-controller="FormController as f_ctrl">
<form ng-submit="f_ctrl.submit()" name="myForm">
<input type="text" ng-model="f_ctrl.user.username"
required
ng-minlength="4"/>
<input type="text" ng-model="f_ctrl.user.password"/>
<input type="submit" value="Submit" ng-disabled="myForm.$invalid">
</form>
</div>
and such controller
.controller('FormController', [function() {
var self = this;
self.submit = function() {
console.log('User submitted form with ' + self.user.username)
}
}]);
I have a problem: when page first loads it immediately shows red border on username field, even before I start typing anything.
I need to highlight invalid fields only after first submission. Can this be done using form.$invalid ?
You have to use $pristine for that. It is true when form controller is not changed. so when you change textbox data its comes false.
Small example for you.
<div class="form-group" ng-class="{ 'has-error' : userForm.password.$invalid && !userForm.password.$pristine }">
<input id="passAnime" type="password" name="password" ng-model="user.password" class="form-control input-md" placeholder="Password" tabindex="5" ng-maxlength="25" ng-minlength="6" required>
<span ng-show="userForm.password.$dirty && userForm.password.$invalid">
<p ng-show="userForm.password.$error.required" class="error-messages">
Your password is required.
</p>
<p ng-show="userForm.password.$error.minlength" class="error-messages">
Your password is too short. Minimum 6 chars.
</p>
<p ng-show="userForm.password.$error.maxlength" class="error-messages">
Your password is too long. Maximum 25 chars.
</p>
</span>
</div>
Angular has helpers that tell you if the form (or form field) is $dirty (user has typed something) or if the form is $touched (the blur event has been triggered on the input). See this demo.
I need to highlight invalid fields only after first submission.
Unfortunately, Angular doesn't support that. But you could implement it yourself rather easily:
Controller
function FormController() {
var vm = this;
vm.submitAttempted = false;
vm.submit = function(isValid) {
if (isValid) {
// do stuff
}
else {
vm.submitAttempted = true;
}
};
}
HTML
<div ng-app='app'>
<div ng-controller='FormController as vm'>
<form name='fooForm' ng-submit='vm.submit(fooForm.$valid)' novalidate>
<label>Username</label>
<input
name='username'
type='text'
ng-model='vm.user.username'
required
ng-minlength='4'
ng-class="{'invalid': vm.submitAttempted && fooForm.username.$invalid}">
<br /><br />
<button type='submit'>Submit</button>
</form>
</div>
</div>
CSS
.invalid {
border-color: red;
}
Demo
I have a problem: when page first loads it immediately shows red border on username field, even before I start typing anything.
That's probably because you have the following CSS class:
.ng-invalid {
border-color: red;
}
Angular will always apply the ng-invalid class to fields that are invalid, and there's nothing you could do about that. So if you don't always want invalid fields to have a red border, you can't use that class and you should do it in a way similar to what I proposed above.
Also, check out ngMessages.
You can disable the default styling on the input field that is adding the red border by default, by adding the following CSS:
input:required {
-moz-box-shadow: none;
box-shadow: none;
}
Then if you want to highlight the field when the form is submitted, you will need to ensure that the form and form fields have relevant name attributes. Doing this will allow you to check if the field is valid or not and apply a class to your text field when it is invalid:
<input type="text" name="username" ng-class="{ 'invalid-field' : f_ctrl.myForm.username.$invalid && !f_ctrl.myForm.username.$pristine }" required />
f_ctrl.myForm and f_ctrl.myform.username will have additional properties that you can use/check to determine if the form or fields are invalid or not, or if they have been modified at any point (e.g. f_ctrl.myform.username.$dirty). You should be able to view these properties on your page by adding the follow HTML:
<div>
<pre>{{f_ctrl.myForm | json}}</pre>
</div>
Or, you could output self.myForm to the console from your controller to view it's properties
console.log(self.myForm);
I've been trying to grab hold of the Angular forms applying best practices for form validations, that forced me to use the form name and have all of the models as children of it so that I can bind the formname.$valid and all the other stuff.
However I haven't been able to set predefined values to any of the form sub models as I have no access to them in the controller.
My biggest problem right now is how to check for falsy checkboxes because initially the checkbox is unchecked but there is no value, it only gets populated when clicked to change the value.
Here is my form code
<form name="addAppForm" ng-if="creatingApp == false">
<input type="text" placeholder="App Name" required autofocus ng-model="addAppForm.appName">
<input icheck id="ios" type="checkbox" ng-init="addAppForm.iOS = false" ng-model="addAppForm.iOS">
<label for="ios"><i class="icon-apple"></i> iOS {{addAppForm.iOS}}</label>
<input icheck id="android" type="checkbox" ng-init="addAppForm.android = false" ng-model="addAppForm.android">
<label for="android"><i class="icon-android"></i> Android {{addAppForm.android}}</label>
<button ng-disabled="addAppForm.$invalid && (addAppForm.iOS != true && addAppForm.android != true)" type="submit" ng-click="addNewApp(addAppForm.iOS, addAppForm.android, addAppForm.appName)" class="button front-primary large radius expand">Let's GO!</button>
</form>
The "required" directive doesn't apply to the checkboxes and I've tried initializing the model but with no luck.
When you add a named form like that, it is added to your controller's scope. You can access it inside the controller using the name, similar to in the HTML:
$scope.addAppForm.android;
This should evaluate to true/false any time after the form has been set up, even if it hasn't been clicked yet.
Edit: Fiddle where form is accessed in the controller.
I've figured out what's wrong with my code, the ng-init actually works, I just mixed up the operators here -->> ng-disabled="addAppForm.$invalid && (addAppForm.iOS != true && addAppForm.android != true)"
Should have been ng-disabled="addAppForm.$invalid || (addAppForm.iOS != true && addAppForm.android != true)"
Still the problem persists of not being able to access the form from the controller not even in the same view outside of the form.
I still don't understand why u have to save your data in the Formcontroller u can use a object ( here i call it 'model' ) and put all your form values inside. Your Formcontroller object ( 'addAppForm' ) has functionality and saves validation errors see here : https://docs.angularjs.org/api/ng/type/form.FormController This object is added to the scope of your Controller late in the initialisation of your Controller
see: https://docs.angularjs.org/api/ng/directive/form
Directive that instantiates FormController.
If the name attribute is specified, the form controller is published onto the current scope under this name.
Here is the way to have the form invalid if not at least one checkbox is selected
var myApp = angular.module("myApp", []);
myApp.controller("myController1", function($scope) {
$scope.model = {
"ios": false,
"android": false
};
});
<div ng-app="myApp" ng-controller="myController1">
<form name="addAppForm">
<input type="text" placeholder="App Name" required autofocus ng-model="model.appName" />
<input id="ios" name="ios" type="checkbox" ng-model="model.ios" ng-required="!model.ios && !model.android" />
<label for="ios"><i class="icon-apple"></i> iOS</label>
<input id="android" name="android" type="checkbox" ng-model="model.android" ng-required="!model.ios && !model.android" />
<label for="android"><i class="icon-android"></i> Android</label>
<button ng-disabled="addAppForm.$invalid " type="submit" ng-click="addNewApp(model.ios, model.android, model.appName)" class="button front-primary large radius expand">Let's GO!</button>
</form>
</div>
<script src="https://code.angularjs.org/1.3.8/angular.min.js"></script>
I try to figure out how I can keep the focus on an input field in angularjs after I click on a button.
My goal is to prevent my mobile to hide his keyboard right after I click on the + button. I want to keep the focus on input choice.
Like this the user can add a new choice without the need to click again on my input.
<div id="demo" ng-app="Foobar">
<div ng-controller="DemoCtrl">
<input type="text" ng-model="title" placeholder="title" />
<input type="text" ng-model="choice" placeholder="choice" />
<button ng-click="addChoice(choice)">+</button>
{{choices}}
</div>
</div>
angular.module('Foobar', [])
.controller('DemoCtrl', ['$scope', function ($scope) {
$scope.choices = [];
$scope.addChoice = function (choice) {
$scope.choices.push(choice);
};
}]);
http://jsfiddle.net/gbg09bto/
What is the best strategy ? (directive, ng-focus)
simplest thing is do it by plain javascript
to do it
in html // put a id attribute
<input type="text" id="choice" ng-model="choice" placeholder="choice" />
in controller function
$scope.addChoice = function (choice) {
$scope.choices.push(choice);
document.getElementById("choice").focus(); // get the element by id & focus the input
};
here is the updated Fiddle