Nested Ng-repeat with ng-if passing proper $index - angularjs

I have a nested ng-repeat with ng-if, inside each ng-if I have a check-box which is containing a ng-click function. I want to pass the nested ng-repeat's $index value through the function.
Here is my code.
<div class="student" ng-repeat="student in studentDetails.childNumber track by $index" ng-init=" studentnumber = $index">
<div ng-repeat="grmnt in student.garmentNumber track by $index" ng-init="grmntidex = $index" ng-if="grmnt.gurmentType === 'shirt'">
<div ng-click="garmentOpen = !garmentOpen;" class="z-depth-1 garmentelement">Garment</div>
<div class="garmentHeader" ng-if="garmentOpen">
<div class="garmentBody">
<div class="row">
<p class="col s6 center-align">
<input type="checkbox" id="BrandMeasurement" ng-click="msrmntSelector(grmnt)" />
<label for="BrandMeasurement">Brand Measurement</label>
</p>
<p class="col s4 center-align">
<input type="checkbox" id="BodyMeasurement" ng-click="msrmntSelector(grmnt)" />
<label for="BodyMeasurement">Body Measurement</label>
<div>
</div>
</div>
</div>
</div>
</div>
</div>
But the problem is when I am selecting the last grmnt element it's passing proper garment with id but after selecting the first element its not passing 2nd or 3rd or 4th any of the garment. In every case it's passing only the first element.
Can any one please tell me where I'm making any mistake (if any)??

Don't use ng-if on the ng-repeat just use a filter in the ng-repeat.
<div ng-repeat="grmnt in student.garmentNumber | filter:{gurmentType: 'shirt'} track by $index" ng-init="grmntidex = $index">
Edit: I think maybe the problem is in your labels. The label's for attribute needs to uniquely match the input's id attribute. Each row needs its own id/for pair. Use $index to do this.
<input type="checkbox" id="BrandMeasurement{{$index}}" ng-click="msrmntSelector(grmnt)" />
<label for="BrandMeasurement{{$index}}">Brand Measurement</label>

Related

can we append the string with a variable in the ng-model?

<div ng-repeat="data in assets">
<input type="checkbox" ng-model="text"+{{$index}}/>
</div>
here I want to generate different ng-models for each checkbox
You can use alias name "data" and assign "data.isChecked" to ng-model.
<div ng-repeat="data in assets">
<input type="checkbox" ng-model="data.isChecked" />
</div>
This will add that "isChecked" variables at run time to all objects of "assets" array.
It's better to have your models in the array you are looping over.
<div ng-repeat="data in assets">
<input type="checkbox" ng-model="data.input"/>
</div>

Get ng-repeat data to appear in 4 columns

I'm getting list of data from Db to a view using ng-repeat. In order to select multiple values at once I'm using checklist-model. My code is as follows,
<div ng-repeat="item in items">
<input type=checkbox checklist-model="user.role" checklist-value="item"/>{{item}}
</div>
This will return a long list one below another. What I need is to get these data in the list to be displayed in 4 columns. Any help please!
Working Demo
This is what you are looking for. Hope that solve your problem.
<div ng-repeat="product in products" ng-if="$index % 3 == 0" class="row">
<div class="col-xs-4"> <input type="checkbox" checklist-model="user.role" checklist-value="{{products[$index]}}"/>{{products[$index]}}</div>
<div class="col-xs-4"> <input type="checkbox" checklist-model="user.role" checklist-value="{{products[$index]}}"/>{{products[$index+1]}}</div>
<div class="col-xs-4"> <input type="checkbox" checklist-model="user.role" checklist-value="{{products[$index]}}"/>{{products[$index+2]}}</div>
</div>
Output:
You could use display:inline-block on your elements that you want in a row. How you lay them out within that row could be done different ways depending on what you are seeking.
<div ng-repeat="item in items" style="display:inline-block;">
<input type=checkbox checklist-model="user.role" checklist-value="item"/>{{item}}
</div>

ng-repeat execution forces input to lose focus

