Skip to content

Commit

Permalink
feat(ng-xforms): onChangeFn parameter added to DynamicField (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
nobreconfrade committed Nov 30, 2018
1 parent 5ca987b commit 6c01689
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 45 deletions.
133 changes: 107 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,11 @@ Template:
```
Component:
```ts
export class HomeComponent implements OnInit {
export class HomeComponent implements OnInit, OnDestroy {

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

@ViewChild(NgXformComponent) xformComponent: NgXformComponent;
private colors: any[] = [
{ id: 0, name: 'other' },
{ id: 1, name: 'blue' },
Expand All @@ -100,18 +102,28 @@ export class HomeComponent implements OnInit {
{ id: 6, name: 'purple' }
];

public onchangefn = new Subject<string>();

public fields: DynamicField[];
public editing = true;
public horizontal = false;
public labelWidth = 2;
public model: any;
public outputhelper = {'A': 1, 'B': 2, 'C': 3};
public subscriptions: Subscription[] = [];

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

ngOnInit() {
const minDate = new Date();
const maxDate = new Date();

this.subscriptions.push(this.onchangefn.asObservable().subscribe(
(value: any) => this.xformComponent.setValue({'outputopt': this.outputhelper[value]})
));

minDate.setDate(minDate.getDate() - 3);
maxDate.setDate(maxDate.getDate() + 3);

this.titleService.setTitle('Home | @esss/ng-xform');
this.fields = [
new TextField({
key: 'name',
Expand Down Expand Up @@ -141,6 +153,8 @@ export class HomeComponent implements OnInit {
label: 'Color',
searchable: true,
options: this.colors,
addNewOption: true,
addNewOptionText: 'Add Color',
optionLabelKey: 'name',
}),
new TextField({
Expand All @@ -152,13 +166,14 @@ export class HomeComponent implements OnInit {
key: 'address',
fields: [
new SelectField({
key: 'street',
label: 'Street',
key: 'country',
label: 'Country',
searchHandler: this.observableSource.bind(this),
searchByValueKeyHandler: this.observableSourceByPlaceId.bind(this),
searchOnFocus: true,
searchable: true,
optionLabelKey: 'formatted_address',
optionValueKey: 'place_id',
optionLabelKey: 'name',
optionValueKey: 'alpha3Code',
validators: [
Validators.required
]
Expand All @@ -184,15 +199,43 @@ export class HomeComponent implements OnInit {
new MeasureField({
key: 'length',
label: 'Length',
modelUnit: 'm',
viewUnit: of('cm').delay(200),
availableUnits: of(['m', 'cm', 'mm', 'ft']).delay(200),
formatOptions: {notation: 'fixed', precision: 4}
modelUnit: 'mm',
viewUnit: of('m').pipe(delay(200)),
availableUnits: of(['m', 'cm', 'mm']).pipe(delay(200))
}),
new MeasureField({
key: 'width',
label: 'Width',
modelUnit: 'inch',
viewUnit: of('inch').pipe(delay(200)),
availableUnits: of(['inch', 'ft']).pipe(delay(200))
}),
new SelectField({
key: 'opt',
label: 'Select an option',
options: [{id: 'A', description: 'Option A'}, {id: 'B', description: 'Option B'}, {id: 'C', description: 'Option C'}],
optionLabelKey: 'description',
optionValueKey: 'id',
onChangeFn: (value: string) => {
this.onchangefn.next(value);
}
}),
new TextField({
key: 'outputopt',
label: 'Output of option',
readOnly: true,
}),
new CheckboxField({
key: 'news',
label: 'News'
}),
new RadioGroupField({
key: 'gender',
label: 'Gender',
options: of([{id: 1, label: 'male'}, {id: 2, label: 'female'}]).pipe(delay(2000)),
optionValueKey: 'id',
optionLabelKey: 'label'
}),
new MultilineField({
key: 'comment',
label: 'Comment',
Expand All @@ -203,22 +246,32 @@ export class HomeComponent implements OnInit {
label: 'Date of birth',
theme: 'blue',
minDate: minDate,
maxDate: maxDate
maxDate: maxDate,
showWeekNumbers: true
}),
new DateRangeField({
key: 'range',
label: 'Date range',
theme: 'blue'
}),
new CustomField({
key: 'custom_amount',
label: 'Custom Field Amount',
tmpl: this.customFieldTmpl
}),
];
}

ngOnInit() {
this.titleService.setTitle('Home | @esss/ng-xform');
ngOnDestroy() {
this.subscriptions.forEach(sub => sub.unsubscribe());
}

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

populate() {
this.xformComponent.form.patchValue({
this.xformComponent.setValue({
name: 'Customer',
email: 'customer@mail.com',
type_tags: [2],
Expand All @@ -228,32 +281,42 @@ export class HomeComponent implements OnInit {
address: {
street: 'ChIJn7h-4b9JJ5URGCq6n0zj1tM'
},
gender: 1,
length: { value: 2, unit: 'm'},
width: { value: 3, unit: 'ft'},
opt: 'A',
news: true,
comment: 'Mussum Ipsum, cacilds vidis litro abertis. Mauris nec dolor in eros commodo tempor. Aenean aliquam molestie leo, vitae ' +
'iaculis nisl. Quem num gosta di mé, boa gentis num é. Tá deprimidis, eu conheço uma cachacis que pode alegrar sua vidis. Em pé ' +
'sem cair, deitado sem dormir, sentado sem cochilar e fazendo pose. Leite de capivaris, leite de mula manquis sem cabeça. Praesent ' +
'vel viverra nisi. Mauris aliquet nunc non turpis scelerisque, eget. Casamentiss faiz malandris se pirulitá. Sapien in monti ' +
'palavris qui num significa nadis i pareci latim.',
birth: new Date()
birth: new Date(),
range: [
'2018-09-06T03:00:00.000Z',
'2018-10-08T03:00:00.000Z'
],
custom_amount: 456
});
}

public observableSource(keyword: any): Observable<any[]> {
const url = `https://maps.googleapis.com/maps/api/geocode/json?address=${keyword}`;
const url = `https://restcountries.eu/rest/v2/name/${keyword}`;
if (keyword) {
return this.http.get(url)
.map((res) => res['results']);
.pipe(
map((res) => res as any[])
);
} else {
return of([]);
}
}

public observableSourceByPlaceId(place_id: any): Observable<any> {
public observableSourceByPlaceId(keyword: any): Observable<any> {
return of({
'place_id': 'ChIJn7h-4b9JJ5URGCq6n0zj1tM',
'formatted_address': 'Florianópolis - State of Santa Catarina, Brazil'
}).delay(300);
'alpha3Code': 'BRA',
'name': 'Brazil'
}).pipe(delay(300));
}
}
```
Expand Down Expand Up @@ -360,6 +423,24 @@ new TextField<User>({
```
the TextField ```key``` attribute will accept only keys of the class User (i.e. 'name', 'email', 'address'), and show and error if any other value is provided.
### On change function
You can add a parameter ```onChangeFn``` on your ```DynamicField``` fields. This parameter receives a
anonymous function, just like in the following example:
```ts
new TextField({
key: 'phrase',
label: 'Write a phrase',
onChangeFn: (value: string) => {
// push new typed value to a subject
this.onchangefnSubject.next(value);
}
}),
```
This parameter can be used to execute async functions that depends on user input or push values of
a field to a ```Subject()``` just like is shown above.


### Locales
DatepickerField can use different locales.

Expand Down
1 change: 1 addition & 0 deletions config/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module.exports = function (config) {
flags: [
'--headless',
'--disable-gpu',
'--no-sandbox',
// Without a remote debugging port, Google Chrome exits immediately.
'--remote-debugging-port=9222',
],
Expand Down
13 changes: 9 additions & 4 deletions demo/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions demo/src/app/home/home.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ <h1>ng-xform</h1>
<div class="input-group-addon">$</div>
<input type="number"
[formControl]="customControl"
[attr.disabled]="!isEditing || null"
[attr.disabled]="!isEditing || null"
class="form-control"
style="text-align:right"
id="exampleInputAmount"
style="text-align:right"
id="exampleInputAmount"
placeholder="Amount" />
<div class="input-group-addon">.00</div>
</div>
Expand Down
36 changes: 32 additions & 4 deletions demo/src/app/home/home.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, OnInit, ViewChild, TemplateRef } from '@angular/core';
import { Component, OnInit, ViewChild, TemplateRef, OnDestroy } from '@angular/core';
import { Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { Title } from '@angular/platform-browser';
Expand All @@ -16,16 +16,16 @@ import {
TextField,
CustomField
} from '@esss/ng-xform';
import { Observable, of } from 'rxjs';
import { delay, map, buffer, skip } from 'rxjs/operators';
import { Observable, of, Subject, Subscription } from 'rxjs';
import { delay, map } from 'rxjs/operators';


@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
export class HomeComponent implements OnInit, OnDestroy {

@ViewChild(NgXformEditSaveComponent) xformComponent: NgXformEditSaveComponent;
@ViewChild('customField') customFieldTmpl: TemplateRef<any>;
Expand All @@ -40,17 +40,25 @@ export class HomeComponent implements OnInit {
{ id: 6, name: 'purple' }
];

public onchangefn = new Subject<string>();

public fields: DynamicField[];
public horizontal = false;
public labelWidth = 2;
public model: any;
public outputhelper = {'A': 1, 'B': 2, 'C': 3};
public subscriptions: Subscription[] = [];

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

ngOnInit() {
const minDate = new Date();
const maxDate = new Date();

this.subscriptions.push(this.onchangefn.asObservable().subscribe(
(value: any) => this.xformComponent.setValue({'outputopt': this.outputhelper[value]})
));

minDate.setDate(minDate.getDate() - 3);
maxDate.setDate(maxDate.getDate() + 3);
this.titleService.setTitle('Home | @esss/ng-xform');
Expand Down Expand Up @@ -140,6 +148,21 @@ export class HomeComponent implements OnInit {
viewUnit: of('inch').pipe(delay(200)),
availableUnits: of(['inch', 'ft']).pipe(delay(200))
}),
new SelectField({
key: 'opt',
label: 'Select an option',
options: [{id: 'A', description: 'Option A'}, {id: 'B', description: 'Option B'}, {id: 'C', description: 'Option C'}],
optionLabelKey: 'description',
optionValueKey: 'id',
onChangeFn: (value: string) => {
this.onchangefn.next(value);
}
}),
new TextField({
key: 'outputopt',
label: 'Output of option',
readOnly: true,
}),
new CheckboxField({
key: 'news',
label: 'News'
Expand Down Expand Up @@ -177,6 +200,10 @@ export class HomeComponent implements OnInit {
];
}

ngOnDestroy() {
this.subscriptions.forEach(sub => sub.unsubscribe());
}

public onSubmit(values: object) {
this.model = values;
}
Expand All @@ -195,6 +222,7 @@ export class HomeComponent implements OnInit {
gender: 1,
length: { value: 2, unit: 'm'},
width: { value: 3, unit: 'ft'},
opt: 'A',
news: true,
comment: 'Mussum Ipsum, cacilds vidis litro abertis. Mauris nec dolor in eros commodo tempor. Aenean aliquam molestie leo, vitae ' +
'iaculis nisl. Quem num gosta di mé, boa gentis num é. Tá deprimidis, eu conheço uma cachacis que pode alegrar sua vidis. Em pé ' +
Expand Down
Loading

0 comments on commit 6c01689

Please sign in to comment.