Angular UI Grid: как создать предварительно заполненное выпадающее меню для фильтрации столбцов

Мне нужна помощь в отношении функции Angular UI Grid. В частности, я изучаю фильтрацию, и пока я смог успешно реализовать сортировку с использованием текстовых полей произвольной формы в моем приложении, как это делается в пример на их сайте Мне нужна помощь в поиске способа вместо сортировки использовать предварительно заполненное раскрывающееся меню для определенных столбцов.

Пояснение: под предварительным заполнением я подразумеваю, что раскрывающийся список заполняется с помощью моего кода. Я согласен, если решение содержит жестко закодированные данные, но моей конечной целью будет предварительное заполнение, состоящее из уникального набора значений данных сортируемого столбца :)

Я видел эту функциональность (например) в пользовательском интерфейсе Kendo (kendodropdownlist), но меня не интересует цена, которая идет вместе с этим решением. Я хотел бы придерживаться Angular UI-сетки, упомянутой (и связанной) выше. В StackOverflow я нашел один похожий вопрос, но, к сожалению, он не получил большого распространения. Я надеюсь, что, дав более подробное объяснение того, что я ищу, я получу более полный ответ, чем нашел там.

Вот что сейчас находится в моем контроллере:

var simpleMessagingApp = angular.module('MainAppCtrl', [ 'ngAnimate',
                                                         'ngTouch', 'ui.grid' ]);

simpleMessagingApp.controller('CacheTableCtrl', [ '$scope', '$http',
                                                  'uiGridConstants', function($scope, $http, uiGridConstants) {
    $scope.columns = [ {
        field : 'trans_detail',
        displayName : 'Transaction'
    }, {
        field : 'cust_name',
        displayName : 'Customer'
    }, {
        field : 'quantity',
        displayName : 'Quantity',
        filters : [ {
            condition : uiGridConstants.filter.GREATER_THAN,
            placeholder : 'greater than'
        }, {
            condition : uiGridConstants.filter.LESS_THAN,
            placeholder : 'less than'
        }
        ]
    }, {
        field : 'today_date',
        displayName : 'Current Date'
    } ];
    $scope.gridOptions1 = {
            enableSorting : true,
            enableFiltering : true,
            columnDefs : $scope.columns,
            onRegisterApi : function(gridApi) {
                $scope.grid1Api = gridApi;
            }
    };

    $http.get("../services/Coherence/Cache").success(function(data) {
        $scope.gridOptions1.data = data;
    });

} ]);

Ниже приведен вывод - с текстовыми полями произвольной формы.

Пример таблицы с фильтрами произвольной формы

Для этого конкретного примера столбцы «Клиент», «Количество» и «Текущая дата» я бы, вероятно, оставил в виде раскрывающихся списков произвольной формы, но мне бы очень хотелось иметь возможность фильтровать с помощью предварительно заполненного раскрывающегося списка для транзакций (и чтобы он был в моем наборе инструментов). для будущих проектов, конечно!).

Спасибо!


person laurenOlga    schedule 22.01.2015    source источник
comment
Можете ли вы опубликовать код для вашего решения, пожалуйста? Я еще не смог решить это. Одна проблема, с которой я столкнулся, заключается в том, что если я укажу имя шаблона, он не будет использовать файл... нужно вставить строку. Но интересно узнать, как вы сделали все остальное, пожалуйста - например, заполнение выпадающего списка!   -  person Phil    schedule 03.03.2015


Ответы (4)


Вы можете использовать встроенную функцию фильтра selectOptions, описанную здесь: http://ui-grid.info/docs/#/tutorial/103_filtering

Пример:

