daily pastebin goal
20%
SHARE
TWEET

Untitled

a guest Feb 24th, 2019 64 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, { Component } from 'react'
  2.  
  3. /*
  4.   Usage:
  5.   <SearchBox
  6.     database= <array of { name, ..other props }> // name field required for filtering results
  7.     onResultSelect= (result) => {} <callback function that receives clicked result as param, triggered when a result is selected>
  8.    
  9.     optional props:
  10.     id= <your-id-name>
  11.     width = <width of search box>
  12.     initValue= <initial value of input>
  13.     resetOnFocus= <boolean, whether search input always empties on focus>
  14.   />
  15. */
  16.  
  17. export default class SearchBox extends Component {
  18.   constructor(props){
  19.     super(props);
  20.   }
  21.  
  22.   componentWillMount() {
  23.     let init = this.props.initValue ? this.props.initValue : ''
  24.  
  25.     this.setState({
  26.       isLoading: false,
  27.       results: [],
  28.       value: init,
  29.       placeholder: true,
  30.       lastValid: init
  31.     })
  32.   }
  33.  
  34.   escapeRegExp = (string) => {
  35.     return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  36.   }
  37.  
  38.   showHideResults = (show) => {
  39.     const search = document.getElementById(`${this.props.id}`)
  40.     const results = search.getElementsByClassName('results')[0]
  41.     results.style.display = show ? 'block' : 'none'
  42.   }
  43.  
  44.   resetComponent = (empty=false) => {
  45.     this.setState({
  46.       results: [],
  47.       isLoading: false,
  48.       value: empty ? '' : this.state.lastValid,
  49.       placeholder: true
  50.     })
  51.   }
  52.  
  53.   handleFocus = () =>{
  54.     if(this.props.resetOnFocus) this.setState({ value: '' })
  55.     this.showHideResults(true)
  56.   }
  57.  
  58.   handleBlur = () =>{
  59.     this.showHideResults(false)
  60.     this.resetComponent()
  61.   }
  62.  
  63.   handleChange = (e) =>{
  64.     if(this.state.isLoading) clearTimeout(this.state.loadResults)
  65.  
  66.     let value = e.target.value
  67.     this.setState({
  68.       placeholder: false,
  69.       isLoading: true,
  70.       value
  71.     });
  72.  
  73.     this.setState({
  74.       loadResults: setTimeout(() => {
  75.       if(value.length < 1) {
  76.         this.resetComponent(true)
  77.         return
  78.       }else{
  79.         const re = new RegExp('.*'+ this.escapeRegExp(value) +'.*', 'i')
  80.         let results = this.props.database.filter(({name}) => name.match(re))
  81.  
  82.         this.setState({
  83.           isLoading: false,
  84.           results
  85.         })
  86.       }
  87.     }, 300)})
  88.   }
  89.  
  90.   handleResultSelect = (result) => {
  91.     this.setState({
  92.       lastValid: result.name
  93.     })
  94.     this.props.onResultSelect(result)
  95.   }
  96.  
  97.   render() {
  98.     const { isLoading, value, results, placeholder } = this.state;
  99.     const { width, id } = this.props;
  100.  
  101.     return (
  102.       <div id={id} style={{ width, position: 'relative' }}>
  103.         <div className='input'>
  104.           <input
  105.             value = {this.state.value}
  106.             type='text'
  107.             onFocus={this.handleFocus}
  108.             onBlur={this.handleBlur}
  109.             onChange={this.handleChange}
  110.           />
  111.         </div>
  112.         <div className='results' style={{display: 'none', position: 'absolute'}}>
  113.           {isLoading &&
  114.             <div className='loading'>
  115.               Loading....
  116.             </div>
  117.           }
  118.  
  119.           {!isLoading && placeholder &&
  120.             <div className='placeholder'>
  121.               Search for something...
  122.             </div>
  123.           }
  124.  
  125.           {!isLoading && !placeholder && results.length < 1 &&
  126.             <div className='empty'>
  127.               No matches
  128.             </div>
  129.           }
  130.  
  131.           { !isLoading && !placeholder &&
  132.             results.map((result, i) =>{
  133.               return (
  134.                 <SearchResult
  135.                   key={i}
  136.                   value={result}
  137.                   onResultSelect={this.handleResultSelect}
  138.                 />
  139.               )
  140.             })
  141.           }
  142.         </div>
  143.       </div>
  144.     )
  145.   }
  146. }
  147.  
  148. class SearchResult extends Component {
  149.   constructor(props){
  150.     super(props);
  151.     this.handleClick = this.handleClick.bind(this);
  152.   }
  153.  
  154.   handleClick(){
  155.     this.props.onResultSelect(this.props.value);
  156.   }
  157.  
  158.   render(){
  159.     const { value } = this.props
  160.     return(
  161.       <div className='result' onMouseDown={this.handleClick}>
  162.         {value.name}
  163.       </div>
  164.     )
  165.   }
  166. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top