AngularJS: Table with ng-repeat on table row / column - angularjs

I need to create a table from an array of objects but I don't want to hardcode the table. I can't do this or this for example. I rather need nested ng-repeats like this. But my case is a little bit different because I have columns which contain two values in an array. The data looks like this:
[
{
"foo":"bar",...,
"key1":[
"value1",
"value2"
],
"key2":[
"value1",
"value2"
],...,
"more_foo":"more_bar"
},...
]
I want the values (which are always strings) of all objects (which have always an equal structure) from the array in the table rows where each key should be the column name. Like this:
table,
th,
td {
border: 1px solid black;
text-align: center;
border-spacing: 0;
}
td,
th {
padding: 0.5em;
}
<table>
<thead>
<tr>
<th>foo</th>
<th colspan="2">key1</th>
<th colspan="2">key2</th>
<th>more_foo</th>
</tr>
</thead>
<tbody>
<tr>
<td>bar</td>
<td>value1</td>
<td>value2</td>
<td>value1</td>
<td>value2</td>
<td>more_bar</td>
</tr>
</tbody>
</table>
Here is what I have come up with:
<table>
<thead>
<tr>
<th ng-repeat="(propName, prop) in myArray[0]"
colspan="{{isUpdateable(propName) ? 2 : undefined}}"> {{propName}}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="object in myArray | filter: searchFilter">
<td ng-repeat="(propName, prop) in object" double-col>{{prop}}</td>
</tr>
</tbody>
</table>
isUpdatable(propName) will return true if this value is an array and false if it is not. This will make it possible to have two tds in this column.
The double-col directive:
app.directive('double-col', function () {
return {
transclude: true,
template: "<td>{{prop[0]}}</td><td class=\"changedProp\">{{prop[1]}}</td>"
};
});
I want this directive to replace the existing td with two tds if and only if prop is an array and otherwise do nothing to display prop (see td above).
Because you are on https://stackoverflow.com (the place where people post things that dont't work well yet), you can probably guess that my current code doesn't not work really well. I am also new to angularJS and have basically no understanding of custom directives (and probably most other stuff too) so it would be nice if someone could help me with this problem and provide an explanation as well.

What about
<tr ng-repeat="object in myArray | filter: searchFilter">
<td ng-repeat="(propName, prop) in object" colspan="{{isArray(prop) ? prop.length : 1}}">
<span ng-if="!isArray(prop)"> {{prop}}</span>
<table ng-if="isArray(prop)"><tr>
<td ng-repeat="prop1 in prop">
{{prop1}}
</td>
</tr></table>
</td>
</tr>
$scope.isArray=function(prop){
return Array.isArray(prop);
}
Here is working fiddle

Related

ng repeat dynamic with key objet json AngularJS

I have a small problem I would like to set up a ng-repeat dynamic with the values I receive from my JSON object,
First, i made my th from my table with the keys
Secondly, i would like to do my td in dynamic (without putting the name of the key ex: obj.NOM, obj.TYPE ...)
I managed to do something with an Object.keys but logic is not good so I need some help
this is my JSON object ( i show you just the little piece of code that I have a problem )
"HEADER":[
{"NOM":"API-APP","TYPE":"string","DESCRIPTION":"Code application"},
{"NOM":"API-SIGNATURE","TYPE":"string","DESCRIPTION":"Signature de la requete API"},
{"NOM":"API-TIMESTAMP","TYPE":"integer","DESCRIPTION":"Timestamp en microseconde"}]
and this is my ng repeat
<span><b>HEADER</b></span>
<br>
<br>
<table class="table">
<th ng-repeat ="(key, itemHeader) in itemHead.HEADER[0] track by $index">{{key}}</th>
<tr ng-repeat ="(key, itemHeader) in itemHead.HEADER track by $index" >
<td>{{getFirstPropertyValue(itemHeader,$index)}}</td>
</tr>
</table>
I explain i made first a ng-repeat for th with the keys and I would like put my data (3 data per row) in td without put ( .NOM .TYPE .DESCRIPTION)
So I took the function object.key which works very well but that makes me just one element per row but I need 3 elements per row
this is my scope for the function object.key
$scope.getFirstPropertyValue = function(obj,index){
return obj[Object.keys(obj)[index]];
}
and this my result
thanks in advance for your help
<table class="table">
<thead>
<tr>
<th ng-repeat="(key, itemHeader) in itemHead.HEADER[0]">
{{key}}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in itemHead.HEADER">
<td ng-repeat="column in row">
{{column}}
</td>
</tr>
</tbody>
</table>

