I have simple fields. I want to populate the input boxes based on the data that I get from axios response. See below image
I am using hooks, to save data to state.
My question is how I am able to populate input boxes upon clicking get details button (response from api).
see below codes
const [data, setData] = useState([])
const [advisoryDetails, setadvisoryDetails] = useState({
ADVISORYID: '',
ADVISORYDESC: '',
CREATEDBY:'',
MODIFIEDBY:'',
STATUS1: ''
})
const [advisoryDetails1, setadvisoryDetails1] = useState([])
const [advisoryID, setadvisoryID] = useState('')
const getAdvisoryTest = async () => {
await axios.post('/API',advisoryID)
.then(response => {
console.log(response.data)
setData(response.data)
console.log('data',data)
setadvisoryDetails1(response.data)
console.log('advisoryDetails1',advisoryDetails1)
alert('success')
})
advisoryDetails1.map(adv => {
advisoryDetails.ADVISORYID = adv.ADVISORYID;
advisoryDetails.ADVISORYDESC = adv.ADVISORYDESC;
advisoryDetails.CREATEDBY = adv.CREATEDBY;
advisoryDetails.MODIFIEDBY = adv.MODIFIEDBY;
if(adv.CREATEDBY && adv.MODIFIEDBY != '')
{
advisoryDetails.STATUS1 = 'Modified'
}
else{ advisoryDetails.STATUS1 = 'New'}
console.log('populate',advisoryDetails)
})
}
const txtAdvIdOnChange = e =>{
setadvisoryID(prevState =>({
...prevState,
'ADVISORYID':e.target.value
}));
console.log('onChange ID:',advisoryID)
}
return(
<div>
<label>AdvisoryID: </label>
<input type='text' placeholder='Advisory ID' className='txtAdvisoryID' onChange={txtAdvIdOnChange} />
<button onClick={()=>getAdvisoryTest()}>Get Details</button>
<br /><br />
<label>Advisory Desc: </label>
<input type='text' placeholder='textbox1' className='txtAdvisoryDesc' value={advisoryDetails&&advisoryDetails.ADVISORYDESC} disabled/>
<br/>
<label>New / Modified: </label>
<input type='text' placeholder='textbox2' className='txtStatus' value={advisoryDetails&&advisoryDetails.STATUS1} disabled/>
</div>)
On those codes input boxes was not populated, even in console.log
Hope you can help me thank you.
I think you can refactor your code like below.
I've moved set setadvisoryDetails to within .then() of axios because you're using the same data and you're don't have to go through the loop if you just want the last iteration's value. And in the inputs you don't have to check if advisoryDetails exists or has non empty value because you've initialized it in const [advisoryDetails, setadvisoryDetails] = useState({...})
const App = (props) => {
const [data, setData] = useState([])
const [advisoryDetails, setadvisoryDetails] = useState({
ADVISORYID: '',
ADVISORYDESC: '',
CREATEDBY: '',
MODIFIEDBY: '',
STATUS1: ''
})
const [advisoryDetails1, setadvisoryDetails1] = useState([])
const [advisoryID, setadvisoryID] = useState('')
const getAdvisoryTest = () => {
axios.post('/API', advisoryID)
.then(response => {
const respData = response.data;
setData(respData)
setadvisoryDetails1(respData)
console.log({
respData, data, advisoryDetails1
});
alert('success');
if (respData.length > 0) {
const adv = respData[respData.length - 1];
setadvisoryDetails((prevState) => ({
...prevState,
...adv,
STATUS1: adv.CREATEDBY && adv.MODIFIEDBY != '' ? 'Modified' : 'New'
}))
}
})
}
const txtAdvIdOnChange = e => {
setadvisoryID(prevState => ({
...prevState,
'ADVISORYID': e.target.value
}));
console.log('onChange ID:', advisoryID)
}
return (
<div>
<label>AdvisoryID: </label>
<input type='text' placeholder='Advisory ID' className='txtAdvisoryID' onChange={txtAdvIdOnChange} />
{/* If you're just passing a function without any param or event params, then just pass the function name like a variable */}
<button onClick={getAdvisoryTest}>Get Details</button>
<br /><br />
<label>Advisory Desc: </label>
<input type='text' placeholder='textbox1' className='txtAdvisoryDesc' value={advisoryDetails.ADVISORYDESC} disabled />
<br />
<label>New / Modified: </label>
<input type='text' placeholder='textbox2' className='txtStatus' value={advisoryDetails.STATUS1} disabled />
</div>
);
}
when you click the get details button your state was not updating that was the issue(value only change when the state was updated otherwise it is not updated)
//before don't do like this
advisoryDetails1.map(adv => {
advisoryDetails.ADVISORYID = adv.ADVISORYID;
advisoryDetails.ADVISORYDESC = adv.ADVISORYDESC;
advisoryDetails.CREATEDBY = adv.CREATEDBY;
advisoryDetails.MODIFIEDBY = adv.MODIFIEDBY;
if(adv.CREATEDBY && adv.MODIFIEDBY != '')
{
advisoryDetails.STATUS1 = 'Modified'
}
else{ advisoryDetails.STATUS1 = 'New'}
console.log('populate',advisoryDetails)
})
//after(only last element of advisoryDetails1 array was updated in the state)
advisoryDetails1.forEach(adv => {
let STATUS1 ='New'
if(adv.CREATEDBY && adv.MODIFIEDBY != '')
{
STATUS1 = 'Modified'
}
setadvisoryDetails({ADVISORYID : adv.ADVISORYID,
ADVISORYDESC:adv.ADVISORYDESC,
CREATEDBY:adv.CREATEDBY,
MODIFIEDBY:adv.MODIFIEDBY,
STATUS1:STATUS1
})
})
if you want to view your last element in your advisoryDetails1 array do like this
let adv=advisoryDetails1[advisoryDetails1.length -1];
let STATUS1 ='New'
if(adv.CREATEDBY && adv.MODIFIEDBY != '')
{
STATUS1 = 'Modified'
}
setadvisoryDetails({ADVISORYID : adv.ADVISORYID,
ADVISORYDESC:adv.ADVISORYDESC,
CREATEDBY:adv.CREATEDBY,
MODIFIEDBY:adv.MODIFIEDBY,
STATUS1:STATUS1
})
//it update your advisoryDetails state when advisoryDetails1 changed
useEffect(()=>{
advisoryDetails1.forEach(adv => {
let STATUS1 ='New'
if(adv.CREATEDBY && adv.MODIFIEDBY != '')
{
STATUS1 = 'Modified'
}
setadvisoryDetails({ADVISORYID : adv.ADVISORYID,
ADVISORYDESC:adv.ADVISORYDESC,
CREATEDBY:adv.CREATEDBY,
MODIFIEDBY:adv.MODIFIEDBY,
STATUS1:STATUS1
})
})
},[advisoryDetails1]);
//check whether advisoryDetails is changed or not
useEffect(()=>{
console.log('populate',advisoryDetails)
},[advisoryDetails])
everything fine but doesn't do like this only the last element of the array was updated so you must need some changes based on your requirements
On your input value properties try adding a space either side of the &&.
<input type='text' placeholder='textbox2' className='txtStatus' value={advisoryDetails.STATUS1 && advisoryDetails.STATUS1} disabled/>
Related
Edited
I am trying to make a form that will enable the user to edit an existing citation. The citation is pulled from the backend with an api call. I then assign the values grabbed from the api to the state variables. These state variables is passed as props to the form jsx where they are used in the value prop of the input field. But for some reason the values assigned to state is not retained by the state and it goes back to its initial state values. I am adding the code as to how the component looks like
const EditEnterCitation = () => {
const [searchParams, setSearchParams] = useSearchParams();
// getting params from the url to pass to the functions
const cat = searchParams.get("cat");
const { id } = useParams();
// state to pass to the value prop in the form input
const [formData, setFormData] = useState({
institution_name: "0",
judge_name: "",
case_no: "",
apelLate_type: "0",
law: "",
point_of_law: "0",
party_name_appelant: "",
party_name_respondent: "",
advocate_petitioner: "",
advocate_respondent: "",
judgements: "",
date_of_order: "",
headnote: "",
references: "",
equivalent_citations: "",
title: "",
});
// state to for select buttonn in the form
const [instName, setInstName] = useState([]);
const [lawChoiceOptions, setlawChoiceOptions] = useState([]);
const [pointOfLawOptions, setPointOfLawOptions] = useState([]);
const [appealateType, setAppealateType] = useState([]);
// getting the choices for select from backend
const allChoices = useQuery(
["allChoices", cat],
() => getAllChoices(cat),
{
enabled: cat !== null,
refetchOnWindowFocus: false,
onSuccess: (response) => {
// setting law choices
if (response.data.law) {
let arr = response.data.law.map((element, index) => {
return { value: element.law_name, label: element.law_name };
});
setlawChoiceOptions(arr);
}
// setting point of law options
setPointOfLawOptions(response.data.pol);
// setting appealate type
setAppealateType(response.data.appeal);
// setting ins choices
if (response.data.ins.length) {
setInstName(response.data.ins);
} else {
let court_names = [];
let tribunal_name = [];
if (response.data.ins.ins_court.length > 0) {
court_names = response.data.ins.ins_court;
}
if (response.data.ins.ins_tribunal.length > 0) {
tribunal_name = response.data.ins.ins_tribunal;
}
let ins_names = court_names.concat(tribunal_name);
setInstName(ins_names);
}
},
}
);
// function to get default values of the citation
const getDefaultValues = useQuery(
["detailCitation", id],
() => detailCitation(cat, id),
{
enabled: allChoices.isFetched === true,
refetchOnWindowFocus: false,
onSuccess: (response) => {
setFormData({
institution_name: response.data.institution_name,
judge_name: response.data.judge_name,
case_no: response.data.case_no,
apelLate_type: response.data.apelLate_type,
law: response.data.law,
point_of_law: response.data.point_of_law,
party_name_appelant: response.data.party_name_appelant,
party_name_respondent: response.data.party_name_respondent,
advocate_petitioner: response.data.advocate_petitioner,
advocate_respondent: response.data.advocate_respondent,
judgements: response.data.judgements,
date_of_order: response.data.date_of_order,
headnote: response.data.headnote,
references: response.data.references,
equivalent_citations: response.data.equivalent_citations,
title: response.data.title,
});
},
}
);
// handling form data change for some fields
const handleFormDataChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
// handling form data change for the judgement
const handleJudgementData = (data) => {
setFormData({ ...formData, judgements: data });
};
const handlePartyAppealData = (data) => {
setFormData({ ...formData, party_name_appelant: data });
};
const handlePartyRespondData = (data) => {
setFormData({ ...formData, party_name_respondent: data });
};
// handling data change of the law choices
const handleOnChangeLaw = (selectedOption) => {
let newArray = [];
selectedOption.map((element) => {
newArray.push(element.value);
});
setFormData({ ...formData, law: newArray.toString() });
};
// hadling sumbimission of citation
const handleFormDataSubmit = async (e) => {
e.preventDefault();
try {
setProgress(80);
let response = await addCitation(cat, formData);
if (response.status === 201) {
toastNotification(
`Citation Uploaded to ${cat.toUpperCase()}`,
`success`
);
setProgress(100);
goToTop();
} else {
toastNotification(`Server Error. Could not upload citation`, `error`);
setProgress(100);
}
} catch (error) {}
};
useEffect(() => {
console.count("formData Appearing");
console.log(formData);
});
return (
<>
<LoadingBar
color="red"
progress={progress}
onLoaderFinished={() => setProgress(0)}
height={4}
/>
<Helmet>
<title>Enter Citation</title>
</Helmet>
<Wrapper>
<FormContainer onSubmit={handleFormDataSubmit}>
<EditInsFormElements
cat={cat}
handleFormDataChange={handleFormDataChange}
formData={formData}
handleJudgementData={handleJudgementData}
handleOnChangeLaw={handleOnChangeLaw}
instName={instName}
/>
<EditOtherFormElements
cat={cat}
handleFormDataChange={handleFormDataChange}
formData={formData}
handleJudgementData={handleJudgementData}
handleOnChangeLaw={handleOnChangeLaw}
lawChoiceOptions={lawChoiceOptions}
pointOfLawOptions={pointOfLawOptions}
appealateType={appealateType}
handlePartyAppealData={handlePartyAppealData}
handlePartyRespondData={handlePartyRespondData}
/>
<FormFooter>
<UploadBtn disabled={disableSubmit()} type="submit">
Upload Citation
</UploadBtn>
</FormFooter>
</FormContainer>
</Wrapper>
</>
);
};
the jsx inside the EditInsFormElements and EditOtherFormElements looks like this
<label className="required-field" htmlFor="apelLate_type">
Apellate Type*
</label>
<select
name="apelLate_type"
id="apelLate_type"
value={formData.apelLate_type}
onChange={handleFormDataChange}
required
>
<option value="0" disabled hidden>
Select
</option>
{appealateType &&
appealateType.length &&
appealateType.map((element, index) => {
return (
<option key={index} value={element.appealate_type}>
{element.appealate_type}
</option>
);
})}
</select>
<label className="required-field" htmlFor="case_no">
Case No*
</label>
<TextArea
name="case_no"
id="case_no"
value={formData.case_no}
onChange={handleFormDataChange}
required
/>
<label className="required-field" htmlFor="title">
Title*
</label>
<input
type="text"
name="title"
value={formData.title}
onChange={handleFormDataChange}
required
/> ....
And the state behaviour in the console that I have produced using useEffect is attached below
Question
Why is this alternating behaviour seen in the console is caused and how to rectify it so that the state retains the values grabbed and assigned from the backend.
So after debugging I founf out that the problem was with the CkEditor component I was using, whose onChange function was creating this behaviour.
the way I was using the onChange function on one of the ckeditor component was like below
<CKEditor
editor={Editor}
data={formData.judgements}
name="judgements"
id="judgements"
onChange={(event, editor, e) => {
const data = editor.getData()
handleJudgementsData(data)
} }
/>
and the onChange function looked like this
const handleJudgementData = (data) => {
setFormData({ ...formData, judgements: data });
};
This was causing the problem as the state was not updating synchronously what I could understand from Phil's answer in the question he linked
so I changed the code in the below way and now it is working
jsx
<CKEditor
editor={Editor}
data={formData.judgements}
onChange={(event, editor, e) => handleJudgementData(event, editor, e)}
/>
onChnage function
const handleJudgementData = (event, editor) => {
let data = editor.getData();
setFormData((prev) => ({ ...prev, judgements: data }));
};
After doing it the above way now the state retains the data fetched from api
So Im having problems with a form in which takes in text inputs to be set on an object. This object will then be updated in a hashmap of <key, object>.
So far, I can type in the input areas, but if I add another item in the hashmap which generates another div with the input elements it will contain the same value of the previous inputs.
So I need a way to reset those labels within the form and a way to update the hashmap.
I got an updateMap function, but I don't know where to place it for it to await the changes.
Edit: I need to reset the state of link, but when I do a function for it. It says something about preventing infinite loops.
export default function Admin() {
const [link, setLink] = useState({ name: "", link: "" });
const [links, setLinks] = useState(new Map());
const clickAddLink = () => addToMap(links.size + 1, link);
const deleteOnMap = (key) => {
setLinks((prev) => {
const newState = new Map(prev);
newState.delete(key);
return newState;
});
};
const getName = (key) =>
{
let linkFromKey = links.get(key)
return linkFromKey.name
}
const getLink = (key) =>
{
let linkFromKey = links.get(key)
return linkFromKey.link
}
const addToMap = (key, value) => {
setLinks((prev) => new Map([...prev, [key, value]]));
};
const updateMap = (key, value) => {
setLinks((prev) => new Map([...prev, [key, value]]));
};
const clear = () => {
setLinks((prev) => new Map(prev.clear()));
};
.... skipping code ....
<div>
{console.log(link.name)}
{console.log(link.link)}
{[...links.keys()].map((key) => (
<div key={key}>
{links.size > 0 && (
<div>
<form>
<span>Name</span>
<input
type="text"
placeholder={getName(key)}
required
value={link.name}
onChange={(e) =>
setLink({ name: e.target.value })
}
/>
<span>Link</span>
<input
type="text"
placeholder={getLink(key)}
required
value={link.link}
onChange={(e) =>
setLink({ link: e.target.value })
}
/>
</form>
</div>
)}
</div>
))}
</div>
{console.log(link.name)}
{console.log(link.link)}
</div>
```
Requirement - There will be two input fields in one row, one being name and second is number. In the second row, again two fields will be there with one being name and second is number. Now, the name field is readOnly and the second field number can be edited by user.
First time, the state which is in [{}] format would be empty. Now, when the user enters the number in the first row input, the state should get updated as [{ name: 'user1', number: 123}]. When the user enters value in row 2, the state should get updated as [{ name: 'user1', number: 123}, { name: 'user2', number: 456}]. If the user enters the value in row number 1 again, the existing object value should updated then adding a new one.
For example, if the user1's number gets updated to 789, the state value now should be [{ name: 'user1', number: 789 }, { name: 'user2', number: 456}].
Once this is achieved, if the numbers are duplicate, I should store and error in another state and with state, I can show on UI that the numbers are duplicate and need to have a unique number.
import { useState } from 'react';
const Test = () => {
const [data, setData] = useState([{}]);
const [error, setError] = useState(null);
const handleChange = (number, name) => {
//set data in the state
//validation
//if the values for number are duplicate for both field
//return an error for which input name the value is duplicate
}
return (
<div>
<input name='user1' value='user1' readOnly={true} />
<input name='number1' onChange={(e) => handleChange(e.target.value, 'user1')} />
<hr />
<input name='user2' value='user2' readOnly={true} />
<input name='number2' onChange={(e) => handleChange(e.target.value, 'user2')} />
</div>
)
}
Your handleChange function would look like this. Please not that I changed your initial data state to [] since a new user would simply be inserted instead of updating {}. I also prefer an empty state over null.
First we check whether the name already exists in data array. If not, we append it using curr callback.
If it exists and we only want to update the specific object, we can make use of map function.
By validating before updating the new user we can easily get the user that already has the value with find and set his name inside error state. Plus you can still decide if you want to update the data state if it has duplicate numbers by putting the // update value of exisiting user block inside of an else.
const [data, setData] = useState([]);
const [error, setError] = useState();
const handleChange = (number, name) => {
const idx = data.findIndex((item) => item.name === name);
if (idx === -1) {
// new user insert
setData((curr) => [...curr, { name: name, number: number }]);
} else {
// validation
const duplicateUser = data.find((item) => item.number === number);
if (duplicateUser) {
setError(duplicateUser.name);
console.log(`${duplicateUser.name} and ${name} have duplicate number`);
}
// update value of exisiting user
setData((curr) =>
curr.map((item) => {
return item.name === name ? { name: name, number: number } : item;
})
);
}
};
Look out code
import React, { useState } from "react";
export const Test = () => {
const [data, setData] = useState([]);
const [error, setError] = useState("");
const handleChange = (number, name) => {
setError("");
let isDuplicate = false;
if (!data.length) {
setData([{ name, number }]);
} else if (data.length == 2) {
const newData = data.map((val) => {
if (val.name === name) {
return { name, number };
} else {
isDuplicate = val.number === number;
}
return val;
});
setData(newData);
} else {
const existingData = data.find((val) => val.name === name);
if (existingData) {
setData([{ name, number }]);
} else {
let [user] = data;
if (user.number === number) {
isDuplicate = true;
}
setData((oldState) => {
return [...oldState, { name, number }];
});
}
}
if (isDuplicate) {
setError("Number is duplicate! Each field should have uniq number.");
}
};
return (
<div>
<div className="error">{error}</div>
<input name="user1" value="user1" readOnly={true} />
<input
name="number1"
onChange={(e) => handleChange(e.target.value, "user1")}
/>
<hr />
<input name="user2" value="user2" readOnly={true} />
<input
name="number2"
onChange={(e) => handleChange(e.target.value, "user2")}
/>
</div>
);
};
I hope this will help you. Happy coding...
You have set handleChange event on onChange event so it will call when user enter the single input and check with existing value.
suggestion:- if you want to check whole value which is user enter and compare with the existing value so please use button and click event so it will check when user click after enter the whole value
Hope this will help you. !
import { useState } from "react";
const Test = () => {
const [data, setData] = useState([]);
const [error, setError] = useState(null);
const handleChange = (number, name) => {
const exists = data.find((e) => e.name === name);
if (!exists) {
setData([...data, { name, number }]);
} else {
if (exists.number === number) {
setError("Number already exists");
} else {
if (number) {
const index = data.findIndex((e) => e.name === name);
data[index].number = number;
setData([...data]);
}
}
}
};
console.log(data, error);
return (
<div>
<input name="user1" value="user1" readOnly={true} />
<input
name="number1"
onChange={(e) => handleChange(e.target.value, "user1")}
/>
<hr />
<input name="user2" value="user2" readOnly={true} />
<input
name="number2"
onChange={(e) => handleChange(e.target.value, "user2")}
/>
</div>
);
};
This might work for you [Updated]
export const Test = () => {
const [data, setData] = useState([]);
const [error, setError] = useState(null);
const handleChange = (number, name) => {
setData((prev) => {
const newState = [...prev];
const index = prev.findIndex((entry) => entry.name === name);
if (index < 0) {
return [
...prev,
{
name,
number
}
];
} else {
const dupEntry = prev.find(
(entry) => entry.name !== name && entry.number === number
);
if (dupEntry) setError(new Error(`${dupEntry.name} already has that value`));
else newState[index].number = number;
}
return newState;
});
//validation
//if the values for number are duplicate for both field
//return an error for which input name the value is duplicate
};
return (
<div>
<input name="user1" value="user1" readOnly={true} />
<input
name="number1"
onChange={(e) => handleChange(e.target.value, "user1")}
/>
<hr />
<input name="user2" value="user2" readOnly={true} />
<input
name="number2"
onChange={(e) => handleChange(e.target.value, "user2")}
/>
</div>
);
};
I have Built a table in which the user does some calculations, but when any row gets removed the values entered appear in the row below it and the next row's value below it, and so on.
What I want is a the user removes any row it should get removed completely with the values entered and the next row should take its place with its own values.
Image 1:Here I have entered values in the First Two rows you can see in the image.
[1]: https://i.stack.imgur.com/wWUBE.png
Image 2: I deleted the first row but as you can see the value of that is still there.
[2]: https://i.stack.imgur.com/HuOuA.png
App.js
const [NewRow2, setNewRow2] = useState(data);
const [IntensificationRatio, setIntensificationRatio] = useState(0)
const [editFormData, setEditFormData] = useState({
Injection_Speed: "",
Fill_Time: "",
Peak_Inj_Press: "",
Viscosity: "",
Shear_Rate: ""
})
const [isRowId, setIsRowId] = useState(null)
const handleEditFormChange = (event) => {
event.preventDefault();
const fieldName = event.target.getAttribute("name");
const fieldValue = event.target.value;
const newFormData = { ...editFormData };
newFormData[fieldName] = fieldValue;
setEditFormData(newFormData);
}
const handleEditFormSubmit = (event) => {
event.preventDefault();
const editedValue = {
id: isRowId,
Injection_Speed: editFormData.Injection_Speed,
Fill_Time: editFormData.Fill_Time,
Peak_Inj_Press: editFormData.Peak_Inj_Press,
Viscosity: editFormData.Fill_Time * editFormData.Peak_Inj_Press * IntensificationRatio,
Shear_Rate: 1 / editFormData.Fill_Time,
}
const newValues = [...NewRow2];
const index = NewRow2.findIndex((value) => value.id === isRowId)
newValues[index] = editedValue;
setNewRow2(newValues);
}
const deleteRow2 = (id) => {
const updatedRows = [...NewRow2].filter((rowId) => {
return rowId !== id;
});
setNewRow2(updatedRows);
};
HandlEditchange and HandleEditSubmit are the two functions that deal with data entered in the row and deleteRow2 for removing the row.
Table Row's
<tr onClick={() => setId(NewRow.id)}>
<td> {rowId} </td>
<td> <input type='text' className="form-control" name="Injection_Speed" onChange={handleEditFormChange}/> </td>
<td> <input type='text' className="form-control" name="Fill_Time" onChange={handleEditFormChange}/> </td>
<td> <input type='text' className="form-control" name="Peak_Inj_Press" onChange={handleEditFormChange}/> </td>
<td> <i className="fa fa-trash viscocity_icons" onClick={() => deleteRow2(NewRow.id)}></i> </td>
</tr>
CodeSandBox Link: Rest You Can Check Over Here.
https://codesandbox.io/s/focused-gauss-lql7r?file=/src/Edit.js
There were a few issues as I identified.
handleEditFormChange was not updating NewRow2 state. You can fix it like below. Need to pass row id along with the event.
const handleEditFormChange = (event, id) => {
event.preventDefault();
setNewRow2((prevState) => {
return prevState.map((item) =>
item.id === id
? { ...item, [event.target.name]: event.target.value }
: item
);
});
};
Need to change the onChange handlers like below.
onChange={(e) => handleEditFormChange(e, NewRow.id)}
Need to bind values from the NewRow2 to each input.
value={NewRow.Injection_Speed}
same for Fill_Time, Peak_Inj_Press
deleteRow2 should be using id correctly when filtering.
const deleteRow2 = (id) => {
const updatedRows = NewRow2.filter((item) => {
return item.id !== id;
});
setNewRow2(updatedRows);
};
Pass the id of the row to be deleted in the onClick handler.
onClick={() => deleteRow2(NewRow.id)}
Code sandbox => https://codesandbox.io/s/stoic-hopper-zi8mw?file=/src/Edit.js:2738-2775
I've issues with the checkbox. I want to get the value and name field data in array format to do further processes.
Here's Checkbox:
<input type="checkbox" id="Honda" name="A1" value="Honda" onClick={CheckHandler} />
<label htmlFor="Honda" >Honda</label>
Now, I want to get the name and value field data in JSON or in an array
Like this:
{ name:"A1", value:"Honda" } //I want this.
So, I've coded like this:
import React, { Fragment, useState, useEffect } from "react";
export default function App() {
const [cars, setCars] = useState([]);
const CheckHandler = (e) => {
const value = e.target.value;
const name = e.target.name;
// setCars((prev) =>
// cars.includes(value)
// ? prev.filter((cur) => cur !== value)
// : [...prev, {[e.target.value]:`${e.target.name}`}]
// );
};
useEffect(() => {
console.log(cars);
}, [cars]);
return (
<Fragment>
<input type="checkbox" id="Honda" name="A1" value="Honda" onClick={CheckHandler}/>
<label htmlFor="Honda">Honda</label>
<br/>
<input type="checkbox" id="Mustang" name="A8" value="Mustang" onClick={CheckHandler}/>
<label htmlFor="Mustang">Mustang</label>
<br />
<input type="checkbox" id="Jeep" name="A12" value="Jeep" onClick={CheckHandler}/>
<label htmlFor="Jeep">Jeep</label>
<br />
</Fragment>
);
}
MY PROBLEM: whenever I Tick on checkbox It works fine, But when I unchecked its not returning sets from remaining items. IT's returning from all items. why ??
Any one Knows Answer ??
Sandbox https://codesandbox.io/s/late-water-piszn
Hi I fiddled a bit of your code and
const checkHandler = (e) => {
const value = e.target.value;
const name = e.target.name;
setCars((prev) =>
cars.find(ch => ch[value] === name)
? prev.filter((cur) => cur[value] !== name)
: [...prev, { [e.target.value]: `${e.target.name}` }]
);
};
update your method like this and it's working.
Here is the updated function I made for you answer
const CheckHandler = (e) => {
console.log(cars);
const value = e.target.value;
const name = e.target.name;
var found = false;
for (var i = 0; i < cars.length; i++) {
if (cars[i][value] === name) {
found = true;
break;
}
}
setCars((prev) =>
found
? prev.filter((cur) => cur[value] !== name)
: [...prev, { [value]: name }]
);
};
Here is the sandbox