Update array of items with help of modal input in React - reactjs

I didn't find any suitable answer for this question. Here is what I am looking for.
I have lists of menus items coming from the state array variable (https://i.imgur.com/FzD0sol.png).
I have an add button which opens a modal. Modal includes an input field. (https://i.imgur.com/6DCZhoj.png)
The final result would be when some click adds button of modal, its field values updated in menus state array. which further updates the menus list on UI.
I able to made all these UI. But I didn't have any idea how can I pass my data from modal input to menus list. Here is codesandebox link of the same problem (https://kx6yr.csb.app/).

There is a way to solve your problem :
You have to give a callback props to your Modal component. As it, The modal will be able to add an item.
There is the codesandBox : https://codesandbox.io/s/friendly-boyd-ptxem

So this is one way to do it, in your modals add this onAdd prop:
<AddModal
heading="Add Food"
modalId="addFood"
inputName="addFood"
onAdd={(textEntered) => { alert(textEntered); }}
ref={this.foodModal}
/>
<AddModal
heading="Add Drink"
modalId="addDrink"
inputName="addDrink"
onAdd={(textEntered) => { alert(textEntered); }}
ref={this.drinkModal}
/>
And within the modal component, call this handler passing the input value:
<button
type="button"
onClick={this.props.onAdd.bind(this, this.state.item)}
className="golden-button-op"
style={{ margin: "0px" }}
>
Add
</button>
Hope it helps!

Related

Text Field Changed Value not updating in OnSubmit - React-Hook-Form & React Js

I am new to React. I am facing an issue while I try to handle a form submit.
Anyone knows this answer please let me know, Using React Material-UI, React-Hook-Form With the controller.
My program has 3 TextFields.
Calculation:
PendingTime=ActualTime-working time;
actual-time is a default value (value is 5). While I change the WorkTime Text field value,
Pending Time automatically updates the pending time value. I added the onChange event in the WorkTime Text field. In the OnSubmit event, I need to get the actual-time value, WorkTimeValue, and PendingTimeValue. But I was not able to get the value onSubmit.
I wrote my code in CodeSandbox.
React-hook-form TextFieldChange value not trigged in onSubmit Event
ScreenShot:
To answer your question, the reason why is not submitting the form is because you're not tying the Button component to the input, add this prop to your component and you'll be able to submit the form
<Button variant="contained" type="submit">Submit</Button>
the type="submit" should allow to submit the form.
Now that you have the answer, you're not using react hook form correctly, you should not mix React.useState with react-hook-form since its loses it purpose, please read the documentation on how to use the register hook with inputs and if you need to update the one of the input values, just watch for the input changes and you'll be read to go.
Also you're getting a warning because you have a form nested inside a form, so instead of using the box as a form change it to be a div or whatever that is valid html nesting:
<Box
component="div"
sx={{
"& > :not(style)": { m: 1, width: "25ch" }
}}
>
Here's a working sandbox with all the functionality you want to do:
Working sandbox
This includes calculating the pending time every-time you change the actualTime and the workTime and it will submit properly, also the useState is removed since you don't need it.
Remove your form tag completely, and place the onSubmit handler inside the Box component.
See, you assigned its component to form, which means you have a nested form inside your form. the submit button is inside the nested form, and onClick does not call the onSubmit function inside the outer form.
Some Material-Ui components accept a component attribute, and it creates an HTML tag of that specified value.
return (
<Box
onSubmit={handleSubmit(onSubmit)}
component="form"
sx={{
"& > :not(style)": { m: 1, width: "25ch" }
}}
noValidate
autoComplete="off"
>
// ...
</Box>
);
CodeSandBox Example

React.js Map Array style for a unique id and each button disabled

I need each question button when it is clicked to be disabled. I would also like to style each question button. I already looked for several answers to this problem but I found nothing. As I don't know much about React in this case, should I use useEffect or children.props? If you have any solution please let me know.
Demo
Your buttons' state is already available for each button, you just need to use state and disable button.
{/* Question buttons */}
{buttons.map((button) => (
<button key={button.id} disabled={button.clicked} onClick={() => buttonClickHandler(button.id)}>
{button.label}
</button>
))}
About styling buttons individually, you can create a className for each button and style buttons depending on that:
<button className={'button-' + button.id}>
and now from css apply color:
.button-01 { background: pink; }
The second approach could be that you create styles for each button inside the state, and consume it from there.
<button style={button.style}>

useState set method for modal not updating

I am trying to build a simple todo list. Basically there is a list of items. When the user clicks the 'edit' button on an item, selectedTodoItem is updated. Then a modal is shown which uses selectedTodoItem as prop.
I am also using ant.design library for the list.
Here is my code (with irrelevant bits left out):
const [selectedTodoItem, setSelectedTodoItem] = useState(selectedTodoList.items[0]);
const editItemHandler = (item) => {
setSelectedTodoItem(item);
dispatch(toggleEditTodoItemModalVisible());
}
return(
<List
className="whitebg listItems"
datasource={selectedTodoList.items}
renderItem={(item) => (
<TodoItemInList item={item} editHandler={editItemHandler} />
)}
/>
<TodoItemEditModal item={selectedTodoItem} />
);
<TodoItemInList> is basically a label and some buttons, one of which calls editHandler(item).
Here's a screenshot so you can get a better idea:
The problem is, when I load the page and click edit (blue, don't mind the delete icon) on an item, say 'Foundation', the edit modal loads fine. But when I click on another blue button, the modal still shows 'Foundation'. No matter what button I click, the modal only shows the first clicked item. It seems like selectedTodoItem is updating though, according to console.log(), but the modal's prop doesn't update with it.
Any nudge in the right direction would be much appreciated.

React Mapbox Extra Button Doesnt Work Inside Popup

I am working with mapbox react gl - It is working pretty nice so far... except one thing.
The user can add their hometown location to the map. When the hometown location appears, it can be clicked to view a popup. I want the user to be able to remove the location from the map from inside the popup - So I added a function that removes the location from the database when a button is clicked. The problem is when the button is inside the popup the function doesn't fire - and I have no idea why.
I have messed with the z index of the button but it seems like whenever the button is clicked, the onClose function is being called instead of my handleDeleteHome function...
Edit* If I remove the onClose function, the handleDeleteHome function fires.
Any help is appriciated! Thanks!
{selectedHome && (
<Popup
latitude={bandLocation[0]}
longitude={bandLocation[1]}
onClose={() => {setSelectedHome(null)}}
offsetLeft={23}
offsetTop={-10}
>
<div>
<h4>Home Town</h4>
<Button
onClick={(e) => {
e.preventDefault()
handleDeleteHome()
}}
color="danger">x</Button>
</div>
</Popup>
)}
Alright! Figured it out - If anyone else needs to know:
You need to add closeOnClick={false} to the popup!

Dynamic Popover in ReactJS

I'm fairly new to React and I'm using the Ant Design framework (https://ant.design/).
I have a table list of items that I'm looking to have a button on each so that when it is pressed additional information about that row becomes available (which is a secondary API call specific to that row).
I'm trying to use a popover but I'm noticing that the popover wants the text before being rendered which is a problem since I don't have that information until the second API call. The best idea I've come up so far is to have the button press trigger the api call and then the state is updated but that creates a funky experience (as it is update after the popover is already opened - after starting with the previous rows information). It isn't a huge amount of time but it still isn't an ideal experience.
This is what I have so far:
<Popover content={this.contentSec([record['section']])} title=
{record['section']} trigger="click">
<Button onClick={() => this.sectionAttributes(record['section'])}>
<Icon type="info-circle-o" />
</Button>
</Popover>
this.sectionAttributes triggers my fetch request. and this.contentSec does the formatting on the existing popup (see below).
contentSec(props) {
const listItems = this.state.attributes.map((item) =>
<li>{item}</li>
);
return <div><ul>{listItems}</ul></div>
}
Any ideas of a better way to handle this so that there isn't that buggy delay when clicking the button for the popover?
Thanks.
As the content is populated after the second api call, You can send two props content which can be empty string or any default value and loading variable as true on click. Once you have the data after the API call you can send the updated props ie content with actual text and loading as false and finally handle your logic and state update in componentwillrecieveprops() in the popover component.
You can use the loading prop to switch from a loader initially to the actual content.
Write a condition to check if the response from this.sectionAttributes(record['section'] is true, if it is true then
<Popover content={this.contentSec([record['section']])} title=
{record['section']} trigger="click">
<Button onClick={() => this.sectionAttributes(record['section'])}>
<Icon type="info-circle-o" />
</Button>
</Popover>
else simply use
<Button onClick={() => this.sectionAttributes(record['section'])}>
<Icon type="info-circle-o" />
</Button>
For the first time user clicks on button, the component rerenders and state gets updated, so when it rerenders you can see popover as the if condition satisfy.

Resources