2016-12-20 16 views
1

Ich versuche, eine select2 Stil-Komponente in React zu erstellen.Reagieren Komponente "Schließen", wenn verloren Fokus

I 90% Funktionalität unten erhalten haben, die ein Bit kann ich einfach nicht hiding the result box when the user clicks away

ist ergründen Die Render-Methode ist:

render() { 
    let resultBlock; 

    if (this.state.showSearch) { 
     resultBlock = (
      <div className="search-input-container" onBlur={this.onBlur}> 
       <div className="search-input-results"> 
        <input 
         type="text" 
         name={this.props.name} 
         placeholder={this.props.placeholder} 
         className="form-control" 
         onChange={this.inputKeyUp} 
         autoComplete="false" /> 
        <ul> 
         {this.state.items.map((item, i) => <li key={i} data-value={item.id} onClick={this.itemSelected} className={item.isSelected ? 'selected' : ''}>{item.text}</li>)} 
        </ul> 
       </div> 
      </div> 
     ); 
    } 

    let displayBlock; 
    if (this.props.value.text) { 
     displayBlock = this.props.value.text; 
    } else { 
     displayBlock = <span className="placeholder">{this.props.placeholder}</span>; 
    } 

    return (
     <div className="form-group"> 
      <label htmlFor={this.props.name}>{this.props.label}:</label> 

      <div className="form-input"> 
       <div className="searchable-dropdown" onClick={this.revealSearch}> 
        {displayBlock} 
        <div className="arrow"><i className="fa fa-chevron-down" aria-hidden="true" /></div> 
       </div> 
       {resultBlock} 
      </div> 
     </div> 
    ); 
} 

Ich habe versucht, um onBlur={this.onBlur} bewegen, aber es nur feuert, wenn der <input... Fokus hatte, bevor man weg geklickt hat.

Es kann nicht so kompliziert sein, der einzige Ansatz, an den ich dachte, ist das Anhängen eines globalen Click-Handlers an die Seite und differierende Klicks, um zu verstehen, ob ein Benutzer nicht auf meine Komponente geklickt hat. Aber das scheint überentwickelt zu sein.

Wie kann dies erreicht werden?

+2

* „einen globalen Click-Handler auf der Seite befestigt“ * - das ist genau, wie es getan werden sollte. – dfsq

+0

Sie ernst ?! Richtig .... zu welchem ​​Objekt, Fenster, Dokument? –

+0

@CallumLinington, Fenster würde funktionieren – Chris

Antwort

1

erreicht ich diese Funktionalität durch:

das Einlochen im Konstruktor:

this.windowClick = this.windowClick.bind(this); 

(Von dem, was dfsq sagte) Setzen Sie dieses in componentDidMount:

if (window) { 
    window.addEventListener('click', this.windowClick, false); 
} 

Dieser Event-Handler:

windowClick(event) { 
    event.preventDefault(); 

    if (event.target.classList.contains('searchable-marker')) { 
     return; 
    } else { 
     this.setState({ 
      showSearch: false 
     }); 
    } 
} 

Wo searchable-marker ist nur eine Klasse Ich legte alle divs, ULs, li und Eingänge, um sicherzustellen, dass, wenn ich einen von diesen, würde es nicht die Box zu schließen.

Hinzufügen der Aushängen:

componentWillUnmount() { 
    window.removeEventListener('click', this.windowClick, false); 
} 
+0

Sie denken in die richtige Richtung. Es ist besser click event in 'componentDidMount' zu binden. Auch 'event.preventDefault()' scheint nutzlos. – dfsq

+0

fertig, ja, das war ziemlich eklatanter Fehler! –

0

was Sie versuchen können, ist onBlur Sie könnten den Wert von this.state.showSearch = false ändern und wenn diese Bedingung erfüllt ist, fügen Sie einen className = "ausblenden" (ausblenden {display: none}) durch Erstellen einer benutzerdefinierten Funktion Das gibt einen Klassennamen als String zurück.

+0

Das würde es nicht ganz schneiden –

Verwandte Themen