Smart-Table "st-sort" not working - angularjs

I'm using angular v1.3.15. I'm fetching data by hitting an api and passing it through the scope to the smart table like so
Here is the data format of the 'scope.rowCollection' as seen on the console
Data populates fine but When i'm trying to click on the table-header and sort it using st-sort method, the table values go blank clearly not sorting the column. Here is a view of my html snippet
Can you please tell me what exactly am i doing wrong. The moment i use my own data collection set(NOT hard coded) the whole table values go haywire.
I have a feeling its something to do with the variable names that i'm using on the angular end.
Any help is much appreciated....Thanks

Following your comment Nikhil. Use st-safe-src like so:
HTML
<table st-table="displayedCollection" st-safe-src="rowCollection">
<thead>
<tr>
<th st-sort="firstName">First Name</th>
<th st-sort="lastName">Last Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in displayedCollection">
<td>{{row.firstName}}</td>
<td>{{row.lastName}}</td>
</tr>
</tbody>
</table>
JS
app.controller('Ctrl', function($scope, service) {
$scope.displayedCollection = [];
service.all.then(function(list) {
$scope.rowCollection = list;
$scope.displayedCollection = list;
});
});
That's it.

If you are bringing in data asynchronously (from a remote database, restful endpoint, ajax call, etc) you must use the stSafeSrc attribute. You must use a seperate collection for both the base and safe collections or you may end up with an infinite loop.
Since I am getting data from restful service
st-table="displayedCollection" st-safe-src="rowCollection"
solve my issue

I think it is trying to sort on row.name in the way that you code it. Try the following to see if it works:
st-sort="employee.name"

Related

Horizontal Table in Apex

I am getting stuck in horizontal table(apex) which I need to share inside the email template.Table structure would be like below:
Html Table
Earlier, I am giving space between them by using ensp; or nbsp; but whenever the data is filling out in these fields, their alignment is not coming correctly.So that I need table instead of using these ( or )
I'm going to make a couple of assumptions here. If these assumptions are wrong, you're kind of SOL.
that you're using a Visualforce Email template
that your comfortable writing both the visualforce and the apex controller
You're aware of how to get a handle on the necessary objects and fields you want to display
If those three things are true, this is actually just an example of how weird visualforce can be.
Visualforce allows you to mix in regular HTML, so the HTML for a table like your image would look something like this:
<table>
<tbody>
<tr>
<td colspan="2">OpportunityNameVar</td>
</tr>
<tr>
<td>AccountNameVar</td>
<td>Opp Type</td>
</tr>
<tr>
<td>Phone</td>
<td>CloseDate</td>
</tr>
</tbody>
</table>

Angular - create a dynamic template for ng-repeat over different objects

Suppose I have an array of objects. I need to create dynamically a table using ng-repeat. The thing is, I don't want to hardcode every property of the object to the html. I created an array which contain the relevant keys to the current object (the input can sometimes be different). How can I create ng-repeat which will run over each object of the data array and printing each property of the keys array I created earlier?
xlsxTableProps is an array with strings which are keys of every object inside parsedXslxData array of objects.
This is how I create the keys for the input (which again, can be different each time)
JS:
Object.keys(this.parsedXslxData[0]).forEach(key => {
this.xlsxTableProps.push(key)
});
HTML:
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col" ng-repeat="header in $ctrl.xlsxTableProps">{{header}}</th>
</tr>
</thead>
<tr ng-repeat="item in $ctrl.parsedXslxData">
<td>{{$index}}</td>
<td ng-repeat="tableItem in $ctrl.xlsxTableProps"></td>
<td>{{item[{{tableItem}}]}}</td>
</tr>
</table>
Problem is with your syntax here {{item[{{tableItem}}]}}, no need to use extra pair of brackets. Simply use {{item[tableItem]}}.

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>

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

Angular-tablesort breaks

angular-tablesort is saving me a lot of time, but i'm hitting a bug where I can't get the header to become sortable even though I am following the examples and adding the classes. My code looks like this:
<table class="table" ts-wrapper>
<thead>
<tr>
<th class="tablesort-sortable" ts-criteria="Name|lowercase" ts-default>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in items" ts-repeat>
<td>{{item.data.title}}</td>
</tr>
</tbody>
</table>
Solved!
As I was working through how best to present this to you guys I realized that this was an RTFM problem. I was confused by the fact that the example matches the ts-criteria with the div contents and didn't match the ng-repeat contents fully. angular-table actually lets you pass in item.data.title or data.title to get a sortable table.
A little embarrassing, but I'm still going to post this in case someone else comes across the same issue. This has nothing to do with bootstrapped angular applications, which was my first hunch. Changed the title to be more generic (from Angular-tablesort breaks when angular is bootstrapped to Angular-tablesort breaks).

Resources