How to change value of Material-UI's Textfield on focus? - reactjs

I'm trying to change the value of Material-UI's TextField when it focuses. It seems that I can do that through inputProps, but I can't find any example of how to implement that.

add onFocus prop with TextField
<TextField value={this.state.value} onFocus={onFocus} label="Custom CSS" variant="outlined" id="custom-css-outlined-input" />
then handle the onFocus event
const onFocus = () => {
this.setState({
value:'new value'
})
}
it should update the value in the field when focus comes on the text field

Related

How to use material UI Checkbox with formik?

I am not able to code in the right way such that formik.values will reflect into Material UI's Checkbox
Checkboxes are a little tricky to include in third party forms packages, and Material UI doesn't help with that either.
What you need to do is use the FormControlLabel component to handle the onChangge event that formik needs. Then on the Checkbox you just set the checked prop to be whatever formik has in its values.
Here is an example I use for a Checkbox to set an isAdmin value.
const formik = useFormik({
initialValues:{
isAdmin: false
},
});
<FormControlLabel
control={<Checkbox checked={formik.values.isAdmin} />}
label="is Admin"
name="isAdmin"
onChange={formik.handleChange}
/>
Using 'as'
Use the as prop with Formik Field and pass any props required to the Field itself. It will pass them onto FormControlLabel. For example, here the label field is passed down to FormControlLabel:
<Field
type="checkbox"
name="myFormikName"
as={FormControlLabel}
control={<Checkbox />}
label="This will trigger my formik name field"
/>
Multiple checkboxes using 'as'
If you have multiple checkboxes with the same name (array) you need to pass the "checked" value like so. Checks if the Formik 'name' array includes the name.
const { values } = useFormikContext()
render (
{names?.map(name => (
<Field
type="checkbox"
name="names"
value={name.fullName}
key={name.id}
as={FormControlLabel}
control={<Checkbox/>}
checked={values.names.includes(name.fullName)}
label={name.fullName}
/>
))}
)
Using 'setFieldValue'
const { values, setFieldValue } = useFormikContext()
<FormControlLabel
control={<Checkbox />}
label="My mui label"
checked={values.myMuiCheck}
onChange={() =>
setFieldValue(
'myMuiCheck',
!values.myMuiCheck,
)
}
/>

React js Material Ui TextField default value doesn't change

I want to change default value of TextField when state change but it doesn't work. I guess it is doesn't re-render.
<TextField
multiline={true}
rows={15}
disabled
id="outlined-basic" label="" variant="outlined"
defaultValue={!isEn?data.data[0].description:data.data[0].descriptionLocalization.en}
/>
<Button style={{position:"absolute",right:"20px",bottom:"5px"}} onClick={changeStateIsEn}>Save</Button>}
Default value is not meant to be changed with state.
You should set the value for reflecting the default value
<TextField
multiline
rows={15}
disabled
id="outlined-basic"
label=""
variant="outlined"
defaultValue="Something that will stay there initially only"
value={!isEn ? data.data[0].description : data.data[0].descriptionLocalization.en}
/>
There are two parts missing to your TextField component that is required to tie the input to state.
As user Mohammad Fasial said, the defaultValue prop is only for the default value the component will have. The correct prop you're looking for is value. State will need to equal value.
To listen for changes when the user inputs new information into the TextField input, you'll need to use the onChange prop. The onChange prop (on change listener) let's you provide a function as an argument to run when the input value changes. In this case we want to set onChange to run setExampleState to set the state to the value of the input field by using the event.target.value property.
function ExampleComponent(){
const [exampleState, setExampleState] = useState([]);
...
return (
<>
<TextField
multiline={true}
rows={15}
disabled
id="outlined-basic" label="" variant="outlined"
defaultValue={!isEn?data.data[0].description:data.data[0].descriptionLocalization.en}
value={exampleState}
onChange={(event) => setExampleState(event.target.value)}
/>
<Button style={{position:"absolute",right:"20px",bottom:"5px"}} onClick={changeStateIsEn}>Save</Button>
</>
);
}
To learn more about the different properties TextField has, you can look at the TextField API Documentation. There are also a lot of TextField code examples that can be expanded on the Material-UI site as well.
Update the key of Element or Container after Default value Change

Capture onChange event from inputComponent passed to OutlinedInput, Material UI

