Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions projects/demo/src/app/pages/modules/search/search.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import { AlertModal } from "../../../modals/alert.modal";
const exampleStandardTemplate = `
<sui-search placeholder="Example Search..."
[hasIcon]="hasIcon"
[allowEmptyQuery]="allowEmptyQuery"
[options]="options"
[searchDelay]="0"
(resultSelected)="alertSelected($event)"></sui-search>

<div class="ui segment">
<sui-checkbox [(ngModel)]="hasIcon">Has icon?</sui-checkbox>
<sui-checkbox [(ngModel)]="allowEmptyQuery">Allow empty query?</sui-checkbox>
</div>
`;

Expand Down Expand Up @@ -57,6 +59,18 @@ export class SearchPage {
description: "Sets whether or not the search displays an icon.",
defaultValue: "true"
},
{
name: "allowEmptyQuery",
type: "boolean",
description: "Sets whether the search element display result with empty query.",
defaultValue: "false"
},
{
name: "resetQueryOnChange",
type: "boolean",
description: "Sets whether the query is reset if options change.",
defaultValue: "true"
},
{
name: "options",
type: "T[]",
Expand Down Expand Up @@ -165,6 +179,7 @@ export class SearchExampleStandard {
"Yellow", "Zebra"];

public hasIcon:boolean = true;
public allowEmptyQuery:boolean = true;

public get options():string[] {
return SearchExampleStandard.standardOptions;
Expand Down
2 changes: 2 additions & 0 deletions projects/lib/src/lib/modules/popup/public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export {
PopupTrigger,
SuiPopupDirective,
SuiPopup,
SuiPopupController,
SuiPopupTemplateController,
} from "./internal";

import { PositioningPlacement } from "../../misc/util/internal";
Expand Down
24 changes: 21 additions & 3 deletions projects/lib/src/lib/modules/search/components/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,23 @@ export class SuiSearch<T> implements AfterViewInit {
@Input()
public hasIcon:boolean;

// Sets whether the query is reset if options change.
@Input()
public set resetQueryOnChange(resetQueryOnChange:boolean) {
this.searchService.resetQueryOnChange = resetQueryOnChange;
}

// Sets whether the search element display result with empty query.
@Input()
public set allowEmptyQuery(allowEmptyQuery:boolean) {
this._allowEmptyQuery = allowEmptyQuery;
this.searchService.allowEmptyQuery = allowEmptyQuery;
}
public get allowEmptyQuery():boolean {
return this._allowEmptyQuery;
}

private _allowEmptyQuery!:boolean;
private _placeholder!:string;

// Gets & sets the placeholder text displayed inside the text input.
Expand Down Expand Up @@ -106,7 +123,7 @@ export class SuiSearch<T> implements AfterViewInit {
// Initialise a delayed search.
this.searchService.updateQueryDelayed(query, () =>
// Set the results open state depending on whether a query has been entered.
this.dropdownService.setOpenState(this.searchService.query.length > 0));
this.dropdownService.setOpenState(this.searchService.query.length > 0 || this.allowEmptyQuery));
}

@Input()
Expand Down Expand Up @@ -196,6 +213,8 @@ export class SuiSearch<T> implements AfterViewInit {
this.hasClasses = true;
this.tabindex = 0;
this.hasIcon = true;
this.allowEmptyQuery = false;
this.resetQueryOnChange = true;
this.retainSelectedResult = true;
this.searchDelay = 200;
this.maxResults = 7;
Expand Down Expand Up @@ -239,15 +258,14 @@ export class SuiSearch<T> implements AfterViewInit {
}

private open():void {
if (this.searchService.query.length > 0) {
if (this.searchService.query.length > 0 || this.allowEmptyQuery) {
// Only open on click when there is a query entered.
this.dropdownService.setOpenState(true);
}
}

@HostListener("focusout", ["$event"])
public onFocusOut(e:IFocusEvent):void {
console.log(e);
if (!this._element.nativeElement.contains(e.relatedTarget)) {
this.dropdownService.setOpenState(false);
}
Expand Down
14 changes: 11 additions & 3 deletions projects/lib/src/lib/modules/search/services/search.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ export class SearchService<T, U> {
return this._results;
}

private _query!:string;
private _query:string;
// Allows the query to be empty when the options change.
public resetQueryOnChange:boolean;
// Allows the empty query to produce results.
public allowEmptyQuery:boolean;
// How long to delay the search for when using updateQueryDelayed. Stored in ms.
Expand All @@ -77,7 +79,7 @@ export class SearchService<T, U> {
return this._isSearching;
}

constructor(allowEmptyQuery:boolean = false) {
constructor(allowEmptyQuery = false) {
this._options = [];
this.optionsFilter = (os, q) => {
// Convert the query string to a RegExp.
Expand All @@ -99,6 +101,8 @@ export class SearchService<T, U> {

// Set default values and reset.
this.allowEmptyQuery = allowEmptyQuery;
this._query = "";
this.resetQueryOnChange = true;
this.searchDelay = 0;
this.reset();
}
Expand Down Expand Up @@ -203,6 +207,10 @@ export class SearchService<T, U> {
this._results = [];
this._resultsCache = {};
this._isSearching = false;
this.updateQuery("");
if (this.resetQueryOnChange || !this.query) {
this.updateQuery("");
} else {
this.updateQuery(this.query);
}
}
}
15 changes: 9 additions & 6 deletions projects/lib/src/lib/modules/select/classes/select-base.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
ViewChild, HostBinding, ElementRef, HostListener, Input, ContentChildren, QueryList,
AfterContentInit, TemplateRef, ViewContainerRef, ContentChild, EventEmitter, Output, OnDestroy, Directive
AfterViewInit, TemplateRef, ViewContainerRef, ContentChild, EventEmitter, Output, OnDestroy, Directive
} from "@angular/core";
import { Subscription } from "rxjs";
import { DropdownService, SuiDropdownMenu } from "../../dropdown/internal";
Expand All @@ -17,11 +17,11 @@ export interface IOptionContext<T> extends ITemplateRefContext<T> {
// We use generic type T to specify the type of the options we are working with,
// and U to specify the type of the property of the option used as the value.
@Directive()
export abstract class SuiSelectBase<T, U> implements AfterContentInit, OnDestroy {
export abstract class SuiSelectBase<T, U> implements AfterViewInit, OnDestroy {
public dropdownService:DropdownService;
public searchService:SearchService<T, U>;

@ViewChild(SuiDropdownMenu, { static: true })
@ViewChild(SuiDropdownMenu)
protected _menu!:SuiDropdownMenu;

// Keep track of all of the rendered select options. (Rendered by the user using *ngFor).
Expand All @@ -43,7 +43,10 @@ export abstract class SuiSelectBase<T, U> implements AfterContentInit, OnDestroy

@HostBinding("class.visible")
public get isVisible():boolean {
return this._menu.isVisible;
if (this._menu) {
return this._menu.isVisible;
}
return false;
}

@Input()
Expand Down Expand Up @@ -246,7 +249,7 @@ export abstract class SuiSelectBase<T, U> implements AfterContentInit, OnDestroy
this.hasClasses = true;
}

public ngAfterContentInit():void {
public ngAfterViewInit():void {
this._menu.service = this.dropdownService;
// We manually specify the menu items to the menu because the @ContentChildren doesn't pick up our dynamically rendered items.
this._menu.items = this._renderedOptions;
Expand Down Expand Up @@ -287,7 +290,7 @@ export abstract class SuiSelectBase<T, U> implements AfterContentInit, OnDestroy
// The search delay is set to the transition duration to ensure results
// aren't rendered as the select closes as that causes a sudden flash.
if (delayed) {
this.searchService.searchDelay = this._menu.menuTransitionDuration;
this.searchService.searchDelay = this._menu?.menuTransitionDuration;
this.searchService.updateQueryDelayed("");
} else {
this.searchService.updateQuery("");
Expand Down