| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589 |
- /*!
- * ui-grid - v4.4.6 - 2018-04-06
- * Copyright (c) 2018 ; License: MIT
- */
- (function () {
- 'use strict';
-
- /**
- * @ngdoc overview
- * @name ui.grid.validate
- * @description
- *
- * # ui.grid.validate
- *
- * <div class="alert alert-warning" role="alert"><strong>Alpha</strong> This feature is in development. There will almost certainly be breaking api changes, or there are major outstanding bugs.</div>
- *
- * This module provides the ability to validate cells upon change.
- *
- * Design information:
- * -------------------
- *
- * Validation is not based on angularjs validation, since it would work only when editing the field.
- *
- * Instead it adds custom properties to any field considered as invalid.
- *
- * <br/>
- * <br/>
- *
- * <div doc-module-components="ui.grid.expandable"></div>
- */
- var module = angular.module('ui.grid.validate', ['ui.grid']);
-
-
- /**
- * @ngdoc service
- * @name ui.grid.validate.service:uiGridValidateService
- *
- * @description Services for validation features
- */
- module.service('uiGridValidateService', ['$sce', '$q', '$http', 'i18nService', 'uiGridConstants', function ($sce, $q, $http, i18nService, uiGridConstants) {
- var service = {
-
- /**
- * @ngdoc object
- * @name validatorFactories
- * @propertyOf ui.grid.validate.service:uiGridValidateService
- * @description object containing all the factories used to validate data.<br/>
- * These factories will be in the form <br/>
- * ```
- * {
- * validatorFactory: function(argument) {
- * return function(newValue, oldValue, rowEntity, colDef) {
- * return true || false || promise
- * }
- * },
- * messageFunction: function(argument) {
- * return string
- * }
- * }
- * ```
- *
- * Promises should return true or false as result according to the result of validation.
- */
- validatorFactories: {},
-
- /**
- * @ngdoc service
- * @name setExternalFactoryFunction
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Adds a way to retrieve validators from an external service
- * <p>Validators from this external service have a higher priority than default
- * ones
- * @param {function} externalFactoryFunction a function that accepts name and argument to pass to a
- * validator factory and that returns an object with the same properties as
- * you can see in {@link ui.grid.validate.service:uiGridValidateService#properties_validatorFactories validatorFactories}
- */
- setExternalFactoryFunction: function(externalFactoryFunction) {
- service.externalFactoryFunction = externalFactoryFunction;
- },
-
- /**
- * @ngdoc service
- * @name clearExternalFactory
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Removes any link to external factory from this service
- */
- clearExternalFactory: function() {
- delete service.externalFactoryFunction;
- },
- /**
- * @ngdoc service
- * @name getValidatorFromExternalFactory
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Retrieves a validator by executing a validatorFactory
- * stored in an external service.
- * @param {string} name the name of the validator to retrieve
- * @param {object} argument an argument to pass to the validator factory
- */
- getValidatorFromExternalFactory: function(name, argument) {
- return service.externalFactoryFunction(name, argument).validatorFactory(argument);
- },
-
- /**
- * @ngdoc service
- * @name getMessageFromExternalFactory
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Retrieves a message stored in an external service.
- * @param {string} name the name of the validator
- * @param {object} argument an argument to pass to the message function
- */
- getMessageFromExternalFactory: function(name, argument) {
- return service.externalFactoryFunction(name, argument).messageFunction(argument);
- },
-
- /**
- * @ngdoc service
- * @name setValidator
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Adds a new validator to the service
- * @param {string} name the name of the validator, must be unique
- * @param {function} validatorFactory a factory that return a validatorFunction
- * @param {function} messageFunction a function that return the error message
- */
- setValidator: function(name, validatorFactory, messageFunction) {
- service.validatorFactories[name] = {
- validatorFactory: validatorFactory,
- messageFunction: messageFunction
- };
- },
- /**
- * @ngdoc service
- * @name getValidator
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Returns a validator registered to the service
- * or retrieved from the external factory
- * @param {string} name the name of the validator to retrieve
- * @param {object} argument an argument to pass to the validator factory
- * @returns {object} the validator function
- */
- getValidator: function(name, argument) {
- if (service.externalFactoryFunction) {
- var validator = service.getValidatorFromExternalFactory(name, argument);
- if (validator) {
- return validator;
- }
- }
- if (!service.validatorFactories[name]) {
- throw ("Invalid validator name: " + name);
- }
- return service.validatorFactories[name].validatorFactory(argument);
- },
- /**
- * @ngdoc service
- * @name getMessage
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Returns the error message related to the validator
- * @param {string} name the name of the validator
- * @param {object} argument an argument to pass to the message function
- * @returns {string} the error message related to the validator
- */
- getMessage: function(name, argument) {
- if (service.externalFactoryFunction) {
- var message = service.getMessageFromExternalFactory(name, argument);
- if (message) {
- return message;
- }
- }
- return service.validatorFactories[name].messageFunction(argument);
- },
- /**
- * @ngdoc service
- * @name isInvalid
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Returns true if the cell (identified by rowEntity, colDef) is invalid
- * @param {object} rowEntity the row entity of the cell
- * @param {object} colDef the colDef of the cell
- * @returns {boolean} true if the cell is invalid
- */
- isInvalid: function (rowEntity, colDef) {
- return rowEntity['$$invalid'+colDef.name];
- },
- /**
- * @ngdoc service
- * @name setInvalid
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Makes the cell invalid by adding the proper field to the entity
- * @param {object} rowEntity the row entity of the cell
- * @param {object} colDef the colDef of the cell
- */
- setInvalid: function (rowEntity, colDef) {
- rowEntity['$$invalid'+colDef.name] = true;
- },
-
- /**
- * @ngdoc service
- * @name setValid
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Makes the cell valid by removing the proper error field from the entity
- * @param {object} rowEntity the row entity of the cell
- * @param {object} colDef the colDef of the cell
- */
- setValid: function (rowEntity, colDef) {
- delete rowEntity['$$invalid'+colDef.name];
- },
- /**
- * @ngdoc service
- * @name setError
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Adds the proper error to the entity errors field
- * @param {object} rowEntity the row entity of the cell
- * @param {object} colDef the colDef of the cell
- * @param {string} validatorName the name of the validator that is failing
- */
- setError: function(rowEntity, colDef, validatorName) {
- if (!rowEntity['$$errors'+colDef.name]) {
- rowEntity['$$errors'+colDef.name] = {};
- }
- rowEntity['$$errors'+colDef.name][validatorName] = true;
- },
- /**
- * @ngdoc service
- * @name clearError
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Removes the proper error from the entity errors field
- * @param {object} rowEntity the row entity of the cell
- * @param {object} colDef the colDef of the cell
- * @param {string} validatorName the name of the validator that is failing
- */
- clearError: function(rowEntity, colDef, validatorName) {
- if (!rowEntity['$$errors'+colDef.name]) {
- return;
- }
- if (validatorName in rowEntity['$$errors'+colDef.name]) {
- delete rowEntity['$$errors'+colDef.name][validatorName];
- }
- },
-
- /**
- * @ngdoc function
- * @name getErrorMessages
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description returns an array of i18n-ed error messages.
- * @param {object} rowEntity gridOptions.data[] array instance whose errors we are looking for
- * @param {object} colDef the column whose errors we are looking for
- * @returns {array} An array of strings containing all the error messages for the cell
- */
- getErrorMessages: function(rowEntity, colDef) {
- var errors = [];
- if (!rowEntity['$$errors'+colDef.name] || Object.keys(rowEntity['$$errors'+colDef.name]).length === 0) {
- return errors;
- }
- Object.keys(rowEntity['$$errors'+colDef.name]).sort().forEach(function(validatorName) {
- errors.push(service.getMessage(validatorName, colDef.validators[validatorName]));
- });
-
- return errors;
- },
-
- /**
- * @ngdoc function
- * @name getFormattedErrors
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description returns the error i18n-ed and formatted in html to be shown inside the page.
- * @param {object} rowEntity gridOptions.data[] array instance whose errors we are looking for
- * @param {object} colDef the column whose errors we are looking for
- * @returns {object} An object that can be used in a template (like a cellTemplate) to display the
- * message inside the page (i.e. inside a div)
- */
- getFormattedErrors: function(rowEntity, colDef) {
- var msgString = "";
- var errors = service.getErrorMessages(rowEntity, colDef);
-
- if (!errors.length) {
- return;
- }
-
- errors.forEach(function(errorMsg) {
- msgString += errorMsg + "<br/>";
- });
- return $sce.trustAsHtml('<p><b>' + i18nService.getSafeText('validate.error') + '</b></p>' + msgString );
- },
- /**
- * @ngdoc function
- * @name getTitleFormattedErrors
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description returns the error i18n-ed and formatted in javaScript to be shown inside an html
- * title attribute.
- * @param {object} rowEntity gridOptions.data[] array instance whose errors we are looking for
- * @param {object} colDef the column whose errors we are looking for
- * @returns {object} An object that can be used in a template (like a cellTemplate) to display the
- * message inside an html title attribute
- */
- getTitleFormattedErrors: function(rowEntity, colDef) {
- var newLine = "\n";
- var msgString = "";
-
- var errors = service.getErrorMessages(rowEntity, colDef);
-
- if (!errors.length) {
- return;
- }
-
- errors.forEach(function(errorMsg) {
- msgString += errorMsg + newLine;
- });
- return $sce.trustAsHtml(i18nService.getSafeText('validate.error') + newLine + msgString);
- },
- /**
- * @ngdoc function
- * @name getTitleFormattedErrors
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description Executes all validators on a cell (identified by row entity and column definition) and sets or clears errors
- * @param {object} rowEntity the row entity of the cell we want to run the validators on
- * @param {object} colDef the column definition of the cell we want to run the validators on
- * @param {object} newValue the value the user just entered
- * @param {object} oldValue the value the field had before
- */
- runValidators: function(rowEntity, colDef, newValue, oldValue, grid) {
-
- if (newValue === oldValue) {
- // If the value has not changed we perform no validation
- return;
- }
-
- if (typeof(colDef.name) === 'undefined' || !colDef.name) {
- throw new Error('colDef.name is required to perform validation');
- }
-
- service.setValid(rowEntity, colDef);
-
- var validateClosureFactory = function(rowEntity, colDef, validatorName) {
- return function(value) {
- if (!value) {
- service.setInvalid(rowEntity, colDef);
- service.setError(rowEntity, colDef, validatorName);
- if (grid) {
- grid.api.validate.raise.validationFailed(rowEntity, colDef, newValue, oldValue);
- }
- }
- };
- };
- var promises = [];
- for (var validatorName in colDef.validators) {
- service.clearError(rowEntity, colDef, validatorName);
- var msg;
- var validatorFunction = service.getValidator(validatorName, colDef.validators[validatorName]);
- // We pass the arguments as oldValue, newValue so they are in the same order
- // as ng-model validators (modelValue, viewValue)
- var promise = $q
- .when(validatorFunction(oldValue, newValue, rowEntity, colDef))
- .then(validateClosureFactory(rowEntity, colDef, validatorName));
- promises.push(promise);
- }
-
- return $q.all(promises);
- },
- /**
- * @ngdoc function
- * @name createDefaultValidators
- * @methodOf ui.grid.validate.service:uiGridValidateService
- * @description adds the basic validators to the list of service validators
- */
- createDefaultValidators: function() {
- service.setValidator('minLength',
- function (argument) {
- return function (oldValue, newValue, rowEntity, colDef) {
- if (newValue === undefined || newValue === null || newValue === '') {
- return true;
- }
- return newValue.length >= argument;
- };
- },
- function(argument) {
- return i18nService.getSafeText('validate.minLength').replace('THRESHOLD', argument);
- });
-
- service.setValidator('maxLength',
- function (argument) {
- return function (oldValue, newValue, rowEntity, colDef) {
- if (newValue === undefined || newValue === null || newValue === '') {
- return true;
- }
- return newValue.length <= argument;
- };
- },
- function(threshold) {
- return i18nService.getSafeText('validate.maxLength').replace('THRESHOLD', threshold);
- });
-
- service.setValidator('required',
- function (argument) {
- return function (oldValue, newValue, rowEntity, colDef) {
- if (argument) {
- return !(newValue === undefined || newValue === null || newValue === '');
- }
- return true;
- };
- },
- function(argument) {
- return i18nService.getSafeText('validate.required');
- });
- },
- initializeGrid: function (scope, grid) {
- grid.validate = {
-
- isInvalid: service.isInvalid,
- getFormattedErrors: service.getFormattedErrors,
-
- getTitleFormattedErrors: service.getTitleFormattedErrors,
- runValidators: service.runValidators
- };
-
- /**
- * @ngdoc object
- * @name ui.grid.validate.api:PublicApi
- *
- * @description Public Api for validation feature
- */
- var publicApi = {
- events: {
- validate: {
- /**
- * @ngdoc event
- * @name validationFailed
- * @eventOf ui.grid.validate.api:PublicApi
- * @description raised when one or more failure happened during validation
- * <pre>
- * gridApi.validate.on.validationFailed(scope, function(rowEntity, colDef, newValue, oldValue){...})
- * </pre>
- * @param {object} rowEntity the options.data element whose validation failed
- * @param {object} colDef the column whose validation failed
- * @param {object} newValue new value
- * @param {object} oldValue old value
- */
- validationFailed: function (rowEntity, colDef, newValue, oldValue) {
- }
- }
- },
- methods: {
- validate: {
- /**
- * @ngdoc function
- * @name isInvalid
- * @methodOf ui.grid.validate.api:PublicApi
- * @description checks if a cell (identified by rowEntity, colDef) is invalid
- * @param {object} rowEntity gridOptions.data[] array instance we want to check
- * @param {object} colDef the column whose errors we want to check
- * @returns {boolean} true if the cell value is not valid
- */
- isInvalid: function(rowEntity, colDef) {
- return grid.validate.isInvalid(rowEntity, colDef);
- },
- /**
- * @ngdoc function
- * @name getErrorMessages
- * @methodOf ui.grid.validate.api:PublicApi
- * @description returns an array of i18n-ed error messages.
- * @param {object} rowEntity gridOptions.data[] array instance whose errors we are looking for
- * @param {object} colDef the column whose errors we are looking for
- * @returns {array} An array of strings containing all the error messages for the cell
- */
- getErrorMessages: function (rowEntity, colDef) {
- return grid.validate.getErrorMessages(rowEntity, colDef);
- },
- /**
- * @ngdoc function
- * @name getFormattedErrors
- * @methodOf ui.grid.validate.api:PublicApi
- * @description returns the error i18n-ed and formatted in html to be shown inside the page.
- * @param {object} rowEntity gridOptions.data[] array instance whose errors we are looking for
- * @param {object} colDef the column whose errors we are looking for
- * @returns {object} An object that can be used in a template (like a cellTemplate) to display the
- * message inside the page (i.e. inside a div)
- */
- getFormattedErrors: function (rowEntity, colDef) {
- return grid.validate.getFormattedErrors(rowEntity, colDef);
- },
- /**
- * @ngdoc function
- * @name getTitleFormattedErrors
- * @methodOf ui.grid.validate.api:PublicApi
- * @description returns the error i18n-ed and formatted in javaScript to be shown inside an html
- * title attribute.
- * @param {object} rowEntity gridOptions.data[] array instance whose errors we are looking for
- * @param {object} colDef the column whose errors we are looking for
- * @returns {object} An object that can be used in a template (like a cellTemplate) to display the
- * message inside an html title attribute
- */
- getTitleFormattedErrors: function (rowEntity, colDef) {
- return grid.validate.getTitleFormattedErrors(rowEntity, colDef);
- }
- }
- }
- };
-
- grid.api.registerEventsFromObject(publicApi.events);
- grid.api.registerMethodsFromObject(publicApi.methods);
- if (grid.edit) {
- grid.api.edit.on.afterCellEdit(scope, function(rowEntity, colDef, newValue, oldValue) {
- grid.validate.runValidators(rowEntity, colDef, newValue, oldValue, grid);
- });
- }
- service.createDefaultValidators();
- }
-
- };
-
- return service;
- }]);
-
-
- /**
- * @ngdoc directive
- * @name ui.grid.validate.directive:uiGridValidate
- * @element div
- * @restrict A
- * @description Adds validating features to the ui-grid directive.
- * @example
- <example module="app">
- <file name="app.js">
- var app = angular.module('app', ['ui.grid', 'ui.grid.edit', 'ui.grid.validate']);
- app.controller('MainCtrl', ['$scope', function ($scope) {
- $scope.data = [
- { name: 'Bob', title: 'CEO' },
- { name: 'Frank', title: 'Lowly Developer' }
- ];
- $scope.columnDefs = [
- {name: 'name', enableCellEdit: true, validators: {minLength: 3, maxLength: 9}, cellTemplate: 'ui-grid/cellTitleValidator'},
- {name: 'title', enableCellEdit: true, validators: {required: true}, cellTemplate: 'ui-grid/cellTitleValidator'}
- ];
- }]);
- </file>
- <file name="index.html">
- <div ng-controller="MainCtrl">
- <div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-edit ui-grid-validate></div>
- </div>
- </file>
- </example>
- */
- module.directive('uiGridValidate', ['gridUtil', 'uiGridValidateService', function (gridUtil, uiGridValidateService) {
- return {
- priority: 0,
- replace: true,
- require: '^uiGrid',
- scope: false,
- compile: function () {
- return {
- pre: function ($scope, $elm, $attrs, uiGridCtrl) {
- uiGridValidateService.initializeGrid($scope, uiGridCtrl.grid);
- },
- post: function ($scope, $elm, $attrs, uiGridCtrl) {
- }
- };
- }
- };
- }]);
- })();
|