在ui-grid中使用Angular Bootstrap datepicker(unstable 3.0.0)

Ant*_*ruk 9 angularjs angular-ui-bootstrap

我在ui-grid中使用AngularJS Bootstrap datepicker(3.0.0 - 不稳定)

我通过自定义cellTemplate(ui-grid)实现了datepicker:

{
      field: 'Wiedervorl',
      displayName: 'Wiedervorl.',
      enableCellEdit: true,
      enableCellEditOnFocus: true,
      enableHiding: false,
      cellTemplate: '<div><input ng-model="row.entity.Wiedervorl" ng-change="grid.appScope.addModifyFlag(row.entity)" ng-click="opened = true;" datepicker-popup="dd.MM.yyyy" is-open="opened" datepicker-options="grid.appScope.dateOptions" datepicker-append-to-body="true" type="text" /></div>',
      cellFilter: 'date',
      cellClass: function () {
        return 'text-left';
      },
      filter: {
        placeholder: 'date',
        condition: uiGridConstants.filter.CONTAINS
      },
      width: '7%'
    },
Run Code Online (Sandbox Code Playgroud)

在datepicker输入内部有一个标记'open',它与该输入元素的一个实例(datepicker实例)完全隔离.

问题是,在另一行中再打开一个日期选择器之后,前一个没有关闭,并且可以同时打开多个日期选择器.

在此输入图像描述

我试图在输入中添加"ng-blur",但是当datepicker打开时,它会执行.

任何想法,如何完成UI-Grid内部之前的datepicker实例的关闭?一次只能激活一个.

谢谢

小智 8

也许这对某人有帮助.我对如何将Bootstrap执行器集成到UI Grid进行了详细调查.

首先,您需要使用editableCellTemplate正确处理END_EDITCANCEL_EDIT事件的自定义和自定义指令.

您可以在下面找到我的指令代码:

var app = angular.module('ui.grid.edit');

