I am iterating over a array of strings with ng-repeat
<div ng-repeat="i in mdsecuritysensorswsize">
in there I have a required select with a 'dynamic model'
ng-model="valueBag[i+'sizes']"
now I want to add a has-error class, if the select is empty (apply bootsrap3 error style)
ng-class="{'has-error': myForm.valueBag[i+'sizes'].$invalid, 'has-success': !myForm.valueBag[i+'sizes'].$invalid}"
But this doesn't seem to work with such a dynamic ng-model name.
Here is the complete code:
<div ng-repeat="i in mdsecuritysensorswsize">
<div class="form-group">
<div class="col-md-2"
ng-class="{'has-error': myForm.valueBag[i+'sizes'].$invalid, 'has-success': !myForm.valueBag[i+'sizes'].$invalid}"
>
<select class="form-control" required
ng-options="resText[j] for j in mdsecuritysensorswsizesizes2"
ng-model="valueBag[i+'sizes']"></select>
</div>
</div>
</div>
Am I missing something here?
this from the comments did the job:
if you create your form inputs dynamically, it will be a problem with this code when you try to access myForm.valueBag[i+'sizes'].$invalid If you create form inputs dynamically, check out my directive to solve this problem here: stackoverflow.com/questions/21455695/… – Khanh TO Feb 3 at 10:04
AngularJS dynamic form field validation
THX #Khanh TO
Related
Is there a way to avoid IDs while creating elements i.e. using ng-model it is easier to validate form fields and other stuff?
<div ng-repeat="x in TestData">
<input type="text" id="nameField-{{$index}}"/>
</div>
The above code will display the number of input boxes equal to the length of the TestData array where every text box will have a unique id "nameField-0", "nameField-1" and so on, using these IDs we can take the textbox values, validate the fields etc.
<div ng-repeat="x in TestData">
<input type="text" ng-model=""/> <!-- what shall be done here to have unique IDs -->
</div>
Although going with IDs is working fine for me but as far as I can understand If I use IDs then that will not be a pure angular way (or IDs cannot be replaced by mg-models), correct me If I am wrong.
You don't need to grab element with id/name/etc. You can use ng-model to bind your values and ng-pattern to validate them.
<div ng-repeat="x in testData">
<ng-form name="tForm">
<input type="text" name="tInput" ng-model="x.name" ng-pattern="/^[A-Z]*$/" />
<span ng-if="tForm.tInput.$error.pattern" style="color:red">Invalid!</span>
</ng-form>
</div>
See this jsbin.
In your controller add this,
$scope.nameField = [];
in ng-reapeat add this,
<div ng-repeat="x in TestData">
<input type="text" ng-model="nameField[$index]"/>
</div>
nameField will be an array with all your values.
<div ng-repeat="x in TestData" ng-init='this["nameField-"+x]'>
<input ng-model='this["nameField-"+x]'/>
</div>
You use ng-init to add new variables to the controller, "this" refer to your scope, and since the scope is an object, since this[bla] == this.bla tou are actually saying, add to my scope a variable name "nameField=" and you add the x value.
after you have created your variable, just use it in the same way in your ng-model.
If you want to show your variable's value in any div/span, just use it via ng-bind:
<div ng-bind='this["nameField-"+x]'></div>
I have an array of objects that I bind to the scope. My view then accesses the objects via ng-options like this:
<div class="tile block box-shadow">
<form role="form">
<div class="form-group">
<label>Reason for change</label>
<select class="form-control" ng-options="item.value as item.description for item in controller.priceChangeReasons" />
</div>
</form>
</div>
but the dropdown has nothing when you select it.
I have logged the priceChangeReasons and can see that the array is working and returning values.
I have made a codepen to show the issue:
http://codepen.io/r3plica/pen/XbQzMa?editors=101
I realise this is probably a syntax error on my part, but I can't see it.
Can someone help?
ngOptions directive requires ngModel, just add:
<select class="form-control" ng-options="item.value as item.description for item in controller.priceChangeReasons" ng-model="controller.reason" />
and all should work
I have a form with input fields generated with an ng-repeat. The field names are set dynamically from the model. I cannot get validation to work.
Here is the input field that is repeated within ng-repeat:
<input class="form-control input" type="number" id="item.id" name="item.name" ng-change="ctrl.updateSub(item)" ng-model="item.qty" max="item.maxqty" min="0">
I am trying to validate against the max value, which is also set dynamically.
What I cannot find anywhere is how to set the name within the ng-show classes.
<div class="col-sm-2 error" ng-show="form.{{item.name}}.$invalid">
<small class="error" ng-show="form.{{item.name}}.$error.max">
You exceeded the maximum allowed
</small>
</div>
How am I supposed to handle the {{item.name}} bit?
Thanks in advance for any help or pointers.
Angular 1.3.12
Firstly form is a reserved keyword, you cannot use that as your form name.
Coming to your problem, unfortunately as of right now it is not possible to generate dynamic names for form inputs.
You can achieve what you want with the help of ng-form
Have a look at this example :
<form name="yourForm" >
<div ng-repeat="field in fields" ng-form="myInnerForm">
<input type="text" name="dynamic_input" ng-model="field.name"/>
<div ng-show="myInnerForm.dynamic_input.$dirty && myInnerForm.dynamic_input.$invalid">
The field is required.
</div>
</div>
</form>
I have an AngularJS form where I'm using ng-repeat to build the fields of the form dynamically based on another selection. I'm trying to generate the model name dynamically and am running into problems.
<div class="form-group" ng-repeat="parameter in apiParameters">
<label for="{{parameter.paramName}}" class="col-sm-2 control-label">{{parameter.paramTitle}}</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="{{parameter.paramName}}" id="{{parameter.paramName}}" ng-model="formData.parameters.{{parameter.paramName}}" placeholder="{{parameter.paramTitle}}">
</div>
</div>
What I need is it to eval to something like ng-model="formData.parameters.fooId" or ng-model="formData.parameters.barId"
The above results in an error:
Error: [$parse:syntax] Syntax Error: Token '{' is an unexpected token at column 21 of the expression [formData.parameters.{{parameter.paramName}}] starting at [{{parameter.paramName}}].
In my controller I have:
$scope.formData = {};
$scope.formData = {
settings:
{
apiEndpoint: '',
method: 'get'
},
parameters: {}
};
I've also tried ng-model="formData.parameters.[parameter.paramName]" (based on this question How can I set a dynamic model name in AngularJS?), but that doesn't eval and fails to set the ng-model value. I'm not sure if what I'm trying to accomplish is even possible. I'm assuming I need to go through the controller to achieve what I want, but any help would be appreciated.
You just need to use hash key as model:
<div class="form-group" ng-repeat="parameter in apiParameters">
<label for="{{parameter.paramName}}" class="col-sm-2 control-label">{{parameter.paramTitle}}</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="{{parameter.paramName}}" id="{{parameter.paramName}}" ng-model="formData.parameters[parameter.paramName]" placeholder="{{parameter.paramTitle}}">
</div>
</div>
There is many other approaches, but this one are simpler than others.
I have tested this solution but it has a problem for my self. The problem is that the parameter "formData" is assigned to each iteration individually. In the other words if you insert a pre tag in every iteration you will see the value of each iteration individually and you cannot get all the formData in your controller after submitting the form.
For this I have found a very simple solution and it is the ng-init !!!!
Simply add this code to your form and before your repetitive tag. For the example of this question we will have:
<form ng-init="formData = []">
<div class="form-group" ng-repeat="parameter in apiParameters">
<label for="{{parameter.paramName}}" class="col-sm-2 control-label">{{parameter.paramTitle}}</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="{{parameter.paramName}}" id="{{parameter.paramName}}" ng-model="formData.parameters[parameter.paramName]" placeholder="{{parameter.paramTitle}}">
</div>
</div>
</form>
I am trying to use $invalid to add a class to a div when the input within the div is not filled out. However I just cannot work out the syntax.
<div ng-app ng-controller="miniC">
<form name="persondetails" novalidate>
<div ng-repeat="account in myAccounts" ng-class="{'has-error': account.amount.$invalid}" >
<input name="{{account.name}}" ng-model="account.amount" required="required"/>
</div>
</form>
</div>
function Account(nameArg, amountArg){
this.name = nameArg;
this.amount = amountArg;
}
The surrounding div needs to have class="has-error" when the inner item is not filled in. I have done similar on single bound elements just cant seem to get this working....
$invalid flag is not attached to the ngModel, but to the form controller (ngFormController).
In your example you're not demonstrating that you're even using ngForm, and you should, if you want angular to validate your form.
Next, you're trying to dynamically set the input's name attribute. ngForm won't like it because ngFormControll will be initialized before your expression is evaluated.
Workaround is to wrap each ng-repeat iteration inside new ngForm (ngForm can be nested and it will just work) and name your inputs with some static string value (e.g. name="amount").
So, you'll want your view written as:
<div
ng-repeat="account in myAccounts"
ng-class="{'has-error': form.amount.$invalid}"
ng-form="form"
>
<input name="amount" ng-model="account.amount" required="required"/>
</div>