OnChange for Storing Value of Selected Drop Down Option - javascript

I have a Material UI dropdown menu. I will make a search later on the basis of the selected option from the drop down menu. How exactly could I use onChange() to store the option selected?
For now, I am trying to print the stored value (criteria) using typography at the end but instead of showing the selected value, I get a black page.
export default class userSearchPage extends Component<{}, { searchItem: string, criteria: string }>{
constructor(props: Readonly<{}>) {
super(props);
this.state = {
searchItem: '',
criteria: '',
};
this.handleDropDownChange = this.handleDropDownChange.bind(this);
}
handleDropDownChange(selected: any) {
this.setState({
criteria: selected
});
}
render() {
return (
<div>
<PermanentDrawerLeft></PermanentDrawerLeft>
<div className='main-content'>
<MuiThemeProvider>
<DropDownMenu onChange = {this.handleDropDownChange}>
<MenuItem style={{ fontSize: "20px" }} primaryText="Search By" />
<MenuItem value={1} style={{ fontSize: "20px" }} primaryText="First Name" />
<MenuItem value={2} style={{ fontSize: "20px" }} primaryText="Last Name" />
<MenuItem value={3} style={{ fontSize: "20px" }} primaryText="Phone Number" />
<MenuItem value={4} style={{ fontSize: "20px" }} primaryText="Email" />
</DropDownMenu>
</MuiThemeProvider>
<Typography>{this.state.criteria}</Typography>
<br></br><br></br>
<SearchBar
onChange={e => this.setState({ searchItem: e })}
value = {this.state.searchItem}
onRequestSearch={() => console.log('onRequestSearch')}
style={{
margin: '0 auto',
maxWidth: 800
}}
/>
<Typography>{this.state.criteria}</Typography>
</div>
</div>
);
}
}
How could I fix this?
Note: This is typescript
Added
export default class userSearchPage extends Component<{}, { searchItem: string, criteria: any}>{
constructor(props: Readonly<{}>) {
super(props);
this.state = {
searchItem: '',
criteria: null,
};
this.handleDropDownChange = this.handleDropDownChange.bind(this);
}
handleDropDownChange(event: any) {
console.log(event.target.value);
this.setState({
criteria: event.target.value
});
}
render() {
return (
<div>
<PermanentDrawerLeft></PermanentDrawerLeft>
<div className='main-content'>
<InputLabel id="demo-simple-select-label">Search By</InputLabel>
<Select
value={this.state.criteria}
onChange={this.handleDropDownChange}
displayEmpty
>
<MenuItem disabled value=" ">
<em>Search By</em>
</MenuItem>
<MenuItem value={1}>First Name</MenuItem>
<MenuItem value={2}>Last Name</MenuItem>
<MenuItem value={3}>Phone Number</MenuItem>
<MenuItem value={4}>Email</MenuItem>
</Select>
</div>
</div>
);
}
}