angular smart-table plugin/directive wont work

I am trying to use smart-tables, Select row plugin, I have added 'smart-table' to my application, like so var myApp = angular.module('myApp', ['ui.bootstrap','smart-table']);
I have also changed the first line of the directive (since it didn't work to just copy-paste it), I changed this:
ng.module('smart-table').directive('stSelectRow', ['stConfig', function (stConfig)
To this: myApp.directive('stSelectRow', ['stConfig', function (stConfig) {
In my html I have this
<table st-table="displayedCollection" st-safe-src="safeCollection" class="table">
<thead>
<tr>
<th>Title</th>
<th>FieldOne</th>
<th>FieldTwo</th>
<th>FieldThree</th>
</tr>
</thead>
<tbody>
<tr st-select-row="row" st-select-mode="multiple" ng-repeat="row in displayedCollection">
<td> {{row.Title}} </td>
<td> {{row.FieldOne}} </td>
<td> {{row.FieldTwo}} </td>
<td> {{row.FieldThree}} </td>
</tr>
</tbody>
If I remove the st-select-row="row" st-select-mode="multiple" the table works, but obviously not the row selection
I am guessing I'm missing some dependency or something, I have only added smart-table.min.js to my application, but I think that should be enough, the directive (select row plugin) is added inside my app.js file. What could it be?
It is because the documentation on the site isn't exactly clear. But it does say
...and the class attribute st-selected is set on the tr element.
You have to define the CSS for st-selected for it to "work":
.st-selected{
background: #216eff !important;
color: white !important;
}

Smart table: conditional st-sort attribute in ng-repeat

I am using Angular Smart Table and it is pretty good, but i faced with problem related to sorting:
let's assume that i have some columns definition and for each column i have information whether i can sort by this column or not:
$scope.columns = [
{
id: "id",
sortable: true
},
{
id: "type",
sortable: false,
}
];
In my html file i want to declare table headers with ng-repeat to avoid stupid refactoring when something in columns definition is changed. Somethig like that:
<table class="table" st-table="records">
<thead>
<tr>
<th ng-repeat="column in columns"> {{ column.title }} </th>
</tr>
</thead>
....
</table>
So my question is: how can i set attribute "st-sort" only for those columns, for which column.sortable is true?
I tried to use custom directive that adds this attribute depending on column.sortable and it actually adds it, but st-sort not works in this case (may be because this directive compilation is happening after table compilation, i have no idea...)
This should work:
<table st-table="records">
<thead>
<tr>
<th ng-repeat="column in columns" st-sort="{{(column.sortable) ? column.id : null}}">
{{column.id}}
</th>
</tr>
</thead>
...
</table>

Bind Table to item in array and repeat over instances

I have a class structure as follows
data
TeamList[]
PlayerList[]
So what I have is a list inside a list. I want to be able to filter the TeamList with the value from a dropdown value, and iterate over the items in Player list as Rows. I am confident on the 2nd part with the following.
<table style="border: 1px ">
<tbody>
<tr>
<td>Player Name</td>
<td>Position</td>
<td>Projected Points</td>
</tr>
<tr ng:repeat="e in data.Team.Roster | orderBy: '-ProjectedPoints' " ">
<td>{{e.Name}}</td>
<td>{{e.Position.Abbreviation}}</td>
<td>{{e.ProjectedPoints}}</td>
</tr>
</tbody>
</table>
But I am not sure how to get the "Team" in the above case to be correct. Is this something you can do in Angular, or are you better doing it on the JS side and pass the correct team back to the $scope?

table with ng-repeat not displaying correctly

Folks I am using a simple ng-repeat directive to display data in table.
However when the directive renders, the first column takes up all the space and dis-figures the table.
Take a look at the plnkr here :
http://plnkr.co/edit/Hahh4uyQ130zOS8noC3D
please focus on the file layout.html
<table>
<thead>
<tr ng-repeat="element in header" class="header-cells" style="width:{{element.width}}px">
<th drop-down-sort-menu>{{element.column}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="element in body">
<td ng-repeat="h in header" row="{{$parent.$index}}" col="{{$index}}" style="width:{{element.width}}px">{{element[h.column]}}
</td>
</tr>
</tbody>
</table>
I am sure it's something minor. any clues
I believe you problem is that for the headers, you have 4 TRs with only one TH, as opposed to one TR with 4 THs. For this reason, the cells on your headers are not matching the cells on your body.
Do the first ng-repeat at the TH level.
Give it a try and let me know.

Resources