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

Tags #2

Merged
merged 2 commits into from
Mar 23, 2015
Merged
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
1 change: 1 addition & 0 deletions examples/tags.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
placeholder
32 changes: 32 additions & 0 deletions examples/tags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
var React = require('react');
var Select = require('rc-select');
var Option = Select.Option;
require('./examples.css');
require('rc-menu/assets/index.css');
require('rc-select/assets/index.css');
var children = [];
for (var i = 10; i < 36; i++) {
children.push(<Option value={i.toString(36) + i}>{i.toString(36) + i}</Option>);
}

function handleChange(value) {
console.log('selected ' + value);
}

var style = '.rc-select-menu {height:200px;overflow:auto;}';

var c2 = (
<div>
<h1>multiple select(scroll the menu)</h1>
<div style={{width: 300}}>
<style>
{style}
</style>
<Select tags value={['name2', 'name3']} onChange={handleChange}>
{children}
</Select>
</div>
</div>
);

React.render(c2, document.getElementById('__react-content'));
31 changes: 19 additions & 12 deletions lib/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ var KeyCode = rcUtil.KeyCode;
var Menu = require('rc-menu');
var MenuItem = Menu.Item;

function isMultipleOrTags(props){
return props.multiple || props.tags;
}

function noop() {
}

Expand Down Expand Up @@ -95,7 +99,7 @@ class Select extends React.Component {
this.setState({
open: open
}, ()=> {
if (open || this.props.multiple || this.props.combobox) {
if (open || isMultipleOrTags(this.props) || this.props.combobox) {
this.refs.input.getDOMNode().focus();
} else {
this.refs.selection.getDOMNode().focus();
Expand Down Expand Up @@ -158,7 +162,7 @@ class Select extends React.Component {

handleMenuSelect(key, item) {
var value;
if (this.props.multiple) {
if (isMultipleOrTags(this.props)) {
value = this.state.value.concat();
value.push(item.props.value);
} else {
Expand All @@ -168,7 +172,7 @@ class Select extends React.Component {
}
value = [item.props.value];
}
this.props.onChange(this.props.multiple ? value : value[0]);
this.props.onChange(isMultipleOrTags(this.props) ? value : value[0]);
this.setState({
value: value,
inputValue: ''
Expand Down Expand Up @@ -207,7 +211,7 @@ class Select extends React.Component {
value = this.state.value.filter((v)=> {
return v !== value;
});
this.props.onChange(this.props.multiple ? value : value[0]);
this.props.onChange(isMultipleOrTags(this.props) ? value : value[0]);
this.setState({
value: value
});
Expand All @@ -216,7 +220,7 @@ class Select extends React.Component {
handleClearSelection(e) {
e.stopPropagation();
if (this.state.value.length) {
this.props.onChange(this.props.multiple ? [] : undefined);
this.props.onChange(isMultipleOrTags(this.props) ? [] : undefined);
this.setState({
value: [],
inputValue: ''
Expand All @@ -228,7 +232,7 @@ class Select extends React.Component {
renderMenu(children) {
var props = this.props;
var menuProps = {};
if (props.multiple) {
if (isMultipleOrTags(props)) {
menuProps.onDeselect = this.handleMenuDeselect;
}
var value = this.state.value;
Expand All @@ -248,7 +252,7 @@ class Select extends React.Component {
onSelect={this.handleMenuSelect}
activeFirst={true}
activeKey={activeKey}
multiple={props.multiple}
multiple={isMultipleOrTags(props)}
focusable={false}
{...menuProps}
selectedKeys={selectedKeys}
Expand All @@ -265,14 +269,14 @@ class Select extends React.Component {
onClick={this.handleClearSelection}>×</span>;
var props = this.props;
// single and not combobox, input is inside dropdown
if (!props.combobox && !props.multiple) {
if (!props.combobox && !isMultipleOrTags(props)) {
return <span className={prefixCls + '-selection__rendered'}>
{value[0]}
{allowClear ? clear : null}
</span>;
}
var selectedValueNodes;
if (props.multiple) {
if (isMultipleOrTags(props)) {
selectedValueNodes = value.map((v) => {
return (
<li className={prefixCls + '-selection__choice'}>
Expand All @@ -287,7 +291,7 @@ class Select extends React.Component {
return (
<ul className={prefixCls + '-selection__rendered'}>
{selectedValueNodes}
{allowClear && !props.multiple ? clear : null}
{allowClear && !isMultipleOrTags(props) ? clear : null}
<li className={joinClasses(prefixCls + '-search', prefixCls + '-search--inline')}>{input}</li>
</ul>
);
Expand Down Expand Up @@ -317,7 +321,7 @@ class Select extends React.Component {

render() {
var props = this.props;
var multiple = props.multiple;
var multiple = isMultipleOrTags(this.props);
var prefixCls = props.prefixCls;

var input = (
Expand All @@ -331,7 +335,9 @@ class Select extends React.Component {

var children = this._getFilterList(this.state.inputValue);
if (!children.length) {
children = <MenuItem disabled>{props.notFoundContent}</MenuItem>;
children = !this.props.tags ?
<MenuItem disabled>{props.notFoundContent}</MenuItem> :
<MenuItem value={this.state.inputValue}>{this.state.inputValue}</MenuItem>;
}

var ctrlNode = this.getTopControlNode(input);
Expand Down Expand Up @@ -377,6 +383,7 @@ class Select extends React.Component {

Select.propTypes = {
multiple: React.PropTypes.bool,
tags: React.PropTypes.bool,
onChange: React.PropTypes.func
};

Expand Down
41 changes: 41 additions & 0 deletions tests/Select.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,47 @@ describe('Select', function () {
done();
}, 100);
});

});

describe('when use option tags', function () {
var div;

this.timeout(400000);

beforeEach(function () {
div = document.createElement('div');
div.tabIndex = 0;
document.body.appendChild(div);
instance = React.render(
<Select tags>
<Option value="1">1</Option>
<Option value="2">2</Option>
</Select>,
div);
});

afterEach(function () {
React.unmountComponentAtNode(div);
});

it('should allow user input as tags', function (done) {
if (navigator.userAgent.indexOf(' Chrome') === -1) {
done();
return;
}

var node = React.findDOMNode(instance.refs.input);
React.addons.TestUtils.Simulate.keyDown( node, {key:"A"} )

setTimeout(function () {
React.addons.TestUtils.Simulate.keyDown( node, {key:"Enter"} )
setTimeout(function () {
expect(instance.state.value).to.contain("A");
}, 100);
done();
}, 100);
});
});

});