angular.module('exampleApp', ['ui.grid'])
  .controller('exampleCtrl', ['$scope', 'uiGridConstants', function($scope, uiGridConstants) {
    var animals = [
      { id: 1, type: 'Mammal', name: 'Elephant' },
      { id: 2, type: 'Reptile', name: 'Turtle' },
      { id: 3, type: 'Mammal', name: 'Human' }
    ];
                                                          
    var animalTypes = [
      { value: 'Mammal', label: 'Mammal' },
      { value: 'Reptile', label: 'Reptile'}
    ];
  
    $scope.animalGrid = {
      enableFiltering: true,
      columnDefs: [
        {
          name: 'type', 
          field: 'type', 
          filter: { selectOptions: animalTypes, type: uiGridConstants.filter.SELECT }
        },
        { name: 'name', name: 'name'}
      ],
      data: animals
    };
      
  }]);
<link href="http://ui-grid.info/release/ui-grid.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="http://ui-grid.info/release/ui-grid.js"></script>

<div ng-app="exampleApp">
  <div ng-controller="exampleCtrl">
    <h1>UI Grid Dropdown Filter Example</h1>
    <div ui-grid="animalGrid" class="grid"></div>
  </div>
</div>

person Justin Fisher    schedule 12.01.2016
comment
Прохладно! Эта встроенная функция была недоступна, когда я разместил вопрос. Приятно видеть, что теперь есть очень простой/встроенный способ получить эту функциональность - спасибо, что поделились! Теперь это доступно, я определенно буду использовать эту опцию в будущем :) - person laurenOlga; 24.02.2016
comment
Как динамически загружать значения в selectOptions из json? Я хочу заполнить каждый столбец фильтрами раскрывающегося списка на основе значения столбца, аналогичного тому, что предлагает Excel. - person Zameer Fouzan; 29.08.2017

Вы можете разместить раскрывающееся меню в заголовке с помощью headerCellTemplate в столбцеDefs.

  columnDefs: [
     {field:'myField',headerCellTempalte: 'mypulldowntemplate.html"...}
  ]

mypulldowntemplate.html

  <div ng-class="{ 'sortable': sortable }">
  <div class="ui-grid-vertical-bar">&nbsp;</div>
<div class="ui-grid-cell-contents {{col.headerClass}}" col-index="renderIndex">
    {{ col.displayName CUSTOM_FILTERS }}
    <br>
    <select ng-model="getExternalScopes().value[col.field]" ng-change="$event.stopPropagation();getExternalScopes().yourFilterFunction(col.field)">
    </select>
      
  ....

yourFilterFunction() может делать все, что вы хотите отфильтровать. Возможно, просто установив некоторые переменные, которые вы используете в пользовательском фильтре, который вы назначаете сетке. Вы можете найти пример установки условия в своем пользовательском фильтре в учебнике по сетке пользовательского интерфейса здесь http://ui-grid.info/docs/#/tutorial/103_filtering

person Scott    schedule 22.01.2015
comment
Да, это то, что я искал - так как он дает мне (пустой) раскрывающийся список, и, используя ваше последнее предложение по применению пользовательского фильтра, я смог настроить раскрывающийся список, чтобы ввести параметры фильтрации, которые я искал - спасибо: ) - person laurenOlga; 27.01.2015
comment
@Scott - почему, если я использую getExternalScopes (), я получаю некоторую неопределенную ошибку, не являющуюся функциональной, в файле angular.js? но это работает для меня: ‹select ng-model=grid.appScope.value[col.field] ng-change=$event.stopPropagation(); grid.appScope.yourFilterFunction(grid.appScope.value[col.field])› ‹option value=222›222‹/option› ‹/select› - person bokkie; 25.02.2015
comment
Я не уверен, но я использую getExternalScopes() следующим образом, и он отлично работает. ‹select ng-model=getExternalScopes().value[col.field] ng-change=$event.stopPropagation();getExternalScopes().checkUncheckAll(col.field)› - person Scott; 27.02.2015
comment
getExternalScopes() был изменен в последней версии ui-grid. Теперь вы используете grid.appScope.YOUR_VALUE вместо getExternalScopes(). - person Scott; 01.04.2015
comment
@Scott - теперь, когда в ui-grid есть встроенная функция для заполнения раскрывающегося списка столбцов уникальными значениями столбцов, я изменил принятый ответ. Ваш ответ - это то, что я использовал сам, но теперь, когда ответ доступен в самой ui-grid, я чувствую, что это лучший вариант для всех, кто смотрит на этот вопрос. - person laurenOlga; 24.02.2016
comment
Таким образом, встроенная функция действительно существует некоторое время, однако она недостаточно надежна, если у вас есть логика, связанная с раскрывающимся списком, который вы отображаете. Просто возможность заполнить раскрывающийся список с помощью какого-либо фильтра в моем случае не сработает, поскольку у меня есть дополнительные критерии, влияющие на отображение раскрывающегося списка. Приложение, которое у меня есть, фактически использует встроенный метод для некоторых раскрывающихся списков, но для других оно просто не обеспечивает достаточной гибкости. Рад слышать, что в вашем случае вы можете использовать встроенную функцию раскрывающегося списка. - person Scott; 25.02.2016

