AngularJS nested ng-repeat - javascript

I have object which contains question and list of choices. I'm display this object on the page using nested ng-repeats. When I'm trying to change 'question' everything changes just fine, but when I'm trying to change 'choice' nothing happens. Where is the problem?
My page:
<div class="panel">
<div class="row">
<div class="large-12 columns">
<h3>{{ title }}</h3>
<ol>
<li ng-repeat="q in quiz">
<input type="text" ng-model="q.question">
<ul class="remove-li-dots">
<li ng-model="choice" ng-repeat="choice in q.choices">
<input type="text" ng-model="choice" name="answer{{ q.id }}" >
</li>
</ul>
</br>
</li>
</ol>
<a class="button" ng-click="submitQuiz()">Submit</a><br>
{{ quiz }}
</div>
</div>
Screenshot of the page:
https://www.dropbox.com/s/i52fwq1os0cvcr9/repeat.png?dl=0

Problem is that choice is a string, so when you are changing it in child scope it is changing only in child scope.
To fix this - reference it by index in array ng-repeat="(choiceIndex,choice) in q.choices,ng-model="q.choices[choiceIndex]".
Also to prevent inputs from loosing focus when changing items - you will need to add track by $index in ng-repeat directive.
<ol>
<li ng-repeat="q in quiz">
<input type="text" ng-model="q.question">
<ul class="remove-li-dots">
<li ng-model="choice" ng-repeat="(choiceIndex,choice) in q.choices track by choiceIndex">
<input type="text" ng-model="q.choices[choiceIndex]" name="answer{{ q.id }}">
</li>
</ul>
</li>
</ol>
working example:
http://plnkr.co/edit/GJacjkzfT4FpfC6szsNk?p=preview
For better understanding how angular scopes works, I recommend reading this: https://github.com/angular/angular.js/wiki/Understanding-Scopes

Related

angular-ui-tree two events instead of one

I'm sure it is pretty simple question, but I can't find answer. I use pretty common pattern for creating tree. I need to know if user click parent node or child node. Everything works fine if I click parent node. But if I click child node, the callback function calls two times - first from child node, second from parent node. Could somebody explain me why? Thank you.
<div id="groups-tree" class="col-sm-4">
<script type="text/ng-template" id="nodes_renderer.html">
<div ui-tree-handle class="tree-node tree-node-content">
<a class="btn btn-success btn-xs" ng-if="node.nodes && node.nodes.length > 0"
ng-click="selected(node)" data-nodrag>
<span class="glyphicon"
ng-class="{
'glyphicon-chevron-right': collapsed,
'glyphicon-chevron-down': !collapsed
}"></span>
</a>
{{node.title}}
</div>
<ol ui-tree-nodes="" ng-model="node.nodes" ng-class="{hidden: collapsed}">
<li ng-repeat="node in node.nodes" ui-tree-node ng-include="'nodes_renderer.html'"
ng-click="selected(node)"*# data-nodrag>
</li>
</ol>
</script>
<div class="row">
<div class="col-sm-6">
<div ui-tree id="tree-root">
<ol ui-tree-nodes ng-model="data" data-nodrag>
<li ng-repeat="node in data" ui-tree-node ng-include="'nodes_renderer.html'"
ng-click="selected(node)"></li>
</ol>
</div>
</div>
</div>
</div>
I found solution here. The angular-ui-tree is sequence of enclosed elements. So I should stop propagate the event from child element to parent element.

I would like to display the div only once - AngularJS

catch is that
I would like to display the div only once, not three times:
//angular js code
$scope.arr=["sunday","mpnday","tuesday"];
//html view
<ul>
<li ng-repeat="x in arr">
<div><p>{{ x }}</p>
</div>
</li>
</ul>
Try:
<ul>
<li ng-repeat="x in arr">
<div ng-if="$first">
<p>{{ x }}</p>
</div>
<p ng-if="!$first">{{ x }}</p>
</li>
</ul>
Anyway, I would recommend you to rewrite your markup in valid way. div inside li is quite bad markup style.

JSON with AngularJS: parent in nested ng-repeat

according to this solution i built my AngularJS app. Now i want to access a parent's value within a nested structure.
I tried this, but it does not work: http://jsfiddle.net/BwDAP/
<body ng-app="WeeklyApp" ng-controller="WeeklyController" >
<div ng-repeat="week in myData">
<div ng-repeat="day in week.days">
{{day.dow}} - {{day.templateDay}}
<b>Jobs:</b><br/>
<ul>
<li ng-repeat="job in day.jobs">
{{job.name}}
<br />
<!-- PARENT -->
parent: {{job.parent.dow}}
</li>
</ul>
</div>
</div>
</body>
Any solutions?
thx
A haha, too easy ;-)
Here is the solution: http://jsfiddle.net/Lm6KZ/
<body ng-app="WeeklyApp" ng-controller="WeeklyController" >
<div ng-repeat="week in myData">
<div ng-repeat="day in week.days">
{{day.dow}} - {{day.templateDay}}
<b>Jobs:</b><br/>
<ul>
<li ng-repeat="job in day.jobs">
{{job.name}}
<br />
<!-- PARENT -->
parent: {{day.dow}}
</li>
</ul>
</div>
</div>
</body>

How can I increment the class names using ng-repeat?

I set up an ng-repeat to rollout a bunch of elements from a JSON file however I would like each element to have a incremental class name .item-1, .item-2, .item-3.
<div ng-controller="itemCtrl">
<div class="item" ng-repeat="item in items">
<span class="item-{{ item.length }}"></span>
</div>
</div>
I would like to add the number to class="item-{{ item.length}}" but I can't seem to get this working.
I don't know what is the benefit of generating dynamic class names like this. A class should mean a class of similar objects.
It's still possible with $index:
<div ng-controller="itemCtrl">
<div class="item" ng-repeat="item in items">
<span class="item-{{ $index }}"></span>
</div>
</div>
https://docs.angularjs.org/api/ng/directive/ngRepeat
As documented on https://docs.angularjs.org/api/ng/directive/ngRepeat just use $index
<div ng-controller="itemCtrl">
<div class="item" ng-repeat="item in items">
<span class="item-{{ $index }}"></span>
</div>
</div>

Listen for ng-dirty in multiple forms

I'm building a app using AngularJs
In one of my template partials I use "ng-repeat" to spawn multiple forms:
<ul class="small-block-grid-2 medium-block-grid-3 large-block-grid-4 usbDevices">
<li ng-repeat="usbDevice in usbDevices">
<div class="block">
<form name="form{{usbDevice.id}}">
<!-- input fields -->
</form>
</div>
</li>
</ul>
How do I make that when any one of this forms shows up "ng-dirty" a "Save" button shows in the bottom? Do I need a watcher?
Save
You can wrap it all in ng-form , something like:
<body ng-controller="MainCtrl" ng-form="MainForm">
<ul class="small-block-grid-2 medium-block-grid-3 large-block-grid-4 usbDevices" >
<li ng-repeat="usbDevice in usbDevices">
<div class="block">
<form name="form{{usbDevice.id}}">
<input required ng-model="usbDevice.description" >
</form>
</div>
</li>
</ul>
<button ng-show="MainForm.$valid">Save</button>
</body>
Working: http://plnkr.co/edit/Z0CyyoqVHzs4ZV1F6uG4

Categories

Resources