Skip to content

Commit

Permalink
new path resolving implementation (closes #414)
Browse files Browse the repository at this point in the history
  • Loading branch information
udos86 committed Jul 17, 2017
1 parent 356bf18 commit 380a651
Show file tree
Hide file tree
Showing 14 changed files with 333 additions and 263 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# 1.4.19

### **Minor Breaking Change**

* **path resolving for nested form arrays from `1.4.17` has been removed in favor of a more global approach due to impasses**

### **Features**

* `parent` property added for `DynamicFormControlModel` via new interface `DynamicFormControlPath`
* `getPath()` method added to `DynamicFormService` (see [#414](https://github.com/udos86/ng2-dynamic-forms/issues/414))


# 1.4.18

### **Minor Breaking Change**
Expand Down
2 changes: 2 additions & 0 deletions example/styles.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import '../node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css';

* {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 100%;
Expand Down
1 change: 1 addition & 0 deletions example/systemjs.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"primeng": "npm:primeng",
"rxjs": "npm:rxjs",
"text-mask-core": "npm:text-mask-core",
"tslib": "npm:tslib/tslib.js"
};

var packages = {
Expand Down
3 changes: 2 additions & 1 deletion karma-test-shim.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ System.config({
"ionic-angular": "npm:ionic-angular/bundles/ionic.umd.js",
"primeng": "npm:primeng",
"rxjs": "npm:rxjs",
"text-mask-core": "npm:text-mask-core"
"text-mask-core": "npm:text-mask-core",
"tslib": "npm:tslib/tslib.js"
},

packages: {
Expand Down
2 changes: 2 additions & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ module.exports = function (config) {
{pattern: "node_modules/primeng/**/*.js", included: false, watched: false},
{pattern: "node_modules/primeng/**/*.js.map", included: false, watched: false},

{pattern: "node_modules/tslib/**/*.js", included: false, watched: false},

{pattern: "dist/@ng2-dynamic-forms/**/*.js", included: false, watched: false},
{pattern: "dist/@ng2-dynamic-forms/**/*.js.map", included: false, watched: false},

Expand Down
35 changes: 28 additions & 7 deletions modules/core/src/model/dynamic-form-control.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,26 @@ export interface ClsConfig {
grid?: Cls;
}

export function createEmptyClsConfig(): Cls {

return {
container: "",
control: "",
errors: "",
group: "",
hint: "",
host: "",
label: ""
};
}

export interface DynamicFormControlPath {

id?: string;
index?: number;
parent: DynamicFormControlPath;
}

export interface DynamicFormControlModelConfig {

disabled?: boolean;
Expand All @@ -37,7 +57,7 @@ export interface DynamicFormControlModelConfig {
relation?: DynamicFormControlRelationGroup[];
}

export abstract class DynamicFormControlModel {
export abstract class DynamicFormControlModel implements DynamicFormControlPath {

@serializable() cls: any = {};
@serializable("disabled") _disabled: boolean;
Expand All @@ -46,6 +66,7 @@ export abstract class DynamicFormControlModel {
@serializable() id: string;
@serializable() label: string | null;
@serializable() name: string;
parent: DynamicFormControlPath | null = null;
@serializable() relation: DynamicFormControlRelationGroup[];

abstract readonly type: string;
Expand All @@ -56,8 +77,8 @@ export abstract class DynamicFormControlModel {
throw new Error("string id must be specified for DynamicFormControlModel");
}

this.cls.element = Utils.merge(cls.element, {container: "", control: "", errors: "", group: "", hint: "", host: "", label: ""});
this.cls.grid = Utils.merge(cls.grid, {container: "", control: "", errors: "", group: "", hint: "", host: "", label: ""});
this.cls.element = Utils.merge(cls.element, createEmptyClsConfig());
this.cls.grid = Utils.merge(cls.grid, createEmptyClsConfig());

this._disabled = Utils.isBoolean(config.disabled) ? config.disabled : false;
this.errorMessages = config.errorMessages || null;
Expand All @@ -70,14 +91,14 @@ export abstract class DynamicFormControlModel {
this.disabledUpdates.subscribe((value: boolean) => this.disabled = value);
}

set disabled(value: boolean) {
this._disabled = value;
}

get disabled(): boolean {
return this._disabled;
}

set disabled(value: boolean) {
this._disabled = value;
}

get hasErrorMessages(): boolean {
return Utils.isDefined(this.errorMessages);
}
Expand Down
12 changes: 0 additions & 12 deletions modules/core/src/model/form-array/dynamic-form-array.model.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,6 @@ describe("DynamicFormArrayModel test suite", () => {
expect(model.get(1) instanceof DynamicFormArrayGroupModel).toBe(true);
});

it("should resolve array group path", () => {

let parent = model.get(0),
groupModel = (parent.get(1) as DynamicFormArrayModel).get(0);

expect(groupModel.path).toEqual(["nestedFormArray", "0"]);

groupModel.parent = parent;

expect(groupModel.path).toEqual([parent.context.id, parent.index.toString(), "nestedFormArray", "0"]);
});

it("should add another form array group", () => {

model.addGroup();
Expand Down
29 changes: 5 additions & 24 deletions modules/core/src/model/form-array/dynamic-form-array.model.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,28 @@
import {
DynamicFormControlModel,
DynamicFormControlModelConfig,
DynamicFormControlPath,
DynamicValidatorsMap,
ClsConfig
ClsConfig,
} from "../dynamic-form-control.model";
import { serializable, serialize } from "../../decorator/serializable.decorator";
import { Utils } from "../../utils/core.utils";

export class DynamicFormArrayGroupModel {
export class DynamicFormArrayGroupModel implements DynamicFormControlPath {

context: DynamicFormArrayModel;
@serializable() group: DynamicFormControlModel[];
@serializable() index: number | null;

private _parent: DynamicFormArrayGroupModel | null = null;

constructor(context: DynamicFormArrayModel, group: DynamicFormControlModel[] = [], index: number = null) {

this.context = context;
this.group = group;
this.index = index;
}

get parent(): DynamicFormArrayGroupModel {
return this._parent;
}

set parent(parent: DynamicFormArrayGroupModel) {
this._parent = parent;
}

get path(): string[] {

let path: string[] = [],
groupModel: DynamicFormArrayGroupModel = this;

while (groupModel) {

path.unshift(groupModel.context.id, groupModel.index.toString());
groupModel = groupModel.parent;
}

return path;
get parent(): DynamicFormArrayModel {
return this.context;
}

get(index: number): DynamicFormControlModel {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,6 @@ describe("DynamicFormGroupModel test suite", () => {
expect(model.validator).toBeDefined();
});

it("should throw when no group array is specified", () => {

expect(() => new DynamicFormGroupModel({id: "test"}))
.toThrow(new Error("group array must be specified for DynamicFormGroupModel"));
});

it("should get the correct DynamicFormControlModel of group", () => {

expect(model.get(0) === model.group[0]).toBe(true);
Expand Down
4 changes: 0 additions & 4 deletions modules/core/src/model/form-group/dynamic-form-group.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ export class DynamicFormGroupModel extends DynamicFormControlModel implements Dy

super(config, cls);

if (!Array.isArray(config.group)) {
throw new Error("group array must be specified for DynamicFormGroupModel");
}

this.asyncValidator = config.asyncValidator || null;
this.group = Array.isArray(config.group) ? config.group : [];
this.legend = config.legend || null;
Expand Down
45 changes: 33 additions & 12 deletions modules/core/src/service/dynamic-form.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe("DynamicFormService test suite", () => {
return new Promise<boolean>(resolve => setTimeout(() => resolve(true), 0));
}


beforeEach(() => {

TestBed.configureTestingModule({
Expand Down Expand Up @@ -126,7 +127,11 @@ describe("DynamicFormService test suite", () => {
groupFactory: () => {
return [
new DynamicInputModel({id: "testFormArrayGroupInput"}),
new DynamicFormArrayModel({id: "testNestedFormArray", groupFactory: () => []})
new DynamicFormArrayModel({
id: "testNestedFormArray", groupFactory: () => [
new DynamicInputModel({id: "testNestedFormArrayGroupInput"})
]
})
];
}
}
Expand Down Expand Up @@ -156,9 +161,11 @@ describe("DynamicFormService test suite", () => {
];
});


beforeEach(inject([DynamicFormService], (formService: DynamicFormService) => service = formService));

it("should create create a form group correctly", () => {

it("should create create a form group", () => {

let formGroup = service.createFormGroup(testModel);

Expand All @@ -178,7 +185,7 @@ describe("DynamicFormService test suite", () => {
});


it("should parse dynamic form JSON correctly", () => {
it("should parse dynamic form JSON", () => {

let json = JSON.stringify(testModel),
formModel = service.fromJSON(json);
Expand Down Expand Up @@ -210,7 +217,7 @@ describe("DynamicFormService test suite", () => {
});


it("should find a dynamic form control model by id correctly", () => {
it("should find a dynamic form control model by id", () => {

expect(service.findById("testCheckbox", testModel) instanceof DynamicFormControlModel).toBe(true);
expect(service.findById("testCheckboxGroup", testModel) instanceof DynamicFormControlModel).toBe(true);
Expand All @@ -228,14 +235,26 @@ describe("DynamicFormService test suite", () => {
});


it("should find a nested dynamic form control model by id correctly", () => {
it("should find a nested dynamic form control model by id", () => {

expect(service.findById("testCheckboxGroup1", testModel) instanceof DynamicFormControlModel).toBe(true);
expect(service.findById("testCheckboxGroup2", testModel) instanceof DynamicFormControlModel).toBe(true);
expect(service.findById("nestedTestInput", testModel) instanceof DynamicFormControlModel).toBe(true);
});


it("should resolve array group path", () => {

service.createFormGroup(testModel);

let model = service.findById("testFormArray", testModel) as DynamicFormArrayModel,
nestedModel = (model.get(0).get(1) as DynamicFormArrayModel).get(0);

expect(service.getPath(model)).toEqual(["testFormArray"]);
expect(service.getPath(nestedModel)).toEqual(["testFormArray", "0", "testNestedFormArray", "0"]);
});


it("should add a form control to an existing form group", () => {

let formGroup = service.createFormGroup(testModel),
Expand Down Expand Up @@ -268,9 +287,11 @@ describe("DynamicFormService test suite", () => {

expect(formGroup.controls[newModel1.id]).toBeTruthy();
expect(testModel[4] === newModel1).toBe(true);
expect(service.getPath(testModel[4])).toEqual(["newInput1"]);

expect((formGroup.controls["testFormGroup"] as FormGroup).controls[newModel2.id]).toBeTruthy();
expect(nestedFormGroupModel.get(0) === newModel2).toBe(true);
expect(service.getPath(nestedFormGroupModel.get(0))).toEqual(["testFormGroup", "newInput2"]);
});


Expand Down Expand Up @@ -322,7 +343,7 @@ describe("DynamicFormService test suite", () => {
});


it("should create a form array correctly", () => {
it("should create a form array", () => {

let model = service.findById("testFormArray", testModel) as DynamicFormArrayModel,
formArray;
Expand All @@ -336,7 +357,7 @@ describe("DynamicFormService test suite", () => {
});


it("should add a form array group correctly", () => {
it("should add a form array group", () => {

let model = service.findById("testFormArray", testModel) as DynamicFormArrayModel,
formArray = service.createFormArray(model);
Expand All @@ -347,7 +368,7 @@ describe("DynamicFormService test suite", () => {
});


it("should insert a form array group correctly", () => {
it("should insert a form array group", () => {

let model = service.findById("testFormArray", testModel) as DynamicFormArrayModel,
formArray = service.createFormArray(model);
Expand All @@ -358,7 +379,7 @@ describe("DynamicFormService test suite", () => {
});


it("should move up a form array group correctly", () => {
it("should move up a form array group", () => {

let model = service.findById("testFormArray", testModel) as DynamicFormArrayModel,
formArray = service.createFormArray(model),
Expand All @@ -383,7 +404,7 @@ describe("DynamicFormService test suite", () => {
});


it("should move down a form array group correctly", () => {
it("should move down a form array group", () => {

let model = service.findById("testFormArray", testModel) as DynamicFormArrayModel,
formArray = service.createFormArray(model),
Expand Down Expand Up @@ -418,7 +439,7 @@ describe("DynamicFormService test suite", () => {
});


it("should remove a form array group correctly", () => {
it("should remove a form array group", () => {

let model = service.findById("testFormArray", testModel) as DynamicFormArrayModel,
formArray = service.createFormArray(model);
Expand All @@ -429,7 +450,7 @@ describe("DynamicFormService test suite", () => {
});


it("should clear a form array correctly", () => {
it("should clear a form array", () => {

let model = service.findById("testFormArray", testModel) as DynamicFormArrayModel,
formArray = service.createFormArray(model);
Expand Down
Loading

0 comments on commit 380a651

Please sign in to comment.