-
-
Save mattatcha/987b2cdc2e029aaeebe7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** @jsx React.DOM */ | |
/** | |
* Our component structure will look like the following: | |
* - WikiBox | |
* -- AutoCompleteBox | |
* --- AutoComplete | |
*/ | |
// this component renders a single entity coming from wikipedia | |
var AutoComplete = React.createClass({ | |
render: function() { | |
return ( | |
<p>{this.props.name}</p> | |
); | |
} | |
}); | |
/** | |
* this component is the parent of AutoComplete | |
*/ | |
var AutoCompleteBox = React.createClass({ | |
render: function() { | |
//note: we are producing a new immutable array here | |
var nodes = this.props.list.map(function(item){ | |
return <AutoComplete name={item} />; | |
}); | |
return ( | |
<div className="autocompleteNodes"> | |
//we need to convert our immutable array back to mutable since React only can deal with standard arrays | |
{nodes.mutable()} | |
</div> | |
); | |
} | |
}); | |
/** | |
* The main action is happening here | |
*/ | |
var WikiBox = React.createClass({ | |
//we initilize the component state with an immutable array | |
getInitialState: function() { | |
return {autocomplete: immutable.array([]), call: {latest:0, term:''}}; | |
}, | |
makeCall: function(term, current) { | |
var wikiUrl = "http://en.wikipedia.org/w/api.php?action=opensearch&format=json&callback=?&search="+encodeURIComponent(term); | |
$.getJSON(wikiUrl, function(data) { | |
// this ensures that we ignore out of order ajax calls and that the last call will win. | |
//Note: an alternative could have been to use jquery's beforeSend callback to abort the previous call | |
//but that would have required an enclosing mutable reference to the previous XHR object. | |
if (current == this.state.call.latest) { | |
var newPriority = this.state.call.latest - 1; | |
this.setState({autocomplete: immutable.array(data[1]), call: {latest: newPriority, term:''} }); | |
} | |
}.bind(this) | |
); | |
}, | |
//set state if user enters at least 3 chars, also reset state if user clears input box. | |
handleKeyUp : function (e) { | |
var k = e.target.value; | |
if (k.length > 3 ) { | |
var priority = this.state.call.latest+1; | |
this.setState({call: {latest: priority, term: k }}); | |
} | |
if (k.length == 0 && this.state.autocomplete.length > 0 ) { | |
this.setState({autocomplete: immutable.array([]), call: {latest:0, term:''}}); | |
} | |
return false; | |
}, | |
render: function() { | |
// if the incoming state contains a search term with a real priority then make the async ajax/jsonp calls | |
if (this.state.call.latest > 0 && this.state.call.term != '') { | |
this.makeCall(this.state.call.term, this.state.call.latest); | |
} | |
return ( | |
<div className="wikibox"> | |
<span>Give it a try:</span> | |
<input type="text" placeholder="search" onKeyUp={this.handleKeyUp} /> | |
<AutoCompleteBox list={this.state.autocomplete} /> | |
</div> | |
); | |
} | |
}); | |
/** | |
* Boostrapping component. | |
* It also attaches React to the root div called `container`. | |
*/ | |
React.renderComponent( | |
<WikiBox />, | |
document.getElementById('container') | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment