In case of multi-select , can someone help me with the onChange function ?
What can I pass inside updateFormState( ) to make the code work. Thanks.
const formState = {
fruits: "",
};
function updateFormState(key, value) {
formState[key] = value;
}
const [fruits] = useState([]);
<Form.Label>fruits</Form.Label>
<MultiSelect
options={[
{ label: "Grapes 🍇", value: "grapes" },
{ label: "Mango 🥭", value: "mango" },
{ label: "Strawberry 🍓", value: "strawberry", disabled: true },
]}
id="fruits"
labelledBy="Select"
value={fruits}
onChange={(e) => updateFormState( )}
/>
</Form.Group>
hi try this i hope it usefull
const [fruits, setFruits] = useState();
console.log("fruits",fruits);
return (
<div>
<select onChange={(e) => setFruits(e.target.value)} value={fruits}>
<option value='' selected disabled hidden>
select a fruits
</option>
<option value='apple'>apple</option>
<option value='banana'>banana</option>
<option value='orange'>orange</option>
</select>
</div>
);
Related
I am working on a React-based Google Docs clone as a side project. I'm using TipTap as the base.
I wanted to try to mimic the functionality in Google Docs where the select field would update with the appropriate value based on whatever text the user selects (ex., "heading 1" would show up on
the select field if a user highlights text with <h1></h1> styling).
Here's a small video of the functionality I want to mimic: https://i.gyazo.com/18cc57f0285c8c5cd80d5dd6051f0ee7.mp4
This is the code I have so far with the React Hook used for the select fields:
const [font, setFont] = useState('sans-serif')
const handleFontChange = (e) => {
setFont(e.target.value)
editor.chain().focus().setFontFamily(e.target.value).run()
}
return (
<select value={font} onChange={handleFontChange}>
{fontFamilies.map((item) => <option key={item.value} value={item.value}>{item.label}</option>)}
</select>
)
I've tried to wrap my head around React Hooks and the Selection API, but I'm stuck. Is this at all possible in Javascript/React?
EDIT:
I found a function from Tiptap's API that does exactly what I'm looking for. I guess now the problem is how do I update that value into the select? Here's my new code:
const font = [
{ value: 'sans-serif', label: 'Sans-serif' }, ...
]
const [selectedFont, setSelectedFont] = useState([])
const handleFontChange = (obj) => {
setSelectedFont(obj)
editor.chain().focus().setFontFamily(obj.value).run()
console.log(editor.isActive('textStyle', {fontFamily: selectedFont.value})) // prints true if the user clicked on text with the property active, otherwise prints false
}
return (
<Select
name="fontFamily"
options={font}
isClearable="true"
isSearchable="true"
value={selectedFont}
onChange={(option) => handleFontChange(option)}
/>
)
It feels like the solution is really simple but I'm just overthinking it.
So I finally figured out what to do. I needed to pass a function in value that iterated over the array:
const fontList = [
{ label: 'Sans-serif', value: 'sans-serif' },
...
]
<Select
name="fontFamily"
placeholder="Select font..."
value={
editor.isActive('textStyle', {fontFamily: font}) ? (
selectedFont.find(index => fontList[index])
) : ''
}
options={fontList}
onChange={({value: fontSel}) => {
setFont(fontSel)
editor.chain().focus().setFontFamily(fontSel).run()
}}
/>
It only took me a whole week of tearing my hair out... Glad to finally get this done.
Just to add to this, I was able to do the following in Vue to select headings with a dropdown.
<select
:value="editor.isActive('heading') ? editor.getAttributes('heading').level : 0"
#input="setSelectedHeading"
>
<option
v-for="heading in headings"
:key="heading.value"
:label="heading.label"
:value="heading.value"
/>
</select>
headings: [
{ value: 0, label: 'Normal text' },
{ value: 1, label: 'Heading 1' },
{ value: 2, label: 'Heading 2' },
{ value: 3, label: 'Heading 3' },
{ value: 4, label: 'Heading 4' },
{ value: 5, label: 'Heading 5' },
{ value: 6, label: 'Heading 6' }
]
setSelectedHeading (selected) {
if (selected === 0) {
const selectedLevel = this.editor.getAttributes('heading').level
return this.editor.chain().focus().toggleHeading({ level: selectedLevel }).run()
}
return this.editor.chain().focus().setHeading({ level: selected }).run()
}
In case someone wants to create a simple dropdown menu with vue and tiptap, since this doesn't seem to work:
<select class="font-type">
<option #click="editor.chain().focus().setParagraph().run()" selected>Paragraph</option>
<option #click="editor.chain().focus().toggleHeading({level: 1}).run()">Heading 1</option>
<option #click="editor.chain().focus().toggleHeading({level: 2}).run()">Heading 2</option>
<option #click="editor.chain().focus().toggleHeading({level: 3}).run()">Heading 3</option>
</select>
you can do this:
<select class="font-type" #change="toggleType(editor, $event)">
<option value="p" selected>Paragraph</option>
<option value="1">Heading 1</option>
<option value="2">Heading 2</option>
<option value="3">Heading 3</option>
</select>
and add this to your <script>:
const toggleType = (editor, event) => {
if (event.target.value == 'p') {
editor.chain().focus().setParagraph().run()
} else {
editor.chain().focus().toggleHeading({level: Number(event.target.value)}).run()
}
}
I have antd multiple row selectable table and for each row a select option is there. and when I click on a checkbox the row should get selected and the defaultvalue of select should change to "Active". when I untick the checkbox the row should not get selected and the defaultvalue of select should change to "Inactive".
also when I select the option as Active, the checkbox of that row should get ticked. and when I give the option as Inactive checkbox should be unticked.
Anyone know how to achive this?
const columns = [
{
title: "name",
dataIndex: "name",
key: "name",
},
{
title: "status",
dataIndex: "status",
key: "status",
render: (text: any, record: any) => {
return (
<Select style={{ width: 120 }} >
<Option value="Active">Active</Option>
<Option value="Inactive">Inactive</Option>
</Select>
);
},
},
]
const dataSource = [
{
key: "1",
name: "Mike",
status: null,
},
{
key: "2",
name: "jane",
status: null,
},
]
const rowSelection = {
onChange: (selectedRowKeys: any, selectedRows: any) => {
console.log("selectedRows ",selectedRows)
console.log("selectedRows ",selectedRowKeys)
},
getCheckboxProps: (record: any) => ({
}),
};
return(
<Table
columns={columns}
rowSelection={{ type: "checkbox", ...rowSelection }}
dataSource={dataSource}
/>
)
You should use state value for Select component.
const [selectedValues, setSelectedValues] = useState(null);
<Select style={{ width: 120 }} value={selectedValues.find(/*write find function that will based on key of record*/) ? "Active" : "Inactive"} >
<Option value="Active">Active</Option>
<Option value="Inactive">Inactive</Option>
</Select>
const rowSelection = {
onChange: (selectedRowKeys: any, selectedRows: any) => {
console.log("selectedRows ",selectedRows)
console.log("selectedRows ",selectedRowKeys)
setSelectedValues(selectedRows);
},
getCheckboxProps: (record: any) => ({
}),
};
When on Select field I hit space, first value from options is being selected. How to disable such behaviour?
<Select
ref={r => (this.selectRef = r)}
className="basic-single"
classNamePrefix="select"
onInputChange={val => {
console.log('va', val)
this.setState({ inputValue: val })
}}
inputValue={this.state.inputValue}
options={[{ value: 'aaa', label: 'aaa bbb' }, { value: 'bbb', label: 'bbb ccc' }]}
name="color"
/>
HERE IS A DEMO
I would suggest to use the onKeyDown props and prevent the action when the use hits the space bar so nothing will be selected.
<Select
ref={r => (this.selectRef = r)}
className="basic-single"
classNamePrefix="select"
onInputChange={val => {
this.setState({ inputValue: val });
}}
onKeyDown={e => {
if (e.keyCode === 32 && !this.selectRef.state.inputValue) e.preventDefault();
}}
inputValue={this.state.inputValue}
options={[
{ value: "aaa", label: "aaa bbb" },
{ value: "bbb", label: "bbb ccc" }
]}
name="color"
/>
Live example here.
I'm trying to read my options from an API so I made a Const InputResponse as follow:
const inputResponse = [
{
key: 'news',
value: "news",
datagrid:{
w:2,
h:9,
x:0,
y:0,
minW:2,
minH:5
}
},
{
key: 'clock',
value: "clock",
datagrid:{
w:2,
h:5,
x:5,
y:0,
minW:2,
minH:5
}
}
]
but I have no clue how to effect my select option
<Select defaultValue="" style={{ width: 120 }} onChange={this.handleChange} >
<Option value="Clock" className="options">Clock</Option>
<Option value="News" className="options">News</Option>
<Option value="Yiminghe" className="options">yiminghe</Option>
</Select>
the capital starting letters in jsx tags are for ant design
You have to iterate the array and just render it as is.
Like this:
<Select style={{ width: 120 }} onChange={this.handleChange}>
{
this.inputResponse.map((item) => {
return <Option value={item} key={item.key} className="options">{item.value}</Option>
})
}
</Select>
I have an array of countries
const countries = [{
name: 'United States', value: 'US', currency: 'USD'
}, {
name: 'Israle', value: 'IL', currency: 'ILS'
}, {
name: 'United Kingdom', value: 'UK', currency: 'GBP'
}]
And following code in react component
handleCountryChange(val){
console.log(val)
}
<select className="form-control input-lg" name="country" placeholder="Country" >
{ countries.map((val, index) => {
return(<option value={val.value} onClick={() => this.handleCountryChange(val)} key={index}>{val.name}</option>)
})}
</select>
but here my onClick is not being called... I want to get all the fields of the array inside the onClick function... How do I do it either with javascript or reactjs?
And onChange gives the event and targeted value not all the fields
You should put the handler on select element. Not on individual option.
Try the following..
<select className="form-control input-lg" name="country" placeholder="Country" onChange={(event) => this.handleCountryChange(event)}>
{ countries.map((val, index) => {
return(<option value={val.value} key={index}>{val.name}</option>)
})}
</select>
I made it by setting value as a index and then get the element by indexed value from the array
handleCountryChange(e){
this.setState({
country: countries[e.target.value].value,
currency: countries[e.target.value].currency
})
}
<select className="form-control input-lg" name="country" onChange={(e) => this.handleCountryChange(e)}>
{ countries.map((val, index) => {
return(<option value={index} key={index}>{val.name}</option>)
})}
</select>
Put the onChange handler on the select element instead.
Example
class App extends React.Component {
state = {
countries: [
{
name: "United States",
value: "US",
currency: "USD"
},
{
name: "Israle",
value: "IL",
currency: "ILS"
},
{
name: "United Kingdom",
value: "UK",
currency: "GBP"
}
]
};
handleCountryChange = event => {
const { value } = event.target;
const option = this.state.countries.find(
country => country.value === value
);
console.log(option);
};
render() {
const { countries } = this.state;
return (
<select
className="form-control input-lg"
name="country"
placeholder="Country"
onChange={this.handleCountryChange}
>
{countries.map((val, index) => {
return (
<option value={val.value} key={index}>
{val.name}
</option>
);
})}
</select>
);
}
}