How to pass or reference $index in the controller - angularjs

In the view (html file) I have:
<tr ng-repeat="task in ctrl.model.unplannedTasks">
<td>{{::$index + 1}}</td>
</tr>
How can I reference $index + 1 value in my controller?
I have tried doing this:
<tr ng-repeat="task in ctrl.model.unplannedTasks" ng-init="myIndex = $index + 1">
<td ng-model = "myIndex">{{myIndex}}</td>
</tr>
And then reference it in the controller with myIndex, but it is undefined.
[EDIT]
$index + 1 is the row number in the table. I would like to reference a current value of the specific row in order to be able to put it in the message like:
Are you sure you want to delete row e.g. 5? (this message is generated inside the controller)

In controller if it is use as value or otherwise use as array:
angular.module('rock').controller('test',['$scope',function($scope){
$scope.myIndex=0;
$scope.unplannedTasks="you can define your object here";
}]);
In view:
<tr ng-repeat="task in unplannedTasks">
<td myIndex={{::$index + 1}}></td>
</tr>

I just had to pass it as it is $index+1 to the function in which the message is generated.
<tr ng-repeat="task in ctrl.model.unplannedTasks">
<td>{{::$index + 1}}</td>
</tr>
...
<button type="button" class="btn btn-primary btn-xs" ng-click="ctrl.openModal(task, $index + 1)" title="{{::msg.common.button.remove}}">{{::msg.common.button.remove}}</button>

Related

ng-class mix string with angular annotation

If I use this code
<td ng-class="'log-level-' + {{log.level | uppercase}}">
This is the rendered result:
<td ng-class="'log-level-' + WARN" class="log-level-">
If I remove the double brackets
<td ng-class="'log-level-' + log.level">
The rendered result is
<td ng-class="'log-level-' + log.level" class="log-level-Warn">
Is it not possible to uppercase the second log.level property in HTML and mix it with a string?
//EDIT//
NEVER MIND. Typing out the question made me realize I could use wrap the angularjs expression in a string.
<td ng-class="'log-level-' + '{{log.level | uppercase}}'">
I thought this would just render the {{log.level | uppercase}} value as a string but it still processes the expression first.
Typing out the question made me realize I could use wrap the angularjs expression in a string.
<td ng-class="'log-level-' + '{{log.level | uppercase}}'">
I thought this would just render the {{log.level | uppercase}} value as a string but it still processes the expression first.
<td class="static-class {{log.level}}">
Test
</td>
I added sample app also check Fiddler
<div ng-controller="testCtrl">
{{test}}
<table>
<tr>
<td class="static-class">
Test
</td>
</tr>
<tr>
<td class="static-class {{runtimeClass}}">
Test
</td>
</tr>
</table>
<button type="button" ng-click="addRuntimeClass()">
click
</button>
</div>
var app = angular.module('testApp',[])
app.controller('testCtrl',['$scope',
function($scope){
$scope.test='Sample test app';
$scope.addRuntimeClass = function(){
$scope.runtimeClass = 'runtime-class'
}
}])
.static-class{
display:block;
color:black;
}
.runtime-class{
display:block;
color:red;
}

AngularJs - allow only one item to be selected in Table

I am using smart table. I have a logic behind where I only need one item to be selected. My current table code allow multiple lines to be selected.
This is my HTML:
<table st-safe-src="flow3.dataSet" st-table="flow3.displayed" class="table table-striped">
<thead>
<tr>
<th st-sort="method">Method</th>
<th st-sort="sample">Sample</th>
<th st-sort="parameters">Parameters</th>
</tr>
</thead>
<tbody ui-sortable ng-model="flow3.displayed">
<tr ng-repeat="row in flow3.displayed track by $index" style="cursor: move;" ng-click="row.selected = !row.selected; flow3.selectRow($event, row)" ng-class="{success: row.selected}">
<td>{{row.method.name}}</td>
<td>{{row.sample}}</td>
<td>
<span ng-repeat="parameter in row.parameters">{{parameter.methodInputParameter.name}} : {{parameter.value}}<br/></span>
</td>
<td>
<button type="button" ng-click="flow3.removeItem(row)"
class="btn btn-danger btn-sm btn-round pull-right"
ng-disabled="flow3.confirmDisabled">
<i class="glyphicon glyphicon-trash"></i>
</button>
</td>
</tr>
</tbody>
</table>
This is my JS:
flow3.selectRow = function($event, row) {
flow3.selectedItem = row;
}
If you want the only one row with selected property set to true, you should modify your selectRow method to accept the collection of all rows and then de-select all before selecting clicked one:
flow3.selectRow = function($event, row, rows) {
//de-select all
angular.forEach(rows, function(r){ r.selected = false; });
//select clicked
row.selected = true;
flow3.selectedItem = row;
}
ng-click="flow3.selectRow($event, row, flow3.dataSet)"
If you want to apply different css class to the clicked/selected item you probably can leave your selectRow method as is (since we have the selected item as flow3.selectedItem) and change the condition in the ngClass directive to be (if rows have some unique id property for example):
ng-class="{success: row.id === flow3.selectedItem.id}"
Hope this helps.
I'd recommend looking at the smart table github page and use guide here.
In particular the section relevant to your question is 'Select Data Rows'.
Essentially you need to use the st-select-row attribute along with the st-select-mode to configure click within your table row (tr) elements.

