matrix-validation.js 2.8 KB
/**
 * Created by Techniv on 11/01/2017.
 */

angular.module('matrixValidation', []).directive('matrixValidator', [
    '$timeout',
    ($timeout) => {
        return {
            restrict: 'A',
            require: 'form',
            link: (scope, element, attributes, ctrl) => {
                let validator = scope.$eval(attributes.all);

                let inputMatrix = [];
                $timeout(()=>{
                    let inputs = angular.element(element[0].querySelectorAll('[data-row]'));
                    for(let i = 0; i < inputs.length; i++){
                        let input = inputs[i];
                        let name = input.name;

                        let $input = angular.element(input);
                        let inputCtrl = ctrl[name];
                        let inputScope = $input.scope();

                        let x = parseInt(inputScope.$eval(input.dataset.row));
                        let y = parseInt(inputScope.$eval(input.dataset.col));


                        if(isNaN(x) || isNaN(y) | ! inputCtrl) continue;

                        if( ! inputMatrix[x] ) inputMatrix[x] = [];
                        inputMatrix[x][y] = inputCtrl;

                        inputCtrl.$validators.matrixValidator = validationHandler.bind(inputCtrl);
                    }

                    validationHandler.call(false);
                });


                function validationHandler(){
                    let returnValidation, input, scope, xInput, yInput;

                    if(this && this.valueOf()){
                        returnValidation = false;
                        input = this.$$element[0];
                        scope = this.$$scope;

                        xInput = parseInt(scope.$eval(input.dataset.row));
                        yInput = parseInt(scope.$eval(input.dataset.col));
                    }

                    let matrix = inputMatrix.map((row) => {
                        return row.map((value) => value.$$rawModelValue);
                    });

                    let validationMatrix = matrix.map( row => row.map(() => null));

                    validationMatrix = validator(matrix, validationMatrix);

                    for(let x = 0; x < inputMatrix.length; x++){
                        let row = inputMatrix[x];
                        for(let y = 0; y < row.length; y++){
                            if(x == xInput && y == yInput){
                                returnValidation = validationMatrix[x][y];
                                continue;
                            }

                            let inputCtrl = row[y];

                            inputCtrl.$setValidity('matrixValidator',validationMatrix[x][y]);
                        }
                    }

                    return returnValidation;
                }
            }
        }
    }
]);