I am using creatable select to allow the user to input a new option that is not in the dropdown list. But after looking I cannot seem to see a way of setting the maximum input to 50 characters for input before creating in the creatable select.
I have looked at taking the new entry and if over 50 characters deleting it however this seems a long way round and would like to use something that is shorter on the actual input when the user selects create.
import CreatableSelect from 'react-select/creatable';
const cars = [
{ label: "audi", value: 1 },
{ label: "bmw", value: 2 },
{ label: "ford", value: 3 },
{ label: "VW", value: 4 },
];
const selectOption = () => (
<div className="app">
<div className="container">
<CreatableSelect
options={cars}
placeholder={"check and enter new car name here"}
isClearable
onChange={(opt, meta) => console.log(opt, meta)}
/>
</div>
</div>
);
export default selectOption
I am hoping there is a max input option i just dont know. Thank you for taking the time to look at this/help, very much appreciated.
Simply put you can use the <CreatableSelect/> s onCreateOption prop. You will have to maintain your options and value in component state. Then put your control logic inside handleCreateOption function ( for onCreateOption prop ). Your handleCreateOption will be something like this. ( look at codesandbox for full code )
handleCreateOption = inputValues => {
if (inputValue.length < 50) {
const newOption = createOption(inputValue);
this.setState({
options: [...options, newOption],
value: newOption
});
}
}
codesandbox : https://codesandbox.io/embed/react-codesandboxer-example-cjbgu
If you don't want the user to be able to type more than the limit, you can add maxLength attribute to the input.
import React, { useEffect, useRef } from 'react';
const myRef = useRef(null);
useEffect(() => {
myRef.current.inputRef.style.minWidth = 'max-content';
myRef.current.inputRef.placeholder = placeholderText;
myRef.current.inputRef.maxLength = 20;
}, []);
<CreatableSelect
ref={myRef}
{...props}
options={options}
value={value}
name={name}
onChange={handleChange}
placeholder={''}
classNamePrefix="multi-select-custom"
isMulti={isMulti}
/>
Related
I'm using react-select library to add dropdown menu for my app, but "required" doesn't work (I read a discussion on GitHub for this library, creators haven't added that function yet), so for now how do I make select required? (I read here another post with the same problem, solution presented there didn't work for me). My code is:
import React, { useState } from "react";
import Select from "react-select";
export default function App() {
const [data, setData] = useState();
const options = [
{ value: "1", label: "1" },
{ value: "2", label: "2" },
{ value: "3", label: "3" },
{ value: "4", label: "4" }
];
const handleSubmit = (e) => {
console.log(data);
};
return (
<div className="App">
<form onSubmit={handleSubmit}>
<input required placeholder="name" />
<Select
options={options}
onChange={(e) => setData(e.value)}
value={options.filter(function (option) {
return option.value === data;
})}
label="Single select"
placeholder={"Select "}
menuPlacement="top"
required
/>
<button> Submit</button>
</form>
</div>
);
}
code sandbox
In my code I have a couple of regular inputs (where required works fine) but I want the Select also be required. Any suggestions are greatly appreciated.
I would think outside the box — in this case the Select component. What can you add that gets the same result? I took a quick stab at this for you:
const [isValid, setIsValid] = useState(false);
// This effect runs when 'data' changes
useEffect(() => {
// If there is data, the form is valid
setIsValid(data ? true : false);
}, [data]);
...
return (
<div>
<Select ... />
{!isValid && <p>You must choose a value</p>}
<button disabled={!isValid}>Submit</button>
</div>
)
https://codesandbox.io/s/vigilant-wiles-6lx5f
In this example, we check the state of the Select component — if it's empty (the user hasn't chosen anything) the form is invalid and the submit button is disabled.
I am working with React and React Forms and i am having trouble trying to handle the state changes for radio buttons. I have a function getField which dynamically renders the type of input from the state. I have another function HandleFormStateChange which handles the change event for the inputs but i am running into an issue with the radio buttons. The user should be able to select only one option at a time but it seems to be selecting simultaneous options.
Please check out this CodeSandbox.
This is the complete code:
import React from "react";
class App extends React.Component {
state = {
Forms: [{ name: "Radio", type: "radio", options: ["a", "b", "c"] }]
};
handleFormStateChange = (event, idx) => {
const target = event.target;
const form = [...this.state.Forms];
form[idx].value = "";
form[idx].value = target.type === "radio" ? target.value : form[idx].value;
this.setState({
form
});
};
getField = (field, index) => {
switch (field.type) {
case "radio":
return (
<div>
{field.options.map(option => (
<label key={field.type + "op" + option}>
{option}:
<input
onChange={event => {
this.handleFormStateChange(event, index);
}}
key={option}
type={field.type}
name={option}
value={option}
/>
</label>
))}
</div>
);
default:
return <div>Unknown form field</div>;
}
};
renderForm = () => {
return this.state.Forms.map((field, index) => (
<label key={index}>
{field.name}
{this.getField(field, index)}
</label>
));
};
render() {
return <div>{this.renderForm()}</div>;
}
}
export default App;
Any help will be appreciated. Thank you :)
It is selecting multiple options because your radio buttons are not grouped by their name, they have separate names of their own. I've made an edit in your codesandbox - we have to have same name for your radio buttons to group them together. The same is the case with checkboxes if you want to group them together.
I've made couple of changes to your code:
I've added a name to identify the radio-group.
state = {
Forms: [
{
name: "Radio",
radioGroupName: "chosenAlphabet",
type: "radio",
options: ["a", "b", "c"]
}
]
};
I've changed the name attribute in your field rendering function.
<input
onChange={event => {
this.handleFormStateChange(event, index);
}}
key={option}
type={field.type}
name={field.radioGroupName}
value={option}
/>
I have a list of countries, with key, value, text.
I would like to have two Dropdown (https://react.semantic-ui.com/modules/dropdown/) list, one shows the key, the other the text.
The goal is to allow to choose by key of by text (we can type in the dropdown); if I update one, the other is synchronized immediately.
How can I achieve this ?
<Dropdown
id='form-input-country'
label='Country'
placeholder='Select Country'
fluid
search
selection
options={countryISOOptions} // will show text
/>
<Dropdown
id='form-input-country'
label='Country'
placeholder='Select Country'
fluid
search
selection
options={countryISOOptions} // want to show key + want to sync in both direction
/>
I import countryISOOptions which looks like:
export const countryISOOptions = [
{key: 'AF', value: '4', text: 'Afghanistan'},
{key: 'AL', value: '8', text: 'Albania'},
{key: 'DZ', value: '12', text: 'Algeria'},
...
Maintain 2 option arrays. One for text and other for keys(derived from the first options array). Then maintain just one state and an onChange for both dropdowns and you will be fine.
See working copy of your code.
See code snippet:
import React, { useState } from "react";
import { Dropdown } from "semantic-ui-react";
import "./styles.css";
const countryISOOptions = [
{ key: "AF", value: "4", text: "Afghanistan" },
{ key: "AL", value: "8", text: "Albania" },
{ key: "DZ", value: "12", text: "Algeria" }
];
const countryKeys = countryISOOptions.map(({ key, value }) => ({
value,
text: key
}));
export default function App() {
const [text, setText] = useState("");
const onChangeTextDropdown = (e, d) => {
console.log("onChangeTextDropdown", e.target.value);
console.log("d", d);
setText(d.value);
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Dropdown
id="form-input-countryz"
label="Country"
placeholder="Select Country - text"
value={text}
onChange={onChangeTextDropdown}
fluid
search
selection
options={countryISOOptions} // will show text
/>
<Dropdown
id="form-input-country"
label="Country"
placeholder="Select Country - key"
value={text}
onChange={onChangeTextDropdown}
fluid
search
selection
options={countryKeys} // want to show key + want to sync in both direction
/>
</div>
);
}
If you are using controlled version, then each Dropdown is a typical Inputthat supports two props called value and onChange. I'll use hook in the following example,
const [value1, setValue1] = setState('')
const [value2, setValue2] = setState('')
const onValue1Change = e => {
const value = e.target.value
setValue1(value)
if (value === 'key') setValue2('country')
}
return (
<div>
<Dropdown
value={value1}
onChange={onValue1Change}
...
/>
<Dropdown
value={value2}
...
/>
</div>
)
I am using react-select for my select dropdown. The issue I am having is that there is no empty option to reset the dropdown value if the user changes their mind.
Currently I am taking the options and manually adding an empty string, but I feel there must be something already in the library to handle this? I cannot find anything in the docs.
My code looks like the below, and there is a code sandbox here.
import React from "react";
import Select from "react-select";
const App = () => {
const options = [
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
];
return <Dropdown options={options} />;
}
const Dropdown = ({ options }) => {
const optionsWithEmptyOption = [{ value: "", label: "" }, ...options];
return <Select options={optionsWithEmptyOption} />;
};
Plase check this out
https://codesandbox.io/s/zow1c?module=/example.js
import React, { Component } from 'react';
import CreatableSelect from 'react-select/creatable';
import { colourOptions } from './docs/data';
export default class CreatableSingle extends Component<*, State> {
handleChange = (newValue: any, actionMeta: any) => {
console.group('Value Changed');
console.log(newValue);
console.log(`action: ${actionMeta.action}`);
console.groupEnd();
};
handleInputChange = (inputValue: any, actionMeta: any) => {
console.group('Input Changed');
console.log(inputValue);
console.log(`action: ${actionMeta.action}`);
console.groupEnd();
};
render() {
return (
<CreatableSelect
isClearable
onChange={this.handleChange}
onInputChange={this.handleInputChange}
options={colourOptions}
/>
);
}
}
Empty Unicode
I add line to options, and write between the apostrophes empty unicode like this: ⠀⠀⠀⠀⠀⠀⠀⠀ .. you can mark it but dont see it.
const options = [
{ value: "", label: "⠀" },
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
];
And I change this:
return <Select options={options} />;
what about const optionsWithEmptyOption = [{ value: null, label: "Select..." }, ...options];
I'm not really good with explanations, but #NicoHaase is right, so here it goes...
as far as I know, you must give a value to value null (if nothing) or string ... same for the label, #1 because of the user UX and second so react-select knows what to display. But if you really need to leave it in black, and you can try to modify in the styles, in order to have the same height as the other options.
I am using react-select for autocomplete and option related field. When i select the option it passes whole that option object as {value: 'abc', label: 'ABC'} but i wanted only to pass the value as a string not the object. Thus, i used getOptionValue but it is not working as expected.
This is what I have done
<Field
name='status'
component={SearchableText}
placeholder="Search..."
options={status}
styles={styles}
getOptionLabel={option => option.label}
getOptionValue={option => option.value}
/>
I have used both getOptionLabel and getOptionValue but is still passing the selected option in object form instead of just the value as string.
Expected one
status: 'active'
Current behavior
status: { value: 'active', label: 'Active'}
I couldn't find getOptionValue in the docs for react-select, but you could always create an adapter around react-select. i.e. create your own Select component that uses react-select's Select component internally. After doing this it becomes possible to create your own getOptionValue. You can use this to make sure the value is a string.
import React from "react";
import Select from "react-select";
class MySelect extends React.Component {
getSelectValue() {
return this.props.options.find(
option => this.props.getOptionValue(option) === this.props.input.value
);
}
render() {
console.log("value", this.props.input.value);
return (
<Select
value={this.getSelectValue()}
onChange={option => {
this.props.input.onChange(this.props.getOptionValue(option));
}}
options={this.props.options}
/>
);
}
}
MySelect.defaultProps = {
getOptionValue: v => v
};
const MyForm = reduxForm({ form: "MyForm" })(
class extends React.PureComponent {
render() {
return (
<Field
name="myCoolSelect"
component={MySelect}
options={[
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
]}
getOptionValue={option => option.value}
/>
);
}
}
);
The above is a basic example of how to get this working. You may want to pass other input or meta props to take advantage of other redux-form features. e.g. onBlur, onFocus, etc. You can see it in action here: https://codesandbox.io/s/6wykjnv32n