Advertisement
Guest User

Untitled

a guest
Feb 24th, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.89 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement