Reactjs Onchange input for function - reactjs

I have a table with multiple inputs and want my second input on each row to change the number next to it with a formula of the first row: 5-DPS(from input). I want the number to change immediately after the DPS value changes.
Is there an easy-to-understand way for someone new to react?
This is my code:
import React, { useState, useEffect, useRef } from "react";
import "./index.css";
import Champions from "./components/Champions";
const Calculator = () => {
let DPS = React.createRef();
let TM = React.createRef();
let CCS = React.createRef();
let ME = React.createRef();
let UD = React.createRef();
const Burst = 5 - DPS;
const Sustain = 5 - TM;
const Hard = 5 - CCS;
const Reposition = 5 - ME;
const Offensive = 5 - UD;
//const [DPS, setDPS] = useState("");
return (
<table border={1} className="inlineTable" id="table2">
<tbody>
<tr>
<td />
<td>Pirmenybė</td>
<td>ŽPS</td>
<td>Staigus šaudymas</td>
</tr>
<tr>
<td>Žala</td>
<td>
<input type="number" id="DP" />
</td>
<td>
<input
type="number"
name="DPS"
id="DPS"
ref={DPS}
// onChange={(e) => setDPS(e.target.value)}
/>
</td>
<td>{Burst}</td>
</tr>
<tr>
<td />
<td>Pirmenybė</td>
<td>Sušvelninimas</td>
<td>Išlaikymas</td>
</tr>
<tr>
<td>Tvirtumas</td>
<td>
<input type="number" id="tP" />
</td>
<td>
{" "}
<input
type="number"
name="TM"
id="TM"
ref={TM}
//onChange={QuickChange.bind(this)}
/>
</td>
<td>Sustain</td>
</tr>
<tr>
<td />
<td>Pirmenybė</td>
<td>Minkštas</td>
<td>kietas</td>
</tr>
<tr>
<td>Minios valdymas</td>
<td>
<input type="number" id="CCP" />
</td>
<td>
<input
type="number"
name="CCS"
id="CCS"
ref={CCS}
// onChange={QuickChange.bind(this)}
/>
</td>
<td>Hard</td>
</tr>
<tr>
<td />
<td>Pirmenybė</td>
<td>Užvedimas</td>
<td>Perdėlioti</td>
</tr>
<tr>
<td>Mobilumas</td>
<td>
<input type="number" id="MP" />
</td>
<td>
<input
type="number"
name="ME"
id="ME"
ref={ME}
// onChange={QuickChange.bind(this)}
/>
</td>
<td>Reposition</td>
</tr>
<tr>
<td />
<td>Pirmenybė</td>
<td>Gynybinis</td>
<td>Agresyvus</td>
</tr>
<tr>
<td>Naudingumas</td>
<td>
<input type="number" id="UP" />
</td>
<td>
{" "}
<input
type="number"
name="UD"
id="UD"
ref={UD}
//onChange={QuickChange.bind(this)}
/>
</td>
<td>Offensive</td>
</tr>
</tbody>
</table>
);
};
export default Calculator;

You can show the value for the input with value of the state. When this value changes, it will be updated with the setDPS function.
const [DPS, setDPS] = useState(0);
<input
type="number"
name="DPS"
value={DPS}
onChange={(e) => setDPS(e.target.value)}
/>
If you want to depend this value and set other values, you can use a useEffect. When the value of DPS changes (inside the dependency array), the effect will run and update the value for the burst.
const [burst, setBurst] = useState();
useEffect(() => {
setBurst(5 - DPS)
}, [DPS])
Or you can set all values when DPS changes directly in the onChange
<input
type="number"
name="DPS"
value={DPS}
onChange={(e) => {
setDPS(e.target.value);
setBurst(5 - e.target.value);
}}
/>

Related

Autocomplete feature shows [Object object]

i am trying to implement auto complete feature in react JS.
it shows the autocomplete box, but shows [Object Object] for some reason, I have no idea why. I want it to show the email in the search box so as to implement autocomplete feature.
I would like to share my source code
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import './Home.css'
const SearchRepo = () => {
const [users, setUsers] = useState([]);
const [text, setText] = useState('');
const [suggestions, setSuggestions] = useState([]);
const onChangeHandler = (text) =>{
//setSeachUser(e.target.value);
let matches = []
if(text.length > 0){
matches = users.filter(user =>{
const regex = new RegExp(`${text}`,"gi");
return user.email.match(regex);
})
}
setSuggestions(matches);
setText(text);
}
useEffect(()=>{
const loadUsers = async()=>{
const response = await axios.get('https://reqres.in/api/users');
setUsers(response.data.data);
}
loadUsers();
},[])
return (
<div align="center">
<table border="0" width="100%" height="212px">
<tr>
<td bgcolor="#C0C0C0" height="55px"> <b>
<font face="Berlin Sans FB" color="#333333">Github Repo Search</font></b></td>
</tr>
<tr>
<td> </td>
</tr>
<tr>
<td>
<div align="center">
<table border="0" width="100%" className="SearchTable">
<div align="center">
<input type="text" placeholder=" Enter github repo ID / username" name="T1" size="88" value={text} onChange={e =>onChangeHandler(e.target.value)} className="inputArea" />
{suggestions && suggestions.map((suggestion,i)=>{
<div key={i}>{suggestion.email}</div>
})}
</div>
</table>
</div>
<div align="center">
<table border="0" width="100%" className="reposresultsTable">
<div align="left">
<tr>
<td bgcolor="#FFFFFF"> <b>
<font face="Verdana" size="2" className="labeltxt"><h3> Repos</h3></font></b>
</td>
</tr>
</div>
<div align="left">
<tr>
<td height="23"> <b>
<font face="Verdana" size="2">
<a href="https://test-restapi2.herokuapp.com/employees/">
mmmmmmmm</a></font></b></td>
</tr>
</div>
</table>
</div>
</td>
</tr>
</table>
</div>
);
}
export default SearchRepo;
why would it be showing that Object rather than the email? Please is there something i am not getting rightly?
Thanks guys, the issue was with a Curly brace. I have been able to resolve it. Thanks everyone.
Changing from this :
<div align="center">
<input type="text" placeholder=" Enter github repo ID / username" name="T1" size="88" value={text} onChange={e =>onChangeHandler(e.target.value)} className="inputArea" />
{suggestions && suggestions.map((suggestion,i)=>{
<div key={i}>{suggestion.email}</div>
})}
</div>
to this
<div align="center">
<input type="text" placeholder=" Enter github repo ID / username" name="T1" size="88" value={text} onChange={e =>onChangeHandler(e.target.value)} className="inputArea" />
{suggestions && suggestions.map((suggestion,i)=>
<div key={i}>{suggestion.email}</div>
)}
</div>

How to map a nested array in react

Ok. I am super lost here. I am attempting to return an a value from a nested array of objects. Here is what the database looks like.
Each object returns an array of staff as seen in this console log.
I cannot for the life of me display both names out of the array. I used the .flatMap() function to extract the data from the array, but when I go to render it in the component only the first name shows. Here is my codebase. Right now I am just console logging the data using .flatMap()
import React, { Fragment, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Table } from 'react-bootstrap';
import Moment from 'react-moment';
import Button from '../components/Button';
import ActivitySummary from '../components/ActivitySummary';
import { projectsInfoDetails } from '../actions/projectInfoActions';
import { projectContacts } from '../actions/projectContactActions';
import { projectStaff } from '../actions/accountableStaffActions';
import SectionHeader from '../components/SectionHeader';
import Loader from '../components/Loader';
import Message from '../components/Message';
const ProjectScreen = ({ match }) => {
const dispatch = useDispatch();
const projectInfoDetails = useSelector(state => state.projectInfoDetails);
const { loading, error, projects } = projectInfoDetails;
const contactDetails = useSelector(state => state.projectContactDetails);
const { projectContact } = contactDetails;
const projectAccountableStaff = useSelector(state => state.projectStaff);
const { accountableProjectStaff } = projectAccountableStaff;
useEffect(() => {
dispatch(projectsInfoDetails(match.params.id));
dispatch(projectContacts(match.params.id));
dispatch(projectStaff(match.params.id));
}, [dispatch, match]);
const lastName = projectContact.map(l => l.contact.lastName);
const firstName = projectContact.map(f => f.contact.firstName);
const accountableStaffLastNames = accountableProjectStaff.flatMap(
({ accountableStaff }) => accountableStaff.map(data => data.lastName)
);
console.log(accountableStaffLastNames);
return (
<Fragment>
<div>
<SectionHeader sectionName='Project' />
<Button buttonName='Edit Project' />
</div>
{loading ? (
<Loader />
) : error ? (
<Message variant='danger'>{error}</Message>
) : (
<div style={{ backgroundColor: '#F8F8F8' }}>
<Table className='borderless'>
<tbody>
<tr>
<td>
<strong>Name: </strong>
{projects.name}
</td>
<td>
<strong>Status: </strong>
{projects.status}
</td>
</tr>
<tr>
<td>
<strong>State: </strong>
{projects.state}
</td>
<td>
<strong>County: </strong>
{projects.county}
</td>
</tr>
<tr>
<td>
<strong>Congressional District: </strong>
{projects.district}
</td>
<td>
<strong>Type: </strong>
{projects.type}
</td>
</tr>
<tr>
<td>
<strong>Funding Source: </strong>
<br />
{`${projects.fundingSource} ${projects.fundingSourceName}`}
</td>
<td>
<strong>Funding Source Goal: </strong>
<br />
{projects.fundingSourceGoal}
</td>
<td>
<strong>Start Date: </strong>
<br />
<Moment format='MM/DD/YYYY'>{projects.startDate}</Moment>
</td>
<td>
<strong>End Date: </strong>
<br />
{projects.endDate === null ? (
''
) : (
<Moment format='MM/DD/YYYY'>{projects.endDate}</Moment>
)}
</td>
<td>
<strong>Funding Percent: </strong>
<br />
{projects.fundingPercent}
</td>
</tr>
<tr>
<td>
<strong>Contact: </strong>
{firstName} {lastName}
</td>
</tr>
<tr>
<td>
<strong>Start Date: </strong>
<Moment format='MM/DD/YYYY'>
{projects.projectStartDate}
</Moment>
</td>
<td>
<strong>End Date: </strong>
{projects.projectEndDate === null ? (
''
) : (
<Moment format='MM/DD/YYYY'>
{projects.projectEndDate}
</Moment>
)}
</td>
</tr>
<tr>
<td colSpan='5'>
<strong>Goals and Objectives: </strong>
{projects.goalsAndObjectives}
</td>
</tr>
<tr>
<td colSpan='5'>
<strong>Success Description: </strong>
{projects.successDescription}
</td>
</tr>
<tr>
<td>
<strong>Accountable Staff: </strong>
</td>
</tr>
<tr>
<td>
<strong>Project ID: </strong>
{projects.projectId}
</td>
</tr>
</tbody>
</Table>
</div>
)}
<ActivitySummary />
</Fragment>
);
};
export default ProjectScreen;

Apply a class to table row when checkbox is checked using states

I have a simple table in parent component where I pass props to child in order to create rows. If the checkbox is checked I want to apply a style to the row and if its unchecked I want to remove it.All checked rows should have the styling. How can I implement this using react states system?
child component
...
render() {
return (
<tr>
<td>
<input className="action-check" type="checkbox"/>
</td>
<td>
<ButtonGroup />
</td>
<td>{this.props.name}</td>
<td>{this.props.date}</td>
</tr>
)
...
Try with hooks:
const [checked, setCheked] = useState(false)
return (
<tr className={"" + (checked ? "my-css-class" : "") }>
<td>
<input className="action-check" type="checkbox" onChange={(e)=> setCheked(e.target.checked)}/>
</td>
<td>
<ButtonGroup />
</td>
<td>{this.props.name}</td>
<td>{this.props.date}</td>
</tr>
)

How to reference other inputs in the same "row"?

onChange = ev => {
// how to get all inputs in this row?
};
render = () =>
<table className="MenuMenuOptionsWidget">
<thead>
<tr>
<th className="id">ID</th>
<th className="label">Label</th>
<th className="order">Order</th>
<th className="key">Key</th>
<th className="active">Active</th>
</tr>
</thead>
<tbody>
{this.state.options.map((opt,i) => <tr key={i}>
<td className="id">
{opt.id ? [<input type="hidden" name={`options[${i}][id]`} defaultValue={opt.id}/>,opt.id] : '*' }
</td>
<td className="label">
<input type="text" defaultValue={opt.label} name={`options[${i}][label]`} readOnly={!opt.active} onChange={this.onChange} />
</td>
<td className="order">
<input type="text" className="number" defaultValue={opt.order} name={`options[${i}][order]`} readOnly={!opt.active} onChange={this.onChange}/>
</td>
<td className="key">
<input type="text" defaultValue={opt.key} name={`options[${i}][key]`} readOnly={!opt.active} onChange={this.onChange}/>
</td>
<td className="active">
{opt.id ? <input type="checkbox" value="1" defaultChecked={opt.active} name={`options[${i}][active]`} onChange={this.onChange} /> : <a href="#" className="cr-delete-link" onClick={ev => this.onClickDelete(ev,i)}/>}
</td>
</tr>)}
</tbody>
</table>;
I've got a "loop" in my render() function which renders a bunch of inputs. I want to add the same onChange event to each of them. How can I access all the inputs in the row that caused the change event if I do this?
I can access the input that caused the change event via ev.target, but how do I get the others?
I could use jQuery: $(ev.target).closest('tr').find(...) but I'm looking for the idiomatic React way of doing it.
you want to make use of the ref property. by adding a unique ref to either the tr and calling children or a unique ref to each td, you can grab them when you need them.
<tr key={i} ref={`row${i}`}>
then grab the ref using refs
this.refs.row1.children
will grab all the td's within row1
You can use refs as a function. See here.
Try something like this: https://jsbin.com/kixowo/edit?js,console,output
var Component = React.createClass({
getInitialState() {
return {
options: [
'Row 1',
'Row 2'
]
};
},
rows: [],
onChange(row) {
this.rows[row].forEach((input) => {
// The values of all inputs in the row that changed
console.log(input.getDOMNode().value);
});
},
renderRows() {
this.rows = [];
return this.state.options.map((opt,i) => {
// Store and cache a new row and store inputs in the
// array using `refs` below.
this.rows.push([]);
return (<tr key={i}>
<td>{opt}</td>
<td>
<input ref={(input) => this.rows[i].push(input)} onChange={this.onChange.bind(this, i)} />
</td>
<td>
<input ref={(input) => this.rows[i].push(input)} onChange={this.onChange.bind(this, i)} />
</td>
</tr>);
});
},
render() {
return (
<table>
{this.renderRows()}
</table>
);
}
});
This way you can build up a dynamic set of inputs and call your on change event with the row number as an argument.

Angularjs Binding data to other table by check radio button, and update after click button

<table>
<tr>
<td><input type="radio" name="groupName" value="song" ng-model="$parent.selectedSong"/></td>
<td>{{song.name}}</td>
<td>{{song.artist}}</td>
<td>{{song.genre}}</td>
<td>{{song.price}}</td>
<td>
<input type="button" value="Delete" ng-click="deleteItem(song.id)" />
</td>
<td>
<input type="button" value="View" ng-click="go('OneSong', song)" />
</td>
</tr>
</table>
<table border="1">
<tr><td id="Td1">Correct Table</td></tr>
<tr>
<td>Name: </td>
<td><input type="text" ng-model="editItem.name"/></td>
</tr>
<tr>
<td>Artist: </td>
<td><input type="text" ng-model="editItem.artist"/></td>
</tr>
<tr>
<td>Genre: </td>
<td><input type="text" ng-model="editItem.genre"/></td>
</tr>
<tr>
<td>Price: </td>
<td><input type="text" ng-model="editItem.price"/></td>
</tr>
<tr>
<td colspan="2">
<!--<input type="button" value="Insert "ng-click="addItem()"/>-->
Add New Song
<input type="button" value="Update" ng-click="updateItem()"/>
<input type="button" value="Cancel" ng-click="cancel()"/>
</td>
</tr>
</table>
From the little information you provided, I am taking a stab at this:
http://jsfiddle.net/V44fQ/
var app = angular.module('songApp',[]);
app.controller('SongCtrl',function($scope) {
$scope.edit_song = {};
$scope.song = [
{name:'Heartbreaker',artist:'Led Zeppelin',genre:'Rock',price:'.99'},
{name:'War Pigs',artist:'Black Sabbath',genre:'Rock',price:'.99'}
];
$scope.applySong = function(song) {
$scope.edit_song = angular.copy(song);
$scope.edit_song.song_index = $scope.song.indexOf(song);
};
$scope.saveSong = function() {
var idx = $scope.edit_song.song_index;
$scope.song[idx] = $scope.edit_song;
$scope.cancelSong();
};
$scope.cancelSong = function() {
$scope.edit_song = {};
};
});

Resources