Skip to content

Commit 44a9d69

Browse files
committed
feat(core): Added support for multiple params
fixes #5
1 parent bff5d3f commit 44a9d69

7 files changed

Lines changed: 64 additions & 68 deletions

File tree

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,11 @@
1-
<!--
2-
<button type="button" (click)="patchGroupValue()">Patch Group</button>
3-
<button type="button" (click)="setGroupValue()">Set Group</button>
4-
-->
5-
61
<demo-browser [group]="paramGroup" initialQueryParams="?q=Hello+World">
72
<ng-container [queryParamGroup]="paramGroup">
83
<input type="text" class="form-control" placeholder="Search" queryParamName="searchText" />
94

10-
<button type="button" (click)="setSearchTextValue('bar')">Set 'bar' with setValue</button>
11-
<button type="button" (click)="setSearchTextRoute('bar')">Set 'bar' with router</button>
12-
13-
<br />
14-
15-
<input type="checkbox" class="form-control" queryParamName="checker" />
16-
17-
<input type="number" class="form-control" queryParamName="counter" />
18-
19-
<input type="range" class="form-control" min="1" max="10" queryParamName="range" />
5+
<select multiple queryParamName="animals">
6+
<option value="Dog">Dog</option>
7+
<option value="Cat">Cat</option>
8+
<option value="Mouse">Mouse</option>
9+
</select>
2010
</ng-container>
2111
</demo-browser>

projects/ngqp-demo/src/app/playground/playground.component.ts

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,42 +18,10 @@ export class PlaygroundComponent {
1818
debounceTime: 1000,
1919
emptyOn: 'foo'
2020
}),
21-
checker: queryParamBuilder.booleanParam({
22-
name: 'yesOrNo',
23-
emptyOn: true,
21+
animals: queryParamBuilder.stringParam({
22+
name: 'animal',
23+
multi: true,
2424
}),
25-
counter: queryParamBuilder.numericParam({
26-
name: 'ctr',
27-
emptyOn: 5,
28-
}),
29-
range: queryParamBuilder.numericParam({
30-
name: 'range',
31-
emptyOn: 2,
32-
}),
33-
});
34-
}
35-
36-
public setSearchTextValue(value: string) {
37-
this.paramGroup.get('searchText').setValue(value);
38-
}
39-
40-
public setSearchTextRoute(value: string) {
41-
this.routerAdapter.navigate({ q: value });
42-
}
43-
44-
public patchGroupValue() {
45-
this.paramGroup.patchValue({
46-
checker: false,
47-
counter: 1337,
48-
range: 9,
49-
});
50-
}
51-
52-
public setGroupValue() {
53-
this.paramGroup.setValue({
54-
checker: false,
55-
counter: 1337,
56-
range: 9,
5725
});
5826
}
5927

projects/ngqp/core/src/lib/accessors/multi-select-control-value-accessor.directive.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,28 +115,38 @@ export class MultiSelectOptionDirective<T> implements OnInit, OnDestroy {
115115
private renderer: Renderer2,
116116
private elementRef: ElementRef,
117117
) {
118-
this.id = this.parent.registerOption(this);
118+
if (this.parent) {
119+
this.id = this.parent.registerOption(this);
120+
}
119121
}
120122

121123
public ngOnInit() {
122-
this.renderer.setProperty(this.elementRef.nativeElement, 'value', this.id);
124+
if (this.parent) {
125+
this.renderer.setProperty(this.elementRef.nativeElement, 'value', this.id);
126+
}
123127
}
124128

125129
public ngOnDestroy() {
126-
this.parent.deregisterOption(this.id);
130+
if (this.parent) {
131+
this.parent.deregisterOption(this.id);
132+
}
127133
}
128134

129135
@Input('value')
130136
public set value(value: T) {
131-
this.parent.updateOptionValue(this.id, value);
137+
if (this.parent) {
138+
this.parent.updateOptionValue(this.id, value);
139+
}
132140
}
133141