I'm trying to use OutlinedInput with KeyboardDatePicker, both from Material UI. I'm passing a DatePicker as input component to 'OutlinedInput' component of Material UI. I want to know how to get date from the inputComponent I'm passing.
With the following code I'm getting "_onChange is not a function" error.
const handleInputChange = (event) => {
if (event.target.name === "deliveryDate") {
temp.deliveryDate = event.target.value;
}
}
function datepicker() {
return <MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
name="deliveryDate"
format="MM/dd/yyyy"
value={projectDetails.deliveryDate}
onChange={props.handleInputChange} /> //not sure if this is how I should write it
</MuiPickersUtilsProvider>;
}
return(
<OutlinedTextBox
name="deliveryDate"
id="deliveryDate"
maxlength={20}
onChange={handleInputChange}
inputComponent = {datepicker} //passing the KeyboardDatePicker as input component
inputLabel="Delivery Date" />
)
Below is my OutlinedTextBox component. It returns
<OutlinedInput
name={props.name}
inputProps={{
maxLength: props.maxlength?props.maxlength:100,
}}
onChange={props.handleInputChange}
{...props}
/>
How to capture onChange function of inputComponent attribute.
Update
From what you said in your comment, all you actually have to do then is edit your datepicker component. You dont need to pass in the value, onChange or name directly as those are already being passed in as props from when you use inputComponent={datepicker}. So all you need to do is declare the props and spread them all into the KeyboardDatePicker.
const DatePicker = (props) => {
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
format="MM/dd/yyyy"
{...props}
/>
</MuiPickersUtilsProvider>
);
};
Original Answer.
You could just add the inputVariant="outlined"property to the KeyboardDatePicker as that will make it outlined. Then you dont actually need to use the OutlinedInput component at all.
<KeyboardDatePicker
name="deliveryDate"
format="MM/dd/yyyy"
value={projectDetails.deliveryDate}
onChange={props.handleInputChange}
inputVariant="outlined
/>

React-hook-form with Material-ui textfield without autoFocus defaultValue disappeared during form submit

I have problem using react-hook-form v7 + material-ui textfield. The defaultValue working if I set autoFocus or I manually change the textfield value. However if I just submit without mouse click on the filed that not autoFocus, the defaultValue disappeared during the form submit. Please check codesandbox link
Test 1: don't touch anything, click submit, you will see submit value only has title but missing name and desc
Test 2: mouse click or change value in name, you will see after submit the value of name is there
My question is how to make this default value always submit even though without mouse click or change the value of the textField?
Please help and thanks in advance
To use Material-ui with react-hook-form. It is better to wrap it with Controller to allow react-hook-form to link with the 3rd party library element.
https://react-hook-form.com/api/usecontroller/controller
Wrap Textfield with Controller
const { handleSubmit, control } = useForm();
...
<Controller
render={({ field }) => (
<TextField
autoFocus
margin="dense"
id="title"
label="Title"
type="text"
fullWidth
{...field}
/>
)}
control={control}
name="title"
defaultValue={data.title}
/>
...
After that, the default value will be able to work as expected.
Here is the codesandbox for demo.

Clear all selected values from material-ui Autocomplete Combo box

Solution
I used renderTags in my Autocomplete:
renderTags={() => (
<div>
{(props.selectedAutocompleteValues).map(value => (
<Chip key={value} label={value} />
))}
</div>
)}
Original question
I'm trying to add a handler that clears all selected values from an Autocomplete with multiple values and a dropdown. Basicly duplicating the action of the clear-button that is inside the Autocomplete, and triggering this action from outside the Autocomplete.
The reason for this is that I want to have a filter (material-ui Select) that allows reduces the number of options in the Autocomplete. When changing the filter-value, the previously selected values of the Autocomplete should be cleared.
I'm rendering the values in the Autocomplete with the following code, so it seems like what I need to do is change the params in some way. Any suggestions on how to do this, or other ways of clearing the values?
renderInput={params => (
<TextField {...params} label="my-label" variant="outlined" fullWidth />
)}
Update after comment from Ryan Cogswell:
<Autocomplete
multiple
disableCloseOnSelect
autoHighlight
clearText='Nullstill'
closeText='Lukk'
openText='Åpne'
options={Array.from(props.myMap.keys())}
onChange={(event: any, value: string) => {
props.myUpdateFunction(value)
}}
renderInput={params => (
<TextField {...params} label="myLabel" variant="outlined" fullWidth />
)}
/>
where myUpdateFunction is in the grandparent-component of where the Autocomplete is:
myUpdateFunction = (myArray: Array<string>) => {
this.setState({
selectedAutocompleteValues: myArray,
})
}
The Select component that I want to use to reset the Autocomplete component:
<Select
labelId="my-select-label"
id="my-select"
autoWidth
value={props.mySelectValue}
onChange={(event: any) => props.updateSelect(event.target.value)}>
{Array.from(props.selectOptions, ([optionNr, optionName]) =>
<MenuItem key={optionNr} value={optionNr}>{optionName}</MenuItem>
)}
</Select>
with the following onChange handler:
updateFylke = (value: number) => {
const selectedAutocompleteValues = new Array<string>();
this.setState({
mySelectValue: value,
selectedAutocompleteValues: selectedAutocompleteValues,
})
}
I recommend using a controlled input approach (i.e. specify the value prop for the Autocomplete using selectedAutocompleteValues). Then clearing the Autocomplete is just a matter of updating your state appropriately.
You can see an example of this approach in this related answer: Material ui Autocomplete: can tags be created on events aside from 'Enter' events?.

Resources