@syncfusion/ej2-angular-base 20.3.47 → 20.3.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ej2-angular-base.umd.min.js +1 -1
- package/dist/global/ej2-angular-base.min.js +1 -1
- package/dist/global/index.d.ts +1 -1
- package/dist/ts/complex-array-base.ts +262 -0
- package/dist/ts/component-base.ts +381 -0
- package/dist/ts/form-base.ts +156 -0
- package/dist/ts/template.ts +81 -0
- package/dist/ts/util.ts +143 -0
- package/package.json +7 -19
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* filename: ej2-angular-base.umd.min.js
|
|
3
|
-
* version : 20.3.
|
|
3
|
+
* version : 20.3.50
|
|
4
4
|
* Copyright Syncfusion Inc. 2001 - 2020. All rights reserved.
|
|
5
5
|
* Use of this code is subject to the terms of our license.
|
|
6
6
|
* A copy of the current license can be obtained at any time by e-mailing
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* filename: ej2-angular-base.min.js
|
|
3
|
-
* version : 20.3.
|
|
3
|
+
* version : 20.3.50
|
|
4
4
|
* Copyright Syncfusion Inc. 2001 - 2020. All rights reserved.
|
|
5
5
|
* Use of this code is subject to the terms of our license.
|
|
6
6
|
* A copy of the current license can be obtained at any time by e-mailing
|
package/dist/global/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* filename: index.d.ts
|
|
3
|
-
* version : 20.3.
|
|
3
|
+
* version : 20.3.50
|
|
4
4
|
* Copyright Syncfusion Inc. 2001 - 2020. All rights reserved.
|
|
5
5
|
* Use of this code is subject to the terms of our license.
|
|
6
6
|
* A copy of the current license can be obtained at any time by e-mailing
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { QueryList, SimpleChanges, SimpleChange, EmbeddedViewRef } from '@angular/core';
|
|
2
|
+
import { getValue, setValue, isNullOrUndefined } from '@syncfusion/ej2-base';
|
|
3
|
+
import { clearTemplate, registerEvents } from './util';
|
|
4
|
+
|
|
5
|
+
const refRegex: RegExp = /Ref$/;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Complex Array Base module
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface IChildChange {
|
|
12
|
+
dirIndex: number;
|
|
13
|
+
change: Object;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface Tag {
|
|
17
|
+
hasChanges: boolean;
|
|
18
|
+
getProperties: Function;
|
|
19
|
+
isInitChanges: boolean;
|
|
20
|
+
clearTemplate?: (args: string[]) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class ComplexBase<T> {
|
|
24
|
+
public isUpdated: boolean;
|
|
25
|
+
public hasChanges?: boolean = false;
|
|
26
|
+
public dirIndex?: number;
|
|
27
|
+
public propCollection?: { [key: string]: Object } = {};
|
|
28
|
+
public dataSource?: { [key: string]: Object } = {};
|
|
29
|
+
public property?: string;
|
|
30
|
+
public tags?: string[] = [];
|
|
31
|
+
public isInitChanges: boolean;
|
|
32
|
+
private tagObjects?: { name: string, instance: Tag }[] = [];
|
|
33
|
+
private registeredTemplate: { [key: string]: EmbeddedViewRef<Object>[] };
|
|
34
|
+
// tslint:disable-next-line:no-any
|
|
35
|
+
public directivePropList: any;
|
|
36
|
+
public ngOnInit(): void {
|
|
37
|
+
this.registeredTemplate = {};
|
|
38
|
+
for (let tag of this.tags) {
|
|
39
|
+
let objInstance: Tag = getValue('child' + tag.substring(0, 1).toUpperCase() + tag.substring(1), this);
|
|
40
|
+
if (objInstance) {
|
|
41
|
+
this.tagObjects.push({ instance: objInstance, name: tag });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
let templateProperties: string[] = Object.keys(this);
|
|
45
|
+
for(let i = 0; i < templateProperties.length; i++) {
|
|
46
|
+
var tempProp = getValue(templateProperties[i], this);
|
|
47
|
+
if (typeof tempProp === 'object' && tempProp.elementRef && !getValue(templateProperties[i].indexOf('Ref') !== -1 ? templateProperties[i] : templateProperties[i] + 'Ref', this)){
|
|
48
|
+
setValue(templateProperties[i].indexOf('Ref') !== -1 ? templateProperties[i] : templateProperties[i] + 'Ref', tempProp, this);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
templateProperties = Object.keys(this)
|
|
52
|
+
templateProperties = templateProperties.filter((val: string): boolean => {
|
|
53
|
+
return /Ref$/i.test(val);
|
|
54
|
+
});
|
|
55
|
+
for (let tempName of templateProperties) {
|
|
56
|
+
let propName: string = tempName.replace('Ref', '');
|
|
57
|
+
setValue(propName.replace('_', '.'), getValue(propName, this), this.propCollection);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Angular 9 compatibility to overcome ngOnchange not get triggered issue
|
|
61
|
+
// To Update properties to "this.propCollection"
|
|
62
|
+
let propList: string[] = Object.keys(this);
|
|
63
|
+
/* istanbul ignore next */
|
|
64
|
+
if (this.directivePropList) {
|
|
65
|
+
for (let k: number = 0; k < this.directivePropList.length; k++) {
|
|
66
|
+
let dirPropName: string = this.directivePropList[k];
|
|
67
|
+
if (propList.indexOf(dirPropName) !== -1 && getValue(dirPropName, this)) {
|
|
68
|
+
setValue(dirPropName, getValue(dirPropName, this), this.propCollection);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
this.hasChanges = true;
|
|
72
|
+
}
|
|
73
|
+
this.isInitChanges = true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
protected registerEvents(eventList: string[]): void {
|
|
77
|
+
registerEvents(eventList, this, true);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public ngOnChanges(changes: SimpleChanges): void {
|
|
81
|
+
for (let propName of Object.keys(changes)) {
|
|
82
|
+
let changedVal: SimpleChange = changes[propName];
|
|
83
|
+
this.propCollection[propName] = changedVal.currentValue;
|
|
84
|
+
}
|
|
85
|
+
this.isUpdated = false;
|
|
86
|
+
this.hasChanges = true;
|
|
87
|
+
}
|
|
88
|
+
/* istanbul ignore next */
|
|
89
|
+
public clearTemplate(templateNames: string[]): void {
|
|
90
|
+
clearTemplate(this, templateNames);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public getProperties(): { [key: string]: Object } {
|
|
94
|
+
/* istanbul ignore next */
|
|
95
|
+
for (let tagObject of this.tagObjects) {
|
|
96
|
+
this.propCollection[tagObject.name] = tagObject.instance.getProperties();
|
|
97
|
+
}
|
|
98
|
+
return this.propCollection;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public isChanged(): boolean {
|
|
102
|
+
let result: boolean = this.hasChanges;
|
|
103
|
+
if (!isNullOrUndefined(this.propCollection[this.property])) {
|
|
104
|
+
let tempProps: any = this.propCollection[this.property];
|
|
105
|
+
let props: string[]= Object.keys(tempProps[0]);
|
|
106
|
+
for (let d: number = 0; d < props.length; d++) {
|
|
107
|
+
if (!isNullOrUndefined(this.propCollection[props[d]])) {
|
|
108
|
+
let val: any = getValue(props[d], this);
|
|
109
|
+
let propVal: any = (this.propCollection[this.property] as any)[0][props[d]];
|
|
110
|
+
if (!isNullOrUndefined(val) && this.propCollection[props[d]] !== val
|
|
111
|
+
&& propVal !== val) {
|
|
112
|
+
setValue(props[d], val, (this.propCollection[this.property] as any)[0]);
|
|
113
|
+
setValue(props[d], val, this.propCollection);
|
|
114
|
+
this.hasChanges = true;
|
|
115
|
+
this.isUpdated = false;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/* istanbul ignore next */
|
|
122
|
+
for (let item of this.tagObjects) {
|
|
123
|
+
result = result || item.instance.hasChanges;
|
|
124
|
+
}
|
|
125
|
+
return result || this.hasChanges;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public ngAfterContentChecked(): void {
|
|
129
|
+
this.hasChanges = this.isChanged();
|
|
130
|
+
if (this.isInitChanges || this.hasChanges){
|
|
131
|
+
let templateProperties: string[] = Object.keys(this);
|
|
132
|
+
templateProperties = templateProperties.filter((val: string) => {
|
|
133
|
+
return refRegex.test(val);
|
|
134
|
+
});
|
|
135
|
+
for (let tempName of templateProperties) {
|
|
136
|
+
let propName: string = tempName.replace('Ref', '');
|
|
137
|
+
setValue(propName.replace('_', '.'), getValue(propName, this), this.propCollection);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public ngAfterViewChecked(): void {
|
|
143
|
+
/* istanbul ignore next */
|
|
144
|
+
if (this.isUpdated) {
|
|
145
|
+
this.hasChanges = false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
public ngAfterViewInit(): void {
|
|
150
|
+
/* istanbul ignore next */
|
|
151
|
+
this.isInitChanges = false;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
public ngOnDestroy(): void {
|
|
155
|
+
/* istanbul ignore next */
|
|
156
|
+
this.directivePropList = [];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export class ArrayBase<T> {
|
|
162
|
+
public isInitChanges: boolean;
|
|
163
|
+
public list: T[] & ComplexBase<T>[] = [];
|
|
164
|
+
public children: QueryList<T>;
|
|
165
|
+
public hasChanges: boolean = false;
|
|
166
|
+
private propertyName: string;
|
|
167
|
+
public hasNewChildren: boolean;
|
|
168
|
+
|
|
169
|
+
constructor(propertyName: string) {
|
|
170
|
+
this.propertyName = propertyName;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public ngOnInit(): void {
|
|
174
|
+
this.isInitChanges = true;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public ngAfterContentInit(): void {
|
|
178
|
+
let index: number = 0;
|
|
179
|
+
/* istanbul ignore next */
|
|
180
|
+
this.list = this.children.map((child: T & ComplexBase<T>) => {
|
|
181
|
+
child.dirIndex = index++;
|
|
182
|
+
child.property = this.propertyName;
|
|
183
|
+
return child;
|
|
184
|
+
});
|
|
185
|
+
this.hasChanges = true;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
public getProperties(): Object[] {
|
|
189
|
+
let onlyProp: Object[] = [];
|
|
190
|
+
for (let item of this.list) {
|
|
191
|
+
onlyProp.push((<{ getProperties: Function }>item).getProperties());
|
|
192
|
+
}
|
|
193
|
+
return onlyProp;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
public isChanged(): boolean {
|
|
197
|
+
let result: boolean = false;
|
|
198
|
+
let index: number = 0;
|
|
199
|
+
let isSourceChanged: boolean = false;
|
|
200
|
+
// tslint:disable-next-line
|
|
201
|
+
let childrenDataSource: any = this.children.map(
|
|
202
|
+
(child: T & ComplexBase<T>) => {
|
|
203
|
+
return child;
|
|
204
|
+
}
|
|
205
|
+
);
|
|
206
|
+
/* istanbul ignore next */
|
|
207
|
+
if (this.list.length === this.children.length) {
|
|
208
|
+
for (let i: number = 0; i < this.list.length; i++) {
|
|
209
|
+
if (this.list[i].propCollection.dataSource) {
|
|
210
|
+
if (this.list[i].dataSource && this.list[i].propCollection.dataSource !== this.list[i].dataSource) {
|
|
211
|
+
this.list[i].propCollection.dataSource = this.list[i].dataSource;
|
|
212
|
+
this.list[i].hasChanges = true;
|
|
213
|
+
}
|
|
214
|
+
isSourceChanged = (JSON.stringify(this.list[i].propCollection.dataSource) !==
|
|
215
|
+
JSON.stringify(childrenDataSource[i].propCollection.dataSource));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
this.hasNewChildren = (this.list.length !== this.children.length || isSourceChanged) ? true : null;
|
|
221
|
+
if (this.hasNewChildren) {
|
|
222
|
+
this.list = this.children.map((child: T & ComplexBase<T>) => {
|
|
223
|
+
child.dirIndex = index++;
|
|
224
|
+
child.property = this.propertyName;
|
|
225
|
+
return child;
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
/* istanbul ignore end */
|
|
229
|
+
for (let item of this.list) {
|
|
230
|
+
result = result || (<{ hasChanges: boolean }>item).hasChanges;
|
|
231
|
+
}
|
|
232
|
+
return !!this.list.length && result;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
public clearTemplate(templateNames: string[]): void {
|
|
236
|
+
/* istanbul ignore next */
|
|
237
|
+
for (let item of this.list) {
|
|
238
|
+
(<{ clearTemplate: Function }>item).clearTemplate(templateNames && templateNames.map((val: string): string => {
|
|
239
|
+
return new RegExp(this.propertyName).test(val) ? val.replace(this.propertyName + '.', '') : val;
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
public ngAfterContentChecked(): void {
|
|
245
|
+
this.hasChanges = this.isChanged();
|
|
246
|
+
for (let i: number = 0; i < this.list.length; i++) {
|
|
247
|
+
if (getValue('childColumns', this.list[i]) && getValue('property', this.list[i]) === 'columns') {
|
|
248
|
+
setValue('columns', getValue('childColumns', this.list[i]).getProperties(), this.list[i].propCollection);
|
|
249
|
+
}
|
|
250
|
+
this.list[i].isUpdated = true;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
public ngAfterViewInit(): void {
|
|
255
|
+
this.isInitChanges = false;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
public ngOnDestroy(): void {
|
|
259
|
+
this.list = [];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
}
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Angular Component Base Module
|
|
3
|
+
*/
|
|
4
|
+
import { getValue, isUndefined, setValue, isNullOrUndefined, attributes, createElement } from '@syncfusion/ej2-base';
|
|
5
|
+
import { EventEmitter, EmbeddedViewRef, Renderer2, ElementRef } from '@angular/core';
|
|
6
|
+
import { clearTemplate, registerEvents } from './util';
|
|
7
|
+
|
|
8
|
+
const SVG_REG: RegExp = /^svg|^path|^g/;
|
|
9
|
+
|
|
10
|
+
export interface IComponentBase {
|
|
11
|
+
registerEvents: (eventList: string[]) => void;
|
|
12
|
+
addTwoWay: (propList: string[]) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface Tag {
|
|
16
|
+
hasChanges: boolean;
|
|
17
|
+
getProperties?: Function;
|
|
18
|
+
isInitChanges: boolean;
|
|
19
|
+
hasNewChildren: boolean;
|
|
20
|
+
list: TagList[];
|
|
21
|
+
clearTemplate?: (arg: string[]) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface TagList {
|
|
25
|
+
getProperties: Function;
|
|
26
|
+
hasChanges: boolean;
|
|
27
|
+
isUpdated: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class ComponentBase<T> {
|
|
31
|
+
public element: HTMLElement;
|
|
32
|
+
public tags: string[];
|
|
33
|
+
private ngAttr: string;
|
|
34
|
+
private srenderer: Renderer2;
|
|
35
|
+
protected isProtectedOnChange: boolean = true;
|
|
36
|
+
private isAngular: boolean;
|
|
37
|
+
private isFormInit: boolean = true;
|
|
38
|
+
public preventChange: boolean;
|
|
39
|
+
public isPreventChange: boolean;
|
|
40
|
+
protected oldProperties: { [key: string]: Object };
|
|
41
|
+
protected changedProperties: { [key: string]: Object };
|
|
42
|
+
protected finalUpdate: Function;
|
|
43
|
+
protected isUpdated: boolean;
|
|
44
|
+
public ngEle: ElementRef;
|
|
45
|
+
|
|
46
|
+
private tagObjects: { name: string, instance: Tag }[];
|
|
47
|
+
public onPropertyChanged: (newProp: Object, oldProp: Object) => void;
|
|
48
|
+
public appendTo: (ele: string | HTMLElement) => void;
|
|
49
|
+
public setProperties: (obj: Object, muteOnChange: boolean) => void;
|
|
50
|
+
public properties: Object;
|
|
51
|
+
public dataBind: Function;
|
|
52
|
+
private createElement: Function;
|
|
53
|
+
protected saveChanges(key: string, newValue: Object, oldValue: Object): void {
|
|
54
|
+
if (this.isProtectedOnChange) { return; }
|
|
55
|
+
this.oldProperties[key] = oldValue;
|
|
56
|
+
this.changedProperties[key] = newValue;
|
|
57
|
+
this.finalUpdate();
|
|
58
|
+
// tslint:disable-next-line:no-any
|
|
59
|
+
let changeTime: any = setTimeout(this.dataBind.bind(this));
|
|
60
|
+
let clearUpdate: Function = () => {
|
|
61
|
+
clearTimeout(changeTime);
|
|
62
|
+
};
|
|
63
|
+
this.finalUpdate = clearUpdate;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
public destroy: Function;
|
|
67
|
+
private registeredTemplate: { [key: string]: EmbeddedViewRef<Object>[] };
|
|
68
|
+
private complexTemplate: string[];
|
|
69
|
+
|
|
70
|
+
private ngBoundedEvents: { [key: string]: Map<object, object> };
|
|
71
|
+
// tslint:disable-next-line:no-any
|
|
72
|
+
public ngOnInit(isTempRef?: any): void {
|
|
73
|
+
// tslint:disable-next-line:no-any
|
|
74
|
+
let tempOnThis: any = isTempRef || this;
|
|
75
|
+
tempOnThis.registeredTemplate = {};
|
|
76
|
+
tempOnThis.ngBoundedEvents = {};
|
|
77
|
+
tempOnThis.isAngular = true;
|
|
78
|
+
tempOnThis.isFormInit = true;
|
|
79
|
+
/* istanbul ignore next */
|
|
80
|
+
if (isTempRef) {
|
|
81
|
+
this.tags = isTempRef.tags;
|
|
82
|
+
}
|
|
83
|
+
tempOnThis.tags = this.tags || [];
|
|
84
|
+
tempOnThis.complexTemplate = this.complexTemplate || [];
|
|
85
|
+
tempOnThis.tagObjects = [];
|
|
86
|
+
tempOnThis.ngAttr = this.getAngularAttr(tempOnThis.element);
|
|
87
|
+
/* istanbul ignore next */
|
|
88
|
+
tempOnThis.createElement = (tagName: string, prop?:
|
|
89
|
+
{ id?: string, className?: string, innerHTML?: string, styles?: string, attrs?: { [key: string]: string } }) => {
|
|
90
|
+
//tslint:disable-next-line
|
|
91
|
+
let ele: Element = tempOnThis.srenderer ? tempOnThis.srenderer.createElement(tagName) : createElement(tagName);
|
|
92
|
+
if (typeof (prop) === 'undefined') {
|
|
93
|
+
return <HTMLElement>ele;
|
|
94
|
+
}
|
|
95
|
+
ele.innerHTML = (prop.innerHTML ? prop.innerHTML : '');
|
|
96
|
+
|
|
97
|
+
if (prop.className !== undefined) {
|
|
98
|
+
ele.className = prop.className;
|
|
99
|
+
}
|
|
100
|
+
if (prop.id !== undefined) {
|
|
101
|
+
ele.id = prop.id;
|
|
102
|
+
}
|
|
103
|
+
if (prop.styles !== undefined) {
|
|
104
|
+
ele.setAttribute('style', prop.styles);
|
|
105
|
+
}
|
|
106
|
+
if (tempOnThis.ngAttr !== undefined) {
|
|
107
|
+
ele.setAttribute(tempOnThis.ngAttr, '');
|
|
108
|
+
}
|
|
109
|
+
if (prop.attrs !== undefined) {
|
|
110
|
+
attributes(ele, prop.attrs);
|
|
111
|
+
}
|
|
112
|
+
return <HTMLElement>ele;
|
|
113
|
+
};
|
|
114
|
+
for (let tag of tempOnThis.tags) {
|
|
115
|
+
let tagObject: { name: string, instance: Tag } = {
|
|
116
|
+
instance: getValue('child' + tag.substring(0, 1).toUpperCase() + tag.substring(1), tempOnThis),
|
|
117
|
+
name: tag
|
|
118
|
+
};
|
|
119
|
+
tempOnThis.tagObjects.push(tagObject);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let complexTemplates: string[] = Object.keys(tempOnThis);
|
|
123
|
+
for (let i = 0; i < complexTemplates.length; i++) {
|
|
124
|
+
var compProp = getValue(complexTemplates[i], tempOnThis);
|
|
125
|
+
if (typeof compProp === 'object' && compProp && compProp.elementRef) {
|
|
126
|
+
if (typeof compProp === 'object' && compProp && compProp.elementRef && complexTemplates[i].indexOf('_') !== -1 && complexTemplates[i].indexOf('Ref') === -1) {
|
|
127
|
+
setValue(complexTemplates[i] + 'Ref', compProp, tempOnThis);
|
|
128
|
+
}
|
|
129
|
+
if (tempOnThis.viewContainerRef && !getValue("_viewContainerRef", compProp.elementRef.nativeElement) && !getValue("propName", compProp.elementRef.nativeElement)) {
|
|
130
|
+
setValue("_viewContainerRef", tempOnThis.viewContainerRef, compProp.elementRef.nativeElement);
|
|
131
|
+
setValue("propName", complexTemplates[i].replace("Ref", ''), compProp.elementRef.nativeElement);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
complexTemplates = Object.keys(tempOnThis);
|
|
136
|
+
complexTemplates = complexTemplates.filter((val: string): boolean => {
|
|
137
|
+
return /Ref$/i.test(val) && /\_/i.test(val);
|
|
138
|
+
});
|
|
139
|
+
for (let tempName of complexTemplates) {
|
|
140
|
+
let propName: string = tempName.replace('Ref', '');
|
|
141
|
+
let val: Object = {};
|
|
142
|
+
setValue(propName.replace('_', '.'), getValue(propName, tempOnThis), val);
|
|
143
|
+
tempOnThis.setProperties(val, true);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
public getAngularAttr(ele: Element): string {
|
|
148
|
+
let attributes: NamedNodeMap = ele.attributes;
|
|
149
|
+
let length: number = attributes.length;
|
|
150
|
+
let ngAr: string;
|
|
151
|
+
for (let i: number = 0; i < length; i++) {
|
|
152
|
+
/* istanbul ignore next */
|
|
153
|
+
if (/_ngcontent/g.test(attributes[i].name)) {
|
|
154
|
+
ngAr = attributes[i].name;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return ngAr;
|
|
158
|
+
};
|
|
159
|
+
// tslint:disable-next-line:no-any
|
|
160
|
+
public ngAfterViewInit(isTempRef?: any): void {
|
|
161
|
+
// tslint:disable-next-line:no-any
|
|
162
|
+
let tempAfterViewThis: any = isTempRef || this;
|
|
163
|
+
let regExp: RegExp = /ejs-tab|ejs-accordion/g;
|
|
164
|
+
/* istanbul ignore next */
|
|
165
|
+
if (regExp.test(tempAfterViewThis.ngEle.nativeElement.outerHTML)) {
|
|
166
|
+
tempAfterViewThis.ngEle.nativeElement.style.visibility = 'hidden';
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Root level template properties are not getting rendered,
|
|
171
|
+
* Due to ngonchanges not get triggered.
|
|
172
|
+
* so that we have set template value for root level template properties,
|
|
173
|
+
* for example: refer below syntax
|
|
174
|
+
* ```html
|
|
175
|
+
* <ejs-grid>
|
|
176
|
+
* <e-column></e-column>
|
|
177
|
+
* <ng-template #editSettingsTemplate></ng-template>
|
|
178
|
+
* </ejs-grid>
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
let templateProperties: string[] = Object.keys(tempAfterViewThis);
|
|
182
|
+
templateProperties = templateProperties.filter((val: string): boolean => {
|
|
183
|
+
return /Ref$/i.test(val);
|
|
184
|
+
});
|
|
185
|
+
for (let tempName of templateProperties) {
|
|
186
|
+
let propName: string = tempName.replace('Ref', '');
|
|
187
|
+
setValue(propName.replace('_', '.'), getValue(propName + 'Ref', tempAfterViewThis), tempAfterViewThis);
|
|
188
|
+
}
|
|
189
|
+
// Used setTimeout for template binding
|
|
190
|
+
// Refer Link: https://github.com/angular/angular/issues/6005
|
|
191
|
+
setTimeout(() => {
|
|
192
|
+
/* istanbul ignore else */
|
|
193
|
+
if (typeof window !== 'undefined' && tempAfterViewThis.element || tempAfterViewThis.getModuleName().includes('btn')) {
|
|
194
|
+
tempAfterViewThis.appendTo(tempAfterViewThis.element);
|
|
195
|
+
tempAfterViewThis.ngEle.nativeElement.style.visibility = '';
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
// tslint:disable-next-line:no-any
|
|
200
|
+
public ngOnDestroy(isTempRef?: any): void {
|
|
201
|
+
// tslint:disable-next-line:no-any
|
|
202
|
+
let tempOnDestroyThis: any = isTempRef || this;
|
|
203
|
+
/* istanbul ignore else */
|
|
204
|
+
setTimeout(() => {
|
|
205
|
+
if (typeof window !== 'undefined' && (tempOnDestroyThis.element.classList.contains('e-control'))) {
|
|
206
|
+
tempOnDestroyThis.destroy();
|
|
207
|
+
tempOnDestroyThis.clearTemplate(null);
|
|
208
|
+
// removing bounded events and tagobjects from component after destroy
|
|
209
|
+
tempOnDestroyThis.ngBoundedEvents = {};
|
|
210
|
+
tempOnDestroyThis.tagObjects = {};
|
|
211
|
+
tempOnDestroyThis.ngEle = null;
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
//tslint:disable-next-line
|
|
216
|
+
public clearTemplate(templateNames?: string[], index?: any): void {
|
|
217
|
+
clearTemplate(this, templateNames, index);
|
|
218
|
+
};
|
|
219
|
+
// tslint:disable-next-line:no-any
|
|
220
|
+
public ngAfterContentChecked(isTempRef?: any): void {
|
|
221
|
+
|
|
222
|
+
// tslint:disable-next-line:no-any
|
|
223
|
+
let tempAfterContentThis: any = isTempRef || this;
|
|
224
|
+
for (let tagObject of tempAfterContentThis.tagObjects) {
|
|
225
|
+
if (!isUndefined(tagObject.instance) &&
|
|
226
|
+
(tagObject.instance.isInitChanges || tagObject.instance.hasChanges || tagObject.instance.hasNewChildren)) {
|
|
227
|
+
if (tagObject.instance.isInitChanges) {
|
|
228
|
+
let propObj: { [key: string]: Object } = {};
|
|
229
|
+
// For angular 9 compatibility
|
|
230
|
+
// Not able to get complex directive properties reference ni Onint hook
|
|
231
|
+
// So we have constructed property here and used
|
|
232
|
+
let complexDirProps;
|
|
233
|
+
let list = getValue('instance.list', tagObject);
|
|
234
|
+
if (list && list.length) {
|
|
235
|
+
complexDirProps = list[0].directivePropList;
|
|
236
|
+
}
|
|
237
|
+
let skip: any = true;
|
|
238
|
+
if ((tempAfterContentThis as any).getModuleName && (tempAfterContentThis as any).getModuleName() === 'gantt') {
|
|
239
|
+
skip = false
|
|
240
|
+
}
|
|
241
|
+
if (complexDirProps && skip && complexDirProps.indexOf(tagObject.instance.propertyName) === -1) {
|
|
242
|
+
let compDirPropList = Object.keys(tagObject.instance.list[0].propCollection);
|
|
243
|
+
for (let h = 0; h < tagObject.instance.list.length; h++) {
|
|
244
|
+
tagObject.instance.list[h].propCollection[tagObject.instance.propertyName] = [];
|
|
245
|
+
let obj: any = {};
|
|
246
|
+
for (let k = 0; k < compDirPropList.length; k++) {
|
|
247
|
+
let complexPropName = compDirPropList[k];
|
|
248
|
+
obj[complexPropName] = tagObject.instance.list[h].propCollection[complexPropName];
|
|
249
|
+
}
|
|
250
|
+
for (let i = 0; i < tagObject.instance.list[h].tags.length; i++) {
|
|
251
|
+
let tag = tagObject.instance.list[h].tags[i];
|
|
252
|
+
let childObj = getValue('child' + tag.substring(0, 1).toUpperCase() + tag.substring(1), tagObject.instance.list[h]);
|
|
253
|
+
if (childObj) {
|
|
254
|
+
let innerchildObj = tagObject.instance.list[h]['child' + tag.substring(0, 1).toUpperCase() + tag.substring(1)];
|
|
255
|
+
if (innerchildObj) {
|
|
256
|
+
for (let j = 0; j < innerchildObj.list.length; j++) {
|
|
257
|
+
let innerTag = innerchildObj.list[0].tags[0];
|
|
258
|
+
if (innerTag) {
|
|
259
|
+
let innerchildTag = getValue('child' + innerTag.substring(0, 1).toUpperCase() + innerTag.substring(1), innerchildObj.list[j]);
|
|
260
|
+
if (innerchildTag) {
|
|
261
|
+
innerchildObj.list[j].tagObjects.push({ instance: innerchildTag, name: innerTag });
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
tagObject.instance.list[h].tagObjects.push({ instance: childObj, name: tag });
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
tagObject.instance.list[h].propCollection[tagObject.instance.propertyName].push(obj);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// End angular 9 compatibility
|
|
273
|
+
propObj[tagObject.name] = tagObject.instance.getProperties();
|
|
274
|
+
tempAfterContentThis.setProperties(propObj, tagObject.instance.isInitChanges);
|
|
275
|
+
} else {
|
|
276
|
+
/* istanbul ignore next */
|
|
277
|
+
if ((tempAfterContentThis[tagObject.name].length !== tagObject.instance.list.length) || (/diagram|tab|DashboardLayout/.test(tempAfterContentThis.getModuleName()))) {
|
|
278
|
+
tempAfterContentThis[tagObject.name] = tagObject.instance.list;
|
|
279
|
+
}
|
|
280
|
+
for (let list of tagObject.instance.list) {
|
|
281
|
+
let curIndex: number = tagObject.instance.list.indexOf(list);
|
|
282
|
+
let curChild: any = getValue(tagObject.name, tempAfterContentThis)[curIndex];
|
|
283
|
+
let complexTemplates: string[] = Object.keys(curChild);
|
|
284
|
+
complexTemplates = complexTemplates.filter((val: string): boolean => {
|
|
285
|
+
return /Ref$/i.test(val);
|
|
286
|
+
});
|
|
287
|
+
if (curChild.properties && Object.keys(curChild.properties).length !== 0){
|
|
288
|
+
for (let complexPropName of complexTemplates) {
|
|
289
|
+
complexPropName = complexPropName.replace(/Ref/, '');
|
|
290
|
+
curChild.properties[complexPropName] = !curChild.properties[complexPropName] ?
|
|
291
|
+
curChild.propCollection[complexPropName] : curChild.properties[complexPropName];
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (!isUndefined(curChild) && !isUndefined(curChild.setProperties)) {
|
|
295
|
+
if (/diagram|DashboardLayout/.test(tempAfterContentThis.getModuleName())) {
|
|
296
|
+
curChild.setProperties(list.getProperties(), true);
|
|
297
|
+
} else {
|
|
298
|
+
curChild.setProperties(list.getProperties());
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
list.isUpdated = true;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
protected registerEvents(eventList: string[]): void {
|
|
309
|
+
registerEvents(eventList, this);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
protected twoWaySetter(newVal: Object, prop: string): void {
|
|
313
|
+
let oldVal: Object = getValue(prop, this.properties);
|
|
314
|
+
if (oldVal === newVal) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
this.saveChanges(prop, newVal, oldVal);
|
|
318
|
+
setValue(prop, (isNullOrUndefined(newVal) ? null : newVal), this.properties);
|
|
319
|
+
getValue(prop + 'Change', this).emit(newVal);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
protected addTwoWay(propList: string[]): void {
|
|
323
|
+
for (let prop of propList) {
|
|
324
|
+
getValue(prop, this);
|
|
325
|
+
Object.defineProperty(this, prop, {
|
|
326
|
+
get: () => {
|
|
327
|
+
return getValue(prop, this.properties);
|
|
328
|
+
},
|
|
329
|
+
set: (newVal: Object) => this.twoWaySetter(newVal, prop)
|
|
330
|
+
});
|
|
331
|
+
setValue(prop + 'Change', new EventEmitter(), this);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
public addEventListener(eventName: string, handler: Function): void {
|
|
336
|
+
let eventObj: EventEmitter<Object> = getValue(eventName, this);
|
|
337
|
+
if (!isUndefined(eventObj)) {
|
|
338
|
+
if (!this.ngBoundedEvents[eventName]) {
|
|
339
|
+
this.ngBoundedEvents[eventName] = new Map();
|
|
340
|
+
}
|
|
341
|
+
this.ngBoundedEvents[eventName].set(handler, eventObj.subscribe(handler));
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
public removeEventListener(eventName: string, handler: Function): void {
|
|
346
|
+
let eventObj: EventEmitter<Object> = getValue(eventName, this);
|
|
347
|
+
if (!isUndefined(eventObj)) {
|
|
348
|
+
(<EventEmitter<object>>this.ngBoundedEvents[eventName].get(handler)).unsubscribe();
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
public trigger(eventName: string, eventArgs: Object, success?: Function): void {
|
|
353
|
+
|
|
354
|
+
let eventObj: { next: Function } = getValue(eventName, this);
|
|
355
|
+
|
|
356
|
+
let prevDetection: boolean = this.isProtectedOnChange;
|
|
357
|
+
this.isProtectedOnChange = false;
|
|
358
|
+
|
|
359
|
+
if (eventArgs) {
|
|
360
|
+
(<{ name: string }>eventArgs).name = eventName;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (!isUndefined(eventObj)) {
|
|
364
|
+
eventObj.next(eventArgs);
|
|
365
|
+
}
|
|
366
|
+
let localEventObj: Function = getValue('local' + eventName.charAt(0).toUpperCase() + eventName.slice(1), this);
|
|
367
|
+
if (!isUndefined(localEventObj)) {
|
|
368
|
+
localEventObj.call(this, eventArgs);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
this.isProtectedOnChange = prevDetection;
|
|
372
|
+
/* istanbul ignore else */
|
|
373
|
+
if (success) {
|
|
374
|
+
this.preventChange = this.isPreventChange;
|
|
375
|
+
success.call(this, eventArgs);
|
|
376
|
+
}
|
|
377
|
+
this.isPreventChange = false;
|
|
378
|
+
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { EventEmitter, ElementRef } from '@angular/core';
|
|
2
|
+
import { getValue, setValue, isNullOrUndefined, isObject } from '@syncfusion/ej2-base';
|
|
3
|
+
import { ControlValueAccessor } from '@angular/forms';
|
|
4
|
+
/**
|
|
5
|
+
* Angular Form Base Module
|
|
6
|
+
*/
|
|
7
|
+
export class FormBase<T> implements ControlValueAccessor {
|
|
8
|
+
public value: T;
|
|
9
|
+
public checked: boolean;
|
|
10
|
+
private skipFromEvent: boolean;
|
|
11
|
+
static readonly isFormBase = true;
|
|
12
|
+
|
|
13
|
+
public propagateChange(_: T): void { return; }
|
|
14
|
+
public propagateTouch(): void { return; }
|
|
15
|
+
public enabled: Object;
|
|
16
|
+
public disabled: Object;
|
|
17
|
+
public angularValue: T;
|
|
18
|
+
private isFormInit: Boolean;
|
|
19
|
+
public objCheck: Boolean;
|
|
20
|
+
public duplicateValue: string;
|
|
21
|
+
public duplicateAngularValue: string;
|
|
22
|
+
|
|
23
|
+
public element: HTMLElement;
|
|
24
|
+
public inputElement: HTMLInputElement;
|
|
25
|
+
private ngEle: ElementRef;
|
|
26
|
+
public appendTo: (ele: string | HTMLElement) => void;
|
|
27
|
+
|
|
28
|
+
public focus: EventEmitter<Object>;
|
|
29
|
+
public blur: EventEmitter<Object>;
|
|
30
|
+
public preventChange: boolean;
|
|
31
|
+
public isUpdated: boolean;
|
|
32
|
+
public oldValue: any;
|
|
33
|
+
|
|
34
|
+
public localChange(e: { value?: T, checked?: T }): void {
|
|
35
|
+
//tslint:disable-next-line
|
|
36
|
+
let value: T | any = (e.checked === undefined ? e.value : e.checked);
|
|
37
|
+
this.objCheck = isObject(value);
|
|
38
|
+
if (this.isUpdated === true) {
|
|
39
|
+
this.angularValue = this.oldValue;
|
|
40
|
+
}
|
|
41
|
+
if (this.objCheck === true) {
|
|
42
|
+
this.duplicateValue = JSON.stringify(value);
|
|
43
|
+
this.duplicateAngularValue = JSON.stringify(this.angularValue);
|
|
44
|
+
if (this.duplicateValue !== this.duplicateAngularValue && this.propagateChange !== undefined && value !== undefined) {
|
|
45
|
+
// Update angular from our control
|
|
46
|
+
this.propagateChange(value);
|
|
47
|
+
this.angularValue = value;
|
|
48
|
+
}
|
|
49
|
+
} else {
|
|
50
|
+
if (value !== this.angularValue && this.propagateChange !== undefined && value !== undefined) {
|
|
51
|
+
// While reset form using reset() method ng-dirty not get updated, so while value is empty just update angularValue only
|
|
52
|
+
if (value !== '' && value !== null) {
|
|
53
|
+
// Update angular from our control
|
|
54
|
+
this.propagateChange(value);
|
|
55
|
+
this.angularValue = value;
|
|
56
|
+
} else {
|
|
57
|
+
//tslint:disable-next-line
|
|
58
|
+
let optionalValue: any = value;
|
|
59
|
+
this.propagateChange(optionalValue);
|
|
60
|
+
this.angularValue = value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public properties: Object;
|
|
67
|
+
public saveChanges: Function;
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
public registerOnChange(registerFunction: (_: T) => void): void {
|
|
71
|
+
this.propagateChange = registerFunction;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public registerOnTouched(registerFunction: () => void): void {
|
|
75
|
+
this.propagateTouch = registerFunction;
|
|
76
|
+
}
|
|
77
|
+
public twoWaySetter(newVal: Object, prop: string): void {
|
|
78
|
+
let oldVal: Object = this.oldValue || getValue(prop, this.properties);
|
|
79
|
+
let ele: HTMLElement = this.inputElement || this.element;
|
|
80
|
+
if (ele && oldVal === newVal && this.value === newVal &&
|
|
81
|
+
((<HTMLInputElement>ele).value === undefined || (<HTMLInputElement>ele).value === '')) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this.saveChanges(prop, newVal, oldVal);
|
|
85
|
+
setValue(prop, (isNullOrUndefined(newVal) ? null : newVal), this.properties);
|
|
86
|
+
getValue(prop + 'Change', this).emit(newVal);
|
|
87
|
+
}
|
|
88
|
+
// tslint:disable-next-line:no-any
|
|
89
|
+
public ngAfterViewInit(isTempRef?: any): void {
|
|
90
|
+
// tslint:disable-next-line:no-any
|
|
91
|
+
let tempFormAfterViewThis: any = isTempRef || this;
|
|
92
|
+
// Used setTimeout for template binding
|
|
93
|
+
// Refer Link: https://github.com/angular/angular/issues/6005
|
|
94
|
+
// Removed setTimeout, Because we have called markForCheck() method in Angular Template Compiler
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
/* istanbul ignore else */
|
|
97
|
+
if (typeof window !== 'undefined') {
|
|
98
|
+
tempFormAfterViewThis.appendTo(tempFormAfterViewThis.element);
|
|
99
|
+
let ele: HTMLElement = tempFormAfterViewThis.inputElement || tempFormAfterViewThis.element;
|
|
100
|
+
ele.addEventListener('focus', tempFormAfterViewThis.ngOnFocus.bind(tempFormAfterViewThis));
|
|
101
|
+
ele.addEventListener('blur', tempFormAfterViewThis.ngOnBlur.bind(tempFormAfterViewThis));
|
|
102
|
+
}
|
|
103
|
+
this.isFormInit = false;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
public setDisabledState(disabled: boolean): void {
|
|
107
|
+
this.enabled = !disabled;
|
|
108
|
+
this.disabled = disabled;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public writeValue(value: T): void {
|
|
112
|
+
let regExp: RegExp = /ejs-radiobutton/g;
|
|
113
|
+
//update control value from angular
|
|
114
|
+
if (this.checked === undefined) {
|
|
115
|
+
this.value = value;
|
|
116
|
+
} else {
|
|
117
|
+
// To resolve boolean type formControl value is not working for radio button control.
|
|
118
|
+
/* istanbul ignore next */
|
|
119
|
+
if (this.ngEle) {
|
|
120
|
+
if (typeof value === 'boolean') {
|
|
121
|
+
if (regExp.test(this.ngEle.nativeElement.outerHTML)) {
|
|
122
|
+
this.checked = value === this.value;
|
|
123
|
+
} else {
|
|
124
|
+
this.checked = value;
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
this.checked = value === this.value;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
this.angularValue = value;
|
|
132
|
+
this.isUpdated = true;
|
|
133
|
+
// When binding Html textbox value to syncfusion textbox, change event triggered dynamically.
|
|
134
|
+
// To prevent change event, trigger change in component side based on `preventChange` value
|
|
135
|
+
this.preventChange = this.isFormInit ? false : true;
|
|
136
|
+
if (value === null) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public ngOnFocus(e: Event): void {
|
|
143
|
+
/* istanbul ignore else */
|
|
144
|
+
if (this.skipFromEvent !== true) {
|
|
145
|
+
this.focus.emit(e);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
public ngOnBlur(e: Event): void {
|
|
150
|
+
this.propagateTouch();
|
|
151
|
+
/* istanbul ignore else */
|
|
152
|
+
if (this.skipFromEvent !== true) {
|
|
153
|
+
this.blur.emit(e);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ViewContainerRef, EmbeddedViewRef, ElementRef, TemplateRef } from '@angular/core';
|
|
2
|
+
import { setTemplateEngine, getTemplateEngine } from '@syncfusion/ej2-base';
|
|
3
|
+
import { setValue, getValue } from '@syncfusion/ej2-base';
|
|
4
|
+
|
|
5
|
+
let stringCompiler: (template: string, helper?: object) => (data: Object | JSON) => string = getTemplateEngine();
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Angular Template Compiler
|
|
9
|
+
*/
|
|
10
|
+
export function compile(templateEle: AngularElementType, helper?: Object):
|
|
11
|
+
//tslint:disable-next-line
|
|
12
|
+
(data: Object | JSON, component?: any, propName?: any) => Object {
|
|
13
|
+
if (typeof templateEle === 'string') {
|
|
14
|
+
return stringCompiler(templateEle, helper);
|
|
15
|
+
} else {
|
|
16
|
+
let contRef: ViewContainerRef = templateEle.elementRef.nativeElement._viewContainerRef;
|
|
17
|
+
let pName: string = templateEle.elementRef.nativeElement.propName;
|
|
18
|
+
//tslint:disable-next-line
|
|
19
|
+
return (data: Object, component?: any, propName?: any): Object => {
|
|
20
|
+
let context: Object = { $implicit: data };
|
|
21
|
+
/* istanbul ignore next */
|
|
22
|
+
let conRef: ViewContainerRef = contRef ? contRef : component.viewContainerRef;
|
|
23
|
+
let viewRef: EmbeddedViewRef<Object> = conRef.createEmbeddedView(templateEle as TemplateRef<Object>, context);
|
|
24
|
+
viewRef.detectChanges();
|
|
25
|
+
/* istanbul ignore next */
|
|
26
|
+
let viewCollection: { [key: string]: EmbeddedViewRef<Object>[] } = (component && component.registeredTemplate) ?
|
|
27
|
+
component.registeredTemplate : getValue('currentInstance.registeredTemplate', conRef);
|
|
28
|
+
propName = (propName && component.registeredTemplate) ? propName : pName;
|
|
29
|
+
if (typeof viewCollection[propName] === 'undefined') {
|
|
30
|
+
viewCollection[propName] = [];
|
|
31
|
+
}
|
|
32
|
+
viewCollection[propName].push(viewRef);
|
|
33
|
+
return viewRef.rootNodes;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Property decorator for angular.
|
|
40
|
+
*/
|
|
41
|
+
export function Template<T>(defaultValue?: Object): PropertyDecorator {
|
|
42
|
+
return (target: Object, key: string) => {
|
|
43
|
+
let propertyDescriptor: Object = {
|
|
44
|
+
set: setter(key),
|
|
45
|
+
get: getter(key, defaultValue),
|
|
46
|
+
enumerable: true,
|
|
47
|
+
configurable: true
|
|
48
|
+
};
|
|
49
|
+
Object.defineProperty(target, key, propertyDescriptor);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function setter(key: string): Function {
|
|
54
|
+
return function (val: AngularElementType): void {
|
|
55
|
+
if (val === undefined) { return; }
|
|
56
|
+
setValue(key + 'Ref', val, this);
|
|
57
|
+
if (typeof val !== 'string') {
|
|
58
|
+
val.elementRef.nativeElement._viewContainerRef = this.viewContainerRef;
|
|
59
|
+
val.elementRef.nativeElement.propName = key;
|
|
60
|
+
} else {
|
|
61
|
+
if (this.saveChanges) {
|
|
62
|
+
this.saveChanges(key, val, undefined);
|
|
63
|
+
this.dataBind();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getter(key: string, defaultValue: Object): Function {
|
|
70
|
+
return function (): Object {
|
|
71
|
+
/* istanbul ignore next */
|
|
72
|
+
return getValue(key + 'Ref', this) || defaultValue;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface AngularElementType {
|
|
77
|
+
elementRef: ElementRef;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//tslint:disable-next-line
|
|
81
|
+
setTemplateEngine({ compile: (compile as any) });
|
package/dist/ts/util.ts
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { EventEmitter } from '@angular/core';
|
|
2
|
+
import { isNullOrUndefined } from '@syncfusion/ej2-base';
|
|
3
|
+
/**
|
|
4
|
+
* Angular Utility Module
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/* tslint:disable */
|
|
8
|
+
export function applyMixins(derivedClass: any, baseClass: any[]): void {
|
|
9
|
+
baseClass.forEach(baseClass => {
|
|
10
|
+
Object.getOwnPropertyNames(baseClass.prototype).forEach(name => {
|
|
11
|
+
if (!derivedClass.prototype.hasOwnProperty(name) || baseClass.isFormBase) {
|
|
12
|
+
derivedClass.prototype[name] = baseClass.prototype[name];
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* tslint:disable */
|
|
19
|
+
export function ComponentMixins(baseClass: Function[]): ClassDecorator {
|
|
20
|
+
return function (derivedClass: Function) {
|
|
21
|
+
applyMixins(derivedClass, baseClass);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
export function registerEvents(eventList: string[], obj: any, direct?: boolean): void {
|
|
29
|
+
let ngEventsEmitter: { [key: string]: Object } = {};
|
|
30
|
+
if (eventList && eventList.length) {
|
|
31
|
+
for (let event of eventList) {
|
|
32
|
+
if (direct === true) {
|
|
33
|
+
obj.propCollection[event] = new EventEmitter(false);
|
|
34
|
+
obj[event] = obj.propCollection[event];
|
|
35
|
+
} else {
|
|
36
|
+
ngEventsEmitter[event] = new EventEmitter(false);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (direct !== true) {
|
|
40
|
+
obj.setProperties(ngEventsEmitter, true);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
export function clearTemplate(_this: any, templateNames?: string[], index?: any): void {
|
|
49
|
+
let regTemplates: string[] = Object.keys(_this.registeredTemplate);
|
|
50
|
+
if (regTemplates.length) {
|
|
51
|
+
/* istanbul ignore next */
|
|
52
|
+
let regProperties: string[] = templateNames && templateNames.filter(
|
|
53
|
+
(val: string) => {
|
|
54
|
+
return (/\./g.test(val) ? false : true);
|
|
55
|
+
});
|
|
56
|
+
for (let registeredTemplate of (regProperties && regProperties || regTemplates)) {
|
|
57
|
+
/* istanbul ignore next */
|
|
58
|
+
if (index && index.length) {
|
|
59
|
+
for (let e = 0; e < index.length; e++) {
|
|
60
|
+
for (let m = 0; m < _this.registeredTemplate.template.length; m++) {
|
|
61
|
+
let value = _this.registeredTemplate.template[m].rootNodes[0];
|
|
62
|
+
if (value === index[e]) {
|
|
63
|
+
let rt = _this.registeredTemplate[registeredTemplate];
|
|
64
|
+
rt[m].destroy();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
if (_this.registeredTemplate[registeredTemplate]) {
|
|
70
|
+
for (let rt of _this.registeredTemplate[registeredTemplate]) {
|
|
71
|
+
if (!rt.destroyed) {
|
|
72
|
+
if (rt._view) {
|
|
73
|
+
let pNode: any = rt._view.renderer.parentNode(rt.rootNodes[0]);
|
|
74
|
+
if (!isNullOrUndefined(pNode)) {
|
|
75
|
+
for (let m: number = 0; m < rt.rootNodes.length; m++) {
|
|
76
|
+
pNode.appendChild(rt.rootNodes[m]);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
rt.destroy();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
delete _this.registeredTemplate[registeredTemplate];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
for (let tagObject of _this.tagObjects) {
|
|
89
|
+
if (tagObject.instance) {
|
|
90
|
+
/* istanbul ignore next */
|
|
91
|
+
tagObject.instance.clearTemplate((templateNames && templateNames.filter(
|
|
92
|
+
(val: string) => {
|
|
93
|
+
return (new RegExp(tagObject.name).test(val) ? true : false);
|
|
94
|
+
})));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* To set value for the nameSpace in desired object.
|
|
101
|
+
* @param {string} nameSpace - String value to the get the inner object
|
|
102
|
+
* @param {any} value - Value that you need to set.
|
|
103
|
+
* @param {any} obj - Object to get the inner object value.
|
|
104
|
+
* @return {void}
|
|
105
|
+
* @private
|
|
106
|
+
*/
|
|
107
|
+
export function setValue(nameSpace: string, value: any, object: any): any {
|
|
108
|
+
let keys: string[] = nameSpace.replace(/\[/g, '.').replace(/\]/g, '').split('.');
|
|
109
|
+
/* istanbul ignore next */
|
|
110
|
+
let fromObj: any = object || {};
|
|
111
|
+
for (let i: number = 0; i < keys.length; i++) {
|
|
112
|
+
let key: string = keys[i];
|
|
113
|
+
if (i + 1 === keys.length) {
|
|
114
|
+
fromObj[key] = value === undefined ? {} : value;
|
|
115
|
+
} else if (fromObj[key] === undefined) {
|
|
116
|
+
fromObj[key] = {};
|
|
117
|
+
}
|
|
118
|
+
fromObj = fromObj[key];
|
|
119
|
+
}
|
|
120
|
+
return fromObj;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* tslint:enable */
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
export interface PropertyCollectionInfo {
|
|
129
|
+
props: PropertyDetails[];
|
|
130
|
+
complexProps: PropertyDetails[];
|
|
131
|
+
colProps: PropertyDetails[];
|
|
132
|
+
events: PropertyDetails[];
|
|
133
|
+
propNames: string[];
|
|
134
|
+
complexPropNames: string[];
|
|
135
|
+
colPropNames: string[];
|
|
136
|
+
eventNames: string[];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface PropertyDetails {
|
|
140
|
+
propertyName: string;
|
|
141
|
+
type: FunctionConstructor | Object;
|
|
142
|
+
defaultValue: Object;
|
|
143
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_from": "@syncfusion/ej2-angular-base@*",
|
|
3
|
-
"_id": "@syncfusion/ej2-angular-base@
|
|
3
|
+
"_id": "@syncfusion/ej2-angular-base@20.3.1",
|
|
4
4
|
"_inBundle": false,
|
|
5
|
-
"_integrity": "sha512-
|
|
5
|
+
"_integrity": "sha512-g5qyk1R4lobmLIVMi3xryHNIbm+1Mw9NejAIaILfZWl6tDpM/GyqLrTorin+ulE20HQ0yrDnXDwsG+/uq1eYRA==",
|
|
6
6
|
"_location": "/@syncfusion/ej2-angular-base",
|
|
7
7
|
"_phantomChildren": {},
|
|
8
8
|
"_requested": {
|
|
@@ -18,42 +18,30 @@
|
|
|
18
18
|
},
|
|
19
19
|
"_requiredBy": [
|
|
20
20
|
"/",
|
|
21
|
-
"/@syncfusion/ej2-angular-barcode-generator",
|
|
22
21
|
"/@syncfusion/ej2-angular-buttons",
|
|
23
22
|
"/@syncfusion/ej2-angular-calendars",
|
|
24
23
|
"/@syncfusion/ej2-angular-charts",
|
|
25
|
-
"/@syncfusion/ej2-angular-circulargauge",
|
|
26
24
|
"/@syncfusion/ej2-angular-diagrams",
|
|
27
25
|
"/@syncfusion/ej2-angular-documenteditor",
|
|
28
26
|
"/@syncfusion/ej2-angular-dropdowns",
|
|
29
|
-
"/@syncfusion/ej2-angular-filemanager",
|
|
30
27
|
"/@syncfusion/ej2-angular-gantt",
|
|
31
28
|
"/@syncfusion/ej2-angular-grids",
|
|
32
29
|
"/@syncfusion/ej2-angular-heatmap",
|
|
33
30
|
"/@syncfusion/ej2-angular-image-editor",
|
|
34
|
-
"/@syncfusion/ej2-angular-inplace-editor",
|
|
35
31
|
"/@syncfusion/ej2-angular-inputs",
|
|
36
|
-
"/@syncfusion/ej2-angular-kanban",
|
|
37
|
-
"/@syncfusion/ej2-angular-layouts",
|
|
38
|
-
"/@syncfusion/ej2-angular-lineargauge",
|
|
39
32
|
"/@syncfusion/ej2-angular-lists",
|
|
40
|
-
"/@syncfusion/ej2-angular-maps",
|
|
41
33
|
"/@syncfusion/ej2-angular-navigations",
|
|
42
|
-
"/@syncfusion/ej2-angular-notifications",
|
|
43
34
|
"/@syncfusion/ej2-angular-pdfviewer",
|
|
44
35
|
"/@syncfusion/ej2-angular-pivotview",
|
|
45
36
|
"/@syncfusion/ej2-angular-popups",
|
|
46
|
-
"/@syncfusion/ej2-angular-progressbar",
|
|
47
37
|
"/@syncfusion/ej2-angular-querybuilder",
|
|
48
38
|
"/@syncfusion/ej2-angular-richtexteditor",
|
|
49
39
|
"/@syncfusion/ej2-angular-schedule",
|
|
50
|
-
"/@syncfusion/ej2-angular-splitbuttons",
|
|
51
40
|
"/@syncfusion/ej2-angular-spreadsheet",
|
|
52
|
-
"/@syncfusion/ej2-angular-treegrid"
|
|
53
|
-
"/@syncfusion/ej2-angular-treemap"
|
|
41
|
+
"/@syncfusion/ej2-angular-treegrid"
|
|
54
42
|
],
|
|
55
|
-
"_resolved": "http://nexus.syncfusion.com/repository/ej2-
|
|
56
|
-
"_shasum": "
|
|
43
|
+
"_resolved": "http://nexus.syncfusion.com/repository/ej2-hotfix-new/@syncfusion/ej2-angular-base/-/ej2-angular-base-20.3.1.tgz",
|
|
44
|
+
"_shasum": "ff689191d5306dde0b27a376d4b6c84a65eec63a",
|
|
57
45
|
"_spec": "@syncfusion/ej2-angular-base@*",
|
|
58
46
|
"_where": "/jenkins/workspace/automation_release_19.1.0.1-ZPMUBNQ6AUYH6YGEFBPVYMEQLRRW2SLD4XCZ6GATNZJFYJ3RIAOA/packages/included",
|
|
59
47
|
"author": {
|
|
@@ -64,7 +52,7 @@
|
|
|
64
52
|
},
|
|
65
53
|
"bundleDependencies": false,
|
|
66
54
|
"dependencies": {
|
|
67
|
-
"@syncfusion/ej2-base": "~20.3.
|
|
55
|
+
"@syncfusion/ej2-base": "~20.3.50",
|
|
68
56
|
"@syncfusion/ej2-icons": "~20.3.47",
|
|
69
57
|
"core-js": "^3.4.8",
|
|
70
58
|
"reflect-metadata": "^0.1.9",
|
|
@@ -97,6 +85,6 @@
|
|
|
97
85
|
"postinstall": "node ./postinstall.js"
|
|
98
86
|
},
|
|
99
87
|
"typings": "index.d.ts",
|
|
100
|
-
"version": "20.3.
|
|
88
|
+
"version": "20.3.50",
|
|
101
89
|
"sideEffects": true
|
|
102
90
|
}
|