Is it possible to have a select drop down inside of the AngularJS ng-grid?
Asked Answered
M

4

10

I have coded the following:

$scope.gridOptions = {
    data: 'myData',
    enableCellEdit: true,
    multiSelect: false,
    columnDefs: [
        { field: 'Id', displayName: 'Id' },
        { field: 'Name', displayName: 'Name', enableCellEdit: true, editableCellTemplate: cellEditableTemplate },
        { field: 'Description', displayName: 'Description', enableCellEdit: true, editableCellTemplate: cellEditableTemplate }
    ]
};

The myData actually contains four colums Id, Name, Status and Description. Where status is a simple javascript array with three types of status called myStatus.

Is it possible for me to somehow link in the data from myStatus to a field in the ng-grid so I can then select a new value from a select drop down?

Multinational answered 9/4, 2013 at 16:25 Comment(0)
W
13

Here is output of some experiment.

http://plnkr.co/edit/W1TkRgsp0klhqquxaiyc?p=preview

It seems that you can put select in cell template. And you can make use of row object to retrieve whatever you need. I used row.rowIndex to property access to the original data.

template example:

<div>
  <select ng-model="myData[ row.rowIndex ].myStatus">
    <option ng-repeat="st in statuses">{{st}}</option>
  </select>
</div>

(It would be beutiful if we can write to ogirinal data through row object. I do not know how.)

Wardmote answered 11/4, 2013 at 0:21 Comment(1)
Is there a way to get the order grid options working with thisStrawn
J
6

The way tosh shimayama are doing it, will not allow for sorting the table in any other order than the model array.

This is kind of an ugly way to do it, but I took a quick look in the source code for ng-grid and found that they use regexp to insert the ng-model. So by using the same variable, COL_FIELD, in your code you can make ng-grid insert the correct model.

<div>
  <select ng-model="COL_FIELD">
    <option ng-repeat="status in statuses">{{status}}</option>
  </select>
</div>

Here is a plunker with a working example: http://plnkr.co/edit/Yj2qmI?p=preview

Judaic answered 1/7, 2013 at 12:4 Comment(1)
I'm using angular ui-grid, and your solution almost works. I had to change ng-model to row.entity.status (my the matching field name) because COL_FIELD cannot be modified. It throws error when compiling each row.Banquer
C
5

A more complete/tidier way to do this in ng-grid 2.x I've included in a plunker here: http://plnkr.co/edit/VABAEu?p=preview, leveraging content from another similar question on stackoverflow here: AngularJS and ng-grid - auto save data to the server after a cell was changed

In summary, my format for the editable field template looks like so:

      $scope.statuses = {1: 'active', 2: 'inactive'};
      $scope.cellSelectEditableTemplate = '<select ng-class="\'colt\' + col.index" 
         ng-input="COL_FIELD" ng-model="COL_FIELD" 
         ng-options="id as name for (id, name) in statuses" 
         ng-blur="updateEntity(row)" />';

I've provided a blog post that has a more thorough walkthrough of the end-to-end code: http://technpol.wordpress.com/2013/12/06/editable-nggrid-with-both-dropdowns-and-selects/

Ng-grid (ui-grid) 3.0 is close to being released, and offers different ways to do editable grids. I have a post on that here: http://technpol.wordpress.com/2014/08/23/upgrading-to-ng-grid-3-0-ui-grid/

Coeternity answered 6/12, 2013 at 2:10 Comment(1)
This is the best answer among allRhodolite
E
0

I can't take credit for the entire solution. I just put the pieces together. My goal was to preserve three-way binding.

Template should look something like this:

        $scope.cellSelectEditableTemplate = '<select ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" ng-options="value.id as value.label for value in OptionsList}" />';
COL_FIELD of course essential to keep the reference to correct cell.

You can capture the change natively:

$scope.$on('ngGridEventEndCellEdit', function (evt) {
            console.log(evt.targetScope.row.entity);
            WaitListArray.$save(evt.targetScope.row.entity)
                .then(function (ref) {
                    console.log('saved');
                });
        });

In this case WaitListArray is my Firebase/AngularFire Array for the table. Using this method, I was able to preserve my tree-way binding.

Field (ng-options):

{
  field: 'status',
  displayName: 'Status',
  enableCellEditOnFocus: true,
  editableCellTemplate: $scope.cellSelectEditableTemplate,
  cellFilter: 'mapStatus:OptionsList'
}

I added filter to replace id with label for my dropdown values.

.filter('mapStatus', function() {
  return function(input, OptionsList) {
    var _out = 'unknown';
    angular.forEach(OptionsList, function(value, key) {

      if (value && value.id == input) {
        _out = value.label;
      }
    });
    return _out;

  };
})

In the above, OptionsList is my dropdown values array example: {id:1,label:"label1"}

I found this solution highly reusable. Hopefully, it saves time for someone.

Elevation answered 19/4, 2015 at 18:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.