Semantic UI React - Dropdown.Menu and Search not working - javascript

I want to display a Dropdown menu which has customizable Items. For this reason I am using Dropdown.Menu -> Dropdown.Item and there I do my styling depending on some data.
import React from "react";
import { Dropdown } from "semantic-ui-react";
const countryOptions = [
{ key: "af", value: "af", flag: "af", text: "Afghanistan" },
{ key: "ax", value: "ax", flag: "ax", text: "Aland Islands" },
{ key: "al", value: "al", flag: "al", text: "Albania" }];
const DropdownExampleSearchSelection = () => (
<Dropdown placeholder="Select Country" selection search options={countryOptions}>
<Dropdown.Menu>
{countryOptions.map((obj) => {
return <Dropdown.Item value={obj.text} classname ={this.getCorrectCSS(obj.key)}></Dropdown.Item>;
})}
</Dropdown.Menu>
</Dropdown>
);
export default DropdownExampleSearchSelection;
However I would like this dropdown to also be searchable. So I include the search flag on the parent component. But the search does not work.
Is there a way to make the search work using Dropdown.Menu and Dropdown.Item?

Related

select default value is not working reactjs

im triying to select by default a value into a select input but the input is not recognizing that value until i change it manually. By the default i set "All" as my default value. here is my code and the codesandbox link:
import "./styles.css";
import React, { useState, useEffect } from "react";
import { FormField } from "react-form-input-fields";
import "react-form-input-fields/dist/index.css";
export default function App() {
let [type, setType] = useState("All");
const types = [
{ label: "All", value: "All" },
{ label: "Afganistan", value: "Afganistan" },
{ label: "Albania", value: "Albania" },
{ label: "Algeria", value: "Algeria" },
{ label: "American Samoa", value: "American Samoa" },
{ label: "Andorra", value: "Andorra" },
{ label: "Angola", value: "Angola" }
];
function handletype(e) {
setType(e);
}
return (
<div className="App">
{/* <h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2> */}
<FormField
type="select"
value={type}
option={types}
label={"Select your type"}
keys={"label"}
handleOnChange={(value) => handletype(value)}
/>
</div>
);
}
link:
https://codesandbox.io/s/select-problem-ykplcm
The library you use has a bug
The source code reveals that the value prop is only checked in componendDidUpdate, but this hooks is not called for the initial render
I would rather use a different library

Select value doesnt change the first time I trigger onChange event when using setSate React

