Combining ng-grid and ui-select2: unable to select a value

萝らか妹 提交于 2019-12-12 00:44:28

问题


In the editableCellTemplate of an ng-grid, I wanted to use a more user-friendly dropdown, and I found ui-select2 to be a good one.

The thing is however, that any click on this component, when it is used inside the ng-grid, results in the cell juming back to non-editable mode.

This way I can't select another value using the mouse (I can using the arrows on my keyboard).

When I put the dropdown in the cellTemplate, it works, but it should also work in the *editable*CellTemplate.

Some code to see what I mean can be found here.

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

Does anyone know why that happens, and what could be done to work around it?


回答1:


I updated the plunker with the solution (last grid shown).

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

The idea is that you should 'talk to ng-grid' exactly like the other editablCellTemplates do. These 'rules' aren't well defined in the documentation, but they could be deduced by looking at ng-grid's source code for the ng-input directive.

Basically, your own component should respond to the ngGridEventStartCellEdit event by focusing your editor element, and the most important thing is: your component MUST emit the ngGridEventEndCellEdit event only when the cell loses focus (or when you want the editor to disappear, like maybe when pressing enter or something).

So for this specific case I created my own directive that adds the necessary behaviour to a ui-select2 element, but I imagine you could understand what you'd have to do for your own specific case.

So, as an example, here is my ui-select2 specific directive:

app.directive(
            'uiSelect2EditableCellTemplate', 
            [ 
                function() {
                    return {
                        restrict: "A",
                        link: function ( scope, elm, attrs ) {
                            //make sure the id is set, so we can focus the ui-select2 by ID later on (because its ID will be generated from our id if we have one)
                            elm.attr( "id", "input-" + scope.col.index +  "-" + scope.row.rowIndex );

                            elm.on( 'click', function( evt ) {
                                evt.stopPropagation();
                            } ); 

                            elm.on( 'mousedown', function( evt ) {
                                evt.stopPropagation();
                            } ); 

                            //select2 has its own blur event !
                            elm.on( 'select2-blur', 
                                        function ( event ) { 
                                            scope.$emit( 'ngGridEventEndCellEdit' );                                                
                                        } 
                            );

                            scope.$on( 'ngGridEventStartCellEdit', function () {
                                //Event is fired BEFORE the new elements are part of the DOM, so try to set the focus after a timeout
                                setTimeout( function () {
                                                $( "#s2id_" + elm[0].id ).select2( 'open' );
                                            }, 10 );
                            } );


                        }
                    };
                }
            ] 
);

and my own editableCellTemplate would have to look something like this:

$scope.cellTemplateDropdownUiSelect3 =
'<select ui-select2-editable-cell-template ui-select2 ng-model="COL_FIELD" style="width: 90%" >' +
            '<option ng-repeat="(fkid, fkrow) in fkvalues_country" value="{{fkid}}" ng-selected="COL_FIELD == fkid" >{{fkrow}} ({{fkid}})</option>' +
'</select>' ;

A little bit of 'official' information can be found here: https://github.com/angular-ui/ng-grid/blob/master/CHANGELOG.md#editing-cells




回答2:


the template for datepicker

<input type="text" datepicker ng-model="COL_FIELD"/>

and the angular directive would look like this.

 app.directive('datepicker',

      function () {
          return {

              restrict: 'A',
              require: '?ngModel',
              scope: {},
              link: function (scope, element, attrs, ngModel) {

                  if (!ngModel) return;
                  var optionsObj = {};
                  optionsObj.dateFormat = 'dd/mm/yy';
                  optionsObj.onClose = function(){
                    scope.$emit( 'ngGridEventEndCellEdit' ); 
                  }


                  var updateModel = function (date) {
                                            scope.$apply(function () {
                                            ngModel.$setViewValue(date);
                                        });
                                };

                  optionsObj.onSelect = function (date, picker) {
                      updateModel(date);
                  };

                  ngModel.$render = function () {
                      element.datepicker('setDate', ngModel.$viewValue || '');
                  };

                scope.$on('ngGridEventStartCellEdit', function (obj) {
                    element.datepicker( "show" );  
                });

                scope.$on('ngGridEventStartCellEdit', function (obj) {
                    element.datepicker( "show" );  
                });
                element.datepicker(optionsObj);

              } 
          };
      });


来源:https://stackoverflow.com/questions/20641433/combining-ng-grid-and-ui-select2-unable-to-select-a-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!