Material UI Autocomplete component not showing values from react state - javascript

I am trying to get value from the state for materialUI's autocomplete component.
I am facing the following problem : -
Autocomplte working fine for selecting the value and with onChange function it saving it into the state too.
But when I refresh my page/ re-render it is not showing value on the textfeild(from saved state):
<Autocomplete
name={"TideLocation"}
disabled={p.disabled}
options={data_source}
getOptionLabel={option => option.text}
inputValue={this.state.tidelocation_searchtext}
onChange={_this.handleUpdateTideLocationField}
onNewRequest={_this.handleChangeTideLocation}
onBlur={_this.handleBlurTideLocationField}
onUpdateInput={_this.handleUpdateTideLocationField}
renderInput={(params) => (
<TextField className="autoCompleteTxt"{...params} label="Location" />
)}
/>
I tried with the debugger and found its getting value in this.state.tidelocation_searchtext
but failed to set it with params.
Thanks in advance !!
Ps: I tried with defaultValue and search text nothing worked for me
following is my ONchangeFunction
handleUpdateTideLocationField = (str, value) => {
debugger
this.setState({tidelocation_searchtext: value.text});
}
after selecting a value,following value saved in sate :
tidelocation_searchtext: "Auckland"

So I found the solution all by myself by doing research and several hit and try, following is the solution of my problem:
<Autocomplete
name={"TideLocation"}
disabled={p.disabled}
options={data_source.map(option=>option.text)}
defaultValue={this.state.tidelocation_searchtext}
onChange={_this.handleUpdateTideLocationField}
onNewRequest={_this.handleChangeTideLocation}
onBlur={_this.handleBlurTideLocationField}
onUpdateInput={_this.handleUpdateTideLocationField}
renderInput={(params) => (
<TextField className="autoCompleteTxt"{...params} label="Location" />
)}
/>
Basically I was doing the following things wrong :
1.There is no need of using input inputValue={this.state.tidelocation_searchtext}& getOptionLabel={option => option.text}
2.as my data is in object form I have to convert it into a string so default value can match this from the state value
options={data_source.map(option=>option.text)}
Thank you all for your valuable support and solution !!

Removing inputValue has worked for me, even when passing object as options.
Using: "#material-ui/core": "^4.12.3"

If data/state not saved externally f.e. in local storage then it will be lost on page refresh, always. It's normal - like RAM memory without power - it (page/app state) only exists in memory !!
It's like using using cookie to keep you logged in.
If you really need such functionality then use f.e. redux-persist

You are right, if object type options are passed, material-ui's AutoComplete component does not seem to reflect the value when mounted. (Perhaps a bug?)
I was able to get around this by passing the proper characters to inputValue.
#RebelCoder
Maybe you should have initialized tidelocation_searchtext.

For me it was coming from the dropdown z-index which was hidden by another css behaviour.
I added this in a css file :
/* Dropdown MUI Component Autocomplete*/
div[role="presentation"].MuiAutocomplete-popper {
z-index: 1000000;
}
And it appeared finally. A bit hacky, but I think it was caused by another library that had something of that kind.
Note that I added several css elements to the selector, because just using the class wasn't enough.

Related

react-admin ReferenceField label not showing when used in a custom component

So I need a ReferenceField to access data from another table. Since I am doing this often i extracted this in a custom component
CustomField.tsx
const CustomField = (props: any) => {
const record = useRecordContext();
return (
<ReferenceField
record={record}
source="someId"
reference="table"
link="show"
label="some label"
{...props}
>
<TextField source="name" />
</ReferenceField>
);
};
now when i use the component:
<CustomField/>
everithing is working fine, data is displayed fine, except no label is shown.
So I am expecting some form of label at the top but no signs.
If I do it without creating a custom field, everything is working just fine, the label and sorting is there. But when I extract the code into a separate component it doesn't seem to work.
Looks like the attributes lose their default values and behavior when extracted to a separate component.
My current workaround
<OrganisationField label="Some label" sortBy="something" />
that is fine, it works but it's not practical (and it's annoying) to do this everytime I or someone else wants to use the component, since that should already be defined inside it.
When you say "no label is shown", I assume that's when you use your custom Field inside a Datagrid.
Datagrid inspects its children for their label prop to display the column header. To make your label inspect-able, declare it as defaultProp:
CustomField.defaultProps = {
label: "someId"
}
This is explained in the react-admin "writing a custom field" documentation: https://marmelab.com/react-admin/Fields.html#writing-your-own-field-component

Storage-design for fetched data (globally?) & navigation

