admin管理员组文章数量:1410717
I'm working on a permissions system to let users control who can access/ment/edit a resource, much like what you can find on Google Drive. I'm using a React-Select multi to let the owner of the resource pick users he wants to give access to the resource to.
When I click on an option displayed by react-select, I want this option to be added to my list of allowed users (a list that is handled by another ponent). This part works, I just used an onChange handler on the select (as you can see on the code below).
export default class AddUsersForm extends Component {
PropTypes = {
onSubmit: PropTypes.func.isRequired,
usersList: PropTypes.array.isRequired, // List of all users in the pany
usersInPermissions: PropTypes.array.isRequired, // Users who already have access to the resource
}
handleChange(users){
// Adds new user to the list of allowed users, an updated value for this.props.usersInPermissions will be received
this.props.onSubmit(users);
}
render() {
return (
<form>
<Select
name="users"
multi={true}
options={this.props.usersList.filter(user => !this.props.usersInPermissions.includes(user.id))}
onChange={(users) => this.handleChange(users)}
/>
</form>
);
}
}
I'm working on a permissions system to let users control who can access/ment/edit a resource, much like what you can find on Google Drive. I'm using a React-Select multi to let the owner of the resource pick users he wants to give access to the resource to.
When I click on an option displayed by react-select, I want this option to be added to my list of allowed users (a list that is handled by another ponent). This part works, I just used an onChange handler on the select (as you can see on the code below).
export default class AddUsersForm extends Component {
PropTypes = {
onSubmit: PropTypes.func.isRequired,
usersList: PropTypes.array.isRequired, // List of all users in the pany
usersInPermissions: PropTypes.array.isRequired, // Users who already have access to the resource
}
handleChange(users){
// Adds new user to the list of allowed users, an updated value for this.props.usersInPermissions will be received
this.props.onSubmit(users);
}
render() {
return (
<form>
<Select
name="users"
multi={true}
options={this.props.usersList.filter(user => !this.props.usersInPermissions.includes(user.id))}
onChange={(users) => this.handleChange(users)}
/>
</form>
);
}
}
This is where I am stuck: once the option has been added, I would like to keep displaying the filter that the user was potentially using while searching for the first option in the text field. The way it works now, the filter is removed and all the options are shown in the dropdown.
Is there any simple way of achieving this with React-Select?
Many thanks!
Share Improve this question edited Apr 20, 2017 at 14:43 asked Apr 20, 2017 at 11:11 user7894778user7894778 7- I would like to remove it from the value? can you explain this. – Ved Commented Apr 20, 2017 at 11:23
- Have you checked github./JedWatson/react-select/blob/master/examples/src/…? – elmeister Commented Apr 20, 2017 at 11:33
- @Ved I just got really confused there, this doesn't make any sense! So my only problem is actually keeping the filter in there, do you know if there is a way to do this? – user7894778 Commented Apr 20, 2017 at 11:37
- My question is once you select any value from Select, what next you want? – Ved Commented Apr 20, 2017 at 11:40
- @Ved Imagine that I have typed a few letters in the search box to find a user. Then this user appears in the dropdown, and when I click on it, the onChange handler is called and he's being added to my list of allowed users (this works fine at the moment). But when I do this, the letters I have typed in the text field are removed and the list of options is not being filtered anymore. I'd like to keep my filter but I don't know if it's possible? – user7894778 Commented Apr 20, 2017 at 11:45
2 Answers
Reset to default 1This code is working. Maybe there are better ways.
// ManageUsers
import React, { PropTypes } from 'react';
import AddUserForm from './AddUserForm'
export default class NoMatch extends React.Component {
constructor(props) {
super(props)
this.handleChange = this.handleChange.bind(this);
let selectedUsers = [ { value: 3, label: 'Three' },
{ value: 4, label: 'Four' } ];
this.state = {
selectedUsers: selectedUsers
}
}
handleChange(selected) {
this.setState({ selectedUsers: selected })
}
render() {
let usersList = [
{ value: 1, label: 'One' },
{ value: 2, label: 'Two' }
];
return (
<div>Users
<AddUserForm usersList={usersList}
selectedUsers={this.state.selectedUsers}
handleChange={this.handleChange} />
</div>
);
}
}
// AddUsersForm
import React, { PropTypes } from 'react';
import Select from 'react-select';
import 'react-select/dist/react-select.css';
export default class AddUsersForm extends React.Component {
PropTypes = {
usersList: PropTypes.array.isRequired,
selectedUsers: PropTypes.array.isRequired,
handleChange: PropTypes.func.isRequired
}
render() {
return (
<form>
<Select
multi={true}
options={this.props.usersList}
value={this.props.selectedUsers}
onChange={(users) => this.props.handleChange(users)}
/>
</form>
);
}
}
If you want to keep the typed text then you have to set the text of the input on the handleChange. There is no build in function to keep the typed text.
onChange={(users) => this.props.handleChange(users, event)}
handleChange(selected, event) {
let selectedFilter = event.target;
// then navigated to the input element with Javascript or jQuery
// and set the value of the input
this.setState({ selectedUsers: selected })
}
My way:
- Replaced
Option
ponent with own ponent (several ponents from Material-UI library). - Overrided
onClick
event handler - here is some logic and callonChange
handler from ReactSelect props. At the end of theonClick
handler addedevent.stopPropagation()
import React from 'react';
import MenuItem from '@material-ui/core/MenuItem/MenuItem';
import Checkbox from '@material-ui/core/Checkbox/Checkbox';
import ListItemText from '@material-ui/core/ListItemText/ListItemText';
const MultiOption = props => (
<MenuItem
buttonRef={props.innerRef}
{...props.innerProps}
onClick={event => {
let values = [];
if (props.isSelected) {
values = props.selectProps.value.filter(
item => item.value !== props.value,
);
} else {
values = [props.data].concat(props.selectProps.value);
}
props.selectProps.onChange(values);
event.stopPropagation();
}}
style={{
overflow: 'initial',
padding: 0,
}}
>
<Checkbox
checked={props.isSelected}
style={{
padding: 4,
}}
/>
<ListItemText
primary={props.label}
classes={{
root: props.selectProps.classes.optionRoot,
}}
/>
</MenuItem>
);
export default MultiOption;
import React from 'react';
import PropTypes from 'prop-types';
import Select from 'react-select';
import { withStyles } from '@material-ui/core/styles';
import { getComponents } from './ponents';
import { styles, getSelectStyles } from './styles';
class Combobox extends React.Component {
handleChange = () => value => {
const { onChange } = this.props;
onChange(value);
};
render() {
const {
classes,
theme,
options,
label,
rootStyle,
value,
error,
isInner,
isMulti,
fullWidth,
...props
} = this.props;
return (
<div className={classes.root} style={{ ...rootStyle }}>
<Select
{...props}
isClearable
classes={classes}
styles={getSelectStyles({
theme,
fullWidth,
})}
options={options}
menuPortalTarget={document.body}
menuPlacement="auto"
value={value || null}
onChange={this.handleChange()}
ponents={getComponents({
isInner,
isMulti,
})}
textFieldProps={{
label,
error: !!error,
helperText: error,
InputLabelProps: { shrink: true },
}}
isMulti={isMulti}
hideSelectedOptions={!isMulti}
closeMenuOnSelect={!isMulti}
loadingMessage={() => 'Loading...'}
/>
</div>
);
}
}
Combobox.propTypes = {
options: PropTypes.arrayOf(PropTypes.shape({})),
label: PropTypes.string,
classes: PropTypes.shape({}).isRequired,
theme: PropTypes.shape({}).isRequired,
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.bool,
PropTypes.arrayOf(PropTypes.any),
PropTypes.shape({}),
]),
error: PropTypes.string,
onChange: PropTypes.func.isRequired,
isInner: PropTypes.bool,
isMulti: PropTypes.bool,
fullWidth: PropTypes.bool,
};
Combobox.defaultProps = {
options: [],
label: '',
value: null,
error: '',
isInner: false,
isMulti: false,
fullWidth: false,
};
export default withStyles(styles, { withTheme: true })(({ ...props }) => (
<Combobox {...props} />
));
import Control from './Control';
import InnerControl from './InnerControl';
import InputComponent from './InputComponent';
import MenuList from './MenuList';
import Option from './Option';
import MultiOption from './MultiOption';
import SingleValue from './SingleValue';
import MultiValue from './MultiValue';
import NoOptionsMessage from './NoOptionsMessage';
import Placeholder from './Placeholder';
import ValueContainer from './ValueContainer';
const getComponents = ({ isInner, isMulti }) => ({
Control: isInner ? InnerControl : Control,
...(isMulti && { MenuList }),
MultiValue,
NoOptionsMessage,
Option: isMulti ? MultiOption : Option,
Placeholder,
SingleValue,
ValueContainer,
});
export {
Control,
InnerControl,
InputComponent,
MenuList,
Option,
MultiOption,
SingleValue,
MultiValue,
NoOptionsMessage,
Placeholder,
ValueContainer,
getComponents,
};
本文标签: javascriptReactselect clear value while keeping filterStack Overflow
版权声明:本文标题:javascript - React-select clear value while keeping filter - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744840643a2627903.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论