Angular UI Grid: How to create a pre-populated dropdown menu for column filtering
Asked Answered
M

4

20

I am looking for some help regarding a feature of the Angular UI Grid. Specifically I am exploring filtering and while I was able to successfully implement sorting using free form text field(s) in my application as they do in the example on their site I would like some help finding a way to instead sort using a pre-populated drop-down menu for certain columns.

To clarify: By pre-populated I mean I would like the drop-down to be populated through my code. I am ok if the solution contains hard-coded data but my eventual goal would be to have the pre-population be comprised of the unique data value set of the column being sorted :)

I have seen this functionality in (for example) the Kendo UI (kendodropdownlist) but I am not interested in the price tag that comes along with that solution. I would like to stick with the Angular UI-grid mentioned (and linked) above. On StackOverflow I found one similar question but unfortunately it didn't seem to have gotten much traction. I am hoping that by giving a more detailed explanation of what I am looking for I will receive a more complete answer than I found there.

Here is what is currently in my controller:

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

} ]);

Below is the output - with the free-form text fields

Example Table with free form filters

For this specific example columns Customer, Quantity, and Current Date I would probably leave as free form drop downs, but I would really like to be able to filter using a pre-populated drop down for the transactions (and to have it in my toolbox for future projects of course!).

Thanks!

Meow answered 22/1, 2015 at 20:8 Comment(1)
Can you post up the code for your solution please? I've not been able to solve this yet. One problem I have is that if i give a template name, it won't use the file...have to put string in. But interested to know how you did the rest please - like population of dropdown!Dave
B
8

You can use the built in selectOptions filter feature documented here: http://ui-grid.info/docs/#/tutorial/103_filtering

Example:

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>
Bismarck answered 12/1, 2016 at 21:10 Comment(2)
Cool! This built in feature was not available when I posted the question. It's great to see that there is now a super easy/built-in way to get this functionality - thanks for sharing! Now it's available I definitely will be using this option in future :)Meow
How to load values in selectOptions dynamically from json? i want to populate each column with select dropdown filters based on the column value similar to what excel offers.Maynord
J
7

You can put a pulldown menu in the header via the headerCellTemplate in your columnDefs

  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() can do whatever it is you want to have filtered. Perhaps just by setting some variables that you use in a custom filter you assign to the grid. You can find an example of setting a condition in your custom filter on the ui Grid Tutorial here http://ui-grid.info/docs/#/tutorial/103_filtering

Jungly answered 22/1, 2015 at 22:45 Comment(6)
Yes this is what I was looking for - as is it gives me a (blank) drop down and using your final suggestion to apply a custom filter I was able to customize the dropdown to bring in the filtering options I was looking for - thanks :)Meow
@Jungly - why is it that if I use getExternalScopes() I get some undefined is not a function error in the angular.js file? but this works for me: <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>Sofer
I'm not sure but I use getExternalScopes() as follows and it works fine. <select ng-model="getExternalScopes().value[col.field]" ng-change="$event.stopPropagation();getExternalScopes().checkUncheckAll(col.field)">Jungly
getExternalScopes() has been changed in the latest version of the ui-grid. You use grid.appScope.YOUR_VALUE now instead of getExternalScopes()Jungly
@Jungly - now that the ui-grid has a built-in feature to accomplish populating a column drop-down with unique column values I have changed the accepted answer. Your answer is what I used myself but now that the answer is available within ui-grid itself I feel that's the better option for anyone looking at this question.Meow
So the built-in feature has actually been there a while, however it is not robust enough if you have logic involved in the dropdown you are displaying. Simply being able to populate the dropdown via some filter would not work in my case as I have additional criteria that affect how the dropdown is displayed. The app I have actually uses the built-in method for some of the dropdowns but for others it simply did not allow enough flexibility. Glad to hear for your case you could use the built-in dropdown feature.Jungly
B
1

I had the same requirement recently.I have figured it out myself.Here is the steps i have followed.If you want to use filters in ui-grid you can use two approaches either use existing ui-grid custom_filters or created a header template and bind it into grid.There is a nice article that how can add drop downs in ui-grid.Based on that codes i have customized my code snippets.What i do is i have created custom template inside 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>

I have created function called filterTableBasedonDropDownSelect($item) it will handle the filtering logic.Note that when you call a function in ui-grid normal function declaration doesn't work. Because ui-grid has its own parent scope. so you should call your function like this.

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

Then you can declare your function logic under controller.

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

Here is my working example.

Hope this will help for someone.

Burdette answered 22/12, 2015 at 5:45 Comment(0)
D
1

An extension to the accepted answer is something I just discovered through trial and error. You can use regular expressions in the 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' }
                    ]
                }
            },
Desert answered 26/6, 2018 at 12:1 Comment(1)
The "filter by several of the possible values" saved me. Thanks for this.Joiejoin

© 2022 - 2024 — McMap. All rights reserved.