Angular using $index and $invalid in a ng-class expression - angularjs

I'm using an ng-repeat directive to generate a set of forms.
I've managed to give unique names to each of the input fields using $index.
<input ng-class="{ 'has-error' : userForm.firstName-$index.$invalid }"
type="text"
class="form-control"
ng-model="passenger.firstName"
id="firstNameId-{{$index}}"
name="firstName-{{$index}}"
required
>
But, I could not get the ng-class expression to work with both the $index and $invalid statements working together.
What should be done in order to get,
ng-class="{ 'has-error' : userForm.firstName-$index.$invalid }"
to work?
Plunker is provided here

I just removed the dash all together from the input name, it is now working as intended
<form name='userForm'>
<div ng-repeat="person in people">
<input ng-class="{ 'has-error' : userForm.firstName{{$index}}.$invalid }" type="text" class="form-control" ng-model="passenger.firstName" id="firstName{{$index}}" name="firstName{{$index}}" required />
</div>
</form>
http://plnkr.co/edit/efLlNT3pUVBmENik61gU?p=preview

Related

AngularJS - how to dynamically insert input name into error state?

I am writing a form with Angular 1.5 and I am using ngMessages.
My forms will be dynamically generated based on what I get back from the server.
E.g.
<!-- dynamic form -->
<div ng-repeat="entry in form.items track by entry.id">
<!-- item type 0, text input -->
<label ng-if="entry.itemtype === '0'" class="item item-input item-stacked-label" ng-class="{ 'has-error' : templateForm.{{entry.id}}.$invalid }">
<span class="input-label"><span ng-if="entry.mandatory === '1'">* </span>{{ entry.itemlabel }}</span>
<input type="text" name="{{ entry.id}}" ng-model="entry.value" placeholder="{{ entry.itemlabel }}" required="entry.mandatory === '1'">
</label>
I want to use the entry id to name the input element. How can I write this part:
ng-class="{ 'has-error' : templateForm.{{entry.id}}.$invalid }"?
I tried to do it without the {{}} and it did not work.
It can be done with this syntax angular 1.5.3+
templateForm[entry.id].$invalid

how can I apply has-error to a single input inside form-group, where multiple inputs exist

Im using angularjs and $invalid to add .has-error to my form group.. problem is one of my form groups has multiple inputs in it, side by side..
<div class="form-group">
<div class="col-sm-6">
<label for="location">Location</label>
<select class="form-control input-lg" name="location" ng-model="newRack.location" ng-options="location as location.name for location in locations" placeholder="Locations" required></select>
</div>
<div class="col-sm-6">
<label for="name">Rack Size</label>
<input type="number" class="form-control input-lg" name="size" ng-model="newRack.size" min="1" max="48" required>
</div>
</div>
validation would look similar to this, but would include additional validations for the size element as well.
ng-class="{ 'has-error': rackForm.location.$invalid && rackForm.location.$dirty }"
if name=size becomes invalid, as it stands .has-error is applied to the entire form group, and that can be confusing to the end user. Is there a way to either
apply the .has-error to a specific input
rearrange my form
layout a bit so each input is in its own form group, yet still retain
the side by side look.
The way i do it is to create form-group for each input element. Also, I believe you don't need inner <div class="col-sm-6"> since you can join that class with form-group and get the same results.
<div class="form-group col-sm-6" ng-class="{ 'has-error': rackForm.location.$invalid && rackForm.location.$dirty }">
<label for="location">Location</label>
<select class="form-control input-lg" name="location" ng-model="newRack.location" ng-options="location as location.name for location in locations" placeholder="Locations" required></select>
</div>
<div class="form-group col-sm-6" ng-class="{ 'has-error': rackForm.size.$invalid && rackForm.size.$dirty }">
<label for="name">Rack Size</label>
<input type="number" class="form-control input-lg" name="size" ng-model="newRack.size" min="1" max="48" required>
</div>
Let me know if it helped
The simple answer is you are trying to put too much logic into your HTML. Look in to creating Angular directives that implement your logic behind the scenes or do it in your controller, and set the state you are trying to check on your scope.
One of the key precepts of Angular is to not put logic in the HTML.
To do this without changing your layout, just use ng-class sintax in each div with col class. Like that:
<div class="form-group">
<div class="col-sm-6" ng-class="{ 'has-error': rackForm.location.$invalid && rackForm.location.$dirty }">
<label for="location">Location</label>
<select class="form-control input-lg" name="location" ng-model="newRack.location" ng-options="location as location.name for location in locations" placeholder="Locations" required></select>
</div>
<div class="col-sm-6" ng-class="{ 'has-error': rackForm.size.$invalid && rackForm.size.$dirty }">
<label for="name">Rack Size</label>
<input type="number" class="form-control input-lg" name="size" ng-model="newRack.size" min="1" max="48" required>
</div>
</div>

