Skip to content

Commit

Permalink
Merge pull request #2 from react-component/tags
Browse files Browse the repository at this point in the history
Tags
  • Loading branch information
yiminghe committed Mar 23, 2015
2 parents f9f07ed + f7a4121 commit 7e66297
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 12 deletions.
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);
});
});

});

0 comments on commit 7e66297

Please sign in to comment.