How to open Dropdown within Antd React AutoComplete options? - javascript

I have an AutoComplete and it has onSearch event. They are working perfectly. Now, I need to add a dropdown to autocomplete options. The problem is that, when I expect to see opening dropdown, still onSearch is working and dropdown options can't be seen. The thing I am trying to do is that, when user click on dropdown I should show dropdown menu. When user click any other part of the option other than dropdown button, then onSearch should work as expected.
This is autocomplete :
<AutoComplete
dropdownClassName="certain-category-search-dropdown"
dropdownMatchSelectWidth={500}
style={{
width: 250
}}
options={options}
onSelect={onSelect}
>
<Input.Search size="large" placeholder="input here" />
</AutoComplete>
This is renderItem function for options, it has dropdown :
const renderItem = (title, count) => ({
value: title,
label: (
<div
style={{
display: "flex",
justifyContent: "space-between"
}}
>
{title}
<span>
<Dropdown overlay={menu} trigger={["click"]}>
<span
className="ant-dropdown-link"
onClick={(e) => e.preventDefault()}
>
Click me <DownOutlined />
</span>
</Dropdown>
{count}
</span>
</div>
)
});
This is a simulation of my situation. Also it does not have to be dropdown. When if it is a button or sth the scenario is the same. I could not prevent onSelect running on click.

In my case, I could use 'dropdownRender' props.
dropdownRender={(menu) =>
<>
{menu}
<span
className="ant-dropdown-link"
onClick={(e) => e.preventDefault()}
>
Click me <DownOutlined />
</span>
</>
}
items passed by options props shall be rendered in {menu} above.
Click me buttons shall not close the dropdown menu.

Related

Side by side React components not displaying how I want

I'm working on a react-app website and I'm pretty new to this all.
The current look is this:
There's a toggle button and a dropdown, and they are above each other. Both are from semantic-ui-react. The code is here:
<Segment>
<LineChart
...
</LineChart>
<div >
<div >
<Checkbox
toggle
label="Full History"
checked={fullHistory}
onChange={() => { changeSettingsState({ fullHistory: !fullHistory }); }}
/>
</div>
<div>
<Dropdown placeholder='Select 2 Flight Data Options' fluid multiple selection options={options} value={this.state.selected} onChange={this.menuChange} />
</div>
</div>
</Segment>
I want the button and dropdown to be side by side, filling the horizontal space together. That's why I've put them in divs. I tried using style={{float:'left'}} and style={{float:'right'}} in the divs that contain Checkbox and Dropdown but that results in the following that bursts out of the box and looks bad.
Any help would be appreciated.
Hard to say for sure if this will work since there's no way to try the code, but this should do the job:
<div style={{display: 'flex', flexDirection: 'row', justifyContent: 'space-between'}}>
<Checkbox
toggle
label="Full History"
checked={fullHistory}
onChange={() => { changeSettingsState({ fullHistory: !fullHistory }); }}
/>
<Dropdown placeholder='Select 2 Flight Data Options' fluid multiple selection options={options} value={this.state.selected} onChange={this.menuChange} />
</div>
Note that the div wrappers around Checkbox and Dropdown are removed since they're unnecessary with this solution.

Open a default input in form tag

