I'm using angular smart table. Smart table has built in filtering using the st-search directive. However, I need some customized filtering using regular expressions.
I tried applying an angular filter to my data source (via the ng-repeat directive). While this works in regards to filtering, because smart table isn't aware of what i'm doing, it throws my paging off.
I've plunked an example of what is going on. (Try entering 1.8 in the account filter input box. You'll see the filter get applied but then if you click other pages, you'll see that they contain some of the filtered items as well.) I need the behavior to work similar to what happens if you filter by description (where filtered items get narrowed down and re-paged).
Here is my html table:
<table st-table="vm.accounts" class="table table-striped table-hover table-condensed">
<thead>
<tr>
<th st-sort="account">Account</th>
<th st-sort="desc">Description</th>
<th>Current Balance</th>
<th> </th>
<th> </th>
</tr>
<tr class="warning">
<th>
<input placeholder="filter accounts" class="form-control input-sm" type="search" ng-model="vm.accountfilter" />
</th>
<th>
<input placeholder="filter description" class="form-control input-sm" type="search" st-search="desc" />
</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in vm.accounts | filter:vm.myfilter" ng-click="vm.selected = item" ng-class="{info: vm.selected == item}">
<td>{{item.account}}</td>
<td>{{item.desc}}</td>
<td>{{item.runbal | currency}}</td>
<td><button class="btn btn-danger btn-xs"><i class="fa fa-times-circle"></i></button></td>
<td><button class="btn btn-primary btn-xs"><i class="fa fa-pencil"></i></button></td>
</tr>
</tbody>
<tfoot>
<tr class="warning">
<td colspan="5" class="text-center">
<button class="btn btn-success btn-sm"><i class="fa fa-plus-circle"></i> Add new account</button>
</td>
</tr>
<tr>
<td colspan="5" class="text-center">
<div st-pagination="" st-items-by-page="20" st-displayed-pages="10"></div>
</td>
</tr>
</tfoot>
</table>
and here is the filter that I'm trying to apply (from my controller):
(function(){
'use strict';
angular.module("myapp", ["smart-table"])
.controller("mycontroller", MyController);
function MyController(){
var me = this;
me.accounts = [];
me.selected = null;
me.myfilter = myFilter;
me.accountfilter = '';
activate();
function activate(){
for(var x = 0; x < 6000; x++)
{
var build = '';
for(build; build.length < (12 / x.toString().length); build += x.toString()){}
var aclass = Math.floor((1800 - 1100 + 1) * Math.random() + 1100).toString();
var adept = Math.floor((800 - 100 + 1) * Math.random() + 100).toString();
var aincex = Math.floor(1001 * Math.random() + 4000).toString();
var asub = Math.floor(2 * Math.random());
var account = aclass + adept + aincex + (asub ? "AB" + x.toString() : "");
me.accounts.push({account: account, desc: "Text for " + x + " Account", runbal: x * 5, begbal: 5000, newbegbal: 20000, newrunbal: x * 7});
}
}
function myFilter(value, index, array){
if(!me.accountfilter) return true;
var valex = new RegExp("^[*0-9a-zA-Z.]{1,22}$");
if(me.accountfilter.match(valex))
{
var filter = me.accountfilter;
debugger;
filter = filter.replace(/\*/g,'\\w+');
filter = "^" + filter + ".*$";
var regex = new RegExp(filter,'i');
return value.account.match(regex)
}
else
return false;
}
}
})();
How can I "smart table enable" my filter?
My suspicions were correct. I'm not sure if this is the best way to do it, but here is how I accomplished the special filtering.
I made 3 change to my html.
I added
st-pipe
to my<table>
element.I removed the angular filter from my
ng-repeat
.I used the smart-table search feature on the account column (in place of the angular filter that I removed).
In my controller I then added the following:
Lastly, I had to change the activate function of my controller to populate the internalList rather than the display/bound list.
You can see it in action here.