I have a directive that host a template that takes in a JSON (that contain some data for building a table, and some method to manipulate the data) and generate a table.
relevant code in the template:
<table class="table" id="table_{{table.name}}">
<thead>
<tr>
<th ng-repeat="header in table.headers track by $index">{{header}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in table.rows track by $index">
<td ng-repeat="item in row track by $index"
ng-Click="table.selectedRow(row)">
{{item}}
</td>
</tr>
</tbody>
</table>
an example of a json being fed into this template
$scope.searchTable = {
headers: ["title", "deleted"],
rows: [ ["ABC", true],
["DEF", false] ],
[...]
}
My question is:
sometimes the table require a column with checkboxs, depending on the data. Is there any way to change my template so that when necessary it will generate a column of checkbox instead of just string?
For example: For the JSON example above, let's say I want the column of deleted to be checkboxes. So if an entry is deleted that row will have a unchecked checkbox under the deleted column.
Does this make any sense? Everything is generated dynamic, so I have no idea which column will be checkboxes. It all depends on the data the page gets from the server. So in the example: the server will tell client which entry is readable, then I will generate that JSON and feed it to the template. How should I structure my JSON and the template
Is this even doable? Any tips?
<tr ng-repeat="row in table.rows track by $index">
<td ng-repeat="item in row track by $index">
<div data-ng-if="item.type!=='checkbox'" ng-Click="table.selectedRow(row)"></div>
<div data-ng-if="item.type==='checkbox'"> <input type="checkbox" /></div>
{{item}}
</td>
</tr>
Related
$scope.values = [1,2,3,4,5,6,7]
How do I generate below html from the above data in the below format, using angular js. using ng-repeat etc..
<table>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td></td>
</tr>
</table>
This is one method:
JS:
$scope.values = [1,2,3,4,5,6,7];
HTML:
<table>
<tr ng-repeat="value in values" ng-if="$index % 2 == 0">
<td>{{values[$index]}}</td>
<td>{{values[$index+1]}}</td>
</tr>
</table>
Because the values is odd, the last will be empty. If you'd prefer to only output one TD when the values are odd you can simply add a ng-if to the TDs so that they are not displayed if they have no value.
Though, I would personally restructure the data before it gets to the view. Break the values apart into rows and then loop through the data set to get the rows, and then loop through the rows to get the individual values.
Far more information and options can be found (on SO already) here: How would I use AngularJS ng-repeat with Twitter Bootstrap's scaffolding?
I have a web app with a view that renders a list of items, where the user is intended to select multiple rows, by means of a checkbox at the start of each row, and then subsequently invokes an action on those rows. My question is: what is the best practice for making this accessible? My first-draft Html looks something like this (it uses Angular.js directives, but that is not of concern here).
<table>
<tbody>
<tr ng-repeat="item in collection.items">
<td class="checkbox">
<input type="checkbox">
</td>
<td tabindex="0">
{{item.title}}
</td>
</tr>
</tbody>
</table>
(My decision to use table, despite there being just one column other than the checkboxes, is because I also need a multi-column 'table' view of the same information. That is not my main concern here).
When I ran an accessibility-checker tool over this, it complained that the checkboxes had no label. But it doesn't strike me as sensible to add an artificial label (e.g. a row number) to it. Should I be using row-scope, perhaps, to make the check-box into a for the row?
You could add an unique id to each input and create a label for that input. $index is a ng-repeat iterator offset of the repeated element (0..length-1).
<table>
<tbody>
<tr ng-repeat="item in collection.items">
<td class="checkbox">
<input type="checkbox" id="{{'item-' + $index }}">
</td>
<td>
<label for="{{'item-' + $index}}">
{{item.title}}
</label>
</td>
</tr>
</tbody>
</table>
i am trying to filter my table data based on the input text, but some how it's not working. Kindly help please.
<div class="panel panel-default">
<div class="panel-heading">search
<input type="text" ng-model="search_text">
Searching for :: {{search_text}}
</div>
<Table>
<table class="table table-hover table-bordered">
<tr>
<td>Item ID</td>
<td>Quantity</td>
</tr>
<tr ng-repeat="item in items | filter:search_text">
<td>{{item.item[0] }}</td>
<td>{{item.item[1] }}</td>
</tr>
</table>
</div>
Please check for the version your angularjs you are using or any errors in console.
Your code seems to work and is correct indeed.
//array of items containing itemID and its quantity
$scope.items = [{
item:['chair',45]
},
{
item:['bed',23]
},
{
item:['laptop',8]
}]
Here's the working plunkr
The table data is indeed filtering with respect to value you enter in textbox
Since Angular 1.1.3 you can use:
<tr ng-repeat="item in items | filter:{item[0]: search_text}">
This will compare it to the object property item[0] in your object.
If you want the exact match, you can set the filtering to true by adding:
<tr ng-repeat="item in items | filter:{item[0]: search_text}:true">
I've got a simple repeating table-row in AngularJS
<tr ng-repeat="item in items">
<td>{{ item.prop1 }}</td>
<td>{{ item.prop2 }}</td>
</tr>
My item object has a comment property on it, and if that comment contains a value, I want to display that in a row all by itself on the line right after the rest of the elements and have it span the entire row. Is that type of thing possible? I looked at ng-repeat-end but that doesn't seem to be what I want, and I can't just add and extra <tr> element inside the ng-repeat as that'd be invalid HTML.
You can use ng-repeat's special repeat start and end points via ng-repeat-start and ng-repeat-end.
DEMO
HTML
<table ng-controller="PostController">
<tr ng-repeat-start="post in posts">
<td>{{post.content}}</td>
</tr>
<tr ng-repeat-end ng-repeat="comment in post.comments">
<td>{{comment.content}}</td>
</tr>
</table>
UPDATE: If the comment is a string, then simply remove the ng-repeat at the ng-repeat-end end point and add an ng-if expression that validates the existence of post.comment.
DEMO
HTML
<table ng-controller="PostController">
<tr ng-repeat-start="post in posts">
<td>{{post.content}}</td>
</tr>
<tr ng-repeat-end ng-if="post.comment">
<td>{{post.comment}}</td>
</tr>
</table>
I have an ng-repeat within a ng-repeat. I am tyring to obtain the index at both levels but am not able to :
<tbody>
<tr ng-repeat="element in body">
<td ng-repeat="h in header" style="width:{{h.width}}px">
<div col="{{$parent.$parent.$index}}" row="{{$parent.$index}}">{{element[h.column]}}</div>
<td>
</tr>
</tbody>
here is a plnkr too.
http://plnkr.co/edit/dGoN43HzQefVpCsp2R3j
The ISSUE is that value of "col" never gets populated. It does not capture the index.
Can anyone assist
You do not have to use $parent, just use $index to get index of inner loop and use indexOf() function of array to get index of outer loop...
HTML
<tr ng-repeat="element in body">
<td ng-repeat="h in header" style="width:{{h.width}}px">
<div col="{{body.indexOf(element)}}" row="{{$index}}">{{element[h.column]}}</div>
<td>
</tr>
UPDATE
Actually using ng-init would much better to get index of outer loop... here you can easily set rowIndex to current index at every turn and use it in inner loop...
<tbody>
<tr ng-repeat="element in body" ng-init="rowIndex = $index">
<td ng-repeat="h in header" style="width:{{h.width}}px">
<div col="{{$index}}" row="{{rowIndex}}">{{element[h.column]}}</div>
<td>
</tr>
</tbody>
here is updated PLUNKER