filterSelectedOptions in autocomplete Material UI Lab is not working with onChnage - javascript

When I am using autocomplete for getting the selected dates, The selected options is not getting filtered. Hence i am able to select multiple instance of the same data. Although when i remove OnChange prop its giving the result but now i am not able to update the state.
<Autocomplete
multiple
name="ClassSchedule"
onChange={(event, value) => setDays(value)}
ChipProps={{
style: {
backgroundColor: "#2EC5B6",
borderRadius: "5px",
color: "#fff",
fontFamily: "Source Sans Pro",
},
}}
id="tags-standard"
options={[
{ title: "sunday" },
{ title: "monday" },
{ title: "tuesday" },
{ title: "wednesday" },
{ title: "thursday" },
{ title: "friday" },
{ title: "saturday" },
]}
getOptionLabel={(option) => option.title}
renderInput={(params) => (
<CssTextField
{...params}
style={{
borderRadius: "10px",
backgroundColor: "#F5FCFB",
fontFamily: "Source Sans Pro",
}}
variant="outlined"
id="custom-css-outlined-input"
/>
)}
/>

According to Autocomplete doc:
value - any - The value of the autocomplete. The value must have reference equality with the option in order to be selected. You can customize the equality behavior with the getOptionSelected prop.
getOptionSelected - func - Used to determine if an option is selected, considering the current value. Uses strict equality by default.
So to know whether to exclude the selected value from the value in the list, you must implement getOptionSelected to check for the equality for exclusion, here is .title
<Autocomplete
...
getOptionSelected={(option, value) => option.title === value.title}
...
/>
Below is the forked codesandbox

Your onChange function needs to be enhanced. You have to set the value array same as given in options array. Both array needs to match. You were getting details from options--> Titles. then You must set it by creating a similar array on onChange. like set options--> Titles
Try My working Sandbox example here

To give you more knowledge on what is happening: the main reason behind why putting your onChange handler is causing the options to be populated again with all the days, is because your component is rerendered everytime you set the state for days versus when you weren't setting the state for days. I've found that Material UI Autocomplete default checking works with an array stored in a state versus the hardcoded options you have
options={availableDays} //state based
CodeSandBox: https://codesandbox.io/s/so-react-material-ui-autocomplete-h2unq?file=/src/App.js

Related

Attribute is not saved in Gutenberg

I am trying to create a custom block for Wordpress Gutenberg.
I have the following attributes:
"icon": {
"type": "object",
"source": "html",
"selector": ".jig_defbox-icon"
},
"color": {
"type": "string",
"default": "#919191"
}
In my EditJS I try to store values from a color-picker and a radiogroup into these attributes.
const [ toggled, setToggled ] = useState( );
return(
<InspectorControls>
<ColorPalette
colors={[
{name: 'lightgray', color: '#d8d8d8'},
{name: 'darkgray', color: '#919191'},
{name: 'red', color: '#dc1a22'}
]}
disableCustomColors={true}
onChange={(value) => {props.setAttributes({color: value});}}
value={props.attributes.color}
clearable={false}
/>
<RadioGroup
onChange={ (value) => {setToggled(value);props.setAttributes({icon: value});} }
checked={props.attributes.icon}
>
{
str_array.map(
item => ( <Radio value={item}><Icon icon={icon_getter(item);}/></Radio>)
)
}
</RadioGroup>
</InspectorControls>
)
In my SaveJS I try to render my markup according to these attributes:
const {attributes} = props
<div style={{"fill": attributes.color}}>
<Icon icon={icon_getter(attributes.icon)}/>
</div>
The goal is to render an svg-icon according to the selection on my radiogroup.
Issue 1: Every new edit-session in backend, the selection of my radiogroup is gone, even with useState (tried without useState first)
Issue 2: Every new edit-session, a console error is logged, that says that the post-body markup does not match the markup returned by the save function, because the save-markup does not contain the icon attribute content
As far as I was able to enclose the problem, the icon attribute is not correctly saved. I tried to save the "key" for the icon as a string and object. If I log the value in the save function, it is empty, while the selected color works as expected, both in frontend and backend.
I was able to fix it via rethinking my concept of fetching the icon.
Apparently, Gutenberg tried to store the code of the icon into the database, but not the key. When loading the backend editor, the icon_getter function received a null value, therefore, the difference between post body and save function code.
I changed my editJS:
<RadioGroup
onChange={ (value) => {props.setAttributes({icon: value});} }
checked={props.attributes.icon}
>
{
my_icons_as_list.map(
item => ( <Radio value={item}><Icon icon={my_icons[props.attributes.icon];}/></Radio>)
)
}
</RadioGroup>
and my saveJS:
<Icon icon={ my_icons[ attributes.icon ] } />