app.directive('uiGridEditDatepicker', ['$timeout', '$document', 'uiGridConstants', 'uiGridEditConstants', function($timeout, $document, uiGridConstants, uiGridEditConstants) {
    return {
        template: function(element, attrs) {
            var html = '<div class="datepicker-wrapper" ><input uib-datepicker-popup is-open="isOpen" ng-model="' + attrs.rowField + '" ng-change="changeDate($event)" on-open-focus="false" disabled/></div>';
            return html;
        },
        require: ['?^uiGrid', '?^uiGridRenderContainer'],
        scope: true,
        compile: function() {
            return {
                pre: function($scope, $elm, $attrs) {

                },
                post: function($scope, $elm, $attrs, controllers) {
                    var setCorrectPosition = function() {
                        var gridElement = $('.ui-grid-viewport');
                        var gridPosition = {
                            width: gridElement.outerWidth(),
                            height: gridElement.outerHeight(),
                            offset: gridElement.offset()
                        };

                        var cellElement = $($elm);
                        var cellPosition = {
                            width: cellElement.outerWidth(),
                            height: cellElement.outerHeight(),
                            offset: cellElement.offset()
                        };

                        var datepickerElement = $('ul', cellElement);
                        var datepickerPosition = {
                            width: datepickerElement.outerWidth(),
                            height: datepickerElement.outerHeight()
                        };
                        var newOffsetValues = {};

                        var isFreeOnRight = (gridPosition.width - (cellPosition.offset.left - gridPosition.offset.left) - cellPosition.width) > datepickerPosition.width;
                        if (isFreeOnRight) {
                            newOffsetValues.left = cellPosition.offset.left + cellPosition.width;
                        } else {
                            newOffsetValues.left = cellPosition.offset.left - datepickerPosition.width;
                        }

                        var freePixelsOnBottom = gridPosition.height - (cellPosition.offset.top - gridPosition.offset.top) - cellPosition.height;
                        var freePixelsOnTop = gridPosition.height - freePixelsOnBottom - cellPosition.height;
                        var requiredPixels = (datepickerPosition.height - cellPosition.height) / 2;
                        if (freePixelsOnBottom >= requiredPixels && freePixelsOnTop >= requiredPixels) {
                            newOffsetValues.top = cellPosition.offset.top - requiredPixels + 10;
                        } else if (freePixelsOnBottom >= requiredPixels && freePixelsOnTop < requiredPixels) {
                            newOffsetValues.top = cellPosition.offset.top - freePixelsOnTop + 10;
                        } else {
                            newOffsetValues.top = gridPosition.height - datepickerPosition.height + gridPosition.offset.top - 20;
                        }

                        datepickerElement.offset(newOffsetValues);
                        datepickerElement.css("visibility", "visible");
                    };

                    $timeout(function() {
                        setCorrectPosition();
                    }, 0);

                    $scope.isOpen = true;

                    var uiGridCtrl = controllers[0];
                    var renderContainerCtrl = controllers[1];

                    var onWindowClick = function (evt) {
                        var classNamed = angular.element(evt.target).attr('class');
                        var inDatepicker = (classNamed.indexOf('datepicker-calendar') > -1);
                        if (!inDatepicker && evt.target.nodeName !== "INPUT") {
                            $scope.stopEdit(evt);
                        }
                    };

                    var onCellClick = function (evt) {
                        console.log('click')
                        angular.element(document.querySelectorAll('.ui-grid-cell-contents')).off('click', onCellClick);
                        $scope.stopEdit(evt);
                    };

                    $scope.changeDate = function (evt) {
                        $scope.stopEdit(evt);
                    };

                    $scope.$on(uiGridEditConstants.events.BEGIN_CELL_EDIT, function () {
                        if (uiGridCtrl.grid.api.cellNav) {
                            uiGridCtrl.grid.api.cellNav.on.navigate($scope, function (newRowCol, oldRowCol) {
                                $scope.stopEdit();
                            });
                        } else {
                            angular.element(document.querySelectorAll('.ui-grid-cell-contents')).on('click', onCellClick);
                        }
                        angular.element(window).on('click', onWindowClick);
                    });

                    $scope.$on('$destroy', function () {
                        angular.element(window).off('click', onWindowClick);
                    });

                    $scope.stopEdit = function(evt) {
                        $scope.$emit(uiGridEditConstants.events.END_CELL_EDIT);
                    };

                    $elm.on('keydown', function(evt) {
                        switch (evt.keyCode) {
                            case uiGridConstants.keymap.ESC:
                                evt.stopPropagation();
                                $scope.$emit(uiGridEditConstants.events.CANCEL_CELL_EDIT);
                                break;
                        }
                        if (uiGridCtrl && uiGridCtrl.grid.api.cellNav) {
                            evt.uiGridTargetRenderContainerId = renderContainerCtrl.containerId;
                            if (uiGridCtrl.cellNav.handleKeyDown(evt) !== null) {
                                $scope.stopEdit(evt);
                            }
                        } else {
                            switch (evt.keyCode) {
                                case uiGridConstants.keymap.ENTER:
                                case uiGridConstants.keymap.TAB:
                                    evt.stopPropagation();
                                    evt.preventDefault();
                                    $scope.stopEdit(evt);
                                    break;
                            }
                        }
                        return true;
                    });
                }
            };
        }
    };
}]);
Run Code Online (Sandbox Code Playgroud)

注意!我的指令需要jQuery来设置网格中datepicker的正确位置.如果你不使用jQuery,你应该注释setCorrectPosition()在指令中调用.在这种情况下,datepicker将根据标准行为放置在网格中.

您可以在Github上找到有关如何使用它和示例代码的一些额外信息:https://github.com/Joiler/ui-grid-edit-datepicker

Plunker:http://plnkr.co/edit/4mNr86cN6wFOLYQ02QND


Raj*_*ush 5

如果万一有人遇到像我一样的情况,ui-grid也已经有它自己的内置日期选择器选项。

 $scope.gridOptions.columnDefs = [
    { name: 'registered', 
      displayName: 'Registered', 
      type: 'date', 
      cellFilter:'date:"yyyy-MM-dd"'}
];
Run Code Online (Sandbox Code Playgroud)

除非像OP这样需要特定类型的外部日期选择器,否则这似乎非常方便且易于使用。

  • 这样做的主要问题之一是,只是将输入类型设置为日期,这是许多常见浏览器(最重要的是Firefox)都未实现的HTML5功能。 (4认同)

Pau*_*ulL 2

您需要实现一个带有日期选择器的指令,并且该指令需要向网格提供 END_EDIT 和 CANCEL_EDIT 事件。请参阅编辑教程:http://ui-grid.info/docs/#/tutorial/201_editable (就在 ColumnDef 选项上方)。

您可以在https://github.com/angular-ui/ng-grid/blob/master/src/features/edit/js/gridEdit.js中看到与下拉指令相关的代码,从底部开始的第二个块