How to get the row value from ng-grid in angular js - angularjs

How can I get a row value, when click cell in ng-grid?
example:
Name Number Class
X 123 A
Y 234 B
Z 345 C
A 456 D
When click on 123 cell or A cell or X cell, how can i get value X.
Please any help me. thanks in Advance

You should write ng-click of cellTemplate ng-click="clicked(row)"
Controller
$scope.clicked = function(row){
alert(row.getProperty("Name"));
};

One option - add an ng-click function on each row that returns the value in the first column.
HTML
<tr ng-repeat="item in items" ng-click="getVal(item)">
<td>{{item.name}}</td>
<td>{{item.number}}</td>
<td>{{item.class}}</td>
</tr>
Controller
$scope.getVal = function(item) {
alert(item.name);
}
Here's a working demo.

Related

Angular-filter omit with dynamic element from scope

JS:
var MyApp = angular.module('SOFdemo',['angular.filter']);
MyApp.controller('SOFCtrl',['$scope','$resource','$location',function($scope,$resource,$location){
$scope.serverSizeOptions = [
{"name":"20 Users","value":20},
{"name":"30 Users","value":30},
{"name":"40 Users","value":40},
{"name":"50 Users","value":50},
{"name":"60 Users","value":60},
{"name":"70 Users","value":70},
{"name":"80 Users","value":80},
{"name":"90 Users","value":90}];
}]);
I want to display on a table the possible options for a customer that subscribe to a max and min size. I'm using the directive angular-filter
I assigned the controller to my body.
The following ng-repeat directive usage on my partial HTML working well for a tr:
< tr ng-repeat="(key,value) in (serverSizeOptions | omit: value<20 | omit: value>50)">
< td>{{key}}
< td>{{value}}
< /tr>
Now, I would like to change 20 or 50 by my project size like:
< tr ng-repeat="(key,value) in (serverSizeOptions | omit: value<20 | omit: value> project.size.value)"> ...
But here, filter is not applied and I have all my list.
project.size.value is on my current scope.
I tried several configuration since hours and I'm starting to think that it's not possible to do what I'm expecting.
Any help will be appreciate.
You can use the filterFilter and define a function on your scope, that selects the valid values.
ng-repeat = "item in serverSizeOptions | filter:myFunction"
$scope.myFunction = function(item) { ..your logic here return a boolean }

How do I set a class based on a child element's state with Angular?

I am trying to display a results 'table' (built with DIVs as it happens) using Angular. Data looks somethingof it like this:
[['sydney','hotel','2','5','1'],
['sydney','bar','6','5','2'],
['sydney','stand','2','7','3'],
['melbourne','hotel','2','5','1'],
['melbourne','bar','8','0','1']]
What I want firstly is to suppress the repeating city name so that the first row says 'sydney' at the start but the second row and third row don't. Then the fourth says 'melbourne' and the fifth says nothing.
I've achieved this using markup like this:
<div class="row-container"
ng-repeat="row in resultsRows"
<div
ng-repeat="cell in row track by $index"
ng-bind="showValue( cell )">
</div>
</div>
The showValue() function in the controller looks like this:
$scope.currentCityName = '';
function showValue( val ) {
var outValue = '';
if (this.$index === 0) {
if (val === $scope.currentCityName) {
outValue = '';
} else {
$scope.currentCityName = val;
outValue = val;
}
} else {
outValue = val;
}
return outValue;
}
Maybe that's a bit clunky but it works and I get:
sydney hotel 2 5 1
bar 6 5 2
stand 2 7 3
melbourne hotel 2 5 1
bar 8 0 1
Now, though, I want rows that have the city name in them to have a different background colour.
What I think I want is for any 'TR' DIV (I call it that because it contains the left-floated 'TD' DIVs with the data points in them) to check if its first child DIV is not empty (because it has the city name in it) and, if so, to colour its background.
My question is: how do I do that with Angular? Or am I missing another trick..?
How do I get an item in an ng-repeat loop to interrogate a child element?
You are using ng-repeat, which has built-in values like $even and $odd:
$even boolean true if the iterator position $index is even (otherwise false).
$odd boolean true if the iterator position $index is odd (otherwise false).
Use ng-class to give different classed depending on $even and $odd.

AngularJS ng-repeat to populate grid from array

