Создание пользовательской директивы редактора в пользовательском интерфейсе для локализации

Я создаю приложение, которое использует ui-grid, которое должно поддерживать IE 11. Локализация работала нормально, за исключением случаев редактирования числовых ячеек (десятичный разделитель не меняется).

Я читал, что способ решить эту проблему - создать собственную директиву редактора. Я создал editableCellTemplate:

var customNumberTemplate = '<div><form name="inputForm"><input type="text" class="customNumber" custom-number ng-class="\'colt\' + col.uid"  ng-model="MODEL_COL_FIELD" pattern="^[+-]?([0-9]+([,][0-9]*)?|[,][0-9]+)$"></form></div>';

Обратите внимание, что он имеет тип текста и шаблон для проверки действительного числа, но с "," в качестве разделителя. Я попытался дать ему type='number', однако это не работает, так как он пытается запустить мой валидатор и стандартный валидатор html-5 (не может иметь ",").

Для директивы я скопировал ui-grid-uiGridEditor и добавил две функции. Цель этого заключалась в том, чтобы, когда пользователь открывает ячейку, я преобразовывал ее в строку, а когда он закрывал, я преобразовывал ее обратно в число с плавающей точкой. Это, по-видимому, невозможно, сетка всегда возвращает мне значение в виде строки, возможно, потому, что тип шаблона установлен на текст (я пытался изменить тип $elm на 'numeric', но это не сработало). Вот код, две функции находятся сверху:

