import React from 'react';
import { MenuItem } from 'react-bootstrap';
import Popup from './popup';
import { objEqual, isEmpty } from '../commons/utils';
/**
* A component that allows use to select a single or multiple elements from a drop down
* selection box.
*/
export default class SelectionBox extends React.Component {
constructor(props) {
super(props);
this.controlClick = this.controlClick.bind(this);
this.itemClick = this.itemClick.bind(this);
this.btnCloseClick = this.btnCloseClick.bind(this);
this.notifyChange = this.notifyChange.bind(this);
this.noSelClick = this.noSelClick.bind(this);
this.btnKeyPress = this.btnKeyPress.bind(this);
// initialize an empty list of values
this.state = { };
}
shouldComponentUpdate(nextProps, nextState) {
return !objEqual(nextProps, this.props) || !objEqual(nextState, this.state);
}
/**
* Notify the parent about change in the selection
* @param {[type]} value The new value selected
* @param {[type]} evt The control event, generated by react
*/
notifyChange(value) {
this._value = value;
if (this.props.onChange) {
this.props.onChange(value);
}
}
/**
* API exposed to the client to get its selected value.
* It is not in the state because when the event is generated, the state is not immediatelly
* updated
* @return {Array|Object} An array, if it is a multi-selection or the item selected in the option list
*/
getValue() {
return this._value;
}
/**
* Return the rendered component for the label
* @return {React.Component} The label component, or null if there is no label
*/
labelRender() {
const label = this.props.label;
return label ? : null;
}
/**
* Return the item to be displayed
* @param {Object} item The item to be displaye
* @return {[type]} [description]
*/
getOptionDisplay(item) {
const idisp = this.props.optionDisplay;
if (!idisp) {
return item;
}
if (typeof idisp === 'function') {
return idisp(item);
}
if (typeof idisp === 'string') {
return item[idisp];
}
return item;
}
/**
* Return the options to be displayed in the popup
* @return {[type]} [description]
*/
getOptions() {
const options = this.props.options;
if (!options) {
return null;
}
const values = this.props.value;
if (this.props.mode === 'single' || !values) {
return options;
}
// filter the items to display just the not selected options
return options.filter(item => values.indexOf(item) === -1);
}
/**
* Create the popup component to be displayed based on the options
* @return {React.Component} Popup component, or null if no option is found
*/
createPopup() {
const options = this.getOptions();
if (options === null) {
return null;
}
// create the components
const opts = options
.map(item => {
return (
);
});
// check if an item for no selection should be included
const noSelLabel = this.props.noSelectionLabel;
if (noSelLabel && this.props.mode === 'single') {
opts.unshift();
}
return opts.length > 0 ?