Thanks in advance for reading. I am trying to utilize angular's ng-repeat to render objects from an array into an Nx3 Table. For the sake of example let's consider a 3x3 table.
Here is a simplified example of the array:
objects = [{"text": "One, One"},{"text": "One, Two"},{"text": "One, Three"},
{"text": "Two, One"},{"text": "Two, Two"},{"text": "Two, Three"},
{"text": "Three, One"},{"text": "Three, Two"},{"text": "Three, Three"}];
The "text" field describes where in the 3x3 grid matrix each element should appear. I would like to use ng-repeat on objects to generate html that looks like this:
<table>
<tr>
<td>One, One</td>
<td>One, Two</td>
<td>One, Three</td>
</tr>
<tr>
<td>Two, One</td>
<td>Two, Two</td>
<td>Two, Three</td>
</tr>
<tr>
<td>Three, One</td>
<td>Three, Two</td>
<td>Three, Three</td>
</tr>
</table>
Is there any way to achieve this without needing to break up the array into separate arrays for each row?
Best possibly way would be to alter your view model in the controller and bind that to ng-repeat (But you already said you do not want to do that). If you ever plan to take that route you can also take a look at user #m59 answer where he creates a reusable filter to do it. However this is just a simple answer making use of built in filter's configurable evaluation expression where we can return truthy/falsy value to determine if they need to be repeated or not. This eventually has the only advantage of no need to create 2 ng-repeat blocks (But that is not so bad though). So in your controller add a function on the scope,
$scope.getFiltered= function(obj, idx){
//Set a property on the item being repeated with its actual index
//return true only for every 1st item in 3 items
return !((obj._index = idx) % 3);
}
and in your view apply the filter:
<tr ng-repeat="obj in objects | filter:getFiltered">
<!-- Current item, i.e first of every third item -->
<td>{{obj.text}}</td>
<!-- based on the _index property display the next 2 items (which have been already filtered out) -->
<td>{{objects[obj._index+1].text}}</td>
<td>{{objects[obj._index+2].text}}</td>
</tr>
Plnkr
I wanted to do the exact same thing.
Convert an array into a matrix/ grid
I have an array which i wanted to convert into a grid/matrix of column size 4. the following implementation worked for me. You can use the two counters : row and col as you like in side the nested ng-repeat
In my case number of columns is 3. But you can replace that 3 with a variable everywhere. h.seats is my array of the objects and i want to print either X or - based on value of element in that array
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th ng-repeat="n in [].constructor(3 + 1) track by $index">{{$index}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(row, y) in getNumber(h.seats.length, 3) track by $index">
<td>{{row+1}}</td>
<td class="text-primary"
ng-repeat="(col, t) in h.seats track by $index"
ng-if="col >= (row)*3 && col < (row+1)*3">
<span ng-show="t.status"> X </span>
<span ng-show="!t.status"> - </span>
</td>
</tr>
</tbody>
</table>
</div>
<th ng-repeat="n in [].constructor(3 + 1) track by $index">{{$index}}</th> prints the header row with column number at the top. getNumber(h.seats.length, 3) returns me the number of rows of that table as follows
.controller('CustomViewController', function ($scope, Principal, $state) {
$scope.getNumber = function(length, columns) {
return new Array(parseInt(length / columns + 1, 10));
}
The line ng-if="col >= (row)*3 && col < (row+1)*3" is important logic to calculate which elements should be put in that row.
The output looks like below
0 1 2 3
1 e1 e2 e3
2 e4 e5 e6
3 e7 e8
Refer to following link for details of how row and col counters are used:
https://stackoverflow.com/a/35566132/5076414

Ng-Repeat array to rows and columns

Thanks for taking the time to read this, I was wondering how I might be able to use ng-repeat to create a grid like box of options. I would like to take an array repeat nth number of items and then move to the next row or column until all items are listed. e.g.
assuming I had an array like [opt1,opt2,opt3,opt4,opt5,opt6,opt7] I would like to display it like this:
opt1 opt2 opt3
opt4 opt5 opt6
opt7
This is more a styling/markup problem than an AngularJS one. If you really want to, you can do:
<span ng:repeat="(index, value) in array">
{{value}}<br ng:show="(index+1)%3==0" />
</span>
http://jsfiddle.net/JG3A5/
Sorry for my HAML and Bootstrap3:
.row
.col-lg-4
%div{'ng:repeat' => "item in array.slice(0, array.length / 3)"}
{{item}}
.col-lg-4
%div{'ng:repeat' => "item in array.slice(array.length / 3, array.length * 2/3)"}
{{item}}
.col-lg-4
%div{'ng:repeat' => "item in array.slice(array.length * 2/3, array.length)"}
{{item}}
There is another version, with possibility to use filters:
<div class="row">
<div class="col-md-4" ng-repeat="remainder in [0,1,2]">
<span ng-repeat="item in array" ng-if="$index % 3 == remainder">{{item}}</span>
</div>
</div>
If all of your items are in one single array, your best bet is to make a grid in CSS. This article should be helpful: http://css-tricks.com/dont-overthink-it-grids/
You can use $index from ng-repeat to apply the correct class for your column (in this case a 4 column grid):
<div class="col-{{ $index % 4 }}"></div>
If you have a 2 dimensional array (split into rows and columns) that opens up more possibilities like actually using an HTML table.
I find it easier to simply use ng-repeat combined with ng-if and offsetting any indexes using $index. Mind the jade below:
div(ng-repeat="product in products")
div.row(ng-if="$index % 2 === 0")
div.col(ng-init="p1 = products[$index]")
span p1.Title
div.col(ng-if="products.length > $index + 1", ng-init="p2 = products[$index + 1]")
span p2.Title
div.col(ng-if="products.length <= $index + 1")
Between Performance, Dynamics and Readability
It seems putting the logic in your JavaScript is the best method. I would just bite-the-bullet and look into:
function listToMatrix(list, n) {
var grid = [], i = 0, x = list.length, col, row = -1;
for (var i = 0; i < x; i++) {
col = i % n;
if (col === 0) {
grid[++row] = [];
}
grid[row][col] = list[i];
}
return grid;
}
var matrix = listToMatrix(lists, 3);
console.log('#RedPill', matrix);
# Params: (list, n)
Where list is any array and n is an arbitrary number of columns desired per row
# Return: A matroid
# Note: This function is designed to orient a matroid based upon an arbitrary number of columns with variance in its number of rows. In other words, x = desired-columns, y = n.
You can then create an angular filter to handle this:
Filter:
angular.module('lists', []).filter('matrical', function() {
return function(list, columns) {
return listToMatrix(list, columns);
};
});
Controller:
function listOfListsController($scope) {
$scope.lists = $http.get('/lists');
}
View:
<div class="row" ng-repeat="row in (lists | matrical:3)">
<div class="col col-33" ng-repeat="list in row">{{list.name}}</div>
</div>
With this, you can see you get n number of rows -- each containing "3" columns. When you change the number of desired columns, you'll notice the number of rows changes accordingly (assuming the list-length is always the same ;)).
Here's a fiddle.
Note, that you get the ol' Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!. This is because Angular is recalling the matrical function upon every iteration. Allegedly, you can use the as results alias to prevent Angular from reevaluating the collection, but I had no luck. For this, it may be better to filter the grid inside of your controller and use that value for your repeater: $filter('matrical')(items) -- but please post back if you come across an elegant way of filtering it in the ng-repeat.
I would stress, again, you're probably heading down a dark alley by trying to write the logic in your view -- but I encourage you to try it in your view if you haven't already.
Edit
The use of this algorithm should be combined with a Matrical Data-Structure to provide methods of push, pop, splice, and additional methods -- in tandem with appropriate logic to complement Bi-Directional Data-Binding if desired. In other words, data-binding will not work out of the box (of course) as when a new item is added to your list, a reevaluation of the entire list must take place to keep the matrix's structural integrity.
Suggestion: Use the $filter('matrical')($scope.list) syntax in combination with $scope.$watch and recompile/calculate item-positions for the matrix.
Cheers!

AngularJS - ngRepeat and ngModel

I have spent the better part of a few hours writing and re-writing this, and am probably just going to write my own directive here if there isn't an answer.
I have a columnized display of inputs, 10 in each of the 6 columns. I am using 2 ngRepeat directives to display them. I am placing 6 fiddles below with my varied attempts at getting them to work right. The problem is, when I use an array of objects, all the data are updated simultaneously. View Fiddle #1 below to see the example.
Here is a quick snippet of the code, which you can also see on the fiddle page. If anyone has some pointers or a way to get #1, #2, or #6 to work, please let me know!
HTML:
<div ng-controller='EntryCtrl'>
<div class="span2" ng-repeat="a in [0,1,2,3,4,5]">
<div ng-repeat="i in entry.slice($index*10, ($index*10)+10)" ng-class="{'control-group': true, error: !entry[($parent.$index*10)+$index].correct}">{{($parent.$index*10)+$index}}<input type="text" class="span12" id="entry-{{($parent.$index*10)+$index}}" ng-model="entry[($parent.$index*10)+$index].input" /></div>
</div>
</div>
Javascript:
var myApp = angular.module('myApp', []);
myApp.controller('EntryCtrl', ['$scope', function($scope) {
$scope.entry=filledArray(60,{input:'',correct:true});
}]);
function filledArray(len, val) {
var rv = new Array(len);
while (--len >= 0) {
rv[len] = val;
}
return rv;
}
Fiddle #1: Array of objects using ng-model pointing to entry using $index and $parent.$index: http://jsfiddle.net/DFEkG/ -- All models update simultaneously
Fiddle #2: Array of objects using ng-model pointing to i instead of $index: http://jsfiddle.net/DFEkG/1/ -- All models update simultaneously
Fiddle #3: Array using ng-model pointing to entry using $index and $parent.$index: http://jsfiddle.net/DFEkG/2/ -- Weird behavior
Fiddle #4 Array using ng-model pointed to i instead of $index: http://jsfiddle.net/DFEkG/3/ -- Broken
Fiddle #5 Array using only $index and $parent.$index and array only in ng-repeat directive: http://jsfiddle.net/DFEkG/4/ -- WORKS! But not as object
Fiddle #6 Same as technique as 5, but with an object: http://jsfiddle.net/DFEkG/5/ -- Same as fiddles 1 and 2
The problem is in your filledArray function. It assigns the same exact object to each array item. The same object {input: '', correct: true} is referenced in all 60 instances.
So, to fix it you can simply make a new copy of it on each iteration:
function filledArray(len, val) {
var rv = new Array(len);
while (--len >= 0) {
rv[len] = angular.copy(val);
}
return rv;
}
Fiddle.

Resources