Issue
I'm working on a React application where I have a form with a select dropdown. When the user clicks on the 'Edit' button, I want the value of the 'uom' field of the selected product record to be set as the default value in the select dropdown. Additionally, I want to dynamically append the remaining values from the 'UnitMasterData' array after the default value. Currently, my code populates the select dropdown with all values from 'UnitMasterData' without setting a default value. How can I achieve this functionality?
I am attaching my code below -
import React, { useEffect, useState } from 'react';
import { useNavigate, generatePath, Link, BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { Navbar, Nav, NavDropdown } from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import axios from 'axios';
import Swal from 'sweetalert2';
import withReactContent from 'sweetalert2-react-content';
import DataTable from 'react-data-table-component';
import { useParams } from 'react-router';
import FormRange from 'react-bootstrap/esm/FormRange';
function App() {
const MySwal = withReactContent(Swal)
const [formData, setFormData] = useState({
productid1: '',
product_name1: '',
product_category1: '',
uom1: '',
purchase_rate1: '',
sales_rate1: '',
mrp1: '',
opqty1: '',
clqty1: '',
status1: '',
product_id_hidden1: '',
operationtype1: 'Add Product'
});
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value,
});
};
const [UnitMasterData, setUnitMasterData] = useState([]);
//2) using axios
useEffect(() => {
// Fetch data from the specified URL
axios.get('http://localhost/api_link/codeigniter_part/public/UnitMaster')
.then((response) => {
// Access the response data directly using response.data
setUnitMasterData(response.data.UnitMasterData);
})
.catch((error) => console.error('Error fetching data:', error));
}, []);
function getdatabyrecordarray(record) {
// console.log(record.customer_mp_id);
setFormData({
productid1: record.productid,
product_name1: record.product_name,
product_category1: record.product_category,
uom1: record.uom,
purchase_rate1: record.purchase_rate,
sales_rate1: record.sales_rate,
mrp1: record.mrp,
opqty1: record.opqty,
clqty1: record.clqty,
status1: record.status,
operationtype1: 'Edit Customer'
});
}
return (
<div className="container" style={{color: '#4229cb', fontWeight: '500' ,backgroundColor: 'rgb(255 255 255)'}} >
<h1 style={{ color: 'white', backgroundColor: '#4229cb', padding: '5px' }} className="text-center"> Product Master</h1>
<nav style={{ marginTop: -8 }} className="navbar navbar-expand-lg navbar-light bg-light">
<div className="container-fluid">
<a className="navbar-brand" href="#">Home</a>
</div>
</nav>
<div className="col-md-4">
<label htmlFor="id-uom" className="form-label">UOM</label>
<select className="form-select" id="id-uom" name="uom" value = {formData.uom1} onChange = {handleInputChange} >
{UnitMasterData.map((umd) => (
<option
value={umd.unitname}
>
{umd.unitname}
</option>
))}
</select>
</div>
</div>
<div className="row mt-4">
<div className="col-md-12 table-responsive-xl">
<table className="table table-bordered">
<thead>
<tr>
<th>Prod. Code</th>
<th>Production Name</th>
<th>Category</th>
<th>UOM</th>
<th>Op Qty</th>
<th>Cl Qty</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{ProductMasterData.map((p) => (
<tr>
<td>{p.productid}</td>
<td>{p.product_name}</td>
<td>{p.product_category}</td>
<td>{p.uom}</td>
<td>{p.opqty}</td>
<td>{p.clqty}</td>
<td>
<button onClick={() => getdatabyrecordarray(p)} className="btn btn-info btn-sm">Edit</button>
{/* <Link to={generatePath(routes.customerDetails, { customerid1: c.customer_mp_id })} className="btn btn-success btn-sm">edit</Link> */}
<button onClick={(event) => confirmDelete(event, p.productid)} className="btn btn-danger btn-sm ml-1">
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
);
}
export default App;
While addressing this concern and considering my limited experience with React, I have tried mapping through the 'UnitMasterData' array and populating the select dropdown using the map function. However, I'm unable to set the default value for the 'uom' field of the selected product record. I expected the select dropdown to display the 'uom' value of the selected product record at the top and the remaining values from 'UnitMasterData' below it. I also attempted to resolve the issue by adding a value attribute to the select box. While this successfully displays the uom value of the selected record at the top, it prevents the selection of any other option from the dropdown.
Solution
I think you are just missing providing the uom
value of the currently selected record as a selectable option.
You can't just use the formData.uom1
value because you are selecting new values and updating the form data, which would constantly change the first option to whatever else is being selected from the list (when a new record isn't being selected).
- Add a new state to hold the initial
uom
value - Update the uom default value when a record is selected
- Conditionally render this default uom as the first option
Example:
const [defaultUom, setDefaultUom] = useState();
...
function getdatabyrecordarray(record) {
setDefaultUom(record.uom);
setFormData({
productid1: record.productid,
product_name1: record.product_name,
product_category1: record.product_category,
uom1: record.uom,
purchase_rate1: record.purchase_rate,
sales_rate1: record.sales_rate,
mrp1: record.mrp,
opqty1: record.opqty,
clqty1: record.clqty,
status1: record.status,
operationtype1: 'Edit Customer'
});
}
...
<select
className="form-select"
id="id-uom"
name="uom1" // <-- should match `formData.uom1` property
value={formData.uom1}
onChange={handleInputChange}
>
{/* uom option from selected record when available */}
{defaultUom && (
<option value={defaultUom}>
{defaultUom}
</option>
)}
{/* dynamically fetched options */}
{UnitMasterData.map((umd) => (
<option key={umd.unitname} value={umd.unitname}>
{umd.unitname}
</option>
))}
</select>
Answered By - Drew Reese
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.