I cannot select multiple values without holding Cmd key
My usage of SelectSearch in the component
<SelectSearch search multiple emptyMessage="Cannot find class" options={this.state.lessonSelections}
placeholder="Class" closeOnSelect={false} printOptions="on-focus"
className='select-search' onChange={this.handleLessonsChange.bind(this)} />
My handleLessonsChange
handleLessonsChange(value, state, props) {
this.setState({
lessons: state
});
}
and then the state
this.state = {
studentSelections: [],
lessonSelections: [],
materialSelections: [],
student: '',
lessons: [],
materials: [],
data: {},
};
I'm just lost on how I can select multiple values like how it is in the storybook
Try to set multiple option to true, it's in the docs https://www.npmjs.com/package/react-select-search. Like this:
export default function App() {
const options = [
{ name: "Swedish", value: "sv" },
{ name: "English", value: "en" },
{ name: "Spanish", value: "sp" }
];
return (
<div className="App">
<SelectSearch
options={options}
value="sv"
name="language"
placeholder="Choose your language"
multiple="true"
/>
</div>
);
}
Related
I have some trouble with my react-select: When I click 'Submit', it save an object that have both 'value' and 'label' like this:
enter image description here
All I need is when I choose, it's show label list, and when I submit, it save only value. What can I do? Here are my code:
const [mainLang, setMainLang] = useState("");
const mainLangOptions = [
{ value: 'vi', label: 'Vietnamese' },
{ value: 'en', label: 'English' },
{ value: 'zh', label: 'Chinese' },
{ value: 'ja', label: 'Japanese' },
{ value: 'de', label: 'German' },
];
//This is Select part
<Select
onChange={(e) =>setMainLang(e)}
options={mainLangOptions}
/>
You need to set the option value as the mainLangOptions.value and the label as
mainLangOptions.label. By doing that you will display the label as option labels and save the value as the value of option tag. Check out the code below :
import React from "react";
import "./styles.css";
class App extends React.Component {
constructor() {
super();
this.state = {
mainLanguage: ""
};
}
onOptionChangeHandler = (event) => {
this.state.mainLanguage = event.target.value;
console.log(this.state.mainLanguage);
};
render() {
const mainLangOptions = [
{ value: "vi", label: "Vietnamese" },
{ value: "en", label: "English" },
{ value: "zh", label: "Chinese" },
{ value: "ja", label: "Japanese" },
{ value: "de", label: "German" }
];
return (
<div>
<select onChange={this.onOptionChangeHandler}>
<option>Please choose one option</option>
{mainLangOptions.map((option, index) => {
return (
<option value={option.value} key={index}>
{option.label}
</option>
);
})}
</select>
</div>
);
}
}
export default App;
You must use e.target.value inside your setMainLang
<Select onChange={(e) => setMainLang(e.target.value)}>
This should work for your code but if it doesn't work, here is a complete code that I have tested in code sandbox and you can try it.
import React, { useState } from "react";
import { Select } from "#chakra-ui/react";
const Users = () => {
const [mainLang, setMainLang] = useState("");
const mainLangOptions = [
{ value: "vi", label: "Vietnamese" },
{ value: "en", label: "English" },
{ value: "zh", label: "Chinese" },
{ value: "ja", label: "Japanese" },
{ value: "de", label: "German" }
];
return (
<>
<Select onChange={(e) => setMainLang(e.target.value)}>
{mainLangOptions.map((op) => (
<option value={op.value}>{op.label}</option>
))}
</Select>
<h1>{mainLang}</h1>
</>
);
};
export default Users;
I want to insert a new object inside the options which is an array property inside the select1 object every time the user clicks on add button, how can I achieve this target, pls reply to this query.
I want to build a simple application where a user enters the options in the select box and can apply conditions based upon the selected option.
const [select1, setSelect1] = useState({
id: uuid(),
type: 'select',
properties: {
label: 'Select1',
options: [
{
id: uuid(),
label: 'text1',
value: {
labelTxt: 'text1',
childOptions: [],
},
},
{
id: uuid(),
label: 'text2',
value: {
labelTxt: 'text2',
childOptions: [],
},
},
],
},
parentId: null,
});
function addOptionsVal() {
setSelect1((prevState) => {
const options = [...prevState.properties.options];
options.splice(1, 0, {
id: uuid(),
label: optionVal,
value: {
labelTxt: optionVal,
childOptions: [],
},
});
console.log(options);
return { ...prevState, options };
});
}
return (
<div>
<select name="" id="">
<option value="">--select--</option>
{select1.properties.options.map((option) => {
return <option>{option.label}</option>;
})}
</select>
</div>
<input
type="text"
value={optionVal}
onChange={(e) => handleValueChange(e)}
/>
<button onClick={addOptionsVal}>Add options</button>
</div>
<div>
<input
type="checkbox"
value="male"
checked={checked}
onChange={toggleCondition}
id="condition"
/>
<label htmlFor="condition">Apply condition</label>
</div>
)
This is the entire code file in case you need
Try this:
function addOptionsVal() {
setSelect1((prevState) => {
return {
...prevState,
properties: {
...prevState.properties,
options: [
...prevState.properties.options,
{
id: uuid(),
label: optionVal,
value: {
labelTxt: optionVal,
childOptions: [],
},
},
],
},
};
});
}
stackblitz
Also, take a look at this question Correct modification of state arrays in React.js
This is my select function
import React from "react";
const Select = ({ name, label, options, error, ...rest }) => {
return (
<div className="form-group">
<label htmlFor={name}>{label}</label>
<select {...rest} id={name} name={name} className="form-control">
<option value="" />
{options.map((option) => (
<option key={option.id} value={option.id}>
{option.name}
</option>
))}
</select>
{error && <div className="alert alert-danger">{error}</div>}
</div>
);
};
export default Select;
This is the component state
state = {
data: {
vat: "",
city: "",
country: "",
mobile_number: "",
address: "",
has_conference: false,
star_rating: "",
},
errors: {},
hotel_type: [],
};
This function to populate data in the hotel_type
populateHotel_Types = () => {
let hotel_type = [...this.state.hotel_type];
hotel_type = [
{ id: "hotel", value: "hotel", name: "Hotel" },
{ id: "apartment", value: "apartment", name: "Apartment" },
{ id: "villa", value: "villa", name: "Villa" },
];
this.setState({ hotel_type });
};
And Finally this is the render function
{this.renderSelect(
"hotel_type",
"Hotel Type",
this.state.hotel_type
)}
Render select function
renderSelect(name, label, options) {
const { data, errors } = this.state;
return (
<Select
options={options}
name={name}
value={data[name]}
label={label}
onChange={this.handleChange}
error={errors[name]}
/>
);
}
Now i am struggling to get the data populated in the renderselect function. I am quite new to react and i am actually assuming this might be a silly question therefore kindly bear with me. What could be wrong with this code. Please help. Thanks
I think in first place, you have a problem here:
populateHotel_Types = () => {
let hotel_type = [...this.state.hotel_type];
hotel_type = [
{ id: "hotel", value: "hotel", name: "Hotel" },
{ id: "apartment", value: "apartment", name: "Apartment" },
{ id: "villa", value: "villa", name: "Villa" },
];
this.setState({ hotel_type });
};
Here, you are filling hotel_type with your state. And below, you are redefining the array, so you will have just this 3 new objects. So should do this to have the full list:
populateHotel_Types = () => {
const hotel_type = [
...this.state.hotel_type,
{ id: "hotel", value: "hotel", name: "Hotel" },
{ id: "apartment", value: "apartment", name: "Apartment" },
{ id: "villa", value: "villa", name: "Villa" },
];
this.setState({ hotel_type });
};
I suspected this was a silly question and indeed it was. I was forgetting to run the function populateHotel_Types in the componentDidMount function. Therefore the state was not being updated appropriately. I am leaving this here so that any newbie like myself will get an answer to such a scenario
I'm trying to get values from an array,
which is inside of objects:
const post = {
sticky: false,
template: "",
format: "standard",
_embedded: {
author: [{
0: {
id: 2,
name: "Charlie"
}
}],
term: ""
}
}
I need to get value of author.name, how should I map through this?
I tried this in my return:
return(
<div className={className}>
<h2>
{post._embedded.author[0].name}
</h2>
</div>
)
But it's not working, I get an error Cannot read property 'author' of undefine.
Sorry for silly question, but it's hard for me to understand.
This should work
post._embedded.author[0]['0'].name
You can try it out using the below snippet.
const post = {
sticky: false,
template: "",
format: "standard",
_embedded: {
author: [{
0: {
id: 2,
name: "Charlie"
}
}],
term: ""
}
};
const name = post._embedded.author[0]['0'].name;
console.log(name)
So the jsx would be
return(
<div className={className}>
<h2>
{post._embedded.author[0]['0'].name}
</h2>
</div>
)
I have two variable a and b in state. which are both copied one constant variable.(all are nested array).
Whenever i try to update a, it update b also, i dont know what the problem?
See The codesandbox demo: https://codesandbox.io/s/busy-maxwell-xvu5w
Code:
import React from "react";
const filterAttributes = [
{
name: "gender",
searchable: false,
search: "",
values: ["Male", "Female", "Child", "Other"]
},
{
name: "size",
searchable: false,
search: "",
values: ["30", "35", "15", "55", "10"]
},
{
name: "brand",
searchable: true,
search: "",
values: [
"Amazon",
"Flipkart",
"Apple",
"Vivo",
"Oppo",
"Samsung",
"Twitter"
]
}
];
export default class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
a: [...filterAttributes],
b: [...filterAttributes]
};
}
changeA = () => {
let a = [...filterAttributes];
a[0].search = "d-1--d";
this.setState({ a: [...a] });
};
render() {
return (
<div>
<pre style={{ maxWidth: "100%", overflowX: "scroll" }}>
<div>A: {JSON.stringify(this.state.a)}</div>
<hr />
<div>B: {JSON.stringify(this.state.b)}</div>
</pre>
<button onClick={this.changeA}>Change A</button>
<button>Change B</button>
</div>
);
}
}
let a = this.state.a;
a[0] = { ...a[0], ...{ search: "3-1--d" } };
this.setState({ a });
Using the spread operator we can make a copy of the object as well. Since this only shallow clones, it will only go one level deep.
The spread operator only goes one level deep (Shallow Copying).This means that the objects in your array are still referenced. I would recommend using lodash for deep copies but also a custom way like this works:
this.state = {
a: JSON.parse(JSON.stringify(filterAttributes)),
b: JSON.parse(JSON.stringify(filterAttributes))
};