Skip to content

Commit

Permalink
[WIP] Move ng-xform buttons to a separate component
Browse files Browse the repository at this point in the history
  • Loading branch information
igortg committed Sep 25, 2018
1 parent ad48d34 commit 01a048b
Show file tree
Hide file tree
Showing 13 changed files with 275 additions and 52 deletions.
5 changes: 3 additions & 2 deletions demo/src/app/home/home.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ <h1>ng-xform</h1>
</form>
<hr />
<div class="panel-body">
<ng-xform [horizontalForm]="horizontal" [labelWidth]="labelWidth" (onSubmit)="onSubmit($event)" [fields]="fields" [(editing)]="editing"></ng-xform>
<ng-xform-save-edit [horizontalForm]="horizontal" [labelWidth]="labelWidth" (submit)="onSubmit($event)" [fields]="fields" [(editing)]="editing">
</ng-xform-save-edit>
<hr>
<pre>{{ xformComponent.form.value | json }}</pre>
<pre>{{ model | json }}</pre>
</div>
</div>
</section>
Expand Down
11 changes: 6 additions & 5 deletions demo/src/app/home/home.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { CustomField } from './../../../../tmp/ng-xform/fields/custom-field';
import { HttpClient } from '@angular/common/http';
import { Component, OnInit, ViewChild, TemplateRef } from '@angular/core';
import { Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { Title } from '@angular/platform-browser';
import {
CheckboxField,
Expand All @@ -10,10 +9,11 @@ import {
MeasureField,
MultilineField,
NestedFormGroup,
NgXformComponent,
NgXformSaveEditComponent,
RadioGroupField,
SelectField,
TextField,
CustomField
} from '@esss/ng-xform';
import { Observable, of } from 'rxjs';
import { delay, map } from 'rxjs/operators';
Expand All @@ -25,7 +25,7 @@ import { delay, map } from 'rxjs/operators';
})
export class HomeComponent implements OnInit {

@ViewChild(NgXformComponent) xformComponent: NgXformComponent;
@ViewChild(NgXformSaveEditComponent) xformComponent: NgXformSaveEditComponent;
@ViewChild('customField') customFieldTmpl: TemplateRef<any>;

private colors: any[] = [
Expand All @@ -42,6 +42,7 @@ export class HomeComponent implements OnInit {
public editing = true;
public horizontal = false;
public labelWidth = 2;
public model: any;

constructor(private titleService: Title, private http: HttpClient) { }

Expand Down Expand Up @@ -170,7 +171,7 @@ export class HomeComponent implements OnInit {

public onSubmit(values: object) {
this.editing = !this.editing;
console.log(values);
this.model = values;
}

populate() {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"karma-mocha-reporter": "^2.2.5",
"karma-remap-coverage": "^0.1.5",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^3.0.0",
"karma-webpack": "^3.0.5",
"lodash": "^4.17.10",
"node-sass": "^4.9.0",
"postcss": "^6.0.22",
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './ng-xform/ng-xform.module';
export * from './ng-xform/ng-xform.component';
export * from './ng-xform/ng-xform-save-edit/ng-xform-save-edit.component';
export * from './ng-xform/fields/index';
export * from './ng-xform/models';
export * from './pipes/pipes.module';
Expand Down
9 changes: 9 additions & 0 deletions src/ng-xform/button-bar/button-bar.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div class="pull-right btn-toolbar">
<button type="submit" class="btn btn-primary" id="formEditBtn" (click)="edit.emit()" *ngIf="editing === false">
<span class="fa fa-pencil"></span> Edit
</button>
<ng-template [ngIf]="editing !== false">
<button type="submit" class="btn btn-primary" id="formSubmitBtn" (click)="save.emit()">Save</button>
<button type="button" class="btn btn-default" id="formCancelBtn" (click)="cancel.emit()">Cancel</button>
</ng-template>
</div>
15 changes: 15 additions & 0 deletions src/ng-xform/button-bar/button-bar.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';


@Component({
selector: 'ng-xform-button-bar',
templateUrl: './button-bar.component.html',
})
export class ButtonBarComponent {

@Input() editing = false;
@Output() save = new EventEmitter();
@Output() cancel = new EventEmitter();
@Output() edit = new EventEmitter();

}
11 changes: 11 additions & 0 deletions src/ng-xform/ng-xform-save-edit/ng-xform-save-edit.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class="row">
<ng-xform [horizontalForm]="horizontalForm" [labelWidth]="labelWidth" [fields]='fields' [editing]='editing'></ng-xform>
</div>
<div class="row">
<ng-xform-button-bar
[editing]='editing'
(save)="onSubmit()"
(cancel)="onCancel()"
(edit)="setEditing(true)"
></ng-xform-button-bar>
</div>
142 changes: 142 additions & 0 deletions src/ng-xform/ng-xform-save-edit/ng-xform-save-edit.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Validators } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { DatePipe } from '@angular/common';
import { BsLocaleService } from 'ngx-bootstrap/datepicker';

import { NgXformSaveEditComponent } from './ng-xform-save-edit.component';
import { DateField, MeasureField, TextField } from '../fields';
import { CheckboxField } from '../fields/checkbox-field';
import { MultilineField } from '../fields/multiline-field';
import { NestedFormGroup } from '../fields/nested-form-group';
import { NgXformModule } from '../ng-xform.module';

describe('NgXformSaveEdit', () => {
let component: NgXformSaveEditComponent;
let fixture: ComponentFixture<NgXformSaveEditComponent>;
let model: any;
let dateTest: Date;
let datePipe: DatePipe;
let bsLocaleService: BsLocaleService;

beforeEach(
async(() => {
TestBed.configureTestingModule({
imports: [
NgXformModule
]
}).compileComponents();
bsLocaleService = TestBed.get(BsLocaleService);
bsLocaleService.use('en');
})
);

beforeEach(() => {
fixture = TestBed.createComponent(NgXformSaveEditComponent);
component = fixture.componentInstance;
dateTest = new Date();
datePipe = new DatePipe('en');
model = {
text1: 'value1',
required: 'value2',
comments: 'comments here...',
address: {
street: 'St wall',
city: 'Ny',
extra_field: 'Extra',
},
nested2: null,
date: dateTest,
};
const colors: any[] = [
{ id: 1, name: 'blue' },
{ id: 2, name: 'yellow' },
{ id: 3, name: 'white' }
];

component.fields = [
new TextField({ key: 'text1', label: 'Text 1' }),
new TextField({ key: 'required', label: 'Required 1', validators: [Validators.required] }),
new MeasureField({ key: 'measure1', label: 'Measure 1', modelUnit: 'degC' }),
new MultilineField({ key: 'comments', label: 'Comments' }),
new TextField({ key: 'other_color', label: 'Other Color', visibilityFn: (formVal: any) => formVal.color === 1 }),
new NestedFormGroup({
key: 'address', label: 'Address',
fields: [
new TextField({ key: 'street', label: 'Street' }),
new TextField({ key: 'city', label: 'City' }),
]
}),
new NestedFormGroup({
key: 'nested2',
fields: [
new TextField({ key: 'field1', label: 'Field1' }),
]
}),
new DateField({ key: 'date', label: 'Date' }),
new CheckboxField({ key: 'isChecked', label: 'Is Checked' }),
];

fixture.detectChanges();
component.setValue(model);
});


it('should patch value', () => {
expect(component.xform.form.value.nested2).toBeTruthy();
});


it('should emit form value on submit', (done: any) => {
const editBtnEl = fixture.debugElement.query(By.css(`#formEditBtn`));
editBtnEl.nativeElement.click();
fixture.detectChanges();

component.submit.subscribe((value: any) => {
setTimeout(() => {
expect(value.text1).toBe(model.text1);
expect(value.comments).toBe(model.comments);
expect(value.date).toBe(dateTest);
expect(value.isChecked).toBeFalsy();
done();
});
});
const buttonEl = fixture.debugElement.query(By.css(`#formSubmitBtn`));
fixture.detectChanges();
expect(buttonEl).toBeTruthy();
expect(component.xform.form.valid).toBeTruthy();
buttonEl.nativeElement.click();
});

it('should be read mode', () => {
const editBtnEl = fixture.debugElement.query(By.css(`#formEditBtn`));
editBtnEl.nativeElement.click();
fixture.detectChanges();

expect(component.editing).toBeTruthy();
const cancelBtnEl = fixture.debugElement.query(By.css(`#formCancelBtn`));
cancelBtnEl.nativeElement.click();
fixture.detectChanges();
expect(component.editing).toBeFalsy();
expectFormLabel('text1', 'Text 1', model.text1);
expectFormLabel('comments', 'Comments', model.comments);
// implement tes of value
expectFormLabel('street', 'Street', model.address.street);
expectFormLabel('city', 'City', model.address.city);
expectFormLabel('date', 'Date', datePipe.transform(dateTest, 'mediumDate', 'en'));
});


function expectFormLabel(fieldId: string, caption: string, value: any) {
const el = fixture.debugElement.query(By.css(`#${fieldId}-div`));
expect(el).toBeTruthy();
expect(el.nativeElement).toBeTruthy();
expect(el.nativeElement.hidden).toBeFalsy();
const label = el.query(By.css('label'));
expect(label.nativeElement.textContent.trim()).toBe(caption);
const labelValue = el.query(By.css('div.text-muted'));
expect(labelValue).toBeTruthy();
expect(labelValue.nativeElement.textContent.trim()).toBe(value);
}

});
61 changes: 61 additions & 0 deletions src/ng-xform/ng-xform-save-edit/ng-xform-save-edit.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { NgXformComponent } from '../ng-xform.component';
import {
Component,
Input,
EventEmitter,
Output,
ViewChild
} from '@angular/core';

import { DynamicField } from '../fields/dynamic-field';

/**
* This component builds a form that switches from editable/non-editable mode.
*
* :editing: Flag to control components state
*/
@Component({
selector: 'ng-xform-save-edit',
templateUrl: './ng-xform-save-edit.component.html',
styles: []
})
export class NgXformSaveEditComponent {

@Input() fields: DynamicField[];
@Input() editing = false;
@Input() horizontalForm = false;
@Input() labelWidth: number;
@Output() editingChange = new EventEmitter();
/** To listening submitSuccessful event */
@Output() submit = new EventEmitter();
/** To listening submitSuccessful event */
@Output() cancel = new EventEmitter();

@ViewChild(NgXformComponent) xform: NgXformComponent;

private currentModel: any;

setEditing(editing: boolean) {
if (editing) {
this.currentModel = this.xform.getModel();
}
this.editing = editing;
}

onSubmit() {
if (this.xform.form.invalid) {
return;
}
this.submit.emit(this.xform.getModel());
}

onCancel() {
this.cancel.emit();
this.xform.setValue(this.currentModel);
this.editing = false;
}

setValue(newModel: any) {
this.xform.setValue(newModel);
}
}
19 changes: 3 additions & 16 deletions src/ng-xform/ng-xform.component.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
<div>
<form [formGroup]="form" [class.form-horizontal]="horizontalForm">
<ng-xform-form-group [isHorizontal]="horizontalForm" [labelWidth]="labelWidth" [fields]='fields' [form]=form [editing]='editing'></ng-xform-form-group>
</form>
</div>
<div class="row">
<div class=" col-sm-12 text-right">
<button type="submit" class="btn btn-primary" (click)="setEditing(true)" *ngIf="editing === false">
<span class="fa fa-pencil"></span> Edit
</button>
<ng-template [ngIf]="editing !== false">
<button [disabled]="form.invalid" type="submit" id="formSubmitBtn" class="btn btn-primary" (click)="submit()">Save</button>
<button type="button" class="btn btn-default" (click)="cancel()">Cancel</button>
</ng-template>
</div>
</div>
<form [formGroup]="form" [class.form-horizontal]="horizontalForm">
<ng-xform-form-group [isHorizontal]="horizontalForm" [labelWidth]="labelWidth" [fields]='fields' [form]=form [editing]='editing'></ng-xform-form-group>
</form>
Loading

0 comments on commit 01a048b

Please sign in to comment.