I am trying to set init values on a redux form load but it is not working for me. i have tried all 3 options from here . I have tried with dispatch and initialize in componentDidMount. also tried in export section at bottom of class. this one i was not sure how to put it in the connect part as i am using map functions. i placed it in the form section
class SecurityExemptionsNew extends Component {
constructor(props) {
super(props);
this.renderSelectField = this.renderSelectField.bind(this);
this.renderTextField = this.renderTextField.bind(this);
this.renderSelect2Field = this.renderSelect2Field.bind(this);
this.runOnce = false;
this.state = {
loaded: false,
isLoading: true,
searchable: true,
selectValue: { value: '0', label: 'All'},
selectMarketValue : "Group Enterprise Technology (GET)",
clearable: true,
rtl: false,
options: [
{ value: '0', label: 'All'}
],
toggleChecked: true,
lm_security_engineer: ''
};
}
omponentDidMount() {
this.passMetaBack;
this.props.dispatch(change('SecurityExemptionsNewForm', 'market', 'Group Enterprise Technology (GET)'));
this.props.initialize({ market: 'Group Enterprise Technology (GET)' });
}
renderSelectField(field) {
let options = [];
if (field.label == 'Type') {
options = this.populateOptions(this.exemptionType, 'name', 'name');
} else if (field.label == 'Market') {
options = this.populateOptions(this.markets, 'name', 'name');
} else if (field.label == 'Service Domain') {
options = this.populateOptions(this.serviceDomain, 'name', 'name');
} else if (field.label == 'Service/Project/Programme') {
options = this.populateOptions(this.servicesList, 'id', 'name');
options.unshift(
<option key="0" value="0" selected>
All
</option>
);
} else if (field.label == 'Comms Matrix') {
options.unshift(
<option key="0" value="0" selected>
All
</option>
);
} else if (field.label == 'Security Engineer') {
options = this.populateOptions(this.securityEngineerList, 'email', 'email');
options.unshift(
<option key="0" value="" selected>
--Select Engineer--
</option>
);
} else if (field.label == 'LM Security Engineer') {
options = this.populateOptions(this.securityEngineerLocalMarketList, 'email', 'email');
options.unshift(
<option key="0" value="" selected>
--Select Engineer--
</option>
);
} else if (field.label == 'Business Priority') {
options = this.populateOptions(this.businessPriority, 'name', 'name');
}
let id = "select_" + field.input.name;
return (
<div className="form-group">
<label className="control-label col-sm-2">{field.label}</label>
<div className="col-sm-10">
<select
id={id}
{...field.select}
name={field.input.name}
className="form-control form-control-inline"
type="select"
onChange={event => {
//props.input.onChange(event); // <-- Propagate the event
this.updateCommsMatrix(event.target.value);
}}
>
{options}
</select>
</div>
</div>
);
}
renderSelect2Field(field){
return(
<div className="form-group">
<label className="control-label col-sm-2">{field.label}</label>
<div className="col-sm-4">
<Async
name={field.input.name}
multi={false}
value={this.state.selectValue}
onChange={this.updateValue}
valueKey="value"
labelKey="label"
loadOptions={this.getCommsmatrices}
onValueClick={this.gotoCommsmatrix}
cache={false}
isLoading={this.state.isLoading}
optionRenderer={(option) => {return option.label;}}
/>
</div>
</div>
);
}
render() {
console.log(this);
if (!this.runOnce && this.props.isReady) {
this.runOnce = true;
this.initData();
}
const { handleSubmit } = this.props;
let form = 'Loading...';
if (this.state.loaded) {
let policiesTable = this.renderPolicies();
return (
<div className="container-fluid">
<form onSubmit={handleSubmit} className="form-horizontal">
<Field
label="Type"
loadFrom="exemptionType"
name="exemption_type"
component={this.renderSelectField}
/>
<Field
label="Market"
loadFrom="markets"
name="market"
component={this.renderSelectField}
/>
<Field
label="Service Domain"
loadFrom="serviceDomain"
name="service_domain"
component={this.renderSelectField}
type="select"
/>
<Field
label="Service/Project/Programme"
loadFrom="servicesList"
name="service_id"
component={this.renderSelectField}
type="select"
/>
<Field
label="Demand Ref"
name="demand_ref"
component={this.renderTextField}
type="text"
/>
<Field
label="Exemption Summary"
name="name"
component={this.renderTextField}
type="text"
/>
<Field
label="Exemption Description"
name="description"
component={this.renderTextareaField}
type="textarea"
/>
<div className="form-group">
<label className="control-label col-sm-2">Comms Matrix:</label>
<div className="col-sm-4">
<Async
multi={false}
value={this.state.selectValue}
onChange={this.updateValue}
valueKey="value"
labelKey="label"
loadOptions={this.getCommsmatrices}
onValueClick={this.gotoCommsmatrix}
cache={false}
/>
</div>
</div>
{policiesTable}
<Field
label="Requestor"
name="requestor"
component={this.renderTextField}
type="text"
readonly="readonly"
/>
<Field
label="Security Engineer"
loadFrom="securityEngineerList"
name="security_engineer"
component={this.renderSelectField}
type="select"
/>
{this.state.lm_security_engineer}
<Field
label="Link to Design Doc"
name="designdoc"
component={this.renderTextField}
type="text"
/>
<Field
label="Business Priority"
loadFrom="businessPriority"
name="business_priority"
component={this.renderSelectField}
type="select"
/>
<Field
label="Expiry date (dd-MMM-yy)"
name="expiry_date"
component={this.renderTextField}
type="text"
/>
<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">
<button id="btnSubmit" type="submit" name="btnSubmit" className="btn btn-vodafone hidden-print">Submit</button>
</div>
</div>
</form>
</div>
);
}
return <div className="container-fluid">{form}</div>;
}
}
function mapStateToProps(state) {
return {
securityExemptions: state.securityExemptions,
commsmatrices: state.commsmatrices
};
}
//Anything returned from this function will end up as props
//on the User container
function mapDispatchToProps(dispatch) {
// Whenever getUser is called, the result should be passed
// to all our reducers
//return {
//actions: bindActionCreators(Object.assign({}, fetchServices, checkServiceEditable ), dispatch)
//};
return bindActionCreators(
{
fetchExemptionType,
fetchMarkets,
fetchServiceDomains,
fetchServicesList,
fetchCommsmatricesByService,
fetchExemptionsForCommsmatrix,
fetchSecurityEngineerList,
fetchBusinessPriorityList
},
dispatch
);
}
SecurityExemptionsNew = connect(mapStateToProps, mapDispatchToProps)(
SecurityExemptionsNew
);
//Decorate the form component
export default reduxForm({
form: 'SecurityExemptionsNewForm', // a unique name for this form
initialValues: { service_domain: 'Corporate (Internal/External)' }
})(SecurityExemptionsNew);
update
Having not being able to use redux-form to init the default values, i just used the default values tag with state
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import FontAwesome from 'react-fontawesome';
import { isServiceName, isServiceRef } from '../../scripts/validation';
import {
fetchExemptionType,
fetchMarkets,
fetchServiceDomains,
fetchServicesList,
fetchExemptionsForCommsmatrix,
fetchSecurityEngineerList,
fetchBusinessPriorityList
} from '../../actions/security';
import { fetchCommsmatricesByService } from '../../actions/commsmatrices';
import axios from 'axios';
import { Field, reduxForm, change } from 'redux-form';
import PropTypes from 'prop-types';
import { Select, Async } from "react-select";
import 'react-select/dist/react-select.css';
class SecurityExemptionsNew extends Component {
constructor(props) {
super(props);
this.handleSaveBtnClick = this.handleSaveBtnClick.bind(this);
this.handleShowError = this.handleShowError.bind(this);
this.initData = this.initData.bind(this);
this.renderSelectField = this.renderSelectField.bind(this);
this.renderTextField = this.renderTextField.bind(this);
this.updateCommsMatrix = this.updateCommsMatrix.bind(this);
this.renderSelect2Field = this.renderSelect2Field.bind(this);
this.clearValue = this.clearValue.bind(this);
this.updateValue = this.updateValue.bind(this);
this.getCommsmatrices = this.getCommsmatrices.bind(this);
this.fnToggleCheckboxes = this.fnToggleCheckboxes.bind(this);
this.handleCheckedValues = this.handleCheckedValues.bind(this);
this.meta = {
title: 'Request Exemption',
description: 'This section allows you to request an exemption'
};
this.passMetaBack = this.passMetaBack.bind(this);
this.runOnce = false;
this.state = {
loaded: false,
isLoading: true,
searchable: true,
selectValue: { value: '0', label: 'All'},
selectMarketValue : "Group Enterprise Technology (GET)",
clearable: true,
rtl: false,
options: [
{ value: '0', label: 'All'}
],
toggleChecked: true,
lm_security_engineer: '',
select_exemption_type: 'Security',
select_market: 'Group Enterprise Technology (GET)',
select_service_domain: 'Corporate (Internal/External)',
select_service_id: '0',
select_security_engineer: null,
select_business_priority: 'Low'
};
this.exemptionType = {};
this.markets = {};
this.serviceDomain = {};
this.servicesList = {};
this.matrices = {};
this.securityEngineerList = {};
this.securityEngineerLocalMarketList = {}
this.businessPriority = {}
this.tableOptions = {
paginationShowsTotal: false,
sizePerPageList: [ {
text: '10', value: 10
}, {
text: '50', value: 50
}, {
text: '100', value: 100
}
],
};
this.checkedValues = [];
}
componentDidMount() {
console.log("componentDidMount");
this.passMetaBack;
this.props.initialize({ market: 'Group Enterprise Technology (GET)' });
this.props.dispatch(change('SecurityExemptionsNewForm', 'market', 'Group Enterprise Technology (GET)'));
}
passMetaBack = () => {
this.props.passMetaBack(this.meta);
};
renderSelectField(field) {
let defaultValue = this.state['select_'+field.input.name];
let options = [];
if (field.label == 'Type') {
options = this.populateOptions(this.exemptionType, 'name', 'name');
} else if (field.label == 'Market') {
options = this.populateOptions(this.markets, 'name', 'name');
} else if (field.label == 'Service Domain') {
options = this.populateOptions(this.serviceDomain, 'name', 'name');
} else if (field.label == 'Service/Project/Programme') {
options = this.populateOptions(this.servicesList, 'id', 'name');
options.unshift(
<option key="0" value="0">
All
</option>
);
} else if (field.label == 'Comms Matrix') {
options.unshift(
<option key="0" value="0">
All
</option>
);
} else if (field.label == 'Security Engineer') {
options = this.populateOptions(this.securityEngineerList, 'email', 'email');
options.unshift(
<option key="0" value="">
--Select Engineer--
</option>
);
} else if (field.label == 'LM Security Engineer') {
options = this.populateOptions(this.securityEngineerLocalMarketList, 'email', 'email');
options.unshift(
<option key="0" value="">
--Select Engineer--
</option>
);
} else if (field.label == 'Business Priority') {
options = this.populateOptions(this.businessPriority, 'name', 'name');
}
let id = "select_" + field.input.name;
return (
<div className="form-group">
<label className="control-label col-sm-2">{field.label}</label>
<div className="col-sm-10">
<select
id={id}
{...field.select}
name={field.input.name}
className="form-control form-control-inline"
type="select"
onChange={event => {
//props.input.onChange(event); // <-- Propagate the event
this.updateCommsMatrix(event.target.value);
}}
defaultValue={defaultValue}
>
{options}
</select>
</div>
</div>
);
}
renderSelect2Field(field){
return(
<div className="form-group">
<label className="control-label col-sm-2">{field.label}</label>
<div className="col-sm-4">
<Async
name={field.input.name}
multi={false}
value={this.state.selectValue}
onChange={this.updateValue}
valueKey="value"
labelKey="label"
loadOptions={this.getCommsmatrices}
onValueClick={this.gotoCommsmatrix}
cache={false}
isLoading={this.state.isLoading}
optionRenderer={(option) => {return option.label;}}
/>
</div>
</div>
);
}
renderTextField(field) {
let value = '';
let readonly = false
if (field.label == 'Requestor') {
value = this.props.activeUser.email;
readonly = true;
}
return (
<div className="form-group">
<label className="control-label col-sm-2">{field.label}</label>
<div className="col-sm-10">
<input
name={field.input.name}
className="form-control form-control-inline"
type="text"
{...field.text}
defaultValue={value}
readOnly={readonly}
/>
</div>
</div>
);
}
renderTextareaField(field) {
return (
<div className="form-group">
<label className="control-label col-sm-2">{field.label}</label>
<div className="col-sm-10">
<textarea
name={field.input.name}
className="form-control form-control-inline"
type="textarea"
{...field.text}
/>
</div>
</div>
);
}
handleCheckedValues({target}){
if (target.checked){
target.setAttribute('checked', true);
this.checkedValues.push({id:$(target).val()});
}else{
target.removeAttribute('checked');
let arr = this.checkedValues.filter(function(item) {
return item.id !== $(target).val()
})
this.checkedValues = arr;
}
}
render() {
console.log(this);
if (!this.runOnce && this.props.isReady) {
this.runOnce = true;
this.initData();
}
const { handleSubmit } = this.props;
let form = 'Loading...';
if (this.state.loaded) {
let policiesTable = this.renderPolicies();
return (
<div className="container-fluid">
<form onSubmit={handleSubmit} className="form-horizontal">
<Field
label="Type"
loadFrom="exemptionType"
name="exemption_type"
component={this.renderSelectField}
/>
<Field
label="Market"
loadFrom="markets"
name="market"
component={this.renderSelectField}
/>
<Field
label="Service Domain"
loadFrom="serviceDomain"
name="service_domain"
component={this.renderSelectField}
type="select"
/>
<Field
label="Service/Project/Programme"
loadFrom="servicesList"
name="service_id"
component={this.renderSelectField}
type="select"
/>
<Field
label="Demand Ref"
name="demand_ref"
component={this.renderTextField}
type="text"
/>
<Field
label="Exemption Summary"
name="name"
component={this.renderTextField}
type="text"
/>
<Field
label="Exemption Description"
name="description"
component={this.renderTextareaField}
type="textarea"
/>
<div className="form-group">
<label className="control-label col-sm-2">Comms Matrix:</label>
<div className="col-sm-4">
<Async
multi={false}
value={this.state.selectValue}
onChange={this.updateValue}
valueKey="value"
labelKey="label"
loadOptions={this.getCommsmatrices}
onValueClick={this.gotoCommsmatrix}
cache={false}
/>
</div>
</div>
{policiesTable}
<Field
label="Requestor"
name="requestor"
component={this.renderTextField}
type="text"
readonly="readonly"
/>
<Field
label="Security Engineer"
loadFrom="securityEngineerList"
name="security_engineer"
component={this.renderSelectField}
type="select"
/>
{this.state.lm_security_engineer}
<Field
label="Link to Design Doc"
name="designdoc"
component={this.renderTextField}
type="text"
/>
<Field
label="Business Priority"
loadFrom="businessPriority"
name="business_priority"
component={this.renderSelectField}
type="select"
/>
<Field
label="Expiry date (dd-MMM-yy)"
name="expiry_date"
component={this.renderTextField}
type="text"
/>
<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">
<button id="btnSubmit" type="submit" name="btnSubmit" className="btn btn-vodafone hidden-print">Submit</button>
</div>
</div>
</form>
</div>
);
}
return <div className="container-fluid">{form}</div>;
}
}
function mapStateToProps(state) {
return {
securityExemptions: state.securityExemptions,
commsmatrices: state.commsmatrices
};
}
//Anything returned from this function will end up as props
//on the User container
function mapDispatchToProps(dispatch) {
// Whenever getUser is called, the result should be passed
// to all our reducers
//return {
//actions: bindActionCreators(Object.assign({}, fetchServices, checkServiceEditable ), dispatch)
//};
return bindActionCreators(
{
fetchExemptionType,
fetchMarkets,
fetchServiceDomains,
fetchServicesList,
fetchCommsmatricesByService,
fetchExemptionsForCommsmatrix,
fetchSecurityEngineerList,
fetchBusinessPriorityList
},
dispatch
);
}
SecurityExemptionsNew = connect(mapStateToProps, mapDispatchToProps)(
SecurityExemptionsNew
);
function validate (values) {
console.log(values);
const errors = {};
if(!values.name){
errors.name = "Enter summary";
}
return errors;
}
//Decorate the form component
export default reduxForm({
form: 'SecurityExemptionsNewForm', // a unique name for this form
validate,
initialValues: { market: 'Group Enterprise Technology (GET)', service_domain: 'Corporate (Internal/External)' }
})(SecurityExemptionsNew);
Related
I am working on form in react. After selecting dish type I want to conditionally display other fields.
For example if I select pizza I want to display number field. If I select soup I want to display other input field.
Here is sample of code:
const Form = () => {
const [dishes] = React.useState([
{
label: "Pizza",
value: "Pizza",
},
{ label: "Soup", value: "Soup" },
{ label: "Sandwich", value: "Sandwich" },
]);
return (
<div>
<form>
<label>Name</label>
<input type="text" required></input>
<label>Preperation Time</label>
<input type="time" step="2" required></input>
<label>Type</label>
<select>
{dishes.map((dish) => (
<option key={dish.value} value={dish.value}>
{dish.label}
</option>
))}
</select>
<button>submit</button>
</form>
</div>
);
};
export default Form;
import React, { useState } from 'react';
function App() {
const [dishes] = React.useState([
{
label: "Pizza",
value: "Pizza",
},
{ label: "Soup", value: "Soup" },
{ label: "Sandwich", value: "Sandwich" },
]);
const [type, setType] = useState([])
const handleChang = (value) => {
setType(value);
}
return (
<div>
<form>
{(type == "Pizza") && (<> <label>Name</label>
<input type="text" required></input></>)
}
{(type == "Soup") && (<> <label>Preperation Time</label>
<input type="time" step="2" required></input></>)
}
<label>Type</label>
<select onChange={(e) => handleChang(e.target.value)}>
{dishes.map((dish) => (
<option key={dish.value} value={dish.value}>
{dish.label}
</option>
))}
</select>
<button>submit</button>
</form>
</div>
);
}
export default App;
Try this (codesandbox: https://codesandbox.io/s/vigilant-kepler-5xuio?file=/src/App.js)
const [dishes] = React.useState([
{
label: "Pizza",
value: "Pizza",
field: (
<div>
<label htmlFor="pizza">Toppings</label>
<input type="number" id="pizza" />
</div>
)
},
{
label: "Soup",
value: "Soup",
field: (
<div>
<label htmlFor="soup">How soupy?</label>
<input type="range" id="soup" />
</div>
)
},
{
label: "Sandwich",
value: "Sandwich",
field: (
<div>
<label htmlFor="sandwich">Enter your ingredients</label>
<input type="text" id="sandwich" />
</div>
)
}
]);
const [selectedDish, setSelectedDish] = React.useState(dishes[0]);
const handleDishSelect = (e) => {
const dish = dishes.find((dish) => dish.value === e.target.value);
if (dish) {
setSelectedDish(dish);
}
};
return (
<div>
<form>
<label>Name</label>
<input type="text" required></input>
<label>Preperation Time</label>
<input type="time" step="2" required></input>
<label>Type</label>
<select onChange={handleDishSelect}>
{dishes.map((dish) => (
<option key={dish.value} value={dish.value}>
{dish.label}
</option>
))}
</select>
{selectedDish && selectedDish.field}
<button>submit</button>
</form>
</div>
);
So you wanna display some JSX on condition right?
you can just check the condition and select a output as if condition
<div>
{dishes.value.equals("pizza") && (<input type="number">)}
{dishes.value.equals("soup") && (<input type="text">)}
</div>
You can use Ternary operation to if else condition
<div>
{dishes.value.equals("pizza") ? (<input type="number">) : (<input type="text">)}
</div>
This is the architecture I would follow (see below). First define your menu, which I presume is not changing so should just be a plain object. Then split you code in a few components:
MenuForm - this can be your main menu form component;
MenuItem - this is a component that generates selection options for a menu item
Crete additional components to handle the specifics of each menu item, say PizzaItemMenu, SoupItemMenu, etc.
Here is a full example app in action based on your code:
const menu = {
pizza: {
type: [
{
label: 'neapolitana',
value: 'npa'
}, {
label: 'chicago',
value: 'ccg'
}, {
label: '4-cheese',
value: 'cse'
}],
number: 1,
addOn: false
},
soup: {
type: [{
label: 'carrot',
value: 'crt'
}, {
label: 'potato',
value: 'ptt'
}],
number: 1,
addOn: false
}
}
const MenuForm = () => {
const [menuItem, setMenuItem] = React.useState(false);
const handleMenuItemSelection = (e) => {
setMenuItem(e.target.value);
}
const additionalMenuItemSelections = () => {
switch (menuItem) {
case 'pizza':
return <PizzaItemMenu />
case 'soup':
return <SoupItemMenu />
default:
return false;
}
}
return (
<div>
<form>
<label>Name</label>
<input type="text" required></input>
<label>Preperation Time</label>
<input type="time" step="2" required></input>
<label>Type</label>
<select className='menu' onChange={handleMenuItemSelection} defaultValue='x'>
<option disabled value="x">Select menu item</option>
{Object.keys(menu).map((item, index) => {
return (
<option key={index} value={item}>{item}</option>
)
})}
</select>
{additionalMenuItemSelections()}
<button>submit</button>
</form>
</div>
);
};
const PizzaItemMenu = () => {
const [pizzaType, setPizzaType] = React.useState(false);
const handleSelection = (e) => {
const data = e.target.value;
setPizzaType(data);
}
return (
<div className='soup-menu'>
<p>You've selected pizza!</p>
<MenuItem menuItem='pizza' handleSelection={handleSelection} />
Additional form menu selection options for pizzas goes here
{pizzaType && <p>You've selected {pizzaType} pizza!</p>}
</div>
)
}
const SoupItemMenu = () => {
const [soupType, setSoupType] = React.useState(false);
const handleSelection = (e) => {
const data = e.target.value;
setSoupType(data);
}
return (
<div className='soup-menu'>
<p>You've selected soup!</p>
<MenuItem menuItem='soup' handleSelection={handleSelection} />
Additional form menu selection options for soups goes here
{soupType && (<p>You've selected {soupType} soup!</p>)}
</div>
)
}
const MenuItem = ({ menuItem, handleSelection }) => {
const itemOptions = menu[menuItem].type;
return (
<select id={menuItem} defaultValue='x' onChange={(e) => handleSelection(e)} >
<option disabled value="x">Select {menuItem} type</option>
{itemOptions.map((itemKey, index) => (
<option key={index} value={itemKey.value}>{itemKey.label}</option>
))}
</select>
)
}
export default MenuForm;
I've made a simple resume portal. What I want is to get all the inputs values displayed on a screen on submit. This all should be done when button(Generate CV) is clicked.
Here's my code below:
Child component ( src -> Routes -> UserForm -> Components -> UserDetails -> index.js )
import React from 'react'
import './style.scss';
import { Row, Col } from 'react-bootstrap'
const UserDetails = (props) => {
const { wrkExpTxtArea, AcQuTxtArea, clickToAdd, clickToRmv, addAcQuTxtArea, rmvAcQuTxtArea, inputChangeHandler } = props
return (
<>
<div className='UserDetails'>
<Row>
<Col lg='6'>
<div className='persnlInfo'>
<h4>
Personal Information
</h4>
<p>Your Name</p>
<input onChange={() => inputChangeHandler('name')} type="text" placeholder="Enter here" />
<p>Your Contact</p>
<input type="text" placeholder="Enter here" />
<p>Your Address</p>
<textarea className='formAddress' rows="5" cols="10" placeholder="Enter here" />
<p id='impLinks'>Important Links</p>
<p>Facebook</p>
<input type="text" placeholder="Enter here" />
<p>Instagram</p>
<input type="text" placeholder="Enter here" />
<p>Linkedin</p>
<input type="text" placeholder="Enter here" />
</div>
</Col>
<Col lg='6'>
<h4>
Professional Information
</h4>
<p>Objective</p>
<textarea className='formObjective' rows="5" cols="10" placeholder="Enter here" />
<p>Work Experience</p>
{wrkExpTxtArea.map(item => (
<textarea className='formWrkExp' value={item.value} rows="3" cols="10" placeholder="Enter here" />
))}
<div className='Button' >
<input type='button' value='Add' onClick={clickToAdd} />
<input type='button' value='Remove' onClick={clickToRmv} />
</div>
<p id='AcQu'>Academic Qualification</p>
{AcQuTxtArea.map(item => (
<textarea className='formAcQu' value={item.value} rows="3" cols="10" placeholder="Enter here" />
))}
<div className='Button' >
<input type='button' value='Add' onClick={addAcQuTxtArea} />
<input type='button' value='Remove' onClick={rmvAcQuTxtArea} />
</div>
</Col>
<Row>
<div className='sbmtButton'>
<input type='button' value='Generate CV' />
</div>
</Row>
</Row>
</div>
</>
)
}
export default UserDetails;
Parent component ( src -> Routes -> UserForm -> index.js )
import React from "react";
import Pages from "../../Components/HOC/Page/index";
import UserDetails from "../UserForm/Components/UserDetails/index";
class UserForm extends React.Component {
state = {
wrkExpTxtArea: [{ text: "" }],
AcQuTxtArea: [{ text: "" }],
inputValues: [{name: 'name', value: ''}],
};
inputChangeHandler = (e,inputName) => {
let updatedInputs = [...this.state.inputValues]
let changedInputValuesIndex = updatedInputs.findIndex(input => input.name === inputName)
if (changedInputValuesIndex > -1) {
let updatedInputValue =
{...updatedInputs[changedInputValuesIndex]}
updatedInputValue.value = e.target.value
updatedInputs[changedInputValuesIndex] = updatedInputValue
}
this.setState({inputValues: updatedInputs})
}
addTextArea = () => {
let updatedTextArea = [...this.state.wrkExpTxtArea];
updatedTextArea.push({ text: "" });
this.setState({ wrkExpTxtArea: updatedTextArea });
};
rmvTextArea = () => {
let updatedTextArea = [...this.state.wrkExpTxtArea];
if (updatedTextArea.length > 1) {
updatedTextArea.pop({ text: "" });
}
this.setState({ wrkExpTxtArea: updatedTextArea });
};
addAcQuTextArea = () => {
let updatedTextArea = [...this.state.AcQuTxtArea];
updatedTextArea.push({ text: "" });
this.setState({ AcQuTxtArea: updatedTextArea });
};
rmvAcQuTextArea = () => {
let updatedTextArea = [...this.state.AcQuTxtArea];
if (updatedTextArea.length > 1) {
updatedTextArea.pop({ text: "" });
}
this.setState({ AcQuTxtArea: updatedTextArea });
};
render() {
return (
<>
<Pages showHeader showFooter>
<UserDetails inputChangeHandler={this.inputChangeHandler} wrkExpTxtArea={this.state.wrkExpTxtArea} clickToAdd={this.addTextArea} clickToRmv={this.rmvTextArea}
AcQuTxtArea={this.state.AcQuTxtArea} addAcQuTxtArea={this.addAcQuTextArea} rmvAcQuTxtArea={this.rmvAcQuTextArea} />
</Pages>
</>
);
}
}
export default UserForm;
Output:
I'm new to programming and getting values of user inputs seems insanely complicated to me. I'm little aware that this can be achieved using state , props etc. But I really have no idea about Where and What code is to place. I need help. That’s it!
You can use useRef hook and give a reference to each of input element.
For Example
const name = useRef();
const handleSubmit = () => {
if(name.current && name.current.value){
console.log(name.current.value) // input element's value
}
}
return (<div>
<input type="text" ref={name} />
<button onClick={handleSubmit}> Submit </button>
</div>)
add an onChange prop to the input tag like this:
const [inputValue, setInputValue] = useState('')
const inputChangeHandler = (e) => {
// e argument has received by default from onChange
const newValue = e.target.value
setInputValue(newValue)
}
<input onChange={inputChangeHandler} />
whenever you start changing the value of the input, inputChangeHandler function will trigger and then update your state
index.js
import React, { useState } from "react";
import Pages from "../../Components/HOC/Page/index";
import UserDetails from "../UserForm/Components/UserDetails/index";
const initialData = {
name: '',
contact: '',
address: '',
facebook: '',
instagram: '',
linkedin: '',
objective: '',
workExperience: [],
academicQualification: [],
}
const UserForm = () => {
// holds all the form data from child component "UserDetails"
const [formData, setFormData] = useState(initialData)
const handleSubmit = () => {
// submit handler
alert(JSON.stringify(formData, undefined, 4))
}
return (
<>
<Pages showHeader showFooter>
<UserDetails form={formData} setter={setFormData} onSubmit={handleSubmit} />
</Pages>
</>
)
}
export default UserForm;
UserDetails
import React, { useState } from 'react'
import './style.scss';
import { Row, Col } from 'react-bootstrap'
const UserDetails = ({ form, setter, onSubmit }) => {
const hanldeOnChange = (e) => {
setter(prev => {
// access property by input element's name
// update the state on parent component
prev[e.target.name] = e.target.value;
return { ...prev } // return copy after updating
})
}
const [listTypeElements, setListTypeElements] = useState({ workExperience: '', academicQualification: '' })
const handleListInput = (property) => {
setter(prev => {
prev[property].push(listTypeElements[property]);
return { ...prev }
})
setListTypeElements(prev => {
prev[property] = ''
return { ...prev }
})
}
const handleRemoveItem = (property) => {
setter(prev => {
prev[property].pop();
return { ...prev }
})
}
return (
<>
<div className='UserDetails'>
<Row>
<Col lg='6'>
<div className='persnlInfo'>
<h4>
Personal Information
</h4>
<p>Your Name</p>
<input type="text" placeholder="Enter here" onChange={hanldeOnChange} name='name' />
<p>Your Contact</p>
<input type="text" placeholder="Enter here" onChange={hanldeOnChange} name='contact' />
<p>Your Address</p>
<textarea className='formAddress' rows="5" cols="10" placeholder="Enter here" onChange={hanldeOnChange} name='address' />
<p id='impLinks'>Important Links</p>
<p>Facebook</p>
<input type="text" placeholder="Enter here" onChange={hanldeOnChange} name='facebook' />
<p>Instagram</p>
<input type="text" placeholder="Enter here" onChange={hanldeOnChange} name='instagram' />
<p>Linkedin</p>
<input type="text" placeholder="Enter here" onChange={hanldeOnChange} name='linkedin' />
</div>
</Col>
<Col lg='6'>
<h4>
Professional Information
</h4>
<p>Objective</p>
<textarea className='formObjective' rows="5" cols="10" placeholder="Enter here" onChange={hanldeOnChange} name='objective' />
<p>Work Experience</p>
{form.workExperience.map((value) =>
<textarea className='formWrkExp' value={value} rows="3" cols="10" disabled={true} />)}
<textarea className='formWrkExp' value={listTypeElements['workExperience']} rows="3" cols="10" placeholder="Enter here" onChange={(e) => setListTypeElements(prev => {
prev['workExperience'] = e.target.value;
return { ...prev }
})} />
< div className='Button' >
<input type='button' value='Add' onClick={() => handleListInput('workExperience')} />
<input type='button' value='Remove' onClick={() => handleRemoveItem('workExperience')} />
</div>
<p id='AcQu'>Academic Qualification</p>
{form.academicQualification.map((value) =>
<textarea className='formAcQu' value={value} rows="3" cols="10" disabled={true} />)}
<textarea className='formAcQu' value={listTypeElements['academicQualification']} rows="3" cols="10" placeholder="Enter here" onChange={(e) => setListTypeElements(prev => {
prev['academicQualification'] = e.target.value;
return { ...prev }
})} />
< div className='Button' >
<input type='button' value='Add' onClick={() => handleListInput('academicQualification')} />
<input type='button' value='Remove' onClick={() => handleRemoveItem('academicQualification')} />
</div>
</Col>
<Row>
<div className='sbmtButton'>
<input type='button' value='Generate CV' onClick={onSubmit} />
</div>
</Row>
</Row>
</div>
</>
)
}
export default UserDetails;
i am using react-redux-form 7.2.3 to create a form and submit. the values submitted are taken from the initialValues set in the config and not taken from the form itself in the browser. I added validate function but if i dont set the initialValues then the validate never passes. i cannot seem to figure out what I am doing wrong here. do i need to set the initValues manually onChange everytime?
class SecurityExemptionsNew extends Component {
constructor(props) {
super(props);
this.handleShowError = this.handleShowError.bind(this);
this.initData = this.initData.bind(this);
this.renderSelectField = this.renderSelectField.bind(this);
this.renderTextField = this.renderTextField.bind(this);
this.updateCommsMatrix = this.updateCommsMatrix.bind(this);
this.renderSelect2Field = this.renderSelect2Field.bind(this);
this.clearValue = this.clearValue.bind(this);
this.updateValue = this.updateValue.bind(this);
this.getCommsmatrices = this.getCommsmatrices.bind(this);
this.fnToggleCheckboxes = this.fnToggleCheckboxes.bind(this);
this.handleCheckedValues = this.handleCheckedValues.bind(this);
this.meta = {
title: 'Request Exemption',
description: 'This section allows you to request an exemption'
};
this.passMetaBack = this.passMetaBack.bind(this);
this.runOnce = false;
this.state = {
loaded: false,
isLoading: true,
searchable: true,
selectValue: { value: '0', label: 'All'},
selectMarketValue : "Group Enterprise Technology (GET)",
clearable: true,
rtl: false,
options: [
{ value: '0', label: 'All'}
],
toggleChecked: true,
lm_security_engineer: '',
select_exemption_type: 'Security',
select_market: 'Group Enterprise Technology (GET)',
select_service_domain: 'Corporate (Internal/External)',
select_service_id: '0',
select_security_engineer: null,
select_business_priority: 'Low'
};
this.exemptionType = {};
this.markets = {};
this.serviceDomain = {};
this.servicesList = {};
this.matrices = {};
this.securityEngineerList = {};
this.securityEngineerLocalMarketList = {}
this.businessPriority = {}
this.tableOptions = {
paginationShowsTotal: false,
sizePerPageList: [ {
text: '10', value: 10
}, {
text: '50', value: 50
}, {
text: '100', value: 100
}
],
};
this.checkedValues = [];
}
componentDidMount() {
console.log("componentDidMount");
this.passMetaBack;
//this.props.initialize({ market: 'Group Enterprise Technology (GET)' });
//this.props.dispatch(change('SecurityExemptionsNewForm', 'market', 'Group Enterprise Technology (GET)'));
}
renderTextField(field) {
let value = '';
let readonly = false
if (field.label == 'Requestor') {
value = this.props.activeUser.email;
readonly = true;
}
return (
<div className="form-group">
<label className="control-label col-sm-2">{field.label}</label>
<div className="col-sm-10">
<input
name={field.input.name}
className="form-control form-control-inline"
type="text"
{...field.text}
defaultValue={value}
readOnly={readonly}
/>
</div>
{field.meta.error}
</div>
);
}
onSubmit(values){
console.log(values);
}
render() {
console.log(this);
if (!this.runOnce && this.props.isReady) {
this.runOnce = true;
this.initData();
}
const { handleSubmit } = this.props;
let form = 'Loading...';
if (this.state.loaded) {
let policiesTable = this.renderPolicies();
return (
<div className="container-fluid">
<form onSubmit={handleSubmit(this.onSubmit.bind(this))} className="form-horizontal">
<Field
label="Type"
loadFrom="exemptionType"
name="exemption_type"
component={this.renderSelectField}
/>
<Field
label="Market"
loadFrom="markets"
name="market"
component={this.renderSelectField}
/>
<Field
label="Service Domain"
loadFrom="serviceDomain"
name="service_domain"
component={this.renderSelectField}
type="select"
/>
<Field
label="Service/Project/Programme"
loadFrom="servicesList"
name="service_id"
component={this.renderSelectField}
type="select"
/>
<Field
label="Demand Ref"
name="demand_ref"
component={this.renderTextField}
type="text"
/>
<Field
label="Exemption Summary"
name="name"
component={this.renderTextField}
type="text"
/>
<Field
label="Exemption Description"
name="description"
component={this.renderTextareaField}
type="textarea"
/>
<div className="form-group">
<label className="control-label col-sm-2">Comms Matrix:</label>
<div className="col-sm-4">
<Async
multi={false}
value={this.state.selectValue}
onChange={this.updateValue}
valueKey="value"
labelKey="label"
loadOptions={this.getCommsmatrices}
onValueClick={this.gotoCommsmatrix}
cache={false}
/>
</div>
</div>
{policiesTable}
<Field
label="Requestor"
name="requestor"
component={this.renderTextField}
type="text"
readonly="readonly"
/>
<Field
label="Security Engineer"
loadFrom="securityEngineerList"
name="security_engineer"
component={this.renderSelectField}
type="select"
/>
{this.state.lm_security_engineer}
<Field
label="Link to Design Doc"
name="designdoc"
component={this.renderTextField}
type="text"
/>
<Field
label="Business Priority"
loadFrom="businessPriority"
name="business_priority"
component={this.renderSelectField}
type="select"
/>
<Field
label="Expiry date (dd-MMM-yy)"
name="expiry_date"
component={this.renderTextField}
type="text"
/>
<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">
<button id="btnSubmit" type="submit" name="btnSubmit" className="btn btn-vodafone hidden-print">Submit</button>
</div>
</div>
</form>
</div>
);
}
return <div className="container-fluid">{form}</div>;
}
}
SecurityExemptionsNew = connect(mapStateToProps, mapDispatchToProps)(
SecurityExemptionsNew
);
function validate (values) {
console.log(values);
const errors = {};
if(!values.exemption_type){
errors.exemption_type = "Select exemption type";
}
if(!values.market){
errors.market = "select market";
}
if(!values.service_domain){
errors.service_domain = "select service domain";
}
if(!values.service_id){
errors.service_id = "Select a service";
}
if(!values.name){
errors.name = "Enter summary";
}
return errors;
}
export default reduxForm({
form: 'SecurityExemptionsNewForm', // a unique name for this form
validate,
initialValues: {
exemption_type: 'Security',
market: 'Group Enterprise Technology (GET)',
service_domain: 'Corporate (Internal/External)',
service_id: '0',
name: 'test',
security_engineer: '',
business_priority: 'Low'
}
})(SecurityExemptionsNew);
I have also tried
export default reduxForm({
form: 'SecurityExemptionsNewForm', // a unique name for this form
validate,
initialValues: {
exemption_type: 'Security',
market: 'Group Enterprise Technology (GET)',
service_domain: 'Corporate (Internal/External)',
service_id: '0',
name: 'test',
security_engineer: '',
business_priority: 'Low'
}
})(
connect(mapStateToProps, mapDispatchToProps)(SecurityExemptionsNew)
);
I think the order must be
1. reduxForm
let form = reduxForm({
form: 'SecurityExemptionsNewForm', // a unique name for this form
validate,
initialValues: {
exemption_type: 'Security',
market: 'Group Enterprise Technology (GET)',
service_domain: 'Corporate (Internal/External)',
service_id: '0',
name: 'test',
security_engineer: '',
business_priority: 'Low'
}
})(SecurityExemptionsNew);
2. Connect()
SecurityExemptionsPage = connect(mapStateToProps, mapDispatchToProps)(form);
3. Export
export { SecurityExemptionsPage as SecurityExemptionsNew };
I am trying to get the values from my second form. It renders some select options and when I hit the delete button it just returns an empty object. How do I get the value from the options. With the normal input fields it would pass values with the name.
For example if I had an input type="text" name="email", when I would submit this it would give my an object like:
{email: "some string"}
Here is the code:
import React , { Component } from 'react';
// import * as actions from '../actions';
import { reduxForm, Field } from 'redux-form';
import {connect} from 'react-redux';
import {postBooks, deleteBook} from '../../actions/booksActions';
class BooksForm extends Component {
renderField(field) {
const { meta: {touched, error} } = field;
const className = `form-group ${touched && error ? 'has-danger' : ''}`;
return (
<div className={className}>
<label className="control-label"><strong>{field.label}:</strong></label>
<input
className="form-control"
type={field.type}
{...field.input}
/>
<div className="text-help">
{ touched ? error : ''}
</div>
</div>
);
}
renderSelectField(field) {
const bookList = _.map(field.options, (book) => {
return (
<option key={book._id}>{book.title}</option>
)
});
return(
<div className="form-group">
<label htmlFor="sel1" className="control-label">{field.label}</label>
<select className="form-control" id="sel1">
{bookList}
</select>
</div>
);
}
onSubmit(values) {
this.props.postBooks(values);
}
onDelete(values) {
console.log(values);
}
render() {
const {handleSubmit} = this.props;
return (
<div>
<div className="well">
<form className="panel" onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<div className="panel-body">
<Field
label="Title"
name="title"
type="text"
component={this.renderField}
/>
<Field
label="Description"
name="description"
type="text"
component={this.renderField}
/>
<Field
label="Price"
name="price"
type="text"
component={this.renderField}
/>
<button className="btn btn-primary">Save Book</button>
</div>
</form>
</div>
<form className="Panel" onSubmit={handleSubmit(this.onDelete.bind(this))}>
<div className="panel-body">
<Field
label="Select Book"
name="selectedBook"
options={this.props.books}
component={this.renderSelectField}
/>
<button className="btn btn-danger">Delete</button>
</div>
</form>
</div>
);
}
}
function validate(values) {
const errors = {};
return errors;
}
function mapStateToProps(state) {
return {
books: state.books
}
}
export default reduxForm({
validate,
form: 'bookForm'
})(connect(mapStateToProps, {postBooks, deleteBook})(BooksForm));
In renderSelectField I needed to add {...field.input} into the select to allow redux-form to monitor it.
<select className="form-control" id="sel1" {...field.input}>
I am using redux-form 6.3 version and in this validate function getting called. below is my code. Please check what is issue in code.
Also is there any need to do changes related to validation in actions
import React, { Component } from 'react';
import { Field, reduxForm, initialize } from 'redux-form';
import { connect } from 'react-redux';
import * as actions from '../../actions';
const renderField = field => (
<div className="form-group">
<label>{field.input.label}</label>
<input {...field.input} value={field.value} onChange={(e)=> console.log(e.target.value) } />
{field.touched && field.error && <div className="error">{field.error}</div>}
</div>
);
const renderSelect = field => (
<div>
<label>{field.input.label}</label>
<select {...field.input}/>
{field.touched && field.error && <div className="error">{field.error}</div>}
</div>
);
function validate(formProps) {console.log("vvv---", formProps);
const errors = {};
if (!formProps.firstName) {
errors.firstName = 'Please enter a first name';
}
if (!formProps.lastName) {
errors.lastName = 'Please enter a last name';
}
if (!formProps.email) {
errors.email = 'Please enter an email';
}
if (!formProps.phoneNumber) {
errors.phoneNumber = 'Please enter a phone number'
}
if(!formProps.sex) {
errors.sex = 'You must enter your sex!'
}
return errors;
}
class ReduxFormTutorial extends Component {
componentDidMount() {
this.handleInitialize();
}
handleInitialize() {
const initData = {
"firstName": "Puneet",
"lastName": "Bhandari",
"sex": "male",
"email": "test#gmail.com",
"phoneNumber": "23424234"
};
this.props.initialize(initData);
}
handleFormSubmit(formProps) {
//console.log(formProps);
this.state = { firstName : null };
this.props.submitFormAction(formProps);
}
//our other functions will go here
render() {
const { fields : [firstName, lastName], handleSubmit } = this.props;
return (
<div>
<form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
<Field name="firstName" value="" type="text" component={renderField} label="First Name" />
<Field name="lastName" value="" type="text" component={renderField} label="Last Name"/>
<Field name="sex" component={renderSelect} label="Gender">
<option></option>
<option name="male">Male</option>
<option name="female">Female</option>
</Field>
<Field name="email" type="email" component={renderField} label="Email" />
<Field name="phoneNumber" type="tel" component={renderField} label="Phone Number"/>
<button action="submit">Save changes</button>
</form>
</div>
)
}
}
const form = reduxForm({
form: 'ReduxFormTutorial',
fields: [ 'firstName', 'lastName' ],
validate
});
function mapStateToProps(state) {
return {
user: state.user
};
}
export default connect(mapStateToProps, actions)(form(ReduxFormTutorial));