Assuming the DropDownMenu component is just a Material-UI Select component (https://material-ui.com/components/selects/#select), you need to update the state of your searchItem to the value of the selected MenuItem.
<DropDownMenu onChange={event => {this.setState({searchItem: event.target.value})}>
Note, currently in your example the first name and last name item are using the same value of 1.
Update - added the comment that contained the solution's code:
Here's an example using Material-UI's Select component instead of DropDownMenu: https://codesandbox.io/s/eager-hugle-tlfri

DropDownMenu menu should have the 'onChange' event that receives selected option as argument, which you can store in the components state

You could use the onChange event to do something when the user is selecting an option. If you want information, you could look at this article: https://www.w3schools.com/jsref/event_onchange.asp

Related

How do I add a clear options icon on selecting an option in MaterialUI select component?

I want to add a clear options icon when any option is selected from the list of the options.
<Select
InputProps={{
startAdornment: (
<InputAdornment position='end'>
<ClearIcon />
</InputAdornment>
),
}}
//MenuProps={{ disableScrollLock: true }}
//defaultValue={customer.swStatus}
value={hwStatus}
onChange={(e) => {
setHwStatus(e.target.value);
filterTable('SEARCH_BY_HW_STATUS', e.target.value);
}}
displayEmpty
inputProps={{ 'aria-label': 'Without label' }}
sx={{ fontSize: '15px', height: '40px' }}>
<MenuItem value='Pending'>Pending</MenuItem>
<MenuItem value='Complete'>Completed</MenuItem>
</Select>
You have to just pass onClear event and update state to blank string.
Try like this, it might works!
Import this two icons:
import ClearIcon from "#mui/icons-material/Clear";
import IconButton from "#mui/material/IconButton";
Your handleClearClick event:
handleClearClick = () => {
setHwStatus('');
}
<Select
endAdornment={<IconButton sx={{visibility: score? "visible": "hidden"}} onClick={handleClearClick}><ClearIcon/></IconButton>}
>
//MenuProps={{ disableScrollLock: true }}
//defaultValue={customer.swStatus}
value={hwStatus}
onChange={(e) => {
setHwStatus(e.target.value);
filterTable('SEARCH_BY_HW_STATUS', e.target.value);
}}
displayEmpty
inputProps={{ 'aria-label': 'Without label' }}
sx={{ fontSize: '15px', height: '40px' }}>
<MenuItem value='Pending'>Pending</MenuItem>
<MenuItem value='Complete'>Completed</MenuItem>
</Select>
Create the handleClear method to reset the state.
const handleClear = () => {
setHwStatus("");
filterTable("SEARCH_BY_HW_STATUS", "");
};
In the InputProps you can add a IconButton with the onClick
import { IconButton } from "#mui/material";
...
InputProps={{
startAdornment: (
<InputAdornment position="end">
<IconButton onClick={handleClear}>
<ClearIcon />
</IconButton>
</InputAdornment>
),
}}

ANT Design Form.List wont remove element

My plan is to build a step-by-step from where users can add more sections as needed to a form. This plan is divided into several files to achieve the result, including a parent, a child, and the Quill editor component. I've followed the examples found in the ANT Design website: https://ant.design/components/form/#components-form-demo-dynamic-form-items but failed to replicate the example.
This is the setup for the React-Quill Editor component:
//texteditorsimple.js
import React from 'react';
import ReactQuill, {Quill} from 'react-quill';
import MagicUrl from 'quill-magic-url';
import 'react-quill/dist/quill.snow.css';
//registering magic url module
Quill.register('modules/magicUrl', MagicUrl);
const modules = {
toolbar: [
...
clipboard: {
...
},
magicUrl: true,
};
const formats = [
'list',
'bullet',
'link',
];
const TextEditorSimple = ({ value, onChange, placeholder }) => {
return (
<>
<ReactQuill
theme="snow"
value={value || ''}
modules={modules}
formats={formats}
onChange={onChange}
placeholder={placeholder} >
</ReactQuill>
<div id='counter'></div>
</>
)
}
export default TextEditorSimple;
This is the Parent component:
//parent.js
import React, { useState, useEffect } from 'react';
...
import Child from '../child';
const Parent = () => {
const [ formValue2, setFormValue2 ] = useState([]);
const deleteY = (data) => {
const newArrayFormValue = formValue2.filter(obj => !obj.name.includes(data));
setFormValue2(newArrayFormValue);
}
return (
<Row justify='center' align="top" style={{ padding: 10}}>
<Col>
<Child deleteX={deleteY} fields={formValue2} onChange={(newFields) => {setFormValue2(newFields)}}/>
</Col>
</Row>
)
}
export default Parent;
And this is the Child component:
//child.js
import React from 'react';
...
import TextEditorSimple from './texteditorsimple';
const Child = ({fields, onChange, deleteX}) => {
<Row justify='start' align="top">
<Col xs={24} style={{ padding: 10}}>
<h2>Pengenalan & Langkah-langkah</h2>
<Form
fields={fields}
name="dynamic_form_nest_item"
onFinish={onFinish}
autoComplete="off"
onFieldsChange={(_,allFields) =>{
onChange(allFields);
}} >
<Form.List name="tutorial" style={{ width: '100%'}}>
{(fields, { add, remove }) => (
<>
{fields.map(({ index, key, name, fieldKey, ...restField }) => (
<div key={key}>
<Row>
{
name === 0 ?
<Col xs={24} style={{ padding: 5 }}>
<Form.Item
{...restField}
label='Pengenalan'
name={[name, 'pengenalan']}
fieldKey={[fieldKey, 'pengenalan']}
>
<TextEditorSimple/>
</Form.Item>
</Col>
:
<Col xs={24} md={16} style={{ padding: 5 }}>
<Form.Item
{...restField}
label={'Langkah '+ name}
name={[name, 'langkah'+name]}
fieldKey={[fieldKey, 'langkah'+name]}
>
<TextEditorSimple/>
</Form.Item>
</Col>
}
<Col xs={24} md={8} style={{ padding: 5 }}>
{
name === 0 ?
''
:
<Space align="start">
<Form.Item
{...restField}
name={[name, 'image'+name]}
fieldKey={[fieldKey, 'image'+name]}
valuePropName="fileList"
getValueFromEvent={normFile}
extra="Muat naik satu (1) imej/tangkap layar">
<Upload
name="image"
customRequest={dummyRequest}
listType="picture-card"
maxCount={1} >
{/* <Button icon={<UploadOutlined />}>Muat naik imej/ tangkap layar</Button> */}
{uploadButton}
</Upload>
</Form.Item>
<DeleteOutlined onClick={() => { remove(name); }} style={{ color: 'red'}}/>
</Space>
}
</Col>
</Row>
<Divider/>
</div>
))}
<Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
Tambah Langkah
</Button>
</Form.Item>
</>
)}
</Form.List>
</Form>
</Col>
</Row>
}
export default Child;
I'm trying to catch the changes made on the Form.List 'tutorial' (add, delete) in the Child and uplift the value to the Parent and store them in the state. But the deletion somehow not reflected in the UI, as the element that should have been deleted persisted on page. Tried to manually change the state through poorly coded deleteX and deleteY function, but not successful.
The GIF showing the error can be viewed here: http://www.giphy.com/gifs/HsIjHuckIflqOr3gOO

Remove Edit and delete button appearing in select box reactJS

I am new to reactJS. I have a select option.
I want to add delete and edit button inside the select option.
Here's the code i tried,
<Select
style={{ width: 240 }}
placeholder="Choose Web Analytics Configuration"
dropdownRender={menu => (
<div>
{menu}
<Divider style={{ margin: '4px 0' }} />
<div
style={{ padding: '4px 8px', cursor: 'pointer' }}
onMouseDown={e => e.preventDefault()}
onClick={this.openModal.bind(this)}
>
<Icon type="plus" /> Add Database
</div>
</div>
)}
>
{dbConfigList.map(item => (
<Option key={item}>{item}
<Icon onClick={this.editFun.bind(this)} type="edit" style={{ fontSize: '20px', color: 'green' }} theme="outlined" />
<Icon onClick={this.deleteFun.bind(this)} type="delete" style={{ fontSize: '20px', color: '#CC160B' }} theme="outlined" />
</Option>
))}
</Select>
I have successfully added the buttons.
Here it looks like:
But when the User selects the option, the edit and delete button appears in the select box. I only needed the name to be shown and not buttons.
Here it looks like,
Help me with some solutions to fix it and inside the dropdown menu of every each option, I want the edit and delete buttons to be appeared at the right corner. Now it was appearing after the text. i can use margin for that. but every name size differs. Ex. Some names will be 6 characters and some will be more than 6 characters. Help me with some solutions.
Check the below example, you need to prevent your <Icon> as I had done for '+ -'
should be like:
{
dbConfigList.map(item => (
<Option key={item}>
{item}
{selectedValue !== item // you need to add state
<Icon
onClick={this.editFun.bind(this)}
type="edit"
style={{ fontSize: "20px", color: "green" }}
theme="outlined"
/>
<Icon
onClick={this.deleteFun.bind(this)}
type="delete"
style={{ fontSize: "20px", color: "#CC160B" }}
theme="outlined"
/> : null}
</Option>
));
}
class App extends React.Component {
constructor() {
super();
this.state = {
optionsdata : [
{key:'101',value:'Lion'},
{key:'102',value:'Giraffe'},
{key:'103',value:'Zebra'},
{key:'104',value:'Hippo'},
{key:'105',value:'Penguin'}
],
selectedValue: null // store selected value
}
}
handleChange = (e) => {
console.log(e.target.value);
var value = this.state.optionsdata.filter(function(item) {
return item.key == e.target.value
})
this.setState({ selectedValue: value[0].value }); // set state
console.log(value[0].value);
}
render() {
const { selectedValue } = this.state;
return (
<select onChange={this.handleChange}>
{this.state.optionsdata.map(function(data, key) { return (
<option key={key} value={data.key}>{data.value} {selectedValue !== data.value ? '+ -' : null } </option> )
})}
</select>
)
}
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.0.1/react-dom.min.js"></script>
<div id="app"></div>
Demo App: https://codesandbox.io/s/button-in-select-menuitem-reactjs-demo-1zyvj
I solved this problem in material-Ui design by using onOpen={() => setIconVisibile(true)} and onClose={() => setIconVisibile(false)} callbacks to set the visibility of icons.
const [isIconVisibile, setIconVisibile] = React.useState(false);
<Select
onOpen={() => setIconVisibile(true)}
onClose={() => setIconVisibile(false)}
>
<MenuItem value={1}>
{"ONE"}
{isIconVisibile ? (
<ListItemSecondaryAction variant="outlined">
<IconButton edge="end" aria-label="delete">
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
) : null}
</MenuItem>
</Select>

change the font size of the checkbox and radio buttons labels

I am trying to change the font size of the checkbox and radio buttons labels.
I tried giving css to this component Checkbox but it's not changing the label's font size
since the labels are added dynamically.
so I researched and found this links. https://material-ui.com/api/radio/#css https://material-ui.com/customization/components/#overriding-styles-with-classes
but this is not helping me.
can you tell me how to fix it.
providing my code snippet and sandbox below.
https://codesandbox.io/s/material-demo-u95z5
const styles = theme => ({
root: {
display: "flex"
},
formControl: {
margin: theme.spacing.unit * 3
},
group: {
margin: `${theme.spacing.unit}px 0`
},
checkboxCSS: {
border: "1px solid red",
fontSize: 40
}
});
return (
<div className={classes.root}>
<FormControl component="fieldset" className={classes.formControl}>
<FormLabel component="legend">Gender</FormLabel>
<RadioGroup
aria-label="Gender"
name="gender1"
className={classes.group}
value={this.state.value}
onChange={this.handleRadioValueChange}
>
{radioValues.map(radio => {
return (
<FormControlLabel
value={radio.value}
control={<Radio />}
label={radio.label}
/>
);
})}
</RadioGroup>
{checkBoxvalues.map((check, index) => {
console.log("this.state[check.value]", this.state[check.value]);
return (
<FormControlLabel
key={check.value}
control={
<Checkbox
checked={check.checked}
onChange={this.handleCheckBoxChange(check.value, index)}
value={check.value}
className={classes.checkboxCSS}
/>
}
label={check.label}
/>
);
})}
</FormControl>
</div>
);
This link helped me: https://material-ui.com/api/form-control-label/#css
The following works in your sandbox.
In the classes object:
{
...,
checkboxLabel: {
fontSize: 40
}
}
On the FormControlLabel component add:
classes={{
label:classes.checkboxLabel
}}

Material-UI how to get the value of SelectField inside const

Actually, my Drawer has a few fields including SelectField but I stuck on getting the value and the onChange part of the Field. and here's my code:
const DrawerCargoAddItem = (props) => {
let { navDrawerOpen } = props;
return (
<Drawer docked={true} width={500} open={navDrawerOpen}>
<div style={styles.logo}>
Fleetcat Web
</div>
<div>
<PageBase title={<Link to="dashboard"><img src="./images/fleetcat.png"/></Link>} style={page}>
<SelectField
floatingLabelText="Category"
fullWidth={true}
value="">
<MenuItem key={0} primaryText="Food and Beverages"/>
<MenuItem key={1} primaryText="Medium"/>
<MenuItem key={2} primaryText="Large"/>
</SelectField>
<Paper style={papers} zDepth={5} >
<Link to="dashboard">
<FlatButton label="Tap to add Items" style={flatbutton}
onClick={() => { alert('foo');
console.log("Success");}}/>
</Link>
</Paper>
</PageBase>
</div>
</Drawer>
);
};
DrawerCargoAddItem.propTypes = {
navDrawerOpen: PropTypes.bool,
menus: PropTypes.array,
username: PropTypes.string,
};
export default DrawerCargoAddItem;
You create a simple function and what you need is a React Component:
import React from 'react';
export default class DrawerCargoAddItem extends React.Component {
state = {
value: 0
};
handleChange = (event, index, value) => this.setState({value});
render() {
let {navDrawerOpen} = this.props;
const {value} = this.state
return (
<Drawer docked={true} width={500} open={navDrawerOpen}>
<div style={styles.logo}>
Fleetcat Web
</div>
<div>
<PageBase
title={< Link to = "dashboard" > <img src="./images/fleetcat.png"/> < /Link>}
style={page}>
<SelectField
floatingLabelText="Category"
fullWidth={true}
value={value}
onChange={this.handleChange}>
<MenuItem value={0} key={0} primaryText="Food and Beverages"/>
<MenuItem value={1} key={1} primaryText="Medium"/>
<MenuItem value={2} key={2} primaryText="Large"/>
</SelectField>
<Paper style={papers} zDepth={5}>
<Link to="dashboard">
<FlatButton
label="Tap to add Items"
style={flatbutton}
onClick={() => {
alert('foo');
console.log("Success");
}}/>
</Link>
</Paper>
</PageBase>
</div>
</Drawer>
);
}
}
Basically you now have access to the full React lifecycle. The current value is now saved in the component's state.
Here it is
<SelectField floatingLabelText="Category"
fullWidth={true}
value=""
onChange={this.handleChanges}>
<MenuItem key={0} value="Food and Beverages" primaryText="Food"/>
<MenuItem key={1} value="Medium" primaryText="Medium"/>
<MenuItem key={2} value="Large" primaryText="Large"/>
</SelectField>
here is handle change event function which should be written:
handleChanges = (e, index, value) => {
alert(value);
}
For me worked this syntax : onBlur={event => { handleChange(event) } }
<Autocomplete
id="size-small-standard"
size="small"
options={lOrigens}
defaultValue={{ title: props.value }}
getOptionLabel={option => option.title}
onBlur={e => { handleChange(e, props, { setChanging: setCurrentChangingItem1, i}) }}
renderInput={params => (
<TextField
{...params}
variant="standard"
label="Origens1"
placeholder="Origens2"
fullWidth
/>
)}
/>
And to access the value: event.target.value

Categories