Недавно у меня было такое же требование. Я сам понял это. Вот шаги, которые я выполнил. Если вы хотите использовать фильтры в ui-grid вы можете использовать два подхода: либо использовать существующую ui-grid custom_filters или создал шаблон заголовка и привязал его к сетке. Есть хорошая статья о том, как добавить раскрывающиеся списки в сетку пользовательского интерфейса. На основе этих кодов я настроил свои фрагменты кода. Что я делаю, так это создаю собственный шаблон внутри index.html.

<script type="text/ng-template" id="uiSelect">

      <ui-select-wrap>
        <label> Gender</label>
        <ui-select ng-model="MODEL_COL_FIELD" theme="selectize" ng-disabled="disabled" append-to-body="true" on-select="grid.appScope.filterTableBasedonDropDownSelect($item)">
          <ui-select-match placeholder="Select...">{{$select.selected}}</ui-select-match>
          <ui-select-choices repeat="item in col.colDef.editDropdownOptionsArray | filter: $select.search">
            <span>{{ item }}</span>
          </ui-select-choices>
        </ui-select>
      </ui-select-wrap>
    </script>

Я создал функцию с именем filterTableBasedonDropDownSelect($item), она будет обрабатывать логику фильтрации. Обратите внимание, что при вызове функции в обычном объявлении функции ui-grid не работает. Поскольку ui-grid имеет собственную родительскую область. поэтому вы должны вызывать свою функцию следующим образом.

on-select="grid.appScope.filterTableBasedonDropDownSelect($item)"

Затем вы можете объявить логику своей функции под контроллером.

$scope.filterTableBasedonDropDownSelect= function(item){
     $scope.gridOptions.data  = $filter('filter')($scope.jsonData,item, undefined);};

Вот мой рабочий пример.

Надеюсь, это поможет кому-то.

person gihan-maduranga    schedule 22.12.2015

Расширение принятого ответа - это то, что я только что обнаружил методом проб и ошибок. Вы можете использовать регулярные выражения в selectOptions:

           columnDefs: [
            {
                name: 'starRating',
                headerCellClass: 'blue',
                headerTooltip: 'Star Rating',
                maxWidth: 100, 
                filter:
                {
                    type: uiGridConstants.filter.SELECT,
                    selectOptions: [
                        { value: /(THREE|FOUR|FIVE)/, label: 'Positive' },  // Here I wanted the user to be able to choose one option that would filter by several of the possible values in the data set
                        { value: /(ONE|TWO)/, label: 'Negative' },  // ...and Here
                        { value: 'ONE', label: '1' },
                        { value: 'TWO', label: '2' },
                        { value: 'THREE', label: '3' },
                        { value: 'FOUR', label: '4' },
                        { value: 'FIVE', label: '5' }
                    ]
                }
            },
person Adam Hey    schedule 26.06.2018