ng-class does is not triggered on invalid form field

I am testing angular-fcsa-number directive, during the process the wrapper element of the input field is not assigned 'has-error' class even though the field is invalid. It seems to me that ng-class does not recognize that the field is invalid. What am I doing wrong here?
<form id="form1" runat="server" name="form1">
<div class="form-group" data-ng-class="{ 'has-error': form1.fcsaPlugin.$invalid }">
<label>FCSA Number</label>
<input type="text" name="fcsaPlugin" class="form-control" data-ng-model="action.FV10036" fcsa-number />
</div>
</form>
as you say it works when you remove the runat="server" attribute. Is by any chance you are using asp.net MasterPages. Had you tried to inspect the html, basically check the name of the form in the rendered html. if you are using MasterPage in asp.net the name of form will be aspnetForm, so your data-ng-class should be
data-ng-class="{ 'has-error': aspnetForm.fcsaPlugin.$invalid }"

AngularJS form validation (using $invalid with ng-reapeat and Bootstrap)

I am trying to validate my AngularJS form, adding has-error class to form-group like:
<div class="form-group" ng-class="{ 'has-error': form.field.$invalid }">
<input type="number" name="field" min="0" max="10" class="form-control">
</div>
And it works!
But it gets complicated when I'm using ng-repeat for fields and my name attribute is set according to key:
<div class="form-group" ng-class="{ 'has-error': form.???.$invalid }" ng-repeat="field in fields">
<input type="number" name="{{ field.key }}" min="0" max="10" class="form-control">
</div>
So what should I enter where ??? is? Tried form.{{ field.key }}.$invalid, form[{{ field.key }}].$invalid, nothing works...
Strange thing if I know the value of field.key for example, and I set form.keyValue.$invalid - it still doesn't work.
Any suggestions?
You need to create an inner form (see ng-form).
And take a look at this post

how to apply required field validation in ng-repeater

I have a repeater in my application and I am trying to add required field validation on the fields inside repeater. I used $index to generate id/name of the fields.
Form name is IPForm and used inside ng-class to highlight the error. Please see below code snap,
<tr ng-repeat="ClaimData in ClaimInfo">
<td>
<div ng-class="{ 'has-error' : IPForm.DateOfLoss{{$index}}.$invalid }">
<input type="text" id ="DateOfLoss{{$index}}" name="DateOfLoss{{$index}}" class="datefield form-control" ng-model="DateOfLoss"
required />
<span ng-if="IPForm.DateOfLoss{{$index}}.$invalid" class="help-block">Please enter Date of
Loss.</span>
</div>
</td>
</tr>
Problem is its not working at all. I think it is unable to evaluate IPForm.DateOfLoss{{$index}}.$invalid.
Alternatively, you can use the ng-form directive to handle your form validation which is a cleaner solution.
e.g.
<tr ng-repeat="ClaimData in ClaimInfo" ng-form="subForm">
<td>
<div ng-class="{ 'has-error' : subForm.DateOfLoss.$invalid }">
<input type="text" id ="DateOfLoss{{$index}}" name="DateOfLoss" class="datefield form-control" ng-model="DateOfLoss"
required />
<span ng-if="subForm.DateOfLoss.$invalid" class="help-block">Please enter Date of
Loss.</span>
</div>
</td>
</tr>

Resources