Increment or decrement a value in react array while mapping - arrays

export default class Cart extends Component {
constructor(props) {
super(props);
this.state = {
selectedForCart: [],
checkOut: true,
priceQuantity: undefined,
total: undefined,
};
}
render() {
return (
<div>
<NavBar />
{this.state.selectedForCart &&
this.state.selectedForCart.map((v, i) => {
return (
<Container className="mt-5" key={i}>
<Row>
<Col lg={2} md={2} sm={12}>
<p>
Price: ₹
{v.priceTaxIncluded}
</p>
<p style={{ fontSize: "10px" }}>Tax inclusive</p>
</Col>
<Col lg={2} md={2} sm={12}>
<Form.Group>
<Form.Label>Quantity</Form.Label>
<Form.Control
type="number"
placeholder="Quantity"
value={1}
onChange={(e) => {
this.setState({
priceQuantity: e.target.value
});
console.log(v.priceTaxIncluded * e.target.value);
}}
/>
</Form.Group>
</Col>
<Col lg={2} md={2} sm={12}>
{this.state.checkOut && (
<>
<p>{this.state.priceQuantity}</p>
</>
)}
</Col>
</Row>
</Container>
);
})}
<Footer />
</div>
);
}
}
Here in the above code, I'm mapping an array of items from the state object "" value. And if I increment a specific item, then that specific item's quantity only should increment. But it is not happening all items are getting incremented. And also the price should be multiplied with the incremented value and should be shown...
Thank You.
As in this image, I'm changing the quantity. But If I change the quantity of a product, then its reflecting the price for all products. As I have only one state object

You can bind the priceQuantity to input value. Then conditionally render in last column. As you are trying to print priceQuantity in last column it will show for all rows.
this.state = {
...
priceQuantity: 0,
..
};
{this.state.selectedForCart &&
this.state.selectedForCart.map((v, i) => {
return (
<Container className="mt-5" key={i}>
<Row>
<Col lg={2} md={2} sm={12}>
<p>
Price: ₹
{v.priceTaxIncluded}
</p>
<p style={{ fontSize: "10px" }}>Tax inclusive</p>
</Col>
<Col lg={2} md={2} sm={12}>
<Form.Group>
<Form.Label>Quantity</Form.Label>
<Form.Control
type="number"
placeholder="Quantity"
value={this.state.priceQuantity}
onChange={(e) => {
this.setState({
priceQuantity: e.target.value
});
console.log(v.priceTaxIncluded * e.target.value);
}}
/>
</Form.Group>
</Col>
<Col lg={2} md={2} sm={12}>
{this.state.checkOut && (
<>
<p>{this.state.priceQuantity ? v.priceTaxIncluded * this.state.priceQuantity : 0}</p>
</>
)}
</Col>
</Row>
</Container>
);
})}

Related

How do I pass one string of an array each time a component is rendered?

This component renders four cards for top teams in a database, they are already sorted by highest scores; I need a <p> tag that displays either "1st", "2nd", "3rd", "4th" on each one. The current code displays "1st2nd3rd4th" in the <p> tag of each card.
const seed = ["1st", "2nd", "3rd", "4th"];
const place = seed.map((seed) => seed);
const TeamCard = ({data}) => {
return (
<TeamCardStyle>
{!data && (
<Spinner />
)}
{data && data.getGroupScores && (data.getGroupScores.slice(0, 4).map((group) => (
<Row>
<Col className="teamCard mt-2 mb-2">
<Row>
<p># {place}</p>
</Row>
<Row>
<Col className="hideSmall">
<img className="mouseOn" src="../images/group.png" />
<img className="mouseOff" src="../images/groupSelected.png" />
</Col>
</Row>
<p>{group.name}</p>
</Col>
</Row>
))
)}
</TeamCardStyle>
)
}
export default TeamCard;
Happy Hacking!
You can use index from map function to get the relevant element from seed array.
const seed = ["1st", "2nd", "3rd", "4th"];
const TeamCard = ({data}) => {
return (
<TeamCardStyle>
{!data && (
<Spinner />
)}
{data && data.getGroupScores && (
data.getGroupScores.slice(0, 4).map((group, index) => {
return (
<Row>
<Col className="teamCard mt-2 mb-2">
<Row>
<p># {seed[index]}</p>
</Row>
<Row>
<Col className="hideSmall">
<img className="mouseOn" src="../images/group.png" />
<img className="mouseOff" src="../images/groupSelected.png" />
</Col>
</Row>
<p>{group.name}</p>
</Col>
</Row>
)
})
)}
</TeamCardStyle>
)
}
export default TeamCard

