Using rowspan in table with AngularJS - angularjs

I want to insert a table with two columns where the first column contains several rows and second column should contain a single row. To achieve this I wrote code like below.
<tr ng-repeat="x in data">
<td>{{ x.no }}</td>
<td ng-if="this.rowIndex === 0" rowspan='{{x.length}}'> ok </td>
</tr>
Where data is an array of JSON objects containing single property called no. Using this.rowIndex is correct here or Am I making mistake here.

You have to use the variable $index from the ng-repeat directive (see the documentation).
Furthermore, you read the length of the x object; I believe you intended to do so with the data variable.
You can see the result in this codepen.

Related

How to make a table sort-able while the whole components is passed as string via ng-bind-html in AngluarJS

Hi I have a situation in AngluarJS that the HTML is generated by back-end and the only thing that front-end should do is to put the HTML which is mostly table tags into the ng-bind-html and show it to the user. But now these tables should be sort-able too. How can I do it?
The thing that I've already done is to create my own directive using this so make the static string HTML take some actions too. But having them sorted is something else. In other word I want to make my fully generated table with all <tr> and <td> to get sorted by my actions.
Here is my simplified code (compile is my directive):
JS:
// The string is fully generated by back-end
$scope.data.html =
'<table> <tr> <th ng-click="sortByHeader($event)"> Name </th>
<th ng-click="sortByHeader($event)"> Age </th> </tr>
<tr> <td> Sara </td> <td> 15 </td> </tr>
<tr> <td> David </td> <td> 20 </td> </tr>'
HTML:
<div compile="data.html"></div>
The ng-click="sortByHeader($event) is something that back-end can prepare for me so I can use it thanks to the compile I wrote that let me find out which header has been clicked. Other than that there is nothing I can do. Unless you can help me :D
Thanks in advance, I hope my question was clear.
Since you tagged your question with sorttable.js I'm going to assume that you are using that script to sort your tables.
Now, if I understand it correctly, sorttable.js parses your HTML for any tables with the class sortable. Your table is apparently loaded dynamically, therefore sorttable.js does not know about it when it parses the HTML.
But you can tell it to make a dynamically added table sortable, too.
Relevant part taken from the following page:
https://kryogenix.org/code/browser/sorttable/#ajaxtables
Sorting a table added after page load
Once you've added a new table to the page at runtime (for example, by
doing an Ajax request to get the content, or by dynamically creating
it with JavaScript), get a reference to it (possibly with var
newTableObject = document.getElementById(idOfTheTableIJustAdded) or
similar), then do this:
sorttable.makeSortable(newTableObject);
You should be able to do that with angular. If not, I can try to put something together later.
Is the answer to the question "Does the rendered table have to exactly match the HTML retrieved by the backend?" a kind of "No"?
If that's the case, then here's a hacky way of gaining control of the table contents by parsing and capturing stuff from the backend HTML string using regular expressions.
For example: grab all row data and apply sorting client side
// Variables to be set by your sortByHeader functions in order to do client-side sorting
$scope.expression = null;
$scope.direction = null;
var regexToGetTableHead = /<table>\s*(.*<\/th>\s*<\/tr>)/g;
$scope.tableHead = regexToGetTableHead.exec($scope.data.html);
$scope.tableRows = [];
var regexToGetRowContents = /<tr>\s*<td>\s*(\w*)\s*<\/td>\s*<td>\s*(\w*)\s*<\/td>\s*<\/tr>/g;
var match;
while ((match = regexToGetRowContents.exec($scope.data.html)) != null) {
$scope.tableRows.push({
"name": match[1],
"age": match[2]
});
}
And HTML
<table>
<thead compile="tableHead"></thead>
<tbody>
<tr ng-repeat="row in tableRows | orderBy: expression : direction">
<td>{{row.name}}</td>
<td>{{row.age}}</td>
</tr>
</tbody>
</table>

Does bind-once in Angular cause problems when elements are added/removed from a collection?

Let's say I'm populating a table with a collection. Since I'm just displaying text I don't need Angular to put watches on everything I populate the table with and I use bind once. What happens when I update my collection by adding/removing elements? Does bind once prevent angular from evaluating newly added elements? Are there any pitfalls I need to be aware of?
Example: Will isDeleteable be evaluated for newly added elements?
<table>
<tr ng-repeat="myElement in myCollection">
<td>{{ ::myElement.Title }}</td>
<td>{{ ::myElement.UploadedDate }}</td>
<td ng-if="::isDeleteable(myElement)"><button type="button" ng-click="deleteElement(myElement)">Delete</button></td>
</tr>
</table>
It will work fine, angular will always watch myCollection.
And what you've done is a good practice :)

AngularJs - Dynamic rows in table