I have a set of select menus and I am trying to change a value when I select an option using onChange={updateValue} event. When I first select an option, the value is not being updated in the select menu.
It only changes the second time I try to choose an option. Not sure what I am doing wrong.
Edit: I did some more research (OnChange event using React JS for drop down) and I believe I need the value of the select to be updated as well, using setState. I cant figure out how to do it without having a variable for each value and set the state again.
let selectMenus = [
{
id: 'id1',
name: 'name1',
label: 'label1',
value: '0',
options: [
{
text: 'All ages',
value: '0',
},
{
text: '35 - 37 yrs',
value: '1',
},
],
buttonLabel: 'Refresh',
},
{
id: 'id2',
name: 'name2',
label: 'label2',
value: '1',
options: [
{
text: 'All ages',
value: '0',
},
{
text: '45 - 50 yrs',
value: '1',
},
],
buttonLabel: 'Refresh',
},
];
const [url, setUrl] = useState('http://localhost:5000/selectDropdowns1');
const updateValue = () => {
setUrl('http://localhost:5000/selectDropdowns2');
};
<form>
{selectMenus.map((select) => (
<div key={select.id} className='select-container'>
<label htmlFor={select.id}>{select.label}</label>
<select id={select.id} name={select.name} value={select.value} onChange={updateValue}>
{select.options.map((option) => (
<option value={option.value} key={uuid()}>
{option.text}
</option>
))}
</select>
<button>{select.buttonLabel}</button>
</div>
))}
</form>;
The problem is that when you provide onChange prop to select component it become a controlled component.
For more information: React Docs - Forms #controlled components
When you dealing with controlled components you must provide a value to it and when onChange triggerd it should update that value to work properly. Since you did not provide the full code, I imagine you have an array of select menus and options attached to it.
So in this case every select component should have own onChange method and own value to work properly. To achive this we should create another component for only Select Options. Like this;
function SelectComponent({ optionList, onSelected }) {
const [value, setValue] = useState();
const updateValue = ({ target }) => {
setValue(target.value);
if (onSelected) onSelected(target.value);
};
return (
<>
<label htmlFor={optionList.id}>{optionList.label}</label>
<select
id={optionList.id}
name={optionList.name}
value={value}
onChange={updateValue}
>
{optionList.options.map((option) => (
<option value={option.value} key={uuid()}>
{option.text}
</option>
))}
</select>
<button>{optionList.buttonLabel}</button>
</>
);
}
This component accepts to props; optionList and onSelected
optionList is the list of options to render
onSelected is a method that we call when user select and option
On main component, we should change the select section with our select component with props optionList and onSelected
return (
<div>
{selectMenus.map((select) => (
<div key={select.id} className="select-container">
<SelectComponent optionList={select} onSelected={updateValue} />
</div>
))}
</div>
);
So overall code is like this:
import { useState } from "react";
import { v4 as uuid } from "uuid";
export default function App() {
const [url, setUrl] = useState();
const updateValue = (value) => {
setUrl(value);
};
const selectMenus = [
{
id: 1,
label: "Menu 1",
name: "menu1",
buttonLabel: "Menu 1",
options: [
{
text: "option 1",
value: "option1"
},
{
text: "option 2",
value: "option2"
},
{
text: "option 3",
value: "option3"
}
]
},
{
id: 2,
label: "Menu 2",
name: "menu2",
buttonLabel: "Menu 2",
options: [
{
text: "option 1",
value: "option1"
},
{
text: "option 2",
value: "option2"
},
{
text: "option 3",
value: "option3"
}
]
},
{
id: 3,
label: "Menu 3",
name: "menu3",
buttonLabel: "Menu 3",
options: [
{
text: "option 1",
value: "option1"
},
{
text: "option 2",
value: "option2"
},
{
text: "option 3",
value: "option3"
}
]
}
];
return (
<div className="App">
<h1>URL Value: {url}</h1>
{selectMenus.map((select) => (
<div key={select.id} className="select-container">
<SelectComponent optionList={select} onSelected={updateValue} />
</div>
))}
</div>
);
}
function SelectComponent({ optionList, onSelected }) {
const [value, setValue] = useState();
const updateValue = ({ target }) => {
setValue(target.value);
if (onSelected) onSelected(target.value);
};
return (
<>
<label htmlFor={optionList.id}>{optionList.label}</label>
<select
id={optionList.id}
name={optionList.name}
value={value}
onChange={updateValue}
>
{optionList.options.map((option) => (
<option value={option.value} key={uuid()}>
{option.text}
</option>
))}
</select>
<button>{optionList.buttonLabel}</button>
</>
);
}
Working example is overhere codesandbox

push to url according to id (reactjs)

new react hooks(typescript) developer here, could somebody suggest on how to implement this: when user has chosen from select option(antd) then the button becomes red and can be clicked, that button should take one to that specific option what he chose (id?) with this?:
history.push(`/info/${....id}`); ??
my code :
import React, { useState } from "react";
import "antd/dist/antd.css";
import { Select } from "antd";
import { useHistory, useRouteMatch } from "react-router-dom";
const { Option } = Select;
const history = useHistory();
function EventsSection() {
const anarray = [
{ name: "obama", address: "usa", id: "81" },
{ name: "obama", address: "usa", id: "86" },
{ name: "putin", address: "russia", id: "91" },
{ name: "erdogan", address: "turkey", id: "31" },
{ name: "jebordoq", address: "alien", id: "29" },
];
return (
<section>
{/* this button becomes red then we know somebody has clicked something from select options */}
<button>if i'm red click me</button>
<Select
className="senderId"
style={{ width: "100%" }}
placeholder="Hide Me"
mode="multiple"
open={true}
listHeight={350}
>
{anarray.map((item, idx) => (
<Option
style={{ width: "100%", height: "100%" }}
className="options"
key={idx}
value={item.id}
>
{item.name}
<br></br>
{item.address}
<br></br>
</Option>
))}
</Select>
</section>
);
}
export default EventsSection;
ask me if needed

