Нужна регулярная фильтрация с помощью угловой таблицы

0

Я использую угловой смарт-стол. Смарт-таблица имеет встроенную фильтрацию с использованием директивы st-search. Тем не менее, мне нужна отдельная фильтрация с использованием регулярных выражений.

Я попытался применить угловой фильтр к источнику данных (через директиву ng-repeat). Хотя это работает в отношении фильтрации, потому что смарт-таблица не знает, что я делаю, она бросает мой пейджинг.

Я выложил пример того, что происходит. (Попробуйте ввести 1,8 в поле ввода фильтра учетной записи. Вы увидите, что фильтр применяется, но затем, если вы нажмете на другие страницы, вы увидите, что они содержат некоторые из фильтрованных элементов.) Мне нужно, чтобы поведение работало аналогично что происходит, если вы фильтруете по описанию (где фильтрованные элементы сужаются и переустанавливаются).

Вот моя таблица html:

        <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>

и вот фильтр, который я пытаюсь применить (от моего контроллера):

(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;
}
}
})();

Как я могу использовать "smart table enable" для моего фильтра?

Теги:
smart-table

1 ответ

1
Лучший ответ

Мои подозрения были правильными. Я не уверен, что это лучший способ сделать это, но вот как я завершил специальную фильтрацию.

Я сделал 3 изменения в своем html.

  1. Я добавил st-pipe в мой элемент <table>.

    <table st-pipe="vm.pipe" st-table="vm.accounts" ... >
    
  2. Я удалил угловой фильтр из моего ng-repeat.

    <tr ng-repeat="item in vm.accounts" ... >
    
  3. Я использовал функцию поиска смарт-таблицы в столбце учетной записи (вместо удаляемого углового фильтра).

    <input st-search="account" ... />
    

В моем контроллере я добавил следующее:

...
var internalList = [];
me.pipe = Pipe;

function Pipe(tableState){
  var perpage = tableState.pagination.number;
  var start = tableState.pagination.start;

  var filtered = internalList;

  //If user has entered filter criteria
  if(tableState.search.predicateObject)
  {
    //clone the filter criteria object
    var myPred = $.extend({},tableState.search.predicateObject);

    //remove the account criteria so I can process that myself
    delete myPred["account"];

    //perform the default filter function for any other filters
    filtered = $filter('filter')(filtered, myPred);

    //if user entered account (regex) filter then call my original filter function
    if(tableState.search.predicateObject["account"])
    {
      filtered = $filter('filter')(filtered,myFilter);
    }
  }

    //apply any sorting that needs to be applied
    if (tableState.sort.predicate) {
        filtered = $filter('orderBy')(filtered, tableState.sort.predicate, tableState.sort.reverse);
    }

  //set the bound array to the filtered contents
  me.accounts = filtered.slice(start, start +perpage);

  //clear the selected item if it is not included on the current page
  if(me.accounts.indexOf(me.selected) < 0)
    me.selected = null;

  //Set the proper number of pages for our filtered list
  tableState.pagination.numberOfPages = (filtered.length ? Math.floor(filtered.length / perpage) : 0);
}

Наконец, мне пришлось изменить функцию активации моего контроллера, чтобы заполнить внутренний список, а не список отображения/привязки.

//me.accounts.push({account: account, desc: "Text for " + x + " Account", runbal: x * 5, begbal: 5000, newbegbal: 20000, newrunbal: x * 7});
internalList.push({account: ...});

Вы можете увидеть это в действии здесь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню