React Multi Column Radio - javascript

I'm implementing a worker shift scheduler in React. See screenshot below
I receive the following employee object from the backend:
[{
"employeeId": "id",
"name": "bob"
},{
"employeeId": "id",
"name": "steve",
}]
I also receive the following shifts object from the backend:
"shifts": [
{
"shiftStart": "03:00",
"shiftEnd": "07:00"
},
{
"shiftStart": "16:00",
"shiftEnd": "24:00"
},
{
"shiftStart": "18:00",
"shiftEnd": "00:00"
},
{
"shiftStart": "12:10",
"shiftEnd": "17:10"
}
]
I'm using Radio component from ant-design. My code is the following:
class PlanningShiftManagement extends Component {
constructor(props) {
super(props);
this.state = {
employees: [],
shifts: [],
employeeshifts: []
}
this._populateTableData = this._populateTableData.bind(this)
this._handleChange = this._handleChange.bind(this)
}
_populateTableData(){
return this.state.employees.map((employee,index) => {
let employeecheckbox = this.state.shifts.map((shift) => {
return(
<RadioButton value={[`${shift.shiftStart}`, `${shift.shiftEnd}`, `${employee.key}`]} key={`${employee.title}-${shift.shiftStart}-${shift.shiftEnd}`}>{shift.shiftStart} - {shift.shiftEnd}</RadioButton>
)
});
return(
<tr key={employee.title}>
<td>{employee.title}</td>
<td>
<RadioGroup onChange={(e) => this.handleChange(e.target.value)}>
{employeecheckbox}
</RadioGroup>
</td>
</tr>
)
})
}
_handleChange() {
}
render() {
return(
<div>
<table>
<thead>
<tr>
<th>Employee Name</th>
<th>Shifts</th>
</tr>
</thead>
<tbody>
{this._populateTableData()}
</tbody>
</table>
</div>
);
}
Now, I'm struggli with how to work on the _handleChange() so that I can store the object in the employeeshifts state so I can send back to the backend.
[{
"shiftStart": "20170313 10:00",
"shiftEnd": "20170313 17:00",
"employeeId": "id"
},
{
"shiftStart": "20170313 10:00",
"shiftEnd": "20170313 17:00",
"employeeId": "id"
}]
Since each employee can only be assigned to one shift, it's a Radio element, so using .push() is not going to work.

You can pass employeeId to handleChange:
<RadioGroup onChange={(e) => this.handleChange(e.target.value, employee.id)}>
Shape your employeeshifts as a object:
{
"employeeId": {
"shiftStart": "20170313 10:00",
"shiftEnd": "20170313 17:00",
},
}
And transform employeeshifts to array before send to server.

Related

How to iterate json object field in react

There is a JSON for categories with the following structure
[
{
"category": "Mobiles",
"sub": [
{
"name": "Apple"
},
{
"name": "Samsung"
}
]
},
{
"category": "Televisions",
"sub": [
{
"name": "Lg"
},
{
"name": "Sony"
}
]
}
]
First i load data from backend to a variable called categories (On the backend side im using expressjs and pass data with res.json(JSON.parse(fs.readFileSync('categories.json')))
I want to iterate through categories sub category with
{categories.map(function (category, i) {
return (
<>
<h6 Key={i}>{category.category}</h6> //For example: <h6>Mobiles</h6>
<>... [logic to iterate the current category's sub categories] ...</> //For example: <p>Apple</p> <p>Samsung</p>
</>
);
})}
I tried to use a second map on category.sub like category.sub.map((s,j)=><p Key={j}>{s.name}</p>) but unfortunely i can't get it work, and I can't describe my problem to Google in English so it can be an easy answer and i am the big L
Any help?
Thanks
Try this, uncomment out the console.log to verify data if screen is white.
return (
<>
{categories.map(function (category, i) {
// console.log(category.category );
// console.log(category.sub );
return (
<>
<h6 key={i}>{category.category}</h6>
<>
{category.sub.map(function (sub, j) {
// console.log(category.category + '' + sub.name);
return <p key={j}> {sub.name}</p>;
})}
</>
</>
);
})}
</>
);
Data:
let categories = [
{
category: 'Mobiles',
sub: [
{
name: 'Apple',
},
{
name: 'Samsung',
},
],
},
{
category: 'Televisions',
sub: [
{
name: 'Lg',
},
{
name: 'Sony',
},
],
},
];

Two select dropdowns list - the second dropdown output will depend on the selected first select dropdown list

I'm using reactJS and I have here the choices for two select dropdown list names categories and items
constructor(props) {
super(props)
}
this.state = {
categories: [
{
"id": 1,
"category_name": "Powertools"
},
{
"id": 2,
"category_name": "Consumables"
}
],
items: [
{
"id": 1,
"item_name": "Grinder",
"category_id": 1
},
{
"id": 2,
"item_name": "Drill",
"category_id": 1
},
{
"id": 3,
"item_name": "Welding rod",
"category_id": 2
},
],
};
}
I'm trying to output the items dropdown list choices depending on the selected value of the categories dropdown list.
For example:
Dropdown 1 Selected Value: Powertools
Dropdown 2 choices: Grinder, Drill
Another example:
Dropdown 1 Selected Value: Consumables
Dropdown 2 choices: Welding rod
As of now, I've found this code snippet that does the thing that I want. Unfortunately, it's in a function component and I'm trying to convert it to a class component but with no success.
I was guided by Sir. Rajesh and I were able to solve the problem.
Here's the code
import { Component } from 'react';
class Testing2 extends Component {
constructor(props) {
super(props)
this.state = {
categories: [
{
"id": 1,
"category_name": "Powertools"
},
{
"id": 2,
"category_name": "Consumables"
}
],
items: [
{
"id": 1,
"item_name": "Grinder",
"category_id": 1
},
{
"id": 2,
"item_name": "Drill",
"category_id": 1
},
{
"id": 3,
"item_name": "Welding rod",
"category_id": 2
},
],
form_transactions: [],
filteredItems: []
};
}
handleChange_transactions = event => {
const { name, value } = event.target;
let form = this.state.form_transactions;
form[name] = value;
this.setState({ form });
const state_filteredItemNames = this.state.items.filter(element => element.category_id == value);
this.setState({ filteredItems: state_filteredItemNames });
}
render() {
//list categories
const list_categories = this.state.categories.map(data =>
<option
value={data.id}
key={data.id}
>
{data.category_name}
</option>
)
const list_items = this.state.filteredItems.map(data =>
<option
value={data.id}
key={data.id}
>
{data.item_name}
</option>
)
return (
<>
<form>
<div>
<select onChange={this.handleChange_transactions}>
{list_categories}
</select>
</div>
<div>
<select>
{list_items}
</select>
</div >
</form >
</>
)
}
}
export default Testing2;
Output:

Join multiple array maps in ReactJs

im new in reactjs, is that possible to do in reactjs,like mysql inner join, here my sample code.
{dataCustomer.map((customer) => (
<tr>
<td>{customer.custid}</td>
<td>{customer.custname}</td>
<td>{customer.mailingaddr}</td>
<td>{customer.stateid}</td>
<td>{customer.districtid}</td>
<td>{customer.postcode}</td>
</tr>
))}
{dataState.map((state) => (
<tr>
<td>{state.stateid}</td>
<td>{state.statename}</td>
</tr>
))}
how to join array map data from customer.stateid & state.stateid to call state.statename without use SQL syntax?..Is that possible?
This should work
let joinedData=[]
dataCustomer.forEach((customer)=>{
let st= dataState.filter((state)=>state.stateid===customer.stateid);
if(st.length>0)
joinedData.push({...customer,statename:st[0].statename})
})
joinedData array will now contain the customer objects with the corresponding statename and you can use it as
{joinedData.map((customer) => (
<tr>
<td>{customer.custid}</td>
<td>{customer.custname}</td>
<td>{customer.mailingaddr}</td>
<td>{customer.stateid}</td>
<td>{customer.districtid}</td>
<td>{customer.postcode}</td>
<td>{customer.statename}</td>
</tr>
))}
It is not exactly the same but I think the function below that I wrote can help you:
let customers = [{
name: "Foo",
stateid: 1
},
{
name: "Boo",
stateid: 3
},
{
name: "Goo",
stateid: 2
},
{
name: "Zoo",
stateid: 2
},
];
let states = [{
name: "State1",
id: 1
},
{
name: "State2",
id: 2
},
];
function join(customers, states, column1, column2) {
return customers.map(customer => {
states.forEach(state => {
if (customer[column1] === state[column2]) {
customer["state"] = { ...state };
}
})
return customer;
})
}
console.log(join(customers, states, "stateid", "id"))
Note that column1 and column2 parameters are the properties you are joining on.

React find and get elements on object array

In my project I have a state object called products.
{
"productName": "flute",
"batches": [{
"_id": {...},
"batchNo": "flu1",
"expDate": "10/2020",
}, {
"_id": {...},
"batchNo": "flu2",
"expDate": "11/2020",
}],
}
mongoose schema of it is
productName:{
type:String
},
batches:[{
batchNo:{
type:String
},
expDate:{
type:String
},
}]
inside the batches array i want to get data only from a specific batch ID(this.props.batchID)
I tried below code but didn't work.
how can I approach it????
getBatchdetails(){
this.state.products.batches.map(function(object,i){
console.log(object.batchNo);
if(object._id==this.props.obj.batchID){
console.log(object.batchNo);
return object.batchNo;
}
});
}
render() {
return (
<tr>
<td>
{this.state.products.productName}
</td>
<td>
{this.getBatchdetails}
</td>
</tr>
)
}
You can use .find() for that purpose. I made up a fake batchID but you can change to your value.
Try the following:
const batchID = 'id002';
const products = {
"productName": "flute",
"batches": [{
"_id": 'id001',
"batchNo": "flu1",
"expDate": "10/2020",
}, {
"_id": 'id002',
"batchNo": "flu2",
"expDate": "11/2020",
}],
};
const result = products.batches.find(e => e._id === batchID);
console.log(result);
console.log(result.batchNo); // or you can return a specific property
I hope this helps!

How to iterate and render nested objects/arrays from data in React?

I am using react (Im not too experienced with it) and want to render data, the problem is everything is nested - with objects and arrays. I have tried so many different things but its just not working.
For example: the data is flight info. For a round trip I have a nested array for each connecting flight and the same back. For other things like departure airport-its again nested differently. Since I want to display multiple flights, I have to iterate through all that when I render the date but I don't know how to. I tried to find something online and have been pretty much staring at my code for a while and I am pretty much lost. If anyone could help, it would be great. I also added the json with the data (I removed some key value pair and left those which are important for the nested/different data structure). Thanks a lot!
data:
{
"PricedItineraries": [{
"AirItinerary": {
"OriginDestinationOptions": {
"OriginDestinationOption": [{
"FlightSegment": [{
"DepartureAirport": {
"LocationCode": "JFK"
},
"ArrivalAirport": {
"LocationCode": "MSP"
},
"DepartureDateTime": "2018-01-07T07:00:00",
"OperatingAirline": {
"FlightNumber": 111,
"Code": "AA"
}
},
{
"DepartureAirport": {
"LocationCode": "MSP"
},
"ArrivalAirport": {
"LocationCode": "LAX"
},
"DepartureDateTime": "2018-01-07T10:05:00",
"OperatingAirline": {
"FlightNumber": 444,
"Code": "SY"
}
}],
"ElapsedTime": 485
},
// ... same structure below for trip back ...
{
"FlightSegment": [{
"DepartureAirport": {
"LocationCode": "LAX"
},
"DepartureTimeZone": {
"GMTOffset": -8
}
},
{
"DepartureAirport": {
"LocationCode": "SEA"
},
"DepartureTimeZone": {
"GMTOffset": -8
}
}],
"ElapsedTime": 745
}]
},
"DirectionInd": "Return"
},
"AirItineraryPricingInfo": {
"PTC_FareBreakdowns": {
"PTC_FareBreakdown": {
"PassengerTypeQuantity": {
"Quantity": 1,
"Code": "ADT"
},
"Endorsements": {
"NonRefundableIndicator": true
}
}
},
"FareInfos": {
"FareInfo": [{
"TPA_Extensions": {
"SeatsRemaining": {
"BelowMin": false,
"Number": 4
}
}
}
}]
},
"ItinTotalFare": {
"TotalFare": {
"CurrencyCode": "USD",
"DecimalPlaces": 2,
"Amount": 341.61
},
"Taxes": {
"Tax": [{
"CurrencyCode": "USD",
"DecimalPlaces": 2,
"TaxCode": "TOTALTAX",
"Amount": 66.25
}]
}
}
},
"TicketingInfo": {
"TicketType": "eTicket"
}
}, {
"AirItinerary": {
..same structure again...repeats multiple times
React Component:
class Search extends React.Component {
constructor(props){
super(props);
this.state={
origin:'',
destination:''
...
// flightinfo
airlineCodeToDestination:[],
airport:[],
departureTime:[],
arivalTime:[],
totalDuration:[],
price:[],
flightInfo:[]
}
this.handleInput=this.handleInput.bind(this);
this.testing=this.testing.bind(this);
}
testing(e){
this.setState({
[e.target.name]:e.target.value
})
}
handleInput(e){
e.preventDefault();
regularSearchData(this.state.origin, this.state.destination, this.state.departuredate, this.state.returndate)
.then(function(response){
return response.data.PricedItineraries;
})
.then(res => {
let response=res,
allFares=[],
airlineCode=[],
airport=[],
x=[],
departureTime=[],
arivalTime=[],
totalDuration=[];
response.map(function(item){
//this here are just a few of my tries
allFares.push(item.AirItineraryPricingInfo.ItinTotalFare.TotalFare.Amount);
x.push(item.AirItinerary.OriginDestinationOptions.OriginDestinationOption);
airlineCode.push(item.AirItinerary.OriginDestinationOptions.OriginDestinationOption[0].FlightSegment[0].MarketingAirline.Code);
});
this.setState({
price:allFares,
airlineCodeToDestination:airlineCode,
flightInfo:x
})
})
}
render () {
const flights = this.state.flightInfo.map((item, i) => {
return (
<div>
<div key={i}> {item} </div>
</div>);
});
return (
<div>
{flights}
<form onSubmit={this.handleInput}>
<input type="text" name="origin" value={this.state.origin} onChange={this.testing} />
<input type="text" name="destination" value={this.state.destination} onChange={this.testing}/>
<input type="date" name="departuredate" value={this.state.departuredate} onChange={this.testing} />
<input type="date" name="returndate" value={this.state.returndate} onChange={this.testing} />
<input type="submit" value="Submit" />
</form>
</div>
)
}
}
export default Search;
In your handleInput method, you are creating new arrays and adding data to them.Then you are calling setState to set these new arrays as your new state, which will result in the old state getting removed and only the new arrays showing up.
If you want your old data to persist, you would need to change the declaration of the variables in the code as follows:
....
allFares=[...this.state.allFares],
airlineCode=[...this.state.airlineCode],
....
This will create copies of the exiting arrays from your state and when you push your new item in them and then call setState to set them, you will not lose your existing data.

Categories