Skip to content

Instantly share code, notes, and snippets.

@cwparsons
Last active November 28, 2018 03:46
Show Gist options
  • Save cwparsons/9f882eb987122ec6754c0afe3e4db5e1 to your computer and use it in GitHub Desktop.
Save cwparsons/9f882eb987122ec6754c0afe3e4db5e1 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>choices-react example</title>
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-size: 16px;
line-height: 1.4;
}
*, :after, :before {
box-sizing: border-box;
}
label {
display: inline-block;
font-size: 13px;
margin-top: 2rem;
}
textarea {
font-family: Consolas, Courier, monospace;
height: 300px;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/public/assets/styles/choices.min.css" integrity="sha256-1HEjcrRcVjuUBhVpS/a0cd1AYHU5KyIBlXKHZJJI1EI=" crossorigin="anonymous">
</head>
<body>
<div id="example"></div>
<form>
<label for="state">ChoicesComponentExample state:</label>
<textarea id="state">
{
"options": {
"choices": [
{ "value": "AB", "label": "Alberta" },
{ "value": "BC", "label": "British Columbia", "selected": true },
{ "value": "MB", "label": "Manitoba" },
{ "value": "NB", "label": "New Brunswick" },
{ "value": "NL", "label": "Newfoundland and Labrador" },
{ "value": "NT", "label": "Northwest Territories" },
{ "value": "NS", "label": "Nova Scotia" },
{ "value": "NU", "label": "Nunavut" },
{ "value": "ON", "label": "Ontario" },
{ "value": "PE", "label": "Prince Edward Island" },
{ "value": "QC", "label": "Quebec" },
{ "value": "SK", "label": "Saskatchewan" },
{ "value": "YT", "label": "Yukon" }
]
},
"id": "test",
"type": "select-one"
}
</textarea>
<button>Update state</button>
</form>
<script src="https://cdn.polyfill.io/v2/polyfill.js?features=es5,fetch,Element.prototype.classList,requestAnimationFrame,Node.insertBefore,Node.firstChild"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/umd/react.development.js" integrity="sha256-vnGDxiDkh+jlZ+edAiZcSOp7moP3WG8z0G0tBuDG6as=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/umd/react-dom.development.js" integrity="sha256-CG/CHJf9GwBrlUTbqjpHjK0qHB8YjrGrJuos/myGe3U=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/public/assets/scripts/choices.min.js" integrity="sha256-a5ZsEWVUTz+PYYJDXQmIEU65SY1/rKccDwgltzJsvt8=" crossorigin="anonymous"></script>
<script>
class ChoicesComponent extends React.Component {
constructor(props) {
super(props);
this._onChange = this._onChange.bind(this);
this._onInput = this._onInput.bind(this);
}
/**
* Initialize the Choices.js class and immediately save if anything is selected.
*/
componentDidMount() {
this._createChoices();
this._setStateValue();
}
/**
* Only re-render the element if a change that requires types is necessary.
*/
shouldComponentUpdate(nextProps) {
return this.props.type !== nextProps.type ||
this.props.id !== nextProps.id ||
JSON.stringify(this.props.options) !== JSON.stringify(nextProps.options);
}
render() {
return React.createElement(
this.props.type === 'text' ? 'input' : 'select',
{
id: this.props.id,
onChange: this._onChange,
onInput: this._onInput
}
);
}
/**
* After re-initializing Choices.js, we need to re-set the previous value if possible.
*/
componentDidUpdate() {
this.choices.destroy();
this._createChoices();
if (this.props.type === 'text') {
this.choices.setValue(this.state.value);
} else {
this.choices.setChoiceByValue(this.state.value);
}
}
componentWillUnmount() {
this.choices.destroy();
this.choices = null;
}
_createChoices() {
const node = ReactDOM.findDOMNode(this);
if (node instanceof HTMLElement) {
this.choices = new Choices(node, this.props.options);
}
}
_setStateValue() {
this.setState({
value: this.choices.getValue(true)
});
}
_onChange(e) {
this._setStateValue();
if (this.props.onChange) {
this.props.onChange(e);
}
}
_onInput(e) {
if (this.props.onInput) {
this.props.onInput(e);
}
}
//
// Choices.js methods
//
destroy() {
this.choices.destroy();
}
init() {
this.choices.init();
}
highlightAll() {
this.choices.highlightAll();
}
unhighlightAll() {
this.choices.unhighlightAll();
}
removeActiveItemsByValue(value) {
this.choices.removeActiveItemsByValue(value);
}
removeActiveItems(excludedId) {
this.choices.removeActiveItems(excludedId);
}
removeHighlightedItems() {
this.choices.removeHighlightedItems();
}
showDropdown() {
this.choices.showDropdown();
}
hideDropdown() {
this.choices.hideDropdown();
}
toggleDropdown() {
this.choices.toggleDropdown();
}
setChoices(choices, value, label, replaceChoices) {
this.choices.setChoices(choices, value, label, replaceChoices);
}
getValue() {
this.choices.getValue();
}
setValue(args) {
this.choices.setValue(args);
}
setChoiceByValue(value) {
this.choices.setChoiceByValue(value);
}
clearStore() {
this.choices.clearStore();
}
clearInput() {
this.choices.clearInput();
}
disable() {
this.choices.disable();
}
enable() {
this.choices.enable();
}
ajax(fn) {
this.choices.ajax(fn);
}
}
ChoicesComponent.defaultProps = {
type: 'select-one'
};
</script>
<script>
class ChoicesComponentExample extends React.Component {
constructor(props) {
super(props);
this.choicesComponentRef = React.createRef();
this.state = {
options: {
choices: [
{ value: 'AB', label: 'Alberta' },
{ value: 'BC', label: 'British Columbia', selected: true },
{ value: 'MB', label: 'Manitoba' },
{ value: 'NB', label: 'New Brunswick' },
{ value: 'NL', label: 'Newfoundland and Labrador' },
{ value: 'NT', label: 'Northwest Territories' },
{ value: 'NS', label: 'Nova Scotia' },
{ value: 'NU', label: 'Nunavut' },
{ value: 'ON', label: 'Ontario' },
{ value: 'PE', label: 'Prince Edward Island' },
{ value: 'QC', label: 'Quebec' },
{ value: 'SK', label: 'Saskatchewan' },
{ value: 'YT', label: 'Yukon' }
]
},
id: 'test',
type: 'select-one'
};
}
render() {
return React.createElement(
ChoicesComponent,
{
...this.state,
onChange: function (e) {
console.log(e.target.value);
},
ref: this.choicesComponentRef
}
);
}
}
var ref = React.createRef();
ReactDOM.render(
React.createElement(ChoicesComponentExample, { ref }),
document.getElementById('example')
);
document.querySelector('form').addEventListener('submit', (e) => {
e.preventDefault();
const textarea = document.getElementById('state');
const json = textarea.value;
const state = JSON.parse(json);
ref.current.setState(state);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment