I have more than three dynamically generated forms. I need to iterate all the errors of the forms in controller. I am assigning form names by using models.
<form name="{{myForm}}" novalidate>
<input type="text" ng-model="username" name="username" required/>
<span ng-show="(submit && myForm.username.$error.required)">
<span>Required</span>
</span>
angular.module("myApp",[]).controller("myCtrl",function($scope) {
$scope.myForm= "validateForm";
console.log("form" + $scope.myForm)
});
What I want is when I console $scope.myForm it should print the form object but what happens is it just prints the "validateForm" string.
You ultimately want $scope.validateForm since "validateForm" is the name you give to the form once name="{{myForm}}" is compiled:
Can get it from $scope[$scope.myForm]
Note that this won't be available in controller until after the view is compiled first time and the validation object is created during the compile process
All you are currently doing is logging a primitive that you assigned on the previous line
Related
A weird thing is happening on my form or maybe i am not doing it right, let me explain to you by presenting my code.
i have defined a form object inside my component
form = {};
There is a button on each row with data that when you click it opens a modal widow and also passes the item as argument.
<a class="btn btn-warning" (click)="open(item)"><i class="glyphicon glyphicon-pencil"></i></a>
This is the method that fires and opens a modal window but also assign the item object to form object above:
open = (item: any) => {
this.inventoryEditModal.open(); //Opens a modal window
this.form = item; // the assignment
}
The item object is available on the view by printing it out like this:
{{ form | json }} // i can see all item properties
The modal window contains a form where user will edit the item, so basically the input form fields should get filled with item properties values but for some reason the third level is undefined and i don't understand why, let me show you an screenshot of the second level
<input type="text" class="form-control" [(ngModel)]="form.alarmSystem" name="wireless">
The third level gets undefined:
<input type="text" class="form-control" [(ngModel)]="form.alarmSystem.wireless" name="wireless">
This issue is happening only for the third level "object.object.property". I am only showing one input field but the form contains more than 8 fields they all have same issue.
Not sure what i am missing here, but logically it should work. Do you have see this issue happening here and there or experienced your self?
Thank you in advance.
I am not sure if it helps your case, but I was in a very similar situation.
What helped me out was using the "safe-navigation-operator".
I assume that what you need to do is just add the ? after form:
<input type="text" class="form-control" [(ngModel)]="form?.alarmSystem.wireless" name="wireless">
The docs can be found here: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#safe-navigation-operator
There can be 3 possible solutions with Angular 5
Don't assign ngForm to the template variable of the form (in form HTML element)
Don't do this -
<form #newItem="ngForm" (ngSubmit)="saveItem(newItem.value);">
Instead, do this -
<form (ngSubmit)="saveItem();">
<input type="text" class="form-control" name="wireless [(ngModel)]="form.alarmSystem.wireless">
<submit type="submit">Save</submit>
</form>
By this, you will be able to assign a 3 level nested property to
[(ngModel)] without any elvis or safe navigation operator (?).
If you are assigning ngForm to the form template variable then [(ngModel)] will give undefined for a 3 level nested property even if it already has some value.
So, use the name attribute instead -
<form #newItem="ngForm" (ngSubmit)="saveItem(newItem.value);">
<input type="text" name="alarmSystem.wireless" ngModel class="form-control">
</form>
Now, in this case, the nested property alarmSystem.wireless assigned
to the name attribute will be bound 2-way using ngModel directive.
And you can easily access it in the Event emitter function.
And the last solution by using elvis operator (?) is -
Here, again we will not assign ngForm in the form template variable, although there will not be any error but it won't store the value entered in input correctly.
So, split 2-way data binding with [ngModel] and (ngModelChange) like this
<form (ngSubmit)="saveItem();">
<input type="text" name="wireless"
[ngModel]="form?.alarmSystem?.wireless"
(ngModelChange)="form.alarmSystem.wireless=$event" class="form-control">
</form>
Also you can refer to this answer - Correct use of Elvis operator in Angular2 for Dart component's view
But, I don't recommend this solution as it adds up a lot of code.
My angular app has > 1 forms on a page. Each form can be saved or reset. The fields on each form don't necessarily map to its own data object.
For example I have two pieces of data that must be gotten and saved separately. Let's call the json chunks, a and b.
HTML:
<form>
<input type="text" ng-model="a.foo"/>
<input type="text" ng-model="b.bar"/>
</form
<form>
<input type="text" ng-model="b.bar[0].baz"/>
<input type="text" ng-model="a.boo"/>
</form
If the first form were mapped to just a and the second to b it would be a simple matter of resetting the data. But I don't want to reset all the a or b data for all forms on the page. I just want to reset the specific data fields for the inputs represented on a particular form.
My current logic mostly works. On cancel I get the elements in the form, get their ng-model attributes and dynamically reset properties on a and b depending on the ng-model string value. This seems "dirty" and plus it doesn't work for some ng-model attributes which use the $index special variable because the attr value isn't parsed by angular when doing .attr(). What's the best solution for this? Different models for each form that map back to the original data?
Make a deep copy of the object you are editing when opening the form and edit it ( angular.extend)
when save just use your save logic
on cancel you will need to do nothing
e g
.controller('myctrl', function($scope, dataService) {
$scope.data = angular.extend( {}, dataService.get())
$scope.save = function ( ) {
dataService.set($scope.data)
}
})
I haven't done this before, but you can try having something like below:
<form>
<input type="text" ng-model="form1.element1" ng-change="a.foo=form1.element1"/>
<input type="text" ng-model="form1.element2" ng-change="b.bar=form1.element2"/>
</form>
<form>
<input type="text" ng-model="form2.element1" ng-change="b.bar[0].baz=form2.element1"/>
<input type="text" ng-model="form2.element2" ng-change="a.boo=form2.element2"/>
</form>
to have an easy reference to your form-specific elements. And then for resetting, you can simply reset the form1 or form2 objects with initial values using angular.copy().
One thing you may need to watch with this approach is, once you enter some values and reset although on the form1 or form2 will be reset, there may still be values in a and b objects, you might want to handle that (disable submit for e.g.)
I have a form with a dynamic name containing fields with dynamic names.
I want to show a visual error feedback using ng-show if the field is invalid.
But since the field is set using a variable, I need to do something like:
ng-show="{{form.name}}.{{form.field.name}}.$dirty && {{form.name}}.{{form.field.name}}.$invalid"
How do I do that?
(The above code is obviously not working)
just do it not using interpolation, ng-show doesn't need it:
HTML form
<form name="testForm">
<input name="testInput" value="123">
</form>
validation ng-show:
ng-show="testForm.testInput.$dirty && testForm.testInput.$invalid"
so, in short just treat the variable name as normal and use it...
Edit: This question is no longer relevant as of Angular version: 1.3.0-beta.12 you can now parse ng-minlength and ng-maxlength dynamic values. See: https://github.com/angular/angular.js/issues/5319
My problem is quite simple: I need to dynamically create input validation (ex. ng-minlength) using interpolation.
And doing that I am running into some issues specifically generating the validation attributes for ng-minlength and ng-maxlength. I assume this is due to them only taking constants?
Below you can see my code, the reason I am using a wrapper through outerForm is that I cannot dynamically generate the name attribute of input elements using interpolation, and that I have to wrap each set of repeated inputs in an ngForm directive and nest these in an outer form element.
So again, the problem lies in the attribute ng-minlength="field.ValidationAttributes['data-val-length-min']" not being properly set.
When I print the value directly using {{field.ValidationAttributes['data-val-length-min']}} the value appears correct.
Do I have to create a directive to parse my information, do I need to create my own min/max validation or am I simply running into a syntax error?
<form name="outerForm">
<div ng-repeat="field in logEntry.StringValues">
<ng-form name="innerForm">
<input type="text" name="foo" ng-model="item.foo" ng-minlength="field.ValidationAttributes['data-val-length-min']" required/>
<span ng-show="innerForm.foo.$error.required">required</span>
<span ng-show="innerForm.foo.$error.minlength">to short</span>
</ng-form>
</div>
</form>
Hi you can use double {} to interpolate dynamic validation rules please see here: http://jsbin.com/xayiro/1/
If you can post you field.ValidationAttributes model I can update jsbin.
HTML:
<ng-form name="innerForm">
<input type="text" name="foo" ng-model="item.foo" ng-minlength="{{validation.minlength}}" required/>
<span ng-show="innerForm.foo.$error.required">required</span>
<span ng-show="innerForm.foo.$error.minlength">to short</span>
</ng-form>
JS:
$scope.validation= {
maxlength:20,
minlength:3
};
below is my html
<div class="container page" ng-controller="Homectrl" style="margin-top:8px;">
<form id ="form" novalidate class="simple-form" >
<input type="text" ng-model = user.name name="id"/>
<button ng-click="init(user)">update</button>
</form>
</div>
and js
$scope.init = function(user) {
alert(user); }
I am trying to take the user input to the query dynamically through the controller.
So I tried to get the value in angular js page but I am getting object object in alert. Please suggest me how to take the user input to the angular js and from the controller dynamically, My sql query is Select * from customer where id =? , so I need to replace the question value with user input, using angular js and spring controllers.
Thanks
Your input value is already in sync with your model, since you use ng-model. Therefore you don't need to pass it to the init function. You can try something like this to alert user name:
HTML
<div class="container page" ng-controller="Homectrl" style="margin-top:8px;">
<form id="form" novalidate class="simple-form" >
<input type="text" ng-model="user.name" name="id"/>
<input type="button" ng-click="init()" value="Update"/>
</form>
</div>
JavaScript
angular.module('app',[]).
controller('Homectrl', function($scope) {
$scope.init = function() {
alert($scope.user.name);
}
});
Plunker: http://plnkr.co/edit/JiWFnL6EFthfRjeeJocu?p=preview
If you want to make a REST call to some server-side API consider look into $http or $resource
Your code is working fine. You are already able to pass the user object in the init function in the controller. Since you are showing the object as alert, you are able to see it only as [object, object].
You can instead use console.log(user) to see the changes in the function. There you will see the user object.
Or alert(user.name) or alert(JSON.stringify(user)). The last one will show all properties and values in quotes.