2 * Created by rcohen on 9/15/2016.
5 import {ValidationUtils, PROPERTY_TYPES} from "app/utils";
6 import {DataTypesService} from "app/services";
7 import {SchemaProperty} from "app/models";
9 export interface ITypeMapScope extends ng.IScope {
10 parentFormObj:ng.IFormController;
11 schemaProperty:SchemaProperty;
12 isMapKeysUnique:boolean;
13 isSchemaTypeDataType:boolean;
15 mapKeys:Array<string>;//array of map keys
16 MapKeyValidationPattern:RegExp;
17 fieldsPrefixName:string;
22 getValidationPattern(type:string):RegExp;
23 validateIntRange(value:string):boolean;
24 changeKeyOfMap(newKey:string, index:number, fieldName:string):void;
25 deleteMapItem(index:number):void;
26 addMapItemFields():void;
27 parseToCorrectType(objectOfValues:any, locationInObj:string, type:string):void;
28 getNumber(num:number):Array<any>;
32 export class TypeMapDirective implements ng.IDirective {
34 constructor(private DataTypesService:DataTypesService,
35 private MapKeyValidationPattern:RegExp,
36 private ValidationUtils:ValidationUtils,
37 private $timeout:ng.ITimeoutService) {
41 valueObjRef: '=',//ref to map object in the parent value object
42 schemaProperty: '=',//get the schema.property object
43 parentFormObj: '=',//ref to parent form (get angular form object)
44 fieldsPrefixName: '=',//prefix for form fields names
45 readOnly: '=',//is form read only
46 defaultValue: '@',//this map default value
52 template = ():string => {
53 return require('./type-map-directive.html');
56 link = (scope:ITypeMapScope, element:any, $attr:any) => {
57 scope.MapKeyValidationPattern = this.MapKeyValidationPattern;
58 scope.isMapKeysUnique = true;
60 //reset valueObjRef and mapKeys when schema type is changed
61 scope.$watchCollection('schemaProperty.type', (newData:any):void => {
62 scope.isSchemaTypeDataType = this.DataTypesService.isDataTypeForSchemaType(scope.schemaProperty);
63 if (scope.valueObjRef) {
64 scope.mapKeys = Object.keys(scope.valueObjRef);
68 //when user brows between properties in "edit property form"
69 scope.$watchCollection('fieldsPrefixName', (newData:any):void => {
70 if (!scope.valueObjRef) {
71 scope.valueObjRef = {};
73 scope.mapKeys = Object.keys(scope.valueObjRef);
75 if ($attr.defaultValue) {
76 scope.mapDefaultValue = JSON.parse($attr.defaultValue);
80 //return dummy array in order to prevent rendering map-keys ng-repeat again when a map key is changed
81 scope.getNumber = (num:number):Array<any> => {
82 return new Array(num);
85 scope.getValidationPattern = (type:string):RegExp => {
86 return this.ValidationUtils.getValidationPattern(type);
89 scope.validateIntRange = (value:string):boolean => {
90 return !value || this.ValidationUtils.validateIntRange(value);
93 scope.changeKeyOfMap = (newKey:string, index:number, fieldName:string):void => {
94 let oldKey = Object.keys(scope.valueObjRef)[index];
95 let existsKeyIndex = Object.keys(scope.valueObjRef).indexOf(newKey);
96 if (existsKeyIndex > -1 && existsKeyIndex != index) {
97 scope.parentFormObj[fieldName].$setValidity('keyExist', false);
98 scope.isMapKeysUnique = false;
100 scope.parentFormObj[fieldName].$setValidity('keyExist', true);
101 scope.isMapKeysUnique = true;
102 if (!scope.parentFormObj[fieldName].$invalid) {
103 //To preserve the order of the keys, delete each one and recreate
105 angular.copy(scope.valueObjRef , newObj);
106 angular.forEach(newObj,function(value:any,key:string){
107 delete scope.valueObjRef[key];
109 scope.valueObjRef[newKey] = value;
111 scope.valueObjRef[key] = value;
118 scope.deleteMapItem = (index:number):void=> {
119 delete scope.valueObjRef[scope.mapKeys[index]];
120 scope.mapKeys.splice(index, 1);
121 if (!scope.mapKeys.length) {//only when user removes all pairs of key-value fields - put the default
122 if (scope.mapDefaultValue) {
123 angular.copy(scope.mapDefaultValue, scope.valueObjRef);
124 scope.mapKeys = Object.keys(scope.valueObjRef);
129 scope.addMapItemFields = ():void => {
130 scope.valueObjRef[''] = null;
131 scope.mapKeys = Object.keys(scope.valueObjRef);
134 scope.parseToCorrectType = (objectOfValues:any, locationInObj:string, type:string):void => {
135 if (objectOfValues[locationInObj] && type != PROPERTY_TYPES.STRING) {
136 objectOfValues[locationInObj] = JSON.parse(objectOfValues[locationInObj]);
141 public static factory = (DataTypesService:DataTypesService,
142 MapKeyValidationPattern:RegExp,
143 ValidationUtils:ValidationUtils,
144 $timeout:ng.ITimeoutService)=> {
145 return new TypeMapDirective(DataTypesService, MapKeyValidationPattern, ValidationUtils, $timeout);
149 TypeMapDirective.factory.$inject = ['Sdc.Services.DataTypesService', 'MapKeyValidationPattern', 'ValidationUtils', '$timeout'];