I have two table, table 1 and table 2.. Table 1 has a field count. based on the count value(count value= no of rows populated), rows should be automatically populated in table 2. I am new to angularjs. Please let me know how can acheive this
To render values in your table you can use ng-repeat directive.
You can use things such the ngIf, ngShow and ngHide directive to hide or show DOM objects based on an expression, or use ngRepeat to dynamically add additional DOM object based on a growing or shrinking array in your controller.
My guess is you're looking for an visibility directive, so I think the following might help:
<table id="table1">
<tr data-ng-repeat="row in table1">
<td>{{row.someData}}</td>
</tr>
</table>
<table id="table2" data-ng-show="table1.length == 0">
<tr data-ng-repeat="row in table2">
<td>{{row.someData}}</td>
</tr>
</table>
Note that both tables are filled with an ngRepeat by using corresponding arrays from your controller as a source. On the second table, you can see an ngShow directive with an expression that says: "if table1 is empty, show me".
I hope this helps.

smart-table actions empties my table

I followed all the steps described in the docs, I installed smart-table via bower, then I ref the script at index.html, then I added the module to one of my sub-modules, and I created my table:
<table st-table="vm.product_conditions" class="table">
<thead>
<tr>
<th st-sort="name">Nombre</th>
<th st-sort="description">Descripcion</th>
<th st-sort="status">Estado</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="condition in vm.product_conditions track by condition.id"
ng-click="vm.detailProductCondition(condition.id, condition.name)">
<td>{{ condition.name }}</td>
<td>{{ condition.description }}</td>
<td>{{ condition.status ? 'Activa' : 'Inactiva' }}</td>
</tr>
</tbody>
</table>
The table gets populated, but whenever I click on the column in order to sort it, the table gets empty, I also tried to implement the global search, and the same result, empty table...
Also, I get no error output, I tried to reproduce the error in a plunker, but to my surprise It worked there...
Is there any way to debug it?
Are you loading data asynchronous? If you are, you will need to have two collections, one that is the displayed collection and the other that contains all the items for the table.
Smart Table has a data attribute for st-safe-src.
The only way that I believe your tables would return a blank result, is if the product_conditions collection is somehow being interpreted as blank or undefined.
I would attempt to log out the collection to the console, before and after sorting the table and confirm if the collection is the same.
Reason why (from the documentation):
smart-table first creates a safe copy of your displayed collection: it
creates an other array by copying the references of the items. It will
then modify the displayed collection (when sorting, filtering etc)
based on its safe copy. So if you don't intend to modify the
collection outside of the table, it will be all fine. However, if you
want to modify the collection (add item, remove item), or if you load
your data asynchronously (via AJAX-Call, timeout, etc) you will have
to tell smart-table to watch the original collection so it can update
its safe copy. This is were you use the stSafeSrc attribute

Order a row or column in a table with angularJS

I have been manually ordering columns in my table using AngularJS. Now I have the problem that I need to order the rows in a very specific way (much like the columns). Instead of making this table huge in the Html, I would rather ask around to see if there is a way that I could perhaps define an array in the .js script and have the columns/rows order themselves based on those arrays.
I have seen plenty of examples of how to sort alphabetically or by index but none so far that show how to sort by a predefined array.
Here is the table I am working with:
<table>
<thead>
<tr>
<th>
<select ng-init="selectedRace='Human'" ng-model="selectedRace">
<option ng-repeat="(raceName, item) in races">{{raceName}}</option>
</select>
</th>
<!--<th ng-repeat="(statGroup, item) in race.Attributes" class="{{statGroup}}">{{statGroup}}</th>-->
<!--Going to manually type the column headers until I figure out how to sort via array or something-->
<th>Starting Attribuites</th>
<th>Hero Limit</th>
<th>Epic Limit</th>
<th>Veteran Limit</th>
</tr>
</thead>
<tbody ng-model="race.Attributes">
<tr ng-repeat="(statName, item) in race.Attributes['Starting Attributes']">
<td class="statsDes">{{statName}}</td><!--These are not in proper order! I need to sort this via array or something-->
<td class="Starting Attributes">{{race.Attributes['Starting Attributes'] | FilterSet:statName}}</td>
<td>{{race.Attributes['Hero Limit'] | FilterSet:statName}}</td>
<td>{{race.Attributes['Epic Limit'] | FilterSet:statName}}</td>
<td>{{race.Attributes['Veteran Limit'] | FilterSet:statName}}</td>
</tr>
</tbody>
</table>
</br>
Any ideas? Other than doing it manually?
No need to do anything manually when you have AngularJS at your disposal.
AngularJS offers the orderBy filter to order an array by expression (http://docs.angularjs.org/api/ng.filter:orderBy).
If you need some feature that is not supported by the default orderBy filter, you can write your own custom filter to manipulate (sort) the array to your liking.
You can read more about custom filters on http://docs.angularjs.org/tutorial/step_09.
Hope that helps!

Resources