var _initCustomNumberDirective = function () {
_angularController.directive('customNumber', ['gridUtil', 'uiGridConstants', 'uiGridEditConstants', '$timeout', 'uiGridEditService',
function (gridUtil, uiGridConstants, uiGridEditConstants, $timeout, uiGridEditService) {
return {
    scope: true,
    require: ['?^uiGrid', '?^uiGridRenderContainer', 'ngModel'],
    compile: function () {


        // START OF MY CODE

        var beforeEdit = function ($scope, $elm) {
            if ($elm.length > 0 && $elm[0].classList.contains('customNumber')) {
                var modelField = $scope.row.getQualifiedColField($scope.col)
                if (eval('!isNaN($scope.' + modelField + ')')) {
                    eval('$scope.' + modelField + '= $scope.' + modelField + '.toString().replace(".", ",")');
                }
            }
        }

        var editionComplete = function ($scope, $elm) {
            if ($elm.length > 0 && $elm[0].classList.contains('customNumber')) {
                $elm[0].value = $elm[0].value.replace(',', '.');
                if (!isNaN($elm[0].value)) {
                    var modelField = $scope.row.getQualifiedColField($scope.col)
                    eval('$scope.' + modelField + ' = parseFloat($elm[0].value)');
                }
            }
        }

        // END OF MY CODE

        return {
            pre: function ($scope, $elm, $attrs) {
                beforeEdit($scope, $elm); // MY CODE
            },
            post: function ($scope, $elm, $attrs, controllers) {
                var uiGridCtrl, renderContainerCtrl, ngModel;
                if (controllers[0]) { uiGridCtrl = controllers[0]; }
                if (controllers[1]) { renderContainerCtrl = controllers[1]; }
                if (controllers[2]) { ngModel = controllers[2]; }

                //set focus at start of edit
                $scope.$on(uiGridEditConstants.events.BEGIN_CELL_EDIT, function (evt, triggerEvent) {
                    $timeout(function () {
                        $elm[0].focus();
                        //only select text if it is not being replaced below in the cellNav viewPortKeyPress
                        if ($elm[0].select && ($scope.col.colDef.enableCellEditOnFocus || !(uiGridCtrl && uiGridCtrl.grid.api.cellNav))) {
                            $elm[0].select();
                        }
                        else {
                            //some browsers (Chrome) stupidly, imo, support the w3 standard that number, email, ...
                            //fields should not allow setSelectionRange.  We ignore the error for those browsers
                            //https://www.w3.org/Bugs/Public/show_bug.cgi?id=24796
                            try {
                                $elm[0].setSelectionRange($elm[0].value.length, $elm[0].value.length);
                            }
                            catch (ex) {
                                //ignore
                            }
                        }
                    });

                    //set the keystroke that started the edit event
                    //we must do this because the BeginEdit is done in a different event loop than the intitial
                    //keydown event
                    //fire this event for the keypress that is received
                    if (uiGridCtrl && uiGridCtrl.grid.api.cellNav) {
                        var viewPortKeyDownUnregister = uiGridCtrl.grid.api.cellNav.on.viewPortKeyPress($scope, function (evt, rowCol) {
                            if (uiGridEditService.isStartEditKey(evt)) {
                                ngModel.$setViewValue(String.fromCharCode(typeof evt.which === 'number' ? evt.which : evt.keyCode), evt);
                                ngModel.$render();
                            }
                            viewPortKeyDownUnregister();
                        });
                    }

                    // macOS will blur the checkbox when clicked in Safari and Firefox,
                    // to get around this, we disable the blur handler on mousedown,
                    // and then focus the checkbox and re-enable the blur handler after $timeout
                    $elm.on('mousedown', function (evt) {
                        if ($elm[0].type === 'checkbox') {
                            $elm.off('blur', $scope.stopEdit);
                            $timeout(function () {
                                $elm[0].focus();
                                $elm.on('blur', $scope.stopEdit);
                            });
                        }
                    });

                    $elm.on('blur', $scope.stopEdit);
                });


                $scope.deepEdit = false;

                $scope.stopEdit = function (evt) {
                    if ($scope.inputForm && !$scope.inputForm.$valid) {
                        evt.stopPropagation();
                        $scope.$emit(uiGridEditConstants.events.CANCEL_CELL_EDIT);
                    }
                    else {
                        editionComplete($scope, $elm); // MY CODE
                        $scope.$emit(uiGridEditConstants.events.END_CELL_EDIT);
                    }
                    $scope.deepEdit = false;
                };


                $elm.on('click', function (evt) {
                    if ($elm[0].type !== 'checkbox') {
                        $scope.deepEdit = true;
                        $timeout(function () {
                            $scope.grid.disableScrolling = true;
                        });
                    }
                });

                $elm.on('keydown', function (evt) {
                    switch (evt.keyCode) {
                        case uiGridConstants.keymap.ESC:
                            evt.stopPropagation();
                            $scope.$emit(uiGridEditConstants.events.CANCEL_CELL_EDIT);
                            break;
                    }

                    if ($scope.deepEdit &&
                        (evt.keyCode === uiGridConstants.keymap.LEFT ||
                        evt.keyCode === uiGridConstants.keymap.RIGHT ||
                        evt.keyCode === uiGridConstants.keymap.UP ||
                        evt.keyCode === uiGridConstants.keymap.DOWN)) {
                        evt.stopPropagation();
                    }
                        // Pass the keydown event off to the cellNav service, if it exists
                    else if (uiGridCtrl && uiGridCtrl.grid.api.cellNav) {
                        evt.uiGridTargetRenderContainerId = renderContainerCtrl.containerId;
                        if (uiGridCtrl.cellNav.handleKeyDown(evt) !== null) {
                            $scope.stopEdit(evt);
                        }
                    }
                    else {
                        //handle enter and tab for editing not using cellNav
                        switch (evt.keyCode) {
                            case uiGridConstants.keymap.ENTER: // Enter (Leave Field)
                            case uiGridConstants.keymap.TAB:
                                evt.stopPropagation();
                                evt.preventDefault();
                                $scope.stopEdit(evt);
                                break;
                        }
                    }

                    return true;
                });

                $scope.$on('$destroy', function unbindEvents() {
                    // unbind all jquery events in order to avoid memory leaks
                    $elm.off();
                });
            }
        };
        }
    };
}]);
}

Поскольку я не мог заставить редактор возвращать число, я нашел обходной путь, непосредственно изменив значение сетки, однако это не работает, когда ячейка не проходит нашу проверку (должно быть <число и т. Д.), так как я уже редактировал непосредственно в сетке, у меня все равно будет неправильное значение.

У меня вопрос: могу ли я заставить свой пользовательский редактор возвращать число вместо строки, и если нет, то как я могу реализовать эту функцию без нее?

0 ответов

Другие вопросы по тегам