values not getting edited from input field in reactjs

So i have this input where user enters some string and then we make an api call and shows some suggestions where user can select one of the suggested data .Once user selects any of these , i want the data in input field equal to that which is happening as of now .However user is not able to edit after selecting .I felt that it's some controlled or uncontrolled component issue in react .
<SearchRectangle>
<SearchImageDiv>
<SearchImg src={SearchImage}/>
</SearchImageDiv>
<div>
<input
style={{borderRadius:'10px',
marginLeft:'30px',
backgroundColor:'rgba(216,216,216,0.41)',
height:'48px',
width:'100%',
outline: 'none',
border: 'none',
fontSize: '1.6rem',
fontFamily: 'Open Sans',
fontWeight: 'normal',
fontStyle: 'normal',
fontStretch: 'normal',
paddingLeft: '10px'
}}
value={ this.state.inputValue || this.state.selectedCity || this.state.selectedPincode } onKeyUp={evt => this.updateInputValue(evt)}/>
</div>
We execute this code when user selects any of the suggested value in autosuggest .
selectsuggestions =(item)=>{
if(item.city){
this.setState({
selectedCity:item.city,
inputValue:null,
selectedPincode:null,
suggestions:[]
})
}
else{
this.setState({
selectedPincode:item.pincode,
selectedCity:null,
inputValue:null,
suggestions:[]
})
}
}
We are executing suggestions using this way .
<Suggestions selectsuggestions={(e,r)=>this.selectsuggestions(e,r)} results ={this.state.suggestions }/>
While using value method of input tag, the value presented is chained to the value of value
So you have two options
call setState on input onChange and then value will assign new state to UI
use defaultValue instead value, that way UI presentation isn't chained

How to add or remove form keys using react-final-form