134142
public get selected(): boolean {
135143
return (this.elementRef.nativeElement as HTMLOptionElement).selected;
136144
}
137145

138146
public set selected(selected: boolean) {
139-
this.renderer.setProperty(this.elementRef.nativeElement, 'selected', this.selected);
147+
if (this.parent) {
148+
this.renderer.setProperty(this.elementRef.nativeElement, 'selected', selected);
149+
}
140150
}
141151

142152
}

projects/ngqp/core/src/lib/accessors/select-control-value-accessor.directive.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,21 +112,29 @@ export class SelectOptionDirective<T> implements OnInit, OnDestroy {
112112
private renderer: Renderer2,
113113
private elementRef: ElementRef,
114114
) {
115-
this.id = this.parent.registerOption();
115+
if (this.parent) {
116+
this.id = this.parent.registerOption();
117+
}
116118
}
117119

118120
public ngOnInit() {
119-
this.renderer.setProperty(this.elementRef.nativeElement, 'value', this.id);
121+
if (this.parent) {
122+
this.renderer.setProperty(this.elementRef.nativeElement, 'value', this.id);
123+
}
120124
}
121125

122126
public ngOnDestroy() {
123-
this.parent.deregisterOption(this.id);
124-
this.parent.writeValue(this.parent.value);
127+
if (this.parent) {
128+
this.parent.deregisterOption(this.id);
129+
this.parent.writeValue(this.parent.value);
130+
}
125131
}
126132

127133
@Input('value')
128134
public set value(value: T) {
129-
this.parent.updateOptionValue(this.id, value);
135+
if (this.parent) {
136+
this.parent.updateOptionValue(this.id, value);
137+
}
130138
}
131139

132140
}