im new to JavaScript & React (and new to stackoverflow too) and I hope to get some ideas/ answers regarding the "logic" in implementing data-storage. I have/ had a dev-background in Obj-C / iOS few years back. So some general concepts in web-dev might not be familiar to me.
Hope I'm doing everything correct in my first post, never really used stackoverflow so far :)
So, basically I have a small project with a Sider und Content (using Ant Design Framework). In this project, im trying to figure out, how generell stuff has to be done, like Navigation through the views, data handling and so on.
In one Tab in the SideBar, i'm using a Table (also antd). If you press on one Item, it should show a detail-View with the props of that specific item (later it should be the form for data change/input).
My App.js:
<Content style=...>
<Switch>
<Route exact path="/tasks" >
<TasksTable
data={this.state.tasksData}
handleOnRowClicked = {this.handleOnRowClicked}
/>
</Route>
<Route exact path="/details">
<TasksDetail currentTask= {this.state.currentDetailTask}/>
</Route>
....
</Switch>
</Content>
In the TasksTable-Component:
...
const history = useHistory()
...
function handleOnRowClicked(record, rowIndex,event) {
console.log("Clicked on cell", event)
history.push("/details/")
props.handleOnRowClicked(record.id)
}
return(
<Table
dataSource={props.data}
onRow={ (record, rowIndex) => {
return {
onClick: event => {
handleOnRowClicked(record, rowIndex,event) }
}
}
}
>
<Column title="Name" dataIndex="name" key="name" />
<Column title="Kunde" dataIndex="client_name" key="client_name" />
<Column title="Fertigstellung bis" dataIndex="completion_date" key="completion_date" />
<Column title="HinzugefĆ¼gt" dataIndex="created" key="created" />
<Column title=""
dataIndex="remove_button"
key="remove_button"
render={removeButton => {
return <button key="ButtonKey" onClick={event => handleOnButtonClicked(event)}>Remove</button>
}}/>
</Table>
)
}
What i want to achive:
When clicked on one row of the table, i want to push another "view"/ Side to show details of selected row. Currently I'm doing this in the TasksTable-Component with history.push(). I'm wondering if this is the correct way of showing (detail-)views? Because I need to call props.myHandleCallbackFunc(selectedItem) in App.js to set a State names "currentlySelected" for then passing this state as prop to the pushed detail view.
Hope you get my point.
As far as I understood, I should use ... for automating the navigation-process. Problem is: As I use the Table from antdesign, I need to make this programatically. Thats why I have this workaround (at least it feels like one) with the onRow property... Is this the correct way of using the table? I have the feeling its not.
Problem with my workaround: I've rendered a Button into the Cells to deliver a delete-Button.
Problem there: Even if i click on the Button, it is registered as a click on the row and therefor pushes my detailview... I tried to differentiate with event.target.key but had no success.
Is it the right way of holding all data fetched by my api in the uppermost component and share it to sup-components via props? How can I update it from subcomponents then? Should every Subcomponent should get a handler via props to call back, when value changed?
Or in other words: Make the http-request from the sub-comp or send the changed data to the App-component and let it then trigger the HTTP-POST-request? I strongly guess its second choice.
Thank you so much, I appreciate every answer. Im trying to get things working since few hours now...
(Sorry for spelling mistakes, english is not my native one).
P.S: Actually I wanted to post this yesterday but took few extra hours for working through the "similar questions"... Still, open questions :D
Robin
Redux is a predictable state container for JavaScript apps.
It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger.
You can use Redux together with React, or with any other view library. It is tiny (2kB, including dependencies), but has a large ecosystem of addons available.
https://redux.js.org/introduction/getting-started

change controlled to unctrolled when using file type input

i defined multiple state for my app like this:
const
[state,setstate]=React.useState({headerpic:'',Headerfontfamily:'',Subheaderfontfamilty:''})
and i use a input as follows for getting an image from my device:
<Button variant='contained' color='primary' className={styler.buttons} name='headerpic'
>Header Pic
<input type='file' value={state.headerpic } style=
{{width:'100%',height:'auto',opacity:'0',position:'absolute',top:'0px'}} onChange=
{(e)=>fileuploader(e)}></input>
</Button>
i defined fileuploader like below:
const fileuploader=()=>{
if (e.target.files && e.target.files[0]) {
let img = e.target.files[0];
console.log(URL.createObjectURL(img))
setstate({
headerpic: URL.createObjectURL(img)
});
} }
when i click on button and choose the desired pic i got below error:
A component is changing a controlled input of type text to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info:
any idea for solving this problem?
An input component that gets changed from controlled to uncontrolled generally means that your <input> goes from having a value to being undefined/null. This is most likely happening when an img gets removed in your case. The easiest fix would be to add a guaranteed value to your input field incase your state is undefined.
<input type='file' value={state.headerpic || ''} ... />
Does this resolve your issue?
It would be good if you let us know what it is you're exactly trying to do :/ and also some fuller code (the code given above, doesn't work!!)
If you're trying to make a file uploader I would recommend googling something like
"How to make file upload with react hooks"
Here's one I found earlier ;)
https://www.educative.io/edpresso/file-upload-in-react
which has a nice simple example of creating a file input and saving it in state with react hooks.