single config example shows what configuration I use for inputs.
export const age = [
{
value: '',
type: 'radio',
name: 'age',
items: [
{value: 'kid', label: 'Im less than 18',
{value: 'adult', label: 'Im 18!',
],
},
];
export const someDate = [
{
type: 'date',
value: null,
name: 'someDate',
label: 'Enter date',
format: 'dd/MM/yyyy',
minDate: new Date('2019-12-31'),
maxDate: new Date('2020-03-31'),
validators: required.required.date
}
];
RFForm is a wrapper for rect-final-form Form component and I pass all components inside as children.
<RFForm
config={[...age, ...someDate, ...somethingElse]}
submit={submit}
>
<SectionBox title="Your age">
<Box mb={5}>
<InputList inputs={age}/>
</Box>
<SectionTitle title="Date"/>
<Box maxWidth="50%">
<InputList inputs={someDate}/>
</Box>
</SectionBox>
<SectionBox title="Something else">
<Box maxWidth="50%">
<InputList inputs={somethingElse}/>
</Box>
</SectionBox>
{
conditionToHideOrShowSection && <SectionWithInputs />
}
{
buttons
}
</RFForm>
I want to add a new section that will hide or show depends on what the user picks. The section should be ONLY present when the second radio button value is selected (adult). The section will contain a component with inputs from the configuration. All the fields should be required. This should only be validated when the section is present.
First question - how should I check if the specific radio button is checked. I don't have access to useForm from here and I need to hide or show section.
Second question - how to dynamically add new inputs when other inputs are changing. Remember that I have to add it to config (RFForm props) because initial value must be updated.
Actually you have access to it, but in other way via render method link
This sample shows how to conditionally show inputs link. Be aware if input hide back the data won't gone, it's still there , so to cleanup you should use change('inputName', undefined) (at least it helps me in my case)
At last you also should checkout about subscription prop. link

react-select 2 setting value/label

I am using react-select 2 and trying to set value on form that needs to perform update of some data fetched from server.
I have tried solution:
handleSelectChange(selectedOption){
this.setState({ selectedOption });
}
const options = [
{ value: 'Value 1', label: 'Value 1' },
{ value: 'Value 2', label: 'Value 2' },
]
<Select
options={options}
onChange={(selectedOption)=>this.handleSelectChange(selectedOption)}
autoFocus={true}
value={options.find(option => option.value === data.valueTyppe)}
/>
By using this it is not possible to change (visualy) label in select input - value changes on select but label stays as one defined by data.ValueType.
I think your problem comes from not allowing full control of the Select input.The value of the Select input should be the component state value property, same as the onChange calback is.
return(
<Select
options={options}
onChange={this.handleSelectChange}
autoFocus={true}
value={this.state.selectedOption}
/>
try this working examle
I have used this solution and it works for me.
First Value/Label pair is set as on defined in options that have value === data.FacilityType (saved string in database).
Then it enables change of option where value/label pair is also updated in Select.
<Select
options={options}
onChange={(selectedOption)=>this.handleSelectChange(selectedOption)}
autoFocus={true}
defaultValue={options.find(option => option.value === data.facilityType)}
/>

Can I specify a Divider or Header in Semantic UI React's options array for the dropdown component?

I am working with ReactJS and using SemanticUI for ReactJS to style the front end,
Is it possible to specify a header or divider from within the options array of objects for a dropdown component?
I get the impression from the documentation that this is not supported yet.
I solved this by changing to object in the options array to have more properties (which allow you to customise the content):
{
text: "YouGov Filters",
value: "yougov-header",
content: <Header content="YouGov Filters" color="teal" size="small" />,
disabled: true
},
It's probably not the ideal way to achieve what I want because I have to set disabled to true (I don't want it to be a selectable option) which means it adopts the greyed out 'disabled' style. I tried to counter this by specifying a color for the header which resulted in the disabled style being applied over the teal colour, not perfect but it will do for now.
Another workaround is to do it by map array:
const options = [
{
text: "note",
icon: 'sticky note outline',
description: 'test',
},
{
divider: true
},
{
text: "task",
icon: 'calendar check outline',
description: 'test',
},
];
return (
<Dropdown className='multicontent__button' text='add new' button>
<Dropdown.Menu>
<Dropdown.Header icon='tags' content='Tag Label' />
{options.map((option, i) => {
if (option.divider === true) return (<Dropdown.Divider key={i}/>);
return (
<Dropdown.Item
key={i}
text={option.text}
icon={option.icon}
description={option.description}
action={option.action}
onClick={this.handleOption}
/>
);
})}
</Dropdown.Menu>
</Dropdown>
);
Mr B's solution is genius. And it can be cleaner with a little modification of his:
function FragmentWithoutWarning({key, children}) {
// to get rid of the warning:
// "React.Fragment can only have `key` and `children` props."
return <React.Fragment key={key}>{children}</React.Fragment>;
}
// then just:
{
as: FragmentWithoutWarning,
content: <Header content="YouGov Filters" color="teal" size="small" />
}
Since <React.Fragment /> is not able to capture any event, you even don't have to disable the item.

Categories

Resources