(ui/advanced-search) Added an example search form that uses query parameters for Advanced Search forms

This commit is contained in:
sercan 2021-06-07 11:40:33 +03:00
parent 11ad2c89df
commit bb57ec2324
6 changed files with 273 additions and 0 deletions

View File

@ -149,6 +149,9 @@ export const appRoutes: Route[] = [
// TailwindCSS
{path: 'tailwindcss', loadChildren: () => import('app/modules/admin/ui/tailwindcss/tailwindcss.module').then(m => m.TailwindCSSModule)},
// Advanced search
{path: 'advanced-search', loadChildren: () => import('app/modules/admin/ui/advanced-search/advanced-search.module').then(m => m.AdvancedSearchModule)},
// Animations
{path: 'animations', loadChildren: () => import('app/modules/admin/ui/animations/animations.module').then(m => m.AnimationsModule)},

View File

@ -695,6 +695,13 @@ export const defaultNavigation: FuseNavigationItem[] = [
icon : 'heroicons_outline:sparkles',
link : '/ui/tailwindcss'
},
{
id : 'user-interface.advanced-search',
title: 'Advanced search',
type : 'basic',
icon : 'heroicons_outline:search-circle',
link : '/ui/advanced-search'
},
{
id : 'user-interface.animations',
title: 'Animations',

View File

@ -0,0 +1,114 @@
<div class="flex flex-col flex-auto min-w-0">
<!-- Header -->
<div class="flex flex-col sm:flex-row flex-0 sm:items-center sm:justify-between p-6 sm:py-8 sm:px-10 border-b bg-card dark:bg-transparent">
<div class="flex-1 min-w-0">
<!-- Breadcrumbs -->
<div class="flex flex-wrap items-center font-medium">
<div>
<a class="whitespace-nowrap text-primary-500">User Interface</a>
</div>
</div>
<!-- Title -->
<div class="mt-2">
<h2 class="text-3xl md:text-4xl font-extrabold tracking-tight leading-7 sm:leading-10 truncate">
Advanced Search
</h2>
</div>
</div>
</div>
<!-- Main -->
<div class="flex-auto p-6 sm:p-10">
<div class="max-w-3xl">
<div class="max-w-3xl prose prose-sm">
<p>
This page demonstrates a query parameters based search using Angular's built-in <code>routerLink</code> directive and its
<code>queryParams</code> input.
</p>
<p>
Fill the form, hit the <strong>Search</strong> button and then observe the address bar of your browser. If you reload the
page with the parameters, you will see that the form will be populated automatically. We also added an output window so
you can observe the query parameters object.
</p>
<p>
This method can be used for implementing <em>Advanced search</em> mechanics as well as <em>Filtering</em> similar to the
products filtering that you can find in most eCommerce websites.
</p>
</div>
<!-- Advanced search form -->
<form
class="flex flex-col items-start w-full max-w-3xl mt-8 p-8 space-y-8 rounded-2xl shadow overflow-hidden bg-card"
[formGroup]="searchForm">
<!-- Keywords -->
<mat-form-field class="fuse-mat-no-subscript w-full">
<mat-label>Keywords</mat-label>
<input
[autocomplete]="'off'"
[formControlName]="'keywords'"
matInput>
</mat-form-field>
<!-- Type -->
<mat-form-field class="fuse-mat-no-subscript w-full">
<mat-label>Type</mat-label>
<mat-select [formControlName]="'type'">
<mat-option [value]="'any'">Any</mat-option>
<mat-option [value]="'files'">Files</mat-option>
<mat-option [value]="'folders'">Folders</mat-option>
</mat-select>
</mat-form-field>
<div class="flex items-center space-x-8">
<!-- In trash -->
<mat-checkbox
[color]="'primary'"
[formControlName]="'isTrashed'">
In trash
</mat-checkbox>
<!-- Archived -->
<mat-checkbox
[color]="'primary'"
[formControlName]="'isArchived'">
Archived
</mat-checkbox>
<!-- Starred -->
<mat-checkbox
[color]="'primary'"
[formControlName]="'isStarred'">
Starred
</mat-checkbox>
</div>
<!-- Actions -->
<div class="flex items-center justify-end w-full mt-8">
<button
(click)="reset()"
type="button"
mat-button>Reset
</button>
<button
class="ml-2"
(click)="search()"
[color]="'primary'"
type="button"
mat-flat-button>Search
</button>
</div>
</form>
<!-- Query params as json -->
<div class="dark w-full mt-8 p-4 rounded-2xl overflow-hidden">
<textarea
fuse-highlight
[code]="queryParams | json"
[lang]="'json'"></textarea>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,108 @@
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({
selector : 'advanced-search',
templateUrl : './advanced-search.component.html',
encapsulation : ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AdvancedSearchComponent implements OnInit, OnDestroy
{
searchForm: FormGroup;
searchFormDefaults: any = {
keywords : '',
type : 'any',
isTrashed : false,
isArchived: false,
isStarred : false
};
queryParams: Params;
private _unsubscribeAll: Subject<any> = new Subject<any>();
/**
* Constructor
*/
constructor(
private _activatedRoute: ActivatedRoute,
private _formBuilder: FormBuilder,
private _router: Router
)
{
// Prepare the search form with defaults
this.searchForm = this._formBuilder.group({
keywords : [this.searchFormDefaults.keywords],
type : [this.searchFormDefaults.type],
isTrashed : [this.searchFormDefaults.isTrashed],
isArchived: [this.searchFormDefaults.isArchived],
isStarred : [this.searchFormDefaults.isStarred]
});
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Subscribe to query params change
this._activatedRoute.queryParams
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((queryParams) => {
// Store the query params
this.queryParams = queryParams;
// Fill the form with the values from query
// params without emitting any form events
this.searchForm.setValue({
keywords : queryParams?.keywords ?? this.searchFormDefaults.keywords,
type : queryParams?.type ?? this.searchFormDefaults.type,
isTrashed : queryParams?.isTrashed ? coerceBooleanProperty(queryParams?.isTrashed) : this.searchFormDefaults.isTrashed,
isArchived: queryParams?.isArchived ? coerceBooleanProperty(queryParams?.isArchived) : this.searchFormDefaults.isArchived,
isStarred : queryParams?.isStarred ? coerceBooleanProperty(queryParams?.isStarred) : this.searchFormDefaults.isStarred
}, {emitEvent: false});
});
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Reset the search form using the default
*/
reset(): void
{
this.searchForm.reset(this.searchFormDefaults);
}
/**
* Perform the search
*/
search(): void
{
// Add query params using the router
this._router.navigate(['./'], {
queryParams: this.searchForm.value,
relativeTo : this._activatedRoute
});
}
}

View File

@ -0,0 +1,32 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { FuseHighlightModule } from '@fuse/components/highlight';
import { SharedModule } from 'app/shared/shared.module';
import { AdvancedSearchComponent } from 'app/modules/admin/ui/advanced-search/advanced-search.component';
import { advancedSearchRoutes } from 'app/modules/admin/ui/advanced-search/advanced-search.routing';
@NgModule({
declarations: [
AdvancedSearchComponent
],
imports : [
RouterModule.forChild(advancedSearchRoutes),
MatButtonModule,
MatCheckboxModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
MatSelectModule,
FuseHighlightModule,
SharedModule
]
})
export class AdvancedSearchModule
{
}

View File

@ -0,0 +1,9 @@
import { Route } from '@angular/router';
import { AdvancedSearchComponent } from 'app/modules/admin/ui/advanced-search/advanced-search.component';
export const advancedSearchRoutes: Route[] = [
{
path : '',
component: AdvancedSearchComponent
}
];