I have the next application:
https://codesandbox.io/s/uwmig?file=/index.js,
There users can add as many fields as they want and add images for each generated input, clicking on add button.
What I want to achieve is to set a default open input in my application and to get something like this:
Now the default section is open by doing:
const firstRowOpen = { name: 0, key: 0, isListField: true, fieldKey: 0 };
and:
{fields.concat(firstRowOpen).map((field, index)... //here i map already concatinated fields and this is why appears first default block
Code:
<Form.List name={[fieldKey, "inner"]}>
{(fields, { add, remove }) => {
return (
<div>
{fields.concat(firstRowOpen).map((field, index) =>
!fieldsOnEdit.includes(index) ? (
<Space
key={field.key}
style={{ display: "flex", marginBottom: 8 }}
align="start"
>
<Demo
idx={index}
upload={upload}
setUpload={setUpload}
field={field}
/>
<Form.Item>
<Button
type="primary"
htmlType="submit"
key="submit"
onClick={() => toggleSmall(index)}
>
Toggle first row
</Button>
</Form.Item>
</Space>
) : (
<Edit value={values} mode={toggleSmall} keyForm={index} />
)
)}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
>
<PlusOutlined /> Add field to inner
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
Issue: when I add an image clicking on add button, and after that click on toggle first row button, appears another buttons bellow.
Question: Why this issue appears? and how to solve the issue?
demo: https://codesandbox.io/s/wonderful-ives-o81ue?file=/SubForm.js:767-2195
If I understand right you need to use initialValues
Here is an updated example of your code
https://codesandbox.io/s/compassionate-fermi-4oedx?file=/SubForm.js
...
<Form
name="dynamic_form_item"
{...formItemLayoutWithOutLabel}
onFinish={onFinish}
initialValues={{ names: [""] }}
>
...

click the text box text a popup menu should open with text box

when I click the text box text a popup menu should open with text box.
similarly when I click a filter icon in the right side corner a menu should open with list of checkboxes.
but right now whats happening is both the menus are opening when I click at both the places.
only one menu should open from one location.
I debugged by putting consoles. the problem is with the below methods
`const handleClick = event => {
setAnchorEl(event.currentTarget);
};
const handleClickFilter = event => {
setAnchorEl(event.currentTarget);
};`
can you tell me how to fix it.
providing my code snippet and sandbox below.
https://codesandbox.io/s/material-demo-kpt5i
const handleClick = event => {
setAnchorEl(event.currentTarget);
};
const handleClickFilter = event => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const handleCloseFilter = () => {
setAnchorEl(null);
};
<Typography variant="h6" id="tableTitle" onClick={handleClickFilter}>
text box
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleCloseFilter}
>
<MenuItem onClick={handleCloseFilter}>
<form
className={classes.container}
noValidate
autoComplete="off"
>
<TextField
id="standard-name"
label="Name"
className={classes.textField}
// value={values.name}
// onChange={handleChange('name')}
margin="normal"
/>
</form>
</MenuItem>
</Menu>
</Typography>
<Tooltip title="Filter list">
<IconButton aria-label="filter list">
<FilterListIcon onClick={handleClick} />
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>
<Checkbox
onChange={handleColumnHide}
inputProps={{ "aria-label": "select all desserts" }}
value="name"
/>
Dessert
</MenuItem>
<MenuItem onClick={handleClose}>
<Checkbox
onChange={handleColumnHide}
inputProps={{ "aria-label": "select all desserts" }}
value="calories"
/>
Calories
</MenuItem>
<MenuItem onClick={handleClose}>
<Checkbox
onChange={handleColumnHide}
inputProps={{ "aria-label": "select all desserts" }}
/>
Fat
</MenuItem>
Alright, you had a couple issues on your code that was preventing this from working properly.
The idea of the 'anchor' element it's that the menu will attach to that DOM object and render right next to it; this is all handled for you by Material and it works like a charm but the thing it's that you need to have this anchors properly set.
First, you need a way to differenciate an anchor element for each menu you want to display (which in your case, it's two).
For this case to work, I used a 'type' prop inside of your anchor state object and another prop called 'target' which is the one that will store the 'event.currentTarget'. Something like this: { type: 'icon', target: event.currentTarget }
Then, you need to have each anchor element (which can be a button, an icon, a label, H1 or whatever you want) separated from the Menu component itself; if you do otherwise, then the Menu will never disappear and it can only be closed using TAB or refreshing. Something like this:
<Typography variant="h6" id="tableTitle">
<span onClick={handleClickFilter}>NOTICE THIS LABEL HAS THE MENU TRIGGER FUNCTION</span>
<Menu
id="simple-menu"
anchorEl={anchorEl && anchorEl.type === 'textbox' && anchorEl.target}
open={Boolean(anchorEl && anchorEl.type === 'textbox')}
onClose={handleClose}
>
<MenuItem>
<form
autoComplete="off"
>
<TextField
label="Name"
margin="normal"
/>
</form>
</MenuItem>
</Menu>
</Typography>
Then, finally you need the anchor handler functions, which at this point it's handled by a hook and it's storing with the same variable name except it's modifying the 'type' prop I mentioned before.
const handleClick = event => {
setAnchorEl({ type: 'textbox', target: event.currentTarget })
}
const handleClose = () => {
setAnchorEl(null)
}
This should do the work successfully.
Anyway, I modified your codepen code and updated it right here.
Hope this helps!

material-ui DropDown with imag on selected value

i am trying to use an image in my dropdown of material-ui of version 0.19.1 for achieving that i writes this code.
<DropDownMenu
autoWidth
style={{ width: 500, marginBottom: 30 }}
underlineStyle={{ marginLeft: -1 }}
menuItemStyle={{ width: 500 }}
value={this.state.value}
onChange={this.handleChange}>
{items.map((item, i) => (
<MenuItem
value={i}
key={item}
leftIcon={<Avatar image={i} src={item.image} />}
primaryText={item.label}
/>))}
but this works good when i click on dropdown for selection of some menuitem but when i select some menuitem image is not shows with selected it only shows label of dropdown.
thanks in advance
Check the "Label example" in the docs (http://www.material-ui.com/#/components/dropdown-menu)
You must add a label in the MenuItem

React Native trigger press event except child component

My use-case is trigger something when click parent component (TouchableOpacity for example), but trigger nothing when click children component (Screen and others for Example). My case is same like prevent bubbling on web. From docs I've read said that it should use onStartShouldSetResponderCapture, but I still don't understand for the usage. Below is the snippet.
<TouchableOpacity style={styles.container} onPress={() => alert('tes')}
>
<Screen style={styles.screenContainer} onStartShouldSetResponderCapture={() => false}>
<Title>Edit Nama Restoran</Title>
<Divider styleName='line' />
<TextInput
style={{ flex: 1 }}
value={value}
onChangeText={value => this.setState({ value })}
onSubmitEditing={this.handleSubmit}
/>
<View styleName='horizontal' style={styles.nameContainer}>
<Button styleName='confirmation dark' onPress={this.handleSubmit}>
<Text>UPDATE</Text>
</Button>
<Button styleName='confirmation' onPress={onClose}>
<Text>CLOSE</Text>
</Button>
</View>
</Screen>
</TouchableOpacity>
EDIT:
Below is an illustration of my case.
If I click overlay (outside of <Screen>), it triggers an alert (expected).
If I click white dialog (<Screen> and children inside), it triggers an alert too (unexpected). What I need is not trigger alert when click <Screen>.
Updated to show how to do with a modal:
<Modal
visible={this.state.modalVisible}
onRequestClose={() => {alert("Modal has been closed.")}}
>
<TextInput
style={{ flex: 1 }}
value={value}
onChangeText={value => this.setState({ value })}
onSubmitEditing={this.handleSubmit}
/>
</Modal>
Not sure if this is the right snippet from your code, but basically the part you want to pop up, pull it out from the touchable opacity and wrap a modal around it. Then on click have it visible/invisible.

Categories

Resources