Ng-repeat - What is the right syntax to send the user to its dynamic id?

So, in my object index I'm working inside a ng-repeat.
Now, when I click on an object, it should go to its matching id.
How would I do this with Angular?
I got something like this now:
<tr ng-repeat="dossier in dossiers">
<td>
#{{dossier.license_plate}}
</td>
</tr>
Why don't you try ngHref directive
<tr ng-repeat="dossier in dossiers">
<td>
<a ng-href="/dossiers/{{dossier.id}}">#{{dossier.license_plate}}</a>
</td>
<a ng-href="http://www.gravatar.com/avatar/{{hash}}">link1</a>
https://docs.angularjs.org/api/ng/directive/ngHref

$index always 0 when using ng-bind-html

I have a directive that contains this markup
<tr ng-if="isComplete()" ng-repeat="row in paged.page() track by $index" ng-click="rowClick(row, $event)" ng-class="assignRowClass(row)">
<td ng-repeat="header in headers" ng-bind-html="trustAsHtml(header.formatter(row[header.property], row, $index))"></td>
</tr>
The problem is that $index is always 0 when passed to the header.formatter function.
try this
<tr ng-if="isComplete()" ng-repeat="(index,val) in paged.page() track by index" ng-click="rowClick(val, $event)" ng-class="assignRowClass(val)">
<td ng-repeat="header in headers" ng-bind-html="trustAsHtml(header.formatter(val[header.property], val, index))"></td>
As saw in my comment this works
$parent.$index
This is because of the new scope created by ng-if and the limit of inheritance between scope in angular (because of javascript limits).
You can either go for $parent.$index of move the ng-if to the upper DOM Element if possible (<thead> / <tbody).

Can ng-model update another ng-model?

This is my code:
<table ng-init="liveTotal={}">
<tr ng-repeat="x in sovCtrl.topics" >
<td> {{x}}</td>
<td><input ng-model="sovCtrl.objects[x]" type="number"></td>
<td ng-hide="true">
<input ng-model="liveTotal[$index]" type="number" value="{{sovCtrl.objects[x]}}">
</td>
</tr>
</table>
<div > Current Result:
{{ 0 + liveTotal[0] + liveTotal[1] + liveTotal[2] + liveTotal[3] + liveTotal[4]}}
</div>
What I'm trying to do is have a live result of the sum of all the Inputted topic values(there will never be more than 5) without using $scope or any extra sovCtrl methods/objects or adding a script;
The topics are strings I can't predict.
The 2nd input CHANGES when I type into the first input, but the result in the div does not.
The result in the div changes only when I type or press on the 2nd input(if I make it visible)
Can this be done using angular but modifying only the above HTML?
Edit: sovCtrl.objects gets passed into functions that graph the values. Modifying the the keys would break those functions.
Why don't you directly do something like shown below
wherein you directly use the first input
You just add an index (which is provided in ng-repeat of any variable) and now you can access values by using index 0,1,2,3,4
<table ng-init="liveTotal={}">
<tr ng-repeat="(i,x) in sovCtrl.topics" >
<td> {{x}}</td>
<td><input ng-model="sovCtrl.objects[x]" ng-change="sovCtrl.objects_yo[i]=sovCtrl.objects[x]" type="number"></td>
</tr>
</table>
<div> Current Result:
{{ 0 + sovCtrl.objects_yo[0] + sovCtrl.objects_yo[1] + sovCtrl.objects_yo[2] + sovCtrl.objects_yo[3] + sovCtrl.objects_yo[4]}}
</div>
Got it, this works.
<table ng-init="liveTotal={}">
<tr ng-repeat="x in sovCtrl.topics" >
<td> {{x}}</td>
<td><input ng-model="sovCtrl.objects[x]" type="number"></td>
<td ng-show="false"> {{ liveTotal[$index]= sovCtrl.shareOfVoice[x]}}</td>
</tr>
</table>
<div > Current Result:
{{ 0 + liveTotal[0] + liveTotal[1] + liveTotal[2] + liveTotal[3] + liveTotal[4]}}
</div>

Resources