UNPKG

react-1poll

Version:

A simple React component to make doodle-like collaborative polls.

115 lines (110 loc) 3.82 kB
module.exports = (function(){ 'use strict'; var React = require('react'); var Checkbox = require('material-ui/Checkbox').default; var TextField = require('material-ui/TextField').default; function renderComponent(children) { var divContainer = [ 'div', { className: '1poll-component' } ]; return React.createElement.apply(React, divContainer.concat(children)); } var Poll = React.createClass({ getDefaultProps: function() { return { autoFocus: true, options: [], labelStyle: undefined, allowNewEntries: true, onSelectionChange: undefined, // function([ { name: String, defaultChecked: Boolean } ]) onNewOption: undefined // function({ name: String, defaultChecked: Boolean }) that should update this.props.options }; }, getInitialState: function() { return { options: this.props.options.map(this._checkByDefault), selectedOptions: [] }; }, componentWillReceiveProps: function(props) { this.setState({ options: props.options.map(this._checkByDefault) }, this._refreshSelectedOptions); }, shouldComponentUpdate: function(nextProps, nextState) { return (nextProps != this.props || this.state.options != nextState.options); }, render: function() { return renderComponent(this.state.options .map(this._renderOption) .concat(!this.props.allowNewEntries ? [] : [ React.createElement(TextField, { autoFocus: this.props.autoFocus, hintText: 'Add an option', onBlur: this._handleEntryBlur, onEnterKeyDown: this._handleAddOption, style: { paddingLeft: '42px', marginBottom: '20px' } }) ]) ); }, _checkByDefault: function(option) { option.checked = option.checked || !!option.defaultChecked; return option; }, _renderOption: function(option, index) { return React.createElement(Checkbox, { name: 'selected', 'data-index': index, value: option.name, label: option.name, defaultChecked: option.checked, onCheck: this._onCheck, labelStyle: this.props.labelStyle, style: { margin: '16px 0' } }); }, _refreshSelectedOptions: function() { var selectedOptions = []; for (var i in this.state.options) { if (this.state.options[i].checked) { selectedOptions.push(this.state.options[i]); } } if (this.state.selectedOptions.length != selectedOptions.length) { this.setState({ selectedOptions: selectedOptions }, this.props.onSelectionChange && function(){ this.props.onSelectionChange(selectedOptions); }); } }, _toggleOption: function(optionIndex, checked) { var options = this.state.options.slice(); // clone array options[parseInt(optionIndex)].checked = checked; this.setState({ options: options }, this._refreshSelectedOptions); }, _onCheck: function(evt, checked) { this._toggleOption(evt.target.getAttribute('data-index'), checked); }, _handleEntryBlur: function(evt) { if (!evt.target.value.trim()) return; this._handleAddOption(evt, true); }, _handleAddOption: function(evt, notChecked) { evt.preventDefault(); // prevent form from being submitted var newOption = { name: evt.target.value, checked: notChecked ? false : true, defaultChecked: notChecked ? false : true }; if (this.props.onNewOption) { this.props.onNewOption(newOption); } else { this.setState({ options: this.state.options.concat([ newOption ]) }); } } }); return Poll; })();