I start to play with angularjs, and having this data model :
friends = [
{name:'John**amine**allo'},
{name:'Mary**aaa**mmm'},
{name:'Mike**bb**kkk'}
]
I would like to split each name by '**' to create a table of names.
I don't know if there is more straightforward way to do this ( maybe using some filter in angular-filter module) but here what I have so far tried:
<table id="searchObjResults">
<tr><th>Name</th></tr>
<tr ng-repeat="x in friends">
<td ng-repeat="y in x.split('**')">
{{y}}
</td>
</tr>
thanks in advance for any help.
You need to split name property if the x elements:
<td ng-repeat="y in x.name.split('**')">{{y}}</td>
However this is probably not very good idea what you are trying to do. First of all, you need to take care of proper table structure (correct header colspan values). Secondary, it's better to render already processed data structure, rather then converting values inside templates. It just makes it overcomplicated, not to mention makes watch expression slower.
Demo: http://plnkr.co/edit/5PXTW1gjpKwg7e3S6hRM?p=preview
You can use a custom filter to specify the separator:
<table id="searchObjResults">
<tr><th>Name</th></tr>
<tr ng-repeat="x in friends">
<td ng-repeat="y in x.name | mysplit:'**'">
{{y}}
</td>
</tr>
</table>
JS:
app.filter('mysplit', function() {
return function(data, sep) {
return data.split(sep);
}
});
Plunker
Related
What I am working on is to perform sort operation in a table on a single or multiple columns. Let's assume that we have a table like this.
On clicking on Heading 1 only the Data 1 and Data 2 should be sorted when clicking on the Heading 2 the Data 3 and Data 4 need to be sorted.
Have implemented simple sort for the table in Angular, but cannot get an idea how to implement this one with two sets of data in a single column.
Even tried separate tables since the order by in Angular is based on the key in the array, both(Data 1,2,3 & 4) are getting updated when clicking on the Heading 1.
ng-repeat is used to form the table
Can anyone point me in the right direction(on Angular 1.x)?
Sample Fiddle http://jsfiddle.net/ANEA6/13/
The problem is that you're using the same variable to handle the reverse!
<div ng-controller="MyCtrl">
<table class="table">
<tr class="heading">
<td ng-click="reverse1=!reverse1;predicate1='id'">id</td>
</tr>
<tr ng-repeat="user in users | orderBy:predicate1:reverse1">
<td>{{user.id}}</td>
</tr>
<tr class="heading">
<td ng-click="reverse2=!reverse2;predicate2='id'">id</td>
</tr>
<tr ng-repeat="user in users | orderBy:predicate2:reverse2">
<td>{{user.id}}</td>
</tr>
</table>
</div>
You can check this working fiddle ==> http://jsfiddle.net/ANEA6/17/
Why don't you create a separate scope variable for each <tr> where there is id inside the <td> like this
<div ng-controller="MyCtrl">
<table class="table">
<tr><td ng-click="reverse1=!reverse1;predicate1='id'">id</td></tr>
<tr ng-repeat="user in users | orderBy:predicate1:reverse1">
<td>{{user.id}}</td>
</tr>
<tr><td ng-click="reverse2=!reverse2;predicate2='id'">id</td></tr>
<tr ng-repeat="user in users | orderBy:predicate2:reverse2">
<td>{{user.id}}</td>
</tr>
</table>
</div>
Controller
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.users = [
{id:1},
{id:2}
]
}
This should work in your case as i do not see the <td> with id being generated dynamically. It is hard coded to two rows with id. The other <tr> following the id <tr> are dynamically generated using ng-repeat so this should be fine.
For your simplicity here is the working link to JSFIDDLE
How can one apply conditional grouping in an Angular ng-repeat directive?
For example, in the below code, I want to groupBy:'var1', but only when some variable, or expression, dontGroup evaluates to true. I don't want to have the bottom tr row duplicated specifically for the dontGroup variable in my HTML because the information cannot be loaded in via a template for a second tr due to the main table being controlled by a directive and needing the template in the DOM before initialization. If there's a way to do this that I'm overlooking, please let me know. I'm utilizing ng-table.
<table>
<tr ng-repeat-start="(key, data) in $data | groupBy:'var1'">
<td ng-bind="key">
<!-- Grouped header info here. -->
</td>
</tr>
<tr ng-repeat-end ng-repeat="item in data"> <!-- Repeat $data when `dontGroup` evaluates to true,
otherwise repeat pre-grouped data from the `groupBy` filter above -->
<td ng-bind="item.var2">
<!-- Individual item info here. -->
</td>
</tr>
</table>
So, I want the lower ng-repeat function to repeat $data as data only when dontGroup evaluates to true, but otherwise I want $data to be run through the groupBy filter such that the data can have a header for the group.
I also cannot just drop an ng-if on the header row when dontGroup evaluates to true because I need the data to sort by other variables such as var2, var3, etc, and not have the var1 grouping affect that.
A fiddle for you to play with showing both wanted functionalities.
You can set the groupBy to reference a function and in the controller you can do a custom groupBy that will check for an indicator of how to group. Please see the following docs for more information.
http://ng-table.com/#/grouping/demo-api
Here is a rough attempt which should show the concept.
http://jsfiddle.net/wwgo4eo4/
//template
<input type="checkbox" ng-click="clickGroupBY()"/>
<table>
<tr ng-repeat-start="(key, data) in $data | groupBy:valueGroupBY">
//controller
$scope.willgroupby = true;
$scope.valueGroupBY = function(group) {
if($scope.willgroupby) {
return group.var1
}
return group.var2
}
$scope.clickGroupBY = function clickGroupBY() {
$scope.willgroupby = !$scope.willgroupby;
}
UPDATE
I ran with the solution you came back with here and cleaned it up. see the following: http://jsfiddle.net/r1mss7s0/1/
I also found this to be informative about the filters you are using:
https://github.com/a8m/angular-filter/wiki/Common-Questions
Here I'm setting a conditional on the header row and returning a dummy object when dontGroup evaluates to true. It does mean, however, that var1 can't be equal to "test" in the grouped array, else the header won't be shown. "test" will just be a protected value.
Further, you could use this syntax with other filters when off of the grouping, as shown below.
<table>
<tr ng-repeat-start="(key, data) in (dontGroup ? {'test': $data} : ($data | groupBy:'var1'))" ng-if="key != 'test'">
<td ng-bind="key">
</td>
</tr>
<tr ng-repeat-end ng-repeat="item in data | orderBy: 'var2')">
<td ng-bind="item.var2">
</td>
</tr>
</table>
Fiddle
Check John Babb's answer for offloading some of this logic into the controller!
I want to add sorting functionality on date header, I added orderBy filter but it's breaking the column.
How can I add sorting to date header? I would like for it to be possible for the user to click the header, which should change the sorting order.
main.html
<table>
<tr>
<th>File</th>
<th>{{date | orderBy: file.fileStat}}</th>
<th>Download</th>
</tr>
<tr ng-repeat="file in data">
<td>{{file.filename}}</td>
<td>{{file.fileStat |date : "dd.MM.y"}}</td>
<td><button type="button" class="btn btn-primary" ng-click="downloadServerFile(file.filename)">download</button></td>
</tr>
</table>
A few errors in the syntax you've attempted, but you've made a good start.
The first error is that the orderBy: applies only to the ng-repeat directive.
Let's first change <th>{{date}}</th>.
Next, let's look at ng-repeat. There's two things which are of use to us. See: OrderBy.
So we can tell it, using a String, which field to sort on, and with a boolean, whether to reverse the order or not. We can try something such <tr ng-repeat="file in data | orderBy: 'fileStat': false">.
We should also set the boolean to a variable, such that we can keep track of when the user changes it.
<tr ng-repeat="file in data | orderBy: 'fileStat': reversed">
Finally, let's have an ng-click, to allow the user to change the order. In this example, I am going to set it on the <th>.
<th ng-click="reversed = !reversed">{{date}}</th>
Please try this and let me know if you run into any errors.
I have a .json with unknown attributes and want to graph them. In my controller I have already extracted the headers and saved them as table_headers, from the doubleObjects Object. The data looks like this:
$scope.items = {[
...,
{doubleObjects: [{...}, {...}, ...]},
...,
]};
This is what I'm trying to output:
<table style="width:100%" border="1px solid black">
<tr>
<th ng-repeat="y in table_headers">{{y}}</th>
</tr>
<tr ng-repeat="x in items.doubleObjects">
<td ng-repeat="y in table_headers">{{x.y}}</td>
</tr>
</table>
So I would like the entire doubleObjects object to be tabulated. It wont let me do:
{{x.y}}
If I do:
{{x.measurement}}
or another attribute that is in doubleObjects then its all fine. But I cant ensure that the "measurement" attribute will be there. (For my test data it is.)
Thoughts and suggestions are most welcome.
You should not use x and y that way {{x.y}} use it this way {{x[y]}} or like the other way shown in this jsfiddle which shows both possibilities. I stated both possibilities, as I didn't really understood what you are looking for and I'm not allowed to comment your post.
<tr ng-repeat="x in items.doubleObjects">
<td ng-repeat="y in table_headers">{{x.measurement}}.{{y}}</td>
<td ng-repeat="y in table_headers">{{x[y]}}</td>
</tr>
I just stepped into the AngularJS world, and need a solution for the application I am working on.
So here is the definition of the module.
var samplesApp = angular.module('samples', []);
samplesApp.controller('samplesController', function ($scope) {
var jsonObj=
[
{"ACTION":"UPDATE","ID":"22","ROUTE":"0015"},
{"ACTION":"DELETE","ID":"20","ROUTE":"0015"},
{"ACTION":"UPDATE","ID":"19","ROUTE":"0015"}
]
$scope.records = jsonObj;
var columnNames = [];
for (var key in jsonObj[0]) {
columnNames.push(key);
}
$scope.columnNames = columnNames;
});
The $scope JSON object is a part of the output of the real data that comes from database. and I need to put these data into a table dynamically
The html is like
<table>
<thead>
<th data-ng-repeat="column in columnNames">{{column}}</th>
</thead>
<tr data-ng-repeat="record in records">
<td data-ng-repeat="column in columnNames">{{ record.{{ column }} }}</td>
</tr>
</table>
Because I have no idea what the column name is, so I made a process to get all the column names and push them into $scope.columnNames. and then bind it to the table header. There is no problem for this part. The issue is I don't know how to get the value coresponse to the specific column. I was trying to do it like this:
<td data-ng-repeat="column in columnNames">{{ record.{{ column }} }}</td>
But apparently it is not working.
Can someone give me some advice? really appreciate it.
Try using brackets, like this:
<tr data-ng-repeat="record in AllRecords">
<td data-ng-repeat="column in columnNames">{{ record[column] }}</td>
</tr>
The expressions inside {{ }} (moustaches?) are evaluated pretty narrowly to how regular javascript is evaluated.
Accessing with the record[column] operator is OK, but
you could try this other alternative. In this example, the semantics
of the code is a bit better, and you have less coupling (your rows just
depend on the data, not the variable used in the header):
<table>
<tr>
<th data-ng-repeat="column in columnNames">{{column}}</th>
</tr>
<tr data-ng-repeat="record in records">
<td data-ng-repeat="(key,value) in record">{{value}}</td>
</tr>
</table>
Here's the working example with your data: http://plnkr.co/edit/CskLQ2ZZlYIURdNPXiZt?p=preview
Here's the Angular docs for the ngRepeat directive (look for "key, value")