UNPKG

react-room-occupancy-input

Version:

React.js component for specifying a hotel room occupancy: how many adults, how many kids, how old kids are

148 lines (122 loc) 4.85 kB
(function () { 'use strict'; var React = require('react'), ChildrenCountInput = require('./ChildrenCountInput'), ChildAgeInput = require('./ChildAgeInput'), ReactIntl = require('react-intl'), FormattedMessage = ReactIntl.FormattedMessage, IntlMixin = ReactIntl.IntlMixin, clone = require('./clone'); function pad(padWhat, newSize, padWith) { var result = padWhat.slice(), i; for (i = 0; i < newSize - padWhat.length; i = i + 1) { result.push(padWith); } return result; } module.exports = React.createClass({ displayName: 'ChildrenInput', mixins: [IntlMixin], propTypes: { value: React.PropTypes.array.isRequired, onChange: React.PropTypes.func.isRequired, onInvalidAge: React.PropTypes.func.isRequired, onAgesBecomingValid: React.PropTypes.func.isRequired }, getInitialState: function () { return {drafting: this.props.value.map(function () { return false; })}; }, render: function () { return React.DOM.div({className: 'room-occupancy-children'}, this.subElements()); }, subElements: function () { return [this.countElement()].concat(this.ageElements()); }, countElement: function () { return React.DOM.div({className: 'room-occupancy-children-count', key: 'k0'}, [ React.DOM.label( {key: 'k0'}, React.createElement(FormattedMessage, { message: this.getIntlMessage('react-room-occupancy-input.children') }) ), React.createElement(ChildrenCountInput, { ref: 'count', value: this.props.value.length, onChange: this.handleCountChange, key: 'k1' }) ]); }, ageElements: function () { var onChangeFactory = function (index) { return function (newAge) { this.handleAgeChange(index, newAge); }.bind(this); }.bind(this), ageInputs = this.props.value.map(function (child, index) { var id = 'age' + index; return React.createElement(ChildAgeInput, { ref: id, value: child.age, onChange: onChangeFactory(index), key: id }); }.bind(this)), labelElement = React.DOM.label( {key: 'label'}, React.createElement( FormattedMessage, { message: this.getIntlMessage('react-room-occupancy-input.childrenAge'), children: ageInputs.length } ) ); if (ageInputs.length > 0) { return [React.DOM.div( {className: 'room-occupancy-children-ages', key: 'k1'}, [labelElement].concat(ageInputs) )]; } return []; }, handleCountChange: function (newCount) { if (newCount <= this.props.value.length) { this.props.onChange(this.props.value.slice(0, newCount)); this.newDraftingState(this.state.drafting.slice(0, newCount)); } else { this.props.onChange(this.padValue(newCount)); this.newDraftingState(this.padDrafting(newCount)); } }, handleAgeChange: function (index, newAge) { var newChildrenValue = clone(this.props.value), newDrafting = this.state.drafting.slice(); newChildrenValue[index].age = newAge; this.props.onChange(newChildrenValue); newDrafting[index] = (newAge === null); this.newDraftingState(newDrafting); }, padValue: function (newCount) { return pad(this.props.value, newCount, {age: null}); }, padDrafting: function (newCount) { return pad(this.state.drafting, newCount, false); }, newDraftingState: function (drafting) { this.setState({drafting: drafting}); if ( drafting.reduce(function (memo, x) { return memo || x; }, false) ) { this.props.onInvalidAge(); } else { this.props.onAgesBecomingValid(); } } }); }());