how to set the state values in react input?

can you please help me how can i show value of state in input field and also input field is editable. i am trying many tricks but not helpful also can't find in Stackoverflow .......................................
I want show brandcode state property "BrandCode" value in input field................................
here is brandcode return values
brandcode : {
BrandCode: "Nick",
BrandID: 1
}
state = {
brandcode: [],
};
Getbrandcode(brandId) {
getBrandCode(brandId)
.then(res => {
debugger;
//console.log(res);
this.setState({
brandcode: res.data.Data // i want show brandcode values in input
});
});
}
``
its a render.....
``
render() {
// const { formikProps} = this.props
return (
<Formik
enableReinitialize={true}
initialValues={this.masterstyledata}
onSubmit={(values, actions) => {
this.onSaveClick(values);
}}
validationSchema={this.validationSchema}
>
{formikProps => (
<>
<Card>
<CardBody>
{this.state.isLoading && <LoadingPanel />}
<Row>
<Col lg={12}>
<Form>
<FormGroup row>
<Label for="Value" sm={3}>Brand</Label>
<Col sm={3}>
<ComboBoxValue
data={this.state.branddesc}
style={{ width: '100%' }}
name="BrandID"
textField="text"
valueField="Value"
dataItemKey="Value"
onChange={(e) => {
this.BrandCodehandleChange(e);
formikProps.setFieldValue("BrandID", e.target.value)
}}
value={formikProps.values.BrandID}
placeholder="Brand Description"
/>
</Col>
</FormGroup>
<FormGroup row>
//here i want set values
<Label for="BrandCode" sm={3}>Style ID</Label>
<Col sm={3}> <Input sm={3}
type="text"
name="BrandCode"
id="BrandCode"
onChange={formikProps.handleChange('MasterStyleCode')}
value={formikProps.values.MasterStyleCode}
placeholder="Enter Style Id"
/>
<Error>{formikProps.errors.MasterStyleCode}</Error>
</Col>
</FormGroup>
</Form>
</Col>
</Row>
</CardBody>
</Card>
you made a mistake in using handleOnChage and onChange, here:
onChange={formikProps.handleChange('MasterStyleCode')}
at render time this function will be executed and the result is undefined (as you know because it's a void function!), and it's not what you want here, to solve this you have to make a HOF and use setFieldValue if your input name is something different than initialValue key which you want to change it, e.g:
onChange={(event) => {
formikProps.setFieldValue('MasterStyleCode', event.target.value)
}}

When i change another form element autocomplete value automatically cleared in Formik React js

The form has two elements.
When I select autocomplete value from emal element and then try to input a text value to titl field, the autocomplete value is automatically changed to empty.
What should I do to fix this issue?
I have tried to change formik initialValues using states but it's not working.
sorry for the language issue. Thanks in advance!
class TicketNew extends React.Component{
state = {
clearForm:false,
spinner:false,
closeForm:false,
emailsugges:[],
}
loadAlldata() {
this.setState({
spinner:false,
})
axios.post(baseUrl+'/api/load_company_list')
.then(res => {
const comanyList = res.data;
const emls = comanyList.emls.map(function(item, i){
return {
value:item.tci, title:item.tcc
}
})
this.setState({
emailsugges:emls
})
})
this.setState({
spinner:false,
})
};
componentDidMount(){
this.loadAlldata();
};
render(){
return(
<React.Fragment>
<Formik
initialValues={{ emal: "", titl: "" }}
validationSchema={formSchema}
>
{
({ errors,
touched,
handleSubmit,
isSubmitting,
handleBlur,
values,
resetForm
}) => (
<div>
<Form onSubmit={handleSubmit}>
<Card>
<CardHeader></CardHeader>
<CardBody>
<Row>
<Col md="5" sm="12">
<FormGroup row className="position-relative">
<Col md="4">
<span>Title</span>
</Col>
<Col md="8">
<Field
type="text"
name="titl"
id="titl"
className={`
form-control ${errors.titl && touched.titl && "is-invalid"}
`}
onBlur={handleBlur('titl')}
/>
{errors.titl &&
touched.titl ? (
<div className="invalid-tooltip mt-25">
{errors.titl}
</div>
) : null}
</Col>
</FormGroup>
</Col>
<Col md="2" sm="12"></Col>
<Col md="5" sm="12">
<FormGroup row className="position-relative"
style={{display:rqst!="1"?'none':''}}
>
<Col md="4">
<span>Email Address</span>
</Col>
<Col md="8">
<Field name="emal"
component={ ({field, form}) =>
<AutoComplete
type="email"
name="emal"
id="emal"
suggestions={this.state.emailsugges}
value={
this.state.emailsugges ?
this.state.emailsugges.find(option =>
option.value === field.value)
: ''}
className={`
form-control ${errors.emal && touched.emal && "is-invalid"}
`}
filterKey="title"
suggestionLimit={4}
/>}
/>
{errors.emal &&
touched.emal ? (
<div className="invalid-tooltip mt-25">
{errors.emal}
</div>
) : null}
</Col>
</FormGroup>
</Col>
</Row>
</CardBody>
</Card>
</Form>
</div>
)}
</Formik>
</React.Fragment>
)
}
};
export default TicketNew;

changing Redux state does not affect the render view

I am making a generic component and using it in a composite component also i pass some props to the generic component to behave in a certain way.I have used Redux to manage my state but when updating the state in Redux the component didn't re-render with the updated state.
Here are the components:
Generic component
export default class LabeledCheckBox extends Component {
constructor(props) {
super(props);
this.state = {
checked: false,
uncheckable: this.props.disableCheckBox
? this.props.disableCheckBox
: false
};
}
handleChange = (event) => {
this.setState({ checked: event.target.checked });
};
render() {
return (
<Form.Group as={Row}>
<Form.Label column="True" sm={9}>
{this.props.controlLabel}
</Form.Label>
<Col sm={3}>
<Form.Check
type="checkbox"
onChange={this.handleChange}
checked={this.state.checked}
onClick={this.props.clicked}
disabled={this.state.uncheckable}
/>
</Col>
</Form.Group>
);
}
}
LabeledCheckBox.propTypes = {
controlLabel: PropTypes.string.isRequired,
disableCheckBox: PropTypes.bool
};
parent component
export default class Endorsments extends Component {
constructor(props, context) {
super(props, context);
this.state = {
open: false
};
}
render() {
const { open } = this.state;
return (
<React.Fragment>
<LabeledCheckBox
clicked={() => this.setState({ open: !open })}
aria-controls="example-collapse-text"
aria-expanded={open}
controlLabel="Apply Endorsment"
disableCheckBox={!this.props.EndorsementSupported}
/>
<Collapse in={this.state.open}>
<div id="example-collapse-text">
<LabeledTextBoxWithCheckBox
controlLabel="BankName"
controlName="setBankName"
style={{ paddingBottom: '10px' }}
/>
<LabeledDateWithCheckBox controlLabel="Cheque Date" />
<Row>
<Col sm={6}>
<LabeledCheckBox controlLabel="User Name" />
</Col>
<Col sm={6}>
<LabeledCheckBox controlLabel="Cheque Sequence" />
</Col>
</Row>
</div>
</Collapse>
</React.Fragment>
);
}
}
Composit Component
class Preferences extends Component {
constructor(props, context) {
super(props, context);
this.props.fetchSupportedVendors();
}
loadScannersBasedOnVendor = () => {
if (
this.props.lastSelected.name === 'scannersVendors' ||
this.props.supportedScannerModule.length !== 0
) {
let select = this.props.supportedScannerModule.filter(
(element) =>
element.vendor ===
this.props.lastSelected.selectedObject.value
);
return select.map((element) => {
return { value: element.Value, label: element.name };
});
}
};
loadScannerMicrFonts = () => {
let supportedMicrs = [];
this.props.scannerCapabilities.supportedMicrFonts.forEach(
(element, key) => {
if (element.supported)
supportedMicrs.push({ value: key, label: element.value });
}
);
return supportedMicrs;
};
loadScannerBitDepth = () => {
let supportedBitDepth = [];
this.props.scannerCapabilities.supportedBitDepth.forEach(
(element, key) => {
if (element.supported)
supportedBitDepth.push({
value: key,
label: element.value
});
}
);
return supportedBitDepth;
};
afterSelectionEnded = () => {
if (
this.props.lastSelected &&
this.props.lastSelected.name === 'scannersModel' &&
!this.props.scannerCapabilities.supportedBitDepth
) {
this.props.loadScannerCapablilitiesToState(
this.props.lastSelected.selectedObject.value
);
}
};
render() {
return (
<Modal
{...this.props}
aria-labelledby="contained-modal-title-vcenter"
centered
dialogClassName="scanningModal"
>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
Preferences
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Row>
<h4>Default Scanner</h4>
</Row>
<Row>
<Col sm={12}>
<LabeledDropDown
controlLabel="Vendor"
controlName="scannersVendors"
placeholder="select a vendor please"
dropdownValues={
this.props.supportedScannerVendor
}
/>
</Col>
</Row>
<Row>
<Col sm={12}>
<LabeledDropDown
controlLabel="Model"
controlName="scannersModel"
placeholder="select model"
dropdownValues={[]}
loadDynamicItems={
this.loadScannersBasedOnVendor
}
afterValueChanged={this.afterSelectionEnded}
/>
</Col>
</Row>
<Row>
<Col sm={6}>
<VerticalLabeledDropDown
controlLabel="MICR Font"
controlName="ScannerMicrFont"
placeholder="select MICR Font"
dropdownValues={[]}
loadDynamicItems={this.loadScannerMicrFonts}
/>
</Col>
<Col sm={6}>
<VerticalLabeledDropDown
controlLabel="Bit Depth"
controlName="scannerBitDipth"
placeholder="select BitDepth"
dropdownValues={[]}
loadDynamicItems={this.loadScannerBitDepth}
/>
</Col>
</Row>
<hr />
<Row>
<h4>Scanner Feature</h4>
</Row>
<Endorsments
EndorsementSupported={
this.props.scannerCapabilities.supportedEndorsement
}
/>
<hr />
<Row>
<h4>General</h4>
</Row>
<Row>
<Col sm={6}>
<LabeledCheckBox controlLabel="Auto Save" />
</Col>
<Col sm={6}>
<LabeledCheckBox controlLabel="View While Scanning" />
</Col>
</Row>
<Row>
<Col sm={6}>
<LabeledCheckBox controlLabel="Use OCR for amount & date" />
</Col>
<Col sm={6}>
<LabeledCheckBox controlLabel="With UV scan" />
</Col>
</Row>
<Row>
<Col sm={12}>
<LabeledCheckBox controlLabel="Dont Show Prining language dialog" />
</Col>
</Row>
</Modal.Body>
<Modal.Footer bsPrefix="internal-modal-footer">
<Button onClick={this.props.onHide}>Close</Button>
<Button onClick={this.props.onHide}>Apply</Button>
</Modal.Footer>
</Modal>
);
}
}
const mapStateToProps = (state) => ({
supportedScannerVendor: state.supportedScanners.supportedVendors,
supportedScannerModule: state.supportedScanners.SupportedScanners,
lastSelected: state.dropdownEvents.dropDownSelectionChanged,
scannerCapabilities: state.supportedScanners.ScannerCapabilities
});
export default connect(mapStateToProps, {
fetchSupportedVendors,
loadScannerCapablilitiesToState
})(Preferences);
Finally
when calling loadScannerCapablilitiesToState the state is changed for this.props.scannerCapabilities.supportedEndorsement but it did not re-render the generic component to be disable or enabled
Am i missing something any help please?
if the Redux state is properly working then you need to change the state in LabeledCheckBox component.
componentDidUpdate() is invoked immediately after updating occurs.
componentDidUpdate = (prevProps, prevState) => {
if (prevProps.disableCheckBox !== this.props.disableCheckBox) {
this.setState({ uncheckable: this.props.disableCheckBox });
}
};
Read more about React lifecycle

How to manage state with complex json object in react js

Below is the code I have so far, my state isn't working as expected with a bit complex object, I was able to work with a simple object with no nested objects in my state and its working as expected.
state assignment works fine if I don't use personalInfo or contactInfo inside the customer object and used all the properties and create simple customer object
import React, {PropTypes} from 'react';
import {Grid,Row,Col,Button,Label} from 'react-bootstrap';
import {connect} from 'react-redux';
import * as customerActions from '../../actions/customerActions';
import {bindActionCreators} from 'redux';
class AddCustomer extends React.Component{
constructor(props , context){
super(props , context);
this.state={
customer:{
personalInfo:{
firstName:"",
lastName:"",
dob:"",
ssn:""
},
contactInfo:{
address:"",
addressLine2:"",
city:"",
state:"",
zip:"",
phoneNumber:"",
emailAddress:""
}
}
};
this.handleChange = this.handleChange.bind(this);
this.onClickCancel = this.onClickCancel.bind(this);
this.onClickSave = this.onClickSave.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
customer: {
personalInfo:{
},
contactInfo:{
},
...this.state.customer,
[name]: value
}
});
console.log(this.state.customer);
}
onClickCancel(){
}
onClickSave(){
this.props.actions.createCustomer(this.state.customer);
}
render() {
return (
<div className="container-fluid">
<Grid>
<Row className="show-grid">
<Col xs={10} md={10}><b>ADD A LEAD</b></Col>
<Col xs={2} md={2}>
<Button>×</Button>
</Col>
</Row>
<Row className="show-grid">
<Col xs={12} md={12}>
<hr/>
</Col>
</Row>
<p><b>Personal Information</b></p>
<br/>
<Row className="show-grid">
<Col xs={6} md={6}>
<Row><Label>First Name*</Label></Row>
<Row><input name="personalInfo.firstName" type="text" value={this.state.customer.personalInfo.firstName} onChange={this.handleChange} required="true"/></Row>
</Col>
<Col xs={6} md={6}>
<Row><Label>Last Name*</Label></Row>
<Row><input name="personalInfo.lastName" type="text" value={this.state.customer.personalInfo.lastName} onChange={this.handleChange} required="true"/></Row>
</Col>
</Row>
<br/>
<Row className="show-grid">
<Col xs={2} md={2}>
<Row><Label>Date of Birth*</Label></Row>
<Row><input name="personalInfo.dob" type="text" value={this.state.customer.personalInfo.dob} onChange={this.handleChange} required="true"/></Row>
</Col>
<Col xs={2} md={2}>
<Row><Label>SSN*</Label></Row>
<Row><input name="personalInfo.ssn" type="text" value={this.state.customer.personalInfo.ssn} onChange={this.handleChange} required="true"/></Row>
</Col>
</Row>
<br/>
<p><b>Contact Information</b></p>
<br/>
<Row className="show-grid">
<Col xs={6} md={6}>
<Row><Label>Address</Label></Row>
<Row><input name="contactInfo.address" type="text" value={this.state.customer.contactInfo.address} onChange={this.handleChange}/></Row>
</Col>
<Col xs={6} md={6}>
<Row><Label>Address Line 2</Label></Row>
<Row><input name="contactInfo.addressLine2" type="text" value={this.state.customer.contactInfo.addressLine2} onChange={this.handleChange}/></Row>
</Col>
</Row>
<br/>
<Row className="show-grid">
<Col xs={2} md={2}>
<Row><Label>City</Label></Row>
<Row><input name="contactInfo.city" type="text" value={this.state.customer.contactInfo.city} onChange={this.handleChange}/></Row>
</Col>
<Col xs={2} md={2}>
<Row><Label>State</Label></Row>
<Row><input name="contactInfo.state" type="text" value={this.state.customer.contactInfo.state} onChange={this.handleChange}/></Row>
</Col>
<Col xs={2} md={2}>
<Row><Label>Zip</Label></Row>
<Row><input name="contactInfo.zip" type="text" value={this.state.customer.contactInfo.zip} onChange={this.handleChange}/></Row>
</Col>
</Row>
<br/>
<Row className="show-grid">
<Col xs={4} md={4}>
<Row><Label>Phone Number</Label></Row>
<Row><input name="contactInfo.phoneNumber" type="text" value={this.state.customer.contactInfo.phoneNumber} onChange={this.handleChange}/></Row>
</Col>
<Col xs={4} md={4}>
<Row><Label>Email Address</Label></Row>
<Row><input name="contactInfo.emailAddress" type="text" value={this.state.customer.contactInfo.emailAddress} onChange={this.handleChange}/></Row>
</Col>
</Row>
<br/>
<Row className="show-grid">
<hr/>
</Row>
<Row className="show-grid">
<input className="pull-right" type="submit" onClick={this.onClickCancel} value="Cancel"/>
<input className="pull-right" type="submit" bsStyle="primary" onClick={this.onClickSave} value="Add"/>
</Row>
</Grid>
</div>
);
}
}
AddCustomer.propTypes={
actions:PropTypes.object.isRequired,
customer:PropTypes.array.isRequired
};
function mapStateToProps(state, ownProps) {
return{
customer:state.customer
};
}
function mapDispatchToProps(dispatch) {
return{
actions: bindActionCreators(customerActions,dispatch)
};
}
export default connect(mapStateToProps,mapDispatchToProps)(AddCustomer);
I'm not sure what's the unxepcted result do you receive, but I gues you may try something like this:
handleChange(type, name, event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
this.setState({
customer: {
...this.state.customer,
[type]:{
...this.state.customer[type],
[name]: value
}
}
});
console.log(this.state.customer);
}
...
render() {
...
<Row><input type="text" value={this.state.customer.personalInfo.firstName} onChange={this.handleChange.bind(this, 'personalInfo', 'firstName')} required="true"/></Row>
...
<Row><input type="text" value={this.state.customer.contactInfo.address} onChange={this.handleChange.bind(this, 'contactInfo', 'address')}/></Row>
...
}

Resources