"toggled" attribute not working (redux-form-material-ui)

I'm trying to use Toggle from redux-form-material-ui:
import { Toggle } from 'redux-form-material-ui'
It works ok updating the toggled value to the store on its onChange:
<Col xs='3'>
<h3 className="title-page">Parceiro</h3>
<Field name="possui-parceiro" component={Toggle} label="Possui parceiro?" />
</Col>
Problem is: I make a call to some API and I need to update the value of this toggled "programatically". Theoretically, I can use the toggled attribute as stated here, but this just doesn't work:
<Col xs='3'>
<h3 className="title-page">Parceiro</h3>
<Field name="possui-parceiro" component={Toggle} toggled={this.state.someBloodyState} label="Possui parceiro?" />
</Col>
Which leads me to believe that in this case redux-form is just on the way of the update / manipulation process, forcing me to somehow update the form on the store to toggle the value, and it looks messy to dispatch such action. Anyway, how do you proceed in such cases?
I would store the API result in the redux state, read it from your mapStateToProps and pass it to the component in the property initialValues setting enableReinitialize: true.
These 2 properties are the way of redux-form to change stuff programmatically "later on" after the form already rendered.
Otherwise , if you can fetch your data before even rendering the form, you can just use initialValues without enableReinitialize.
Another way is to use the change function provided by redux form
More info in the docs

Why won't my placeholder show up properly? (react-native-datepicker)

I'm having a really hard time getting a placeholder to show up properly in this datepicker package I'm using for react native...
Here's how I have the component setup:
The _onDateChange function:
const _onDateChange = (startTime) => {
pickDate(props.setPatrolStartTime, startTime)
this.setState({startTime: props.setPatrolStartTime})
}
The datepicker component:
<DatePicker
//date={props.startTime}
mode="datetime"
iconComponent={ <Icon name='chevron-down' type='font-awesome' color='green'/> }
style={ styles.datePickerStyle }
placeholder={`Select Start Time`}
confirmBtnText='Confirm'
cancelBtnText='Cancel'
customStyles={{
dateInput:{
borderWidth: 0,
},
dateText: {
color: 'white',
textAlign: 'left',
fontSize: 20
},
}}
onDateChange={this._onDateChange(props.startTime) }
/>
Expected behavior: I thought it would show the placeholder until I changed the date, but it would not show the placeholder until I commented out the date prop, and after googling and searching stackoverflow for a while, I saw various posts, some saying that I need to bind the onDateChange prop, and some requesting that I make a separate onDateChange function and call it from the prop.
Actual behavior:
I can't seem to figure out how to bind it, and when I try to call it as shown above, it red screens, saying that undefined is not a function, referencing _onDateChange. When I try to use the placeholder prop, the placeholder will not show unless I comment out the date prop, and when I do that, it shows the placeholder, except when I set the date, the placeholder doesn't change to the date I set.
At this point, I can't really figure out what I'm doing wrong. Can anyone give me some input?
Thanks!
Try to use placeholderText instead of placeholder
You can get reference from here
You have used backticks instead of normal quotes, it should be
placeholder="Select start time"
You can check the example on github https://github.com/xgfe/react-native-datepicker
placeholder does not take an object, however, it takes a string like this:
placeholder="select date"
not like this:
placeholder={"select date"}
also, the placeholder value only shows up when this.props.date is false
Seems to be a bug in the library, and it hasn't been updated in a year. If you want to prevent the current date from showing up by using a placeholder, you will need to set placeholder to be a non-empty string and it should work.
The input value still needs to be falsy for the placeholder to appear (e.g. an empty string as date/time).
Update 2022,
there still is a bug trying to display a placeholder, the work around I found is to use the customInput to return a div and use the ::after CSS pseudoelement to insert whatever text you like

Categories

Resources