import * as React from 'react' ; import { ISearchBoxContainerProps } from './ISearchBoxContainerProps' ; import { QueryPathBehavior , UrlHelper , PageOpenBehavior } from '../../../helpers/UrlHelper' ; import { MessageBar , MessageBarType , SearchBox , IconButton , ITheme , ISearchBox } from 'office-ui-fabric-react' ; import { ISearchBoxContainerState } from './ISearchBoxContainerState' ; import { isEqual } from '@microsoft/sp-lodash-subset' ; import * as webPartStrings from 'SearchBoxWebPartStrings' ; import SearchBoxAutoComplete from './SearchBoxAutoComplete/SearchBoxAutoComplete' ; import styles from './SearchBoxContainer.module.scss' ; import { BuiltinTokenNames } from '../../../services/tokenService/TokenService' ; export default class SearchBoxContainer extends React . Component < ISearchBoxContainerProps , ISearchBoxContainerState > { public constructor ( props ) { super ( props ) ; this . state = { searchInputValue : ( props . inputValue ) ? decodeURIComponent ( props . inputValue ) : '' , errorMessage : null , showClearButton : ! ! props . inputValue , } ; this . _onSearch = this . _onSearch . bind ( this ) ; } private renderSearchBoxWithAutoComplete ( ) { return < SearchBoxAutoComplete inputValue = { this . props . inputValue } onSearch = { this . _onSearch } placeholderText = { this . props . placeholderText } suggestionProviders = { this . props . suggestionProviders } themeVariant = { this . props . themeVariant } domElement = { this . props . domElement } numberOfSuggestionsPerGroup = { this . props . numberOfSuggestionsPerGroup } / > ; } private renderBasicSearchBox ( ) { let searchBoxRef = React . createRef < ISearchBox > ( ) ; return ( < div className = { styles . searchBoxWrapper } > < SearchBox componentRef = { searchBoxRef } placeholder = { this . props . placeholderText ? this . props . placeholderText : webPartStrings . SearchBox . DefaultPlaceholder } ariaLabel = { this . props . placeholderText ? this . props . placeholderText : webPartStrings . SearchBox . DefaultPlaceholder } theme = { this . props . themeVariant as ITheme } className = { styles . searchTextField } value = { this . state . searchInputValue } autoComplete = "off" onChange = { ( event ) => this . setState ( { searchInputValue : event . currentTarget . value } ) } onSearch = { ( ) => this . _onSearch ( this . state . searchInputValue ) } onClear = { ( ) => { this . _onSearch ( '' , true ) ; searchBoxRef . current . focus ( ) ; } } /> < div className = { styles . searchButton } > { this . state . searchInputValue && < IconButton onClick = { ( ) => this . _onSearch ( this . state . searchInputValue ) } iconProps = { { iconName : 'Forward' } } ariaLabel = { webPartStrings . SearchBox . SearchButtonLabel } / > } < /div> < /div>); } public async _onSearch ( queryText , isReset = false ) { if ( queryText || isReset ) { this . setState ( { searchInputValue : queryText , showClearButton : ! isReset } ) ; if ( this . props . searchInNewPage && ! isReset && this . props . pageUrl ) { this . props . tokenService . setTokenValue ( BuiltinTokenNames . inputQueryText , queryText ) ; queryText = await this . props . tokenService . resolveTokens ( this . props . inputTemplate ) ; const urlEncodedQueryText = encodeURIComponent ( queryText ) ; const searchUrl = new URL ( this . props . pageUrl ) ; let newUrl ; if ( this . props . queryPathBehavior === QueryPathBehavior . URLFragment ) { searchUrl . hash = urlEncodedQueryText ; newUrl = searchUrl . href ; } else { newUrl = UrlHelper . addOrReplaceQueryStringParam ( searchUrl . href , this . props . queryStringParameter , queryText ) ; } const behavior = this . props . openBehavior === PageOpenBehavior . NewTab ? '_blank' : '_self' ; window . open ( newUrl , behavior ) ; } else { this . props . onSearch ( queryText ) ; } } } public componentDidUpdate ( prevProps , prevState ) { if ( ! isEqual ( prevProps . inputValue , this . props . inputValue ) ) { let query = this . props . inputValue ; try { query = decodeURIComponent ( this . props . inputValue ) ; } catch ( error ) { } this . setState ( { searchInputValue : query , } ) ; } } public render ( ) { let renderErrorMessage = null ; if ( this . state . errorMessage ) { renderErrorMessage = < MessageBar messageBarType = { MessageBarType . error } dismissButtonAriaLabel = 'Close' isMultiline = { false } onDismiss = { ( ) => { this . setState ( { errorMessage : null , } ) ; } } className = { styles . errorMessage } > { this . state . errorMessage } < /MessageBar>; } const renderSearchBox = this . props . enableQuerySuggestions ? this . renderSearchBoxWithAutoComplete ( ) : this . renderBasicSearchBox ( ) ; return ( < div className = { styles . searchBox } > { renderErrorMessage } { renderSearchBox } < /div>); } }