how to render data in vertical Tab

I need to render data using React vertical tabs, I have given code which I have tried and also the data coming from API. I am not getting how to loop inside <TabPanel>.
link for codesandbox https://codesandbox.io/s/jovial-darkness-qob1n?file=/src/tab.js
<Tabs
defaultTab="vertical-tab-one"
vertical
className="vertical-tabs"
>
<TabList>
{subProducts.map((subProduct, index) => (
<Tab>{subProduct.subProductName}</Tab>
))}
</TabList>
{subProducts.map((subProduct, index) => (
<TabPanel className="tab-pane fade mt-4 show ">
{subProduct.bookingDetails.map((attr, i) => (
<>
<table id="customers">
<tbody>
<tr>
<td>{attr.name}</td>
<td>{attr.value}</td>
</tr>
</tbody>
</table>
</>
))}
</TabPanel>
))}
</Tabs>
API output:
subProducts: [
{
bookingDetails: [
{
name: "Birthday Decoration",
value: "YES"
},
{
name: "Photographer",
value: "NO"
}
],
subProductName: "Celebration"
},
{
bookingDetails: [
{
name: "Decoration",
value: "YES"
},
{
name: "Video",
value: "NO"
}
],
subProductName: "FamilY"
}
]
In the sandbox you try to map over bookingDetails for each object in the subProducts array, but in the second object of subProducts you have a Details property, but not a bookingDetails property so bookingDetails will be undefined.
So you probably want to change Details to bookingDetails:
subProducts: [
{
bookingDetails: [
{
name: "Birthday Decoration",
value: "YES",
},
{
name: "Photographer",
value: "NO",
},
],
subProductName: "Celebration",
},
{
bookingDetails: [
{
name: "Decoration",
value: "YES",
},
{
name: "Video",
value: "NO",
},
],
subProductName: "FamilY",
},
];
If the API returns Details instead of bookingDetails as in your original question do it the other way around. Change it so it maps over Details instead:
So subProduct.Details.map instead of subProduct.bookingDetails.map.
The data not being displayed correctly on click is because each Tab component need to have a tabFor prop value that corresponds with a TabPanel's tabId prop value. Otherwise react-web-tabs doesn't know what content to show when.
For this example I've used the map's index and called toString on it before passing it to the props as the id needs to be a string. But a more natural id would be to have id fields in your data and use those.
Example Sandbox

How to move SemanticUIReact Icon left of text element in sub-menu?

The image below demonstrates the current GUI, i simply wish to place the icon to the left of the 'Language' menu instead of the current position (right)
Current Code
</Dropdown.Item>
<Dropdown text="Language" icon="angle down" pointing="right"
options={[
{ text: 'English', value: 'en', flag: 'gb'},
{ text: 'Svenska', value: 'se', flag: 'se' },
{ text: 'Dansk', value: 'de', flag: 'de' },
{ text: 'Norsk', value: 'no', flag: 'no' },
]}
/>
Any suggestions on how i could locate the "angle down" icon to the left of the "language" text would be much appreciated.
You could use the trigger prop in stead of text as per the docs and remove the default icon.
const trigger = (
<span>
<Icon name="angle down" /> Language
</span>
);
const options = [
{ text: "English", value: "en", flag: "gb" },
{ text: "Svenska", value: "se", flag: "se" },
{ text: "Dansk", value: "de", flag: "de" },
{ text: "Norsk", value: "no", flag: "no" }
];
const DropdownTriggerExample = () => (
<Dropdown pointing="right" trigger={trigger} options={options} icon={null} />
);
Also note that you have a typo for the Danish element ("de" where it should be "dk").

Categories