projects/ngqp/core/src/lib/model.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export interface QueryParamControlOpts<T> {
2929
/** TODO Documentation */
3030
compareWith: Comparator<T>;
3131
/** TODO Documentation */
32+
multi?: boolean;
33+
/** TODO Documentation */
3234
debounceTime?: number | null;
3335
/** TODO Documentation */
3436
emptyOn?: T | null;
@@ -144,14 +146,17 @@ export class QueryParamControl<T> {
144146
/** TODO Documentation See QueryParamControlOpts */
145147
public compareWith: Comparator<T>;
146148

149+
/** TODO Documentation See QueryParamControlOpts */
150+
public multi: boolean;
151+
147152
/** TODO Documentation See QueryParamControlOpts */
148153
public debounceTime: number | null;
149154

150155
private parent: QueryParamGroup;
151156
private changeFunctions: OnChangeFunction<T>[] = [];
152157

153158
constructor(opts: QueryParamControlOpts<T>) {
154-
const { name, serialize, deserialize, debounceTime, emptyOn, compareWith } = opts;
159+
const { name, serialize, deserialize, debounceTime, emptyOn, compareWith, multi } = opts;
155160

156161
if (!isFunction(serialize)) {
157162
throw new Error(`serialize must be a function, but received ${serialize}`);
@@ -175,6 +180,7 @@ export class QueryParamControl<T> {
175180
`Error while deserializing value for ${name || 'control'}`
176181
);
177182
this.compareWith = compareWith;
183+
this.multi = multi === true;
178184
this.debounceTime = debounceTime;
179185
}
180186

projects/ngqp/core/src/lib/query-param-builder.service.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,18 @@ export class QueryParamBuilder {
3838
* Redirects to {@link stringParam}.
3939
* @see stringParam
4040
*/
41-
public param(opts: QueryParamControlOptsInput<string>): QueryParamControl<string> {
41+
public param(opts: QueryParamControlOptsInput<string> & { multi: true }): QueryParamControl<string[]>;
42+
public param(opts: QueryParamControlOptsInput<string>): QueryParamControl<string>;
43+
public param(opts: QueryParamControlOptsInput<string>): QueryParamControl<string | string[]> {
4244
return this.stringParam(opts);
4345
}
4446

4547
/**
4648
* TODO Documentation
4749
*/
48-
public stringParam(opts: QueryParamControlOptsInput<string>): QueryParamControl<string> {
50+
public stringParam(opts: QueryParamControlOptsInput<string> & { multi: true }): QueryParamControl<string[]>;
51+
public stringParam(opts: QueryParamControlOptsInput<string>): QueryParamControl<string>;
52+
public stringParam(opts: QueryParamControlOptsInput<string>): QueryParamControl<string | string[]> {
4953
return new QueryParamControl({
5054
serialize: DEFAULT_STRING_SERIALIZER,
5155
deserialize: DEFAULT_STRING_DESERIALIZER,
@@ -57,7 +61,9 @@ export class QueryParamBuilder {
5761
/**
5862
* TODO Documentation
5963
*/
60-
public numericParam(opts: QueryParamControlOptsInput<number>): QueryParamControl<number> {
64+
public numericParam(opts: QueryParamControlOptsInput<number> & { multi: true }): QueryParamControl<number[]>;
65+
public numericParam(opts: QueryParamControlOptsInput<number>): QueryParamControl<number>;
66+
public numericParam(opts: QueryParamControlOptsInput<number>): QueryParamControl<number | number[]> {
6167
return new QueryParamControl({
6268
serialize: DEFAULT_NUMBER_SERIALIZER,
6369
deserialize: DEFAULT_NUMBER_DESERIALIZER,
@@ -69,7 +75,9 @@ export class QueryParamBuilder {
6975
/**
7076
* TODO Documentation
7177
*/
72-
public booleanParam(opts: QueryParamControlOptsInput<boolean>): QueryParamControl<boolean> {
78+
public booleanParam(opts: QueryParamControlOptsInput<boolean> & { multi: true }): QueryParamControl<boolean[]>;
79+
public booleanParam(opts: QueryParamControlOptsInput<boolean>): QueryParamControl<boolean>;
80+
public booleanParam(opts: QueryParamControlOptsInput<boolean>): QueryParamControl<boolean | boolean[]> {
7381
return new QueryParamControl({
7482
serialize: DEFAULT_BOOLEAN_SERIALIZER,
7583
deserialize: DEFAULT_BOOLEAN_DESERIALIZER,
@@ -81,7 +89,9 @@ export class QueryParamBuilder {
8189
/**
8290
* TODO Documentation
8391
*/
84-
public customParam<T>(opts: QueryParamControlOpts<T>): QueryParamControl<T> {
92+
public customParam<T>(opts: QueryParamControlOpts<T> & { multi: true }): QueryParamControl<T[]>;
93+
public customParam<T>(opts: QueryParamControlOpts<T>): QueryParamControl<T>;
94+
public customParam<T>(opts: QueryParamControlOpts<T>): QueryParamControl<T | T[]> {
8595
return new QueryParamControl(opts);
8696
}
8797

projects/ngqp/core/src/lib/query-param-group.directive.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ export class QueryParamGroupDirective implements OnInit, OnDestroy {
5959
this.routerAdapter.queryParamMap.subscribe(queryParamMap => {
6060
Object.keys(this.queryParamGroup.controls).forEach(controlName => {
6161
const control: QueryParamControl<any> = this.queryParamGroup.get(controlName);
62-
const newModel = control.deserialize(queryParamMap.get(control.name));
62+
const newModel = control.multi
63+
? queryParamMap.getAll(control.name).map(control.deserialize)
64+
: control.deserialize(queryParamMap.get(control.name));
6365

6466
// Get the directive, if it has been initialized yet.
6567
const directive = this.directives.find(dir => dir.name === controlName);
@@ -129,7 +131,9 @@ export class QueryParamGroupDirective implements OnInit, OnDestroy {
129131

130132
private getParamsForModel(control: QueryParamControl<any>, model: any): Params {
131133
return {
132-
[ control.name ]: control.serialize(model)
134+
[ control.name ]: control.multi
135+
? (model || <any[]>[]).map(control.serialize)
136+
: control.serialize(model)
133137
};
134138
}
135139

0 commit comments

Comments
 (0)