Reputation: 2733
This is for a react project I am working on. need help with table. I have a table for employees where each row has a different employee and I input the days for each employee and the other values gets calculated based on the number of days. so, let's say pf, esi, amount payable gets calculated based on that.
Now, there is a way to do those calculations. for each row we could setup different variables like for row1, employee1, we could do days1 and the pf1, esi1, amtPayable1 would get calculated accordingly and then I could do the same for row2. so it would be days2 and the pf2, esi2, amtPayable2 would get calculated accordingly. but I dont think this is the best way to do this. what if there are a 100 rows? would I create these variables 100 times?? and the code wont be dynamic anymore.
so, what is the best way to do this?
I havent written the full code yet, because I was going to write it like this but saw the problem with this approach and therefore am asking about the correct and better way to do this.
But still, people want to see some relevant code to better understand what I mean, so here's the relevant code This code is for 3 rows i.e. 3 employees, which means I may have to create days100, pf100, esi100, amtPayable100 if there are a 100 employees.
this made me think that it was not the best way and therfore I thought there's got to be a better way.
anyways, here's the code
let days1 = e.target.value;
let pf1 = days1*(12/100);
let esi1 = pf1*0.25;
let amtPayable1 = pf1 + es1 + 100;
let days2 = e.target.value;
let pf2 = days2*(12/100);
let esi2 = pf2*0.25;
let amtPayable2 = pf2 + es2 + 100;
let days3 = e.target.value;
let pf3 = days3*(12/100);
let esi3 = pf3*0.25;
let amtPayable3 = pf3 + es3 + 100;
after getting the values for all the variables above, I will be using it as data for a different table. something like this:
const data = [{
key: '1',
name: 'Jerry gold',
days: days1,
amtpayable:amtPayable1,
pf:pf1,
esi:esi1,
}, {
key: '2',
name: 'Arnold Smith',
days: days2,
amtpayable:amtPayable2,
pf:pf2,
esi:esi2,
},
{
key: '3',
name: 'Baker',
days: days3,
amtpayable:amtPayable3,
pf:pf3,
esi:esi3,
}
];
so, you see there is a lot of duplication going on here and I want a way to avoid that.
@Rafael , it's not an ajax call. everything is getting calculated based on number of days. so, someone, say the employer, inputs the number of days each employee was present and based on that input the other values are calculated and the data is provided to a different table.
Upvotes: 0
Views: 79
Reputation: 7746
This question is quite broad, but after chat discussion, it sounds like you're unsure how to reduce duplication using hard-coded employee names that will eventually be retrieved from a database.
Here is an example of using an employee array that populates a table and updates the pf, esi, and amount payable according to changes per employee days:
let employees = [ 'Jerry gold', 'Arnold Smith', 'Baker' ];
let tbody = document.getElementById('list');
let tbodyHTML = '';
employees.forEach(insertRow);
tbody.innerHTML = tbodyHTML;
function insertRow(employeeName) {
tbodyHTML += `
<tr class="employee">
<th scope="row" class="name" style="text-align: left">${employeeName}</th>
<td class="pf">--</td>
<td class="esi">--</td>
<td class="payable">--</td>
<td class="days">
<input type="number" min="0" onchange="updateEmployeeData(this)">
</td>
</tr>
`;
}
function updateEmployeeData(aNumberInput) {
let days = parseInt(aNumberInput.value);
let tr = aNumberInput.parentNode.parentNode;
let pf = days * 12 / 100;
let esi = pf * 0.25;
let payable = pf + esi + 100;
const HUNDREDTHS_PLACE = 2;
let payable_td = tr.querySelector('.payable');
tr.querySelector('.pf').innerHTML = pf.toFixed(HUNDREDTHS_PLACE);
tr.querySelector('.esi').innerHTML = esi.toFixed(HUNDREDTHS_PLACE);
payable_td.innerHTML = '$' + payable.toFixed(HUNDREDTHS_PLACE);
if (payable <= 100.15) {
payable_td.dataset.range = 'low';
} else if (payable > 100.15 && payable < 100.50) {
payable_td.dataset.range = 'med';
} else if (payable > 100.50) {
payable_td.dataset.range = 'high';
} else {
delete payable_td.dataset.range;
}
}
#employeeTable tbody>tr:nth-child(odd) {
background-color: lightgrey;
}
#employeeTable th,
td {
padding: 0.5em;
text-align: center;
}
#employeeTable th {
text-transform: uppercase;
}
#employeeTable caption {
font-style: italic;
color: grey;
}
#employeeTable td.payable {
transition: background-color 1s;
}
#employeeTable td.payable[data-range="low"] {
background-color: red;
}
#employeeTable td.payable[data-range="med"] {
background-color: yellow;
}
#employeeTable td.payable[data-range="high"] {
background-color: lightgreen;
}
<table id="employeeTable">
<colgroup class="name_col"></colgroup>
<caption>employee data</caption>
<thead>
<tr>
<th scope="col">name</th>
<th scope="col">pf</th>
<th scope="col">esi</th>
<th scope="col">payable</th>
<th scope="col">days</th>
</tr>
</thead>
<tbody id="list">
</tbody>
</table>
Upvotes: 1
Reputation: 11720
Here's the basics of how I would go about it. Use classes with properties instead of raw data objects. Create properties for the calculated fields of a person. Pass the objects to React components that know how to display the fields of the Person nicely. A Table component can create a Row for each person, for example.
class Person {
constructor(properties) {
Object.assign(this, properties);
}
get pf() {
return this.days * 12 / 100;
}
get esi() {
return this.pf * 0.25;
}
get amtPayable() {
return this.pf + this.esi + 100;
}
}
let MyRow = (props) => (
<tr>
<td>{props.item.name}</td>
<td>{props.item.days}</td>
<td>{props.item.pf}</td>
<td>{props.item.esi}</td>
<td>{props.item.amtPayable}</td>
</tr>
);
let MyTable = (props) => (
<table>
<tr>
<th>Name</th>
<th>Days</th>
<th>pf</th>
<th>esi</th>
<th>amtPayable</th>
</tr>
{props.data.map(item => <MyRow item={item} />)}
</table>
);
const data = [
new Person({
key: '1',
name: 'Jerry gold',
days: 101
}),
new Person({
key: '2',
name: 'Arnold Smith',
days: 102
}),
new Person({
key: '3',
name: 'Baker',
days: 103
})
];
// Render it
ReactDOM.render(
<MyTable data={data} />,
document.getElementById("react")
);
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid black;
padding: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Upvotes: 1