I have an input that is created using ng-repeat
<div data-ng-repeat="(index, answer) in currentQuestion['possible_answers']" class="form-group">
<label class="col-md-3 control-label">Answer {{ index + 1 }}</label>
<div class="col-md-8">
<div class="input-icon">
<i class="fa fa-sun-o"></i>
<input data-ng-model="currentQuestion['possible_answers'][index]" type="text" class="form-control" >
</div>
</div>
</div>
I want this to prepopulate the inputs with the values that are in currentQuestion['possible_answers'] and I also want any changes to bind to this variable as well.
However, everytime I start typing into one of these text fields, I type one letter and then it looses focus of the input box. I have a feeling that this is because I start typing and the data bidning updates currentQuestion. Because currentQuestion is updated, the ng-repeat is executed again.
Is there a way to make the ng-repeat action a one off action isntead of constantly revalutating?
Yes (looking at the symptoms, you did not show us the data) your issue could be because your model is the text in the array that you (may have), so whenever you update the model, it will trigger digest cycle since ng-repeat is tracked by the text. You can easily fix this by providing. track by $index, so that the ng-repeat is watched over and repeat watch gets updated only when the array changes in its length.
<div data-ng-repeat="answer in currentQuestion['possible_answers'] track by $index" class="form-group">
<label class="col-md-3 control-label">Answer {{ $index + 1 }}</label>
<div class="col-md-8">
<div class="input-icon">
<i class="fa fa-sun-o"></i>
<input data-ng-model="currentQuestion['possible_answers'][$index]" type="text" class="form-control" >
</div>
</div>
</div>
Demo
You can also use $index to get the array's index. you do not need to iterate with (key, value).
However i would just make my answer array an array of objects and get rid of all these issues, and it would just be (_note the usage of $index and ng-model):-
<div data-ng-repeat="answer in currentQuestion['possible_answers'] track by $index" class="form-group">
<label class="col-md-3 control-label">Answer {{ $index + 1 }}</label>
<div class="col-md-8">
<div class="input-icon">
<i class="fa fa-sun-o"></i>
<input data-ng-model="answer.text" type="text" class="form-control" >
</div>
</div>
</div>
Demo
The ng-repeat creates a new child scope for each item in the list. In this scope it knows index and answer. You bind the value of the input to something outside the scope, namely the same item in the array. Changing it triggers the list to be redrawn, which causes the input to loose focus.
<div data-ng-repeat="(index, answer) in currentQuestion['possible_answers']" class="form-group">
<label class="col-md-3 control-label">Answer {{ index + 1 }}</label>
<div class="col-md-8">
<div class="input-icon">
<i class="fa fa-sun-o"></i>
<input data-ng-model="answer" type="text" class="form-control" >
</div>
</div>
</div>

Can I use ng-repeat to iterate over an array in AngularJS?

I am having some trouble with using AngularJS ng-repeat. Here is what I have:
<div ng:show="selected == 3">
<div class="columns">
<textarea rows="4" data-ng-model="modal.data.answer[1].text" cols="91">1</textarea>
</div>
<div class="columns">
<label>Explanation</label>
<textarea rows="2" data-ng-model="modal.data.answer[1].explanation" cols="91"></textarea>
</div>
<div class="columns">
<div class="colx2-left">
<span class="label">Correct</span>
<input type="checkbox" data-ng-model="modal.data.answer[1].correct" class="check-box"><input type="hidden" value="false" name="Details[0].Correct">
</div>
<div class="colx2-right">
<label>Image File</label>
<input type="text" data-ng-model="modal.data.answer[1]image" class="full-width">
</div>
</div>
</div>
The modal.data.answer array will always have six elements. Can I use ng-repeat to create the HTML for these and have it repeat even the [x] numbers in the array and have it increment the number on the first line for "selected =" from 3 to 8 ?
As far as I know I can use <div ng-repeat="t in [3,4,5,6,7,8]"> </div> but how can I get the values of t into things like:
data-ng-model="modal.data.answer[1].text"
your edit is heading in the right way, you can iterate through a list of integers easily, the you just use the value of you index like that
<div ng-repeat="t in [3,4,5,6,7,8]">
....
data-ng-model="modal.data.answer[t].text"
...
I made a fiddle if you want to try http://jsfiddle.net/DotDotDot/tweyS/ (the input field is just here to change the selected value, as in your code sample, in order to display the right fields)
have fun
Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys.
<div ng-repeat="n in [42, 42, 43, 43] track by $index">
{{n}}
</div>

How to get a repeat input's value

ng-repeat's each item get its own scope, but how to get the input value?
In a normal situation, just set a ng-model and refer it through $scope.
<div ng-repeat="item in items">
<input type="text">
</div>
Is thre a way to work around this?
<div ng-repeat="item in items">
<input type="text" ng-model="item.value">
</div>

Resources