Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SelectField] Include option to select multiple values. #4252

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';

const style = {
overflow: 'hidden',
whiteSpace: 'nowrap',
};

export default class SelectFieldExampleMultiple extends React.Component {

constructor(props) {
super(props);
this.state = {value: []};
}

handleChange = (event, index, value) => {
const stateValueIndex = this.state.value.indexOf(value);
if (stateValueIndex === -1) {
this.state.value.push(value);
} else {
this.state.value.splice(stateValueIndex, 1);
}
}

render() {
return (
<div>
<SelectField
value={this.state.value}
onChange={this.handleChange}
multiple={true}
style={style}
>
<MenuItem value={1} primaryText="Never" />
<MenuItem value={2} primaryText="Every Night" />
<MenuItem value={3} primaryText="Weeknights" />
<MenuItem value={4} primaryText="Weekends" />
<MenuItem value={5} primaryText="Weekly" />
</SelectField>
</div>
);
}
}
11 changes: 11 additions & 0 deletions docs/src/app/components/pages/components/SelectField/Page.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import selectFieldExampleFloatingLabelCode from '!raw!./ExampleFloatingLabel';
import SelectFieldExampleError from './ExampleError';
import selectFieldExampleErrorCode from '!raw!./ExampleError';
import selectFieldCode from '!raw!material-ui/SelectField/SelectField';
import SelectFieldExampleMultiple from './ExampleMultiple';
import selectFieldExampleMultipleCode from '!raw!./ExampleMultiple';

const descriptions = {
simple: '`SelectField` is implemented as a controlled component, with the current selection set through the ' +
Expand All @@ -29,6 +31,8 @@ const descriptions = {
'with the `floatingLabelText` property.',
errorText: 'The `errorText` property displays an error message below the Select Field. This can be customised with ' +
'the `errorStyle` property.',
multiple: '`SelectField` supports selecting multiple values. This can be set ' +
'with the `multiple` property.',
};

const SelectFieldPage = () => (
Expand Down Expand Up @@ -70,6 +74,13 @@ const SelectFieldPage = () => (
>
<SelectFieldExampleError />
</CodeExample>
<CodeExample
title="Multiple example"
description={descriptions.multiple}
code={selectFieldExampleMultipleCode}
>
<SelectFieldExampleMultiple />
</CodeExample>
<PropTypeDescription code={selectFieldCode} />
</div>
);
Expand Down
29 changes: 23 additions & 6 deletions src/DropDownMenu/DropDownMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ class DropDownMenu extends Component {
* Overrides the styles of `Menu` when the `DropDownMenu` is displayed.
*/
menuStyle: PropTypes.object,
/**
* If true, `value` must be an array and the menu will support
* multiple selections.
*/
multiple: PropTypes.bool,
/**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this prop useful outside of SelectField, or can it be @ignored for the public DropDownMenu API docs?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't think of a use case for multiple items in a "regular" drop down menu, but I might be wrong. If that's the case @ignore should works.

* Callback function fired when a menu item is clicked, other than the one currently selected.
*
Expand Down Expand Up @@ -142,6 +147,7 @@ class DropDownMenu extends Component {
static defaultProps = {
autoWidth: true,
disabled: false,
multiple: false,
openImmediately: false,
maxHeight: 500,
};
Expand Down Expand Up @@ -222,9 +228,11 @@ class DropDownMenu extends Component {
handleItemTouchTap = (event, child, index) => {
this.props.onChange(event, index, child.props.value);

this.setState({
open: false,
});
if (!this.props.multiple) {
this.setState({
open: false,
});
}
};

render() {
Expand Down Expand Up @@ -252,10 +260,18 @@ class DropDownMenu extends Component {
const styles = getStyles(this.props, this.context);

let displayValue = '';
const displayValueArray = [];
React.Children.forEach(children, (child) => {
if (value === child.props.value) {
// This will need to be improved (in case primaryText is a node)
displayValue = child.props.label || child.props.primaryText;
if (!this.props.multiple) {
if (value === child.props.value) {
// This will need to be improved (in case primaryText is a node)
displayValue = child.props.label || child.props.primaryText;
}
} else {
if (value.indexOf(child.props.value) !== -1) {
displayValueArray.push(child.props.label || child.props.primaryText);
displayValue = displayValueArray.join(', ');
}
}
});

Expand Down Expand Up @@ -298,6 +314,7 @@ class DropDownMenu extends Component {
style={menuStyle}
listStyle={listStyle}
onItemTouchTap={this.handleItemTouchTap}
multiple={this.props.multiple}
>
{children}
</Menu>
Expand Down
7 changes: 7 additions & 0 deletions src/SelectField/SelectField.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ class SelectField extends Component {
* Override the label style when the select field is inactive.
*/
labelStyle: PropTypes.object,
/**
* If true, `value` must be an array and the menu will support
* multiple selections.
*/
multiple: PropTypes.bool,
/**
* Callback function fired when the select field loses focus.
*
Expand Down Expand Up @@ -130,6 +135,7 @@ class SelectField extends Component {
autoWidth: false,
disabled: false,
fullWidth: false,
multiple: false,
};

static contextTypes = {
Expand Down Expand Up @@ -191,6 +197,7 @@ class SelectField extends Component {
autoWidth={autoWidth}
value={value}
onChange={onChange}
multiple={this.props.multiple}
{...other}
>
{children}
Expand Down