onChange Event not Triggered in React JS - javascript

export default function ActionRolesPage(props) {
const [authorities, setAuthorities] = useState([]);
const [name, setName] = useState("");
let list = [];
useEffect(() => {
getAuthorities();
}, []);
const getAuthorities = () => {
doGetAllAuthorities()
.then((res) => {
getValidatedData(res.data, "array").map((data) => (
list.push({ authority: data})
))
setAuthorities(list);
}).catch((e) => {
console.log(e);
})
}
const handleChange = (e) => {
console.log(e);
const { name, checked } = e.target
console.log(name,checked);
let tempUser = authorities.map((user) => (
user.authority === name ? { ...user, isChecked: checked } : user
));
setAuthorities(tempUser);
}
if(authorities.length){
console.log(authorities);
}
return (
<React.Fragment>
<Suspense fallback={<div>Loading....</div>}>
<div className="page-content">
<MetaTags>
<title>Add Role | IG One</title>
</MetaTags>
<Container fluid>
<Breadcrumb
title="Add Role"
breadcrumbItems={[{ title: "Settings" }, { title: "Roles" }, { title: "Add" }]}
/>
<Form onSubmit={handleSubmit}>
<Card>
<CardBody>
<Row className="mb-3">
<label
htmlFor="example-text-input"
className="col-md-2 col-form-label"
>
Name
</label>
<div className="col-md-8 mx-0">
<Input
className="form-control"
type="text"
name="name"
required
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name Of User "
/>
</div>
</Row>
<br></br>
<br></br>
<Row className="mb-3">
<CardTitle>
Authorities
</CardTitle>
<div className="col-md-2">
{
authorities.map((data,index) => (
<>
<div key={index} style={{ display: "flex" }}>
<div className='col-md-10 mx-0 mt-2'>
<Input type={"checkbox"}
checked={data?.isChecked || false}
name={data.authority}
onChange={(e) => console.log(e)}
className="form-control"
style={{ cursor: "pointer", paddingLeft: "1rem" }}
/></div>
<div>
<label style={{ cursor: "pointer" }} htmlFor={data.authority} className="col-md-50 col-form-label"> {data.authority}</label>
</div>
</div>
</>
))
}
</div>
</Row>
<Row className="d-flex justify-content-center mt-4">
<Button color="dark" type='submit' className="btn-xs" style={{ width: "40%", cursor: "pointer" }}
>
Add Role
</Button>
</Row>
</CardBody>
</Card>
</Form>
</Container>
</div>
</Suspense>
</React.Fragment>
)
}
Here is the whole code. I want to handle multiple checkboxes but onChange Event not triggered. There is a function handleChange it calls when onChange triggered but in my case there is no error seen in console as well as not display any event at console please resolve my doubt.
I also need to update the form getting respose from backend is checked authority name array How to handle checked state in checkbox.

If you have created a custom component for input, pass your onChange handler as prop and call inside the component as onChage event of <input> field. Or if you used any third-party lib, then you just need to pass a callback as prop. Otherwise Try this: <input> instead of <Input>
<input type={"checkbox"}
checked={data?.isChecked || false}
name={data.authority}
onChange={(e) => console.log(e)}
className="form-control"
style={{ cursor: "pointer", paddingLeft: "1rem" }}
/>

Related

Dynamic input in FieldArray

i have form, inside i have this part of code:
<FieldArray name="items_list" component={renderItemList} explicitProp={id}/>
<div className="buttons mb-4 text-center">
<div className="btn btn-outline-info mt-4" type="button" onClick={() => push('items_list', undefined)}> Añadir Parametros </div>
</div>
outside of the form i have this:
const renderItemList = ({ fields, explicitProp }) => {
return (
<>
{fields.map((member, index) => (
<>
<div className="row mt-4" key={index}>
<div className="col-md-3">
<h4>{index + 1}- Valor de la Lista </h4>
</div>
<Field
className="form-control"
name={`${member}.idResponse`}
type='text'
component={renderIdResponse}
props={explicitProp + '_E_' + Number(index + 1)}
hidden
/>
<div className="col-md-3 mb-4">
<Field
className="form-control"
name={`${member}.title_item`}
type="text"
component="input"
/>
</div>
<div className="col-md-4">
<FieldArray name={`${member}.value_item`} component={renderValueItems} />
</div>
<div className="col-md-1"
onClick={() => fields.remove(index)}
style={{ cursor: 'pointer' }}
>
❌
</div>
</div>
</>
))}
</>
);
};
const renderValueItems = ({ fields, meta: { error } }) => (
<div className="row">
<div>
<button className="btn btn-outline-primary col-md-12" type="button" onClick={() => fields.push()}>Añadir Sinonimos</button>
</div>
{fields.map((valor, index) => (
<div className="mt-3" key={index}>
<div className="row">
<div className="col-md-10">
<Field
className="form-control"
name={valor}
type="text"
component="input"
label={`Sinónimo ${index + 1}`}
/>
</div>
<div className="col-md-2"
onClick={() => fields.remove(index)}
style={{ cursor: 'pointer' }}
> ❌
</div>
</div>
</div>
))}
{error && <li className="error">{error}</li>}
</div>
);
const renderIdResponse = ({props}) => (
console.log(props),
<Field name='texto' {...props} />
);
I would like to get inside the items_list array the object for every item like this:
"items_list": [
{
"idResponse": CA2_3_E_(index + 1)
"title_item": "RESPUESTA 1",
"value_item": [
"SINONIMO 1",
"SINONIMO 2"
]
}
]
but i can not achieve the idResponse. i pass the 'id' in the form like a explicitProp, and then inside the renderItemList i did try to pass directly a value, created with the explicitProp and index to augment the value.
But not works.
I did try to create i component "renderIdResponse" pass the explicitProp like a prop, and inside try to create the value for every object in the array, but i don't know how.
Some idea.
Thanks

React - multi step form with checkbox in child step does not set to true

I am creating a multistep form in react. The Parent component has 3 child components which are the steps of the form. In the first step I have 4 text inputs and need a checkbox to allow wpp communication, the problem is that i can't set the state of the checkbox to true when is clicked.
The parent component is something like this:
import React from 'react';
import FormStep0 from './formStepZero';
import FormStep1 from './formStepOne';
class VendeForm extends React.Component {
constructor(props) {
super(props)
this.state = {
currentStep: 0,
nombre: '',
apellido: '',
celular: '',
email: '',
username: '',
password: '',
checkbox: false,
}
}
handleChange = event => {
const {name, value} = event.target
this.setState({
[name]: value
})
}
handleSubmit = event => {
event.preventDefault()
const { email, username, password, nombre, apellido, celular,checkbox } = this.state
alert(`Your registration detail: \n
Email: ${email} \n
Username: ${username} \n
Password: ${password} \n
Nombre: ${nombre} \n
Apellido: ${apellido} \n
Celular: ${celular} \n
Checkbox: ${checkbox} \n`)
}
_next = () => {
let currentStep = this.state.currentStep
currentStep = currentStep >= 2? 3: currentStep + 1
this.setState({
currentStep: currentStep
})
}
_prev = () => {
let currentStep = this.state.currentStep
currentStep = currentStep <= 0? 0: currentStep - 1
this.setState({
currentStep: currentStep
})
}
/*
* the functions for our button
*/
previousButton() {
let currentStep = this.state.currentStep;
if(currentStep > 1){
return (
<div className='vertical-center'>
<button
className="btn btn-secondary float-right mx-2 my-2"
type="button" onClick={this._prev}>
Previous
</button>
</div>
)
}
return null;
}
nextButton(){
let currentStep = this.state.currentStep;
if(currentStep <3 && currentStep >=1){
return (
<div className='vertical-center'>
<button
className="btn primary-bg-style float-left mx-2 my-2"
type="button" onClick={this._next}>
Siguiente
</button>
</div>
)
}
return null;
}
empecemosButton(){
let currentStep = this.state.currentStep;
if(currentStep === 0){
return (
<div className='vertical-center'>
<button
className="btn primary-bg-style"
type="button" onClick={this._next}>
Vamos!
</button>
</div>
)
}
return null;
}
render() {
return (
<React.Fragment>
{/*render the form steps and pass required props in*/}
<Step0
currentStep={this.state.currentStep}
handleChange={this.handleChange}
/>
<div className="container d-flex flex-column py-2">
<form onSubmit={this.handleSubmit}>
<Step1
currentStep={this.state.currentStep}
handleChange={this.handleChange}
nombre={this.state.nombre}
apellido={this.state.apellido}
celular={this.state.celular}
email={this.state.email}
checkbox={this.state.checkbox}
/>
<Step2
currentStep={this.state.currentStep}
handleChange={this.handleChange}
username={this.state.username}
/>
<Step3
currentStep={this.state.currentStep}
handleChange={this.handleChange}
password={this.state.password}
/>
</form>
<div className='prev-next-btn'>
{this.previousButton()}
{this.nextButton()}
</div>
{this.empecemosButton()}
</div>
</React.Fragment>
);
}
}
function Step0(props){
if (props.currentStep !== 0) {
return null
}
return(
<div className="vertical-center"> {/*<!--^--- Added class --> */}
...
</div>
)
}
function Step1(props) {
if (props.currentStep !== 1) {
return null
}
return(
<div className="form-group">
<div className="vertical-center">
<div className="container">
<h1 className='pb-4 px-2'>Datos de Contacto</h1>
<CircleSteps currentStep={props.currentStep} />
<FormStep1 nombre={props.nombre}
apellido={props.apellido}
celular={props.celular}
email={props.email}
checkbox={props.checkbox}
handleChange = {props.handleChange}
/>
</div>
</div>
</div>
);
}
export default VendeForm;
and the child component where is the checkbox is:
import React from 'react';
import {Col, Row,Container} from 'reactstrap'
function FormStep1(props) {
return(
<div>
<Container className="vende-form-container pt-3">
<Row className='align-items-center justify-content-center'>
<Col md={4} sm={12}>
<div className="form-group">
<label htmlFor="nombre">Nombre</label>
<input
className="form-control"
id="nombre"
name="nombre"
type="text"
placeholder="Escribe tu nombre"
value={props.nombre}
onChange={props.handleChange}
/>
</div>
</Col>
<Col md={4} sm={12} >
<div className="form-group">
<label htmlFor="apellido">Apellido</label>
<input
className="form-control"
id="apellido"
name="apellido"
type="text"
placeholder="Escribe tu apellido"
value={props.apellido}
onChange={props.handleChange}
/>
</div>
</Col>
</Row>
<Row className='align-items-center justify-content-center'>
<Col md={4} sm={12}>
<div className="form-group">
<label htmlFor="celular">Celular</label>
<input
className="form-control"
id="celular"
name="celular"
type="text"
placeholder="Escribe tu celular"
value={props.celular}
onChange={props.handleChange}
/>
</div>
</Col>
<Col md={4} sm={12}>
<div className="form-group">
<label htmlFor="email">Email</label>
<input
className="form-control"
id="email"
name="email"
type="text"
placeholder="Escribe tu email"
value={props.email}
onChange={props.handleChange}
/>
</div>
</Col>
</Row>
<Row className='align-items-center justify-content-start'>
{/* checkbox allowing whatsapp communication */}
<Col sm={{size:6, offset:2}} md={{size:3, offset:2}}>
<div className="form-check">
<input
className="form-check-input"
id="wppCheckbox"
name="controlled"
type="checkbox"
checked={props.checkbox}
onChange={props.handleChange}
/>
<label className="form-check-label" htmlFor="wppCheckbox">
Aceptas comunicacion via Whatsapp
</label>
</div>
</Col>
</Row>
</Container>
</div>
);
}
export default FormStep1;
The behavior that currently I have is that i click the checkbox but remains in blank, also the others fields of the form are working well and are passed to state properly
If I understand correctly, your checkbox is handled by generic handleChange() function:
handleChange = event => {
const {name, value} = event.target
this.setState({
[name]: value
})
}
Simplest thing you could try for debugging is just logging what you get in that function when you click the checkbox. Most probably in this case you are always getting the same value ("on") hence nothing changes in the state.
I would suggest either use a dedicated handler, or modify this one to be sth like
handleChange = event => {
const {name, type, value} = event.target
if (type === 'checkbox') {
return this.setState({
[name]: event.target.checked
})
}
this.setState({
[name]: value
})
}

None of the Tabs' children match with `[object Object]`. You can provide one of the following values: 0, 1

I am building header using material UI Tab Component but I see below error:
index.js:2178 Material-UI: The value provided to the Tabs component is invalid.
None of the Tabs' children match with [object Object].
You can provide one of the following values: 0, 1.
I tried console.log the newValue to see what value it is getting and I can see 0 and 1 while navigating through tabs.
Note : Removed Some Code for better visibility
Here is my component:
const Header = (props) => {
const { classes } = props;
const [value, setValue] = useState(0);
const [modalIsOpen, setIsOpen] = React.useState(false);
const openModal = () => {
setIsOpen(true);
};
const closeModal = () => {
setIsOpen(false);
};
const handleTabChange = (event, newValue) => {
console.log(newValue);
setValue({ newValue });
};
return (
<div>
<div className="topnav">
<img src={logo} className="logo" alt="Movies App Logo" />
<div className="topnav-right">
<Button variant="contained" color="default" onClick={openModal}>
Login
</Button>
</div>
<div className="topnav-right">
<Button variant="contained" color="default">
Logout
</Button>
</div>
</div>
<Modal
ariaHideApp={false}
isOpen={modalIsOpen}
onRequestClose={closeModal}
contentLabel="Login"
aria-labelledby="Modal"
aria-describedby="Modal for Login and Registration"
style={customStyles}
>
<Paper className={classes.Paper}>
<CardContent>
<Tabs
className="tabs"
value={value}
onChange={handleTabChange}
centered
>
<Tab label="Login" />
<Tab label="Register" />
</Tabs>
{value === 0 && (
<div>
<FormControl required>
<InputLabel htmlFor="username" className={classes.inputLable}>
Username
</InputLabel>
<Input
className={classes.Input}
id="username"
type="text"
username={username}
onChange={usernameChangeHandler}
/>
<FormHelperText>
<span className="red">required</span>
</FormHelperText>
</FormControl>
<br />
<br />
<FormControl required>
<InputLabel
htmlFor="loginPassword"
className={classes.inputLable}
>
Password
</InputLabel>
<Input
className={classes.Input}
id="loginPassword"
type="password"
password={password}
onChange={passwordChangeHandler}
/>
<FormHelperText>
<span className="red">required</span>
</FormHelperText>
</FormControl>
<br />
<br />
{loggedIn === true && (
<FormControl>
<span className="success-text">Login Successful!</span>
</FormControl>
)}
<br />
<br />
<Button
variant="contained"
color="primary"
onClick={loginHandler}
>
LOGIN
</Button>
</div>
)}
{value === 1 && (
<div>
<h1>something</h2>
</div>
)}
</CardContent>
</Paper>
</Modal>
</div>
);
};
export default withStyles(styles)(Header);
For some reason you enclosed the value in an object (curly braces syntax).
Replace setValue({ newValue }) with setValue(newValue).

TypeError: Cannot read property 'length' of undefined in react.js

this is the error i'm getting in my react application. please help me fix this. I've extended the code for better understanding. Have any idea what's the problem
const TextEditor = (value, props) => {
console.log(props.value)
console.log(props.value.length)
const renderElement = useCallback(props => <Element {...props} />, [])
const renderLeaf = useCallback(props => <Leaf {...props} />, [])
const editor = useMemo(() => withHistory(withReact(createEditor())), [])
update-as told, I've added the code where i pass my values.
I've used value= {value.document} where I've initialised document in the initialValues below
const TextEditor = (value, props) => {
console.log(props.value)
console.log(props.value.length)
const renderElement = useCallback(props => <Element {...props} />, [])
const renderLeaf = useCallback(props => <Leaf {...props} />, [])
const editor = useMemo(() => withHistory(withReact(createEditor())), [])
const [isPreviewModalOpen, setPreviewModal] = useState(false);
const initialValues= {
title:value.title,
document: value.document,
}
return (
<>
<div className="text-center pt-3">
<h2 style={{color: "#3D44C8", fontWeight: "bold"}}>Ask an expert</h2>
<p style={{color: "#DB262F", fontWeight: "bold", fontSize: "18px"}}>Get your questions solved within 24 hours!</p>
</div>
<Slate editor={editor} value={props.value} onChange={value => {
props.setValue(value);}} >
<div className="textEditor_toolbar">
<div className="textEditor_buttonedit">
<Navbar style={{padding: "0"}} expand="lg">
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Navbar.Brand>
<ButtonGroup>
<MarkButton format="bold" tooltip="bold" icon={faBold}/>
<MarkButton format="italic" icon={faItalic} />
<MarkButton format="underline" icon={faUnderline} />
</ButtonGroup>
<ButtonGroup>
<MarkButton2 format="code" icon={faCode}/>
<BlockButton format="bulleted-list" icon={faListUl} />
<BlockButton format="numbered-list" icon={faListOl} />
</ButtonGroup>
</Navbar.Brand>
<Nav>
<label className="custom-file-upload">
<input
type="file"
name="profileImg"
accept="image/png, image/jpeg"
multiple="false"
onChange={setImage}
/>
<FontAwesomeIcon className="custom-file-icon" icon={faPaperclip}/>
</label>
</Nav>
<Form>
<Choice />
</Form>
</Navbar.Collapse>
</Navbar>
</div>
</div>
<div>
</div>
<Editable
className="textEditorMain"
renderElement={renderElement}
renderLeaf={renderLeaf}
value={value.document}
placeholder="Type your Question, Paste your Question text or Attach images or PDF here"
spellCheck
autoFocus
useReadOnly
onPaste = {onPaste}
onKeyPress={event => {
for (const hotkey in HOTKEYS) {
if (isHotkey(hotkey, event )) {
event.preventDefault()
const mark = HOTKEYS[hotkey]
toggleMark(editor, mark)
}
}
}}
/>
</Slate>
props.value is undefined, make sure you are correctly passing your props

React not closing dialog box

Im using materialUI to click a menu item that then opens a dialog box(child component) however after the dialogbox opens it wont seem to close and wont update the data for noticeModal. There are not any errors being thrown and i belive it has to do with using useEffect to setNoticeModal(props.open) for the initial state. Ive tried removing the useEffect() and throwing props.open into the default useDate() for the noticeModal however upon doing that then my dialogbox wont open anymore at all. What am i over looking here?
holidaySettings.js
...
const [dialogOpen, setDialogOpen] = React.useState(false);
const handleDialogOpen = (dataElement) => {
setDialogData(dataElement);
setDialogOpen(true);
setOpen(false);
}
...
<ClickAwayListener onClickAway={handleClose}>
<MenuList autoFocusItem={open} id="menu-list-grow" onKeyDown={handleListKeyDown}>
<MenuItem onClick={handleDialogOpen}>Add Holiday</MenuItem>
</MenuList>
</ClickAwayListener>
...
<div className="card-body">
<div className="row">
<div className="text-left col-12">
<Styles>
<Table columns={columns} data={data} />
<HolidayDialog open={dialogOpen} onClose={handleDialogClose} data={dialogData}/>
</Styles>
</div>
</div>
</div>
...
holidayDialog.js
const HolidayDialog = (props) => {
const [noticeModal, setNoticeModal] = useState(false);
const [selectedDate, setSelectedDate] = useState(new Date());
const [holidayData, setHolidayData] = useState(props.data);
useEffect(() => {
setNoticeModal(props.open)
});
const handleDateChange = (date) => {
setSelectedDate(date);
};
const handleClose = () => {
setNoticeModal(false);
console.log(noticeModal);
};
const handleChange = (e) => {
const { name, checked } = e.target;
setHolidayData((prevState) => ({ ...prevState, [name]: checked }));
};
const updateValues = (e) => {
const { name, value } = e.target;
setHolidayData((prevState) => ({ ...prevState, [name]: value }));
}
return (
<Dialog
open={noticeModal}
TransitionComponent={Transition}
keepMounted
onClose={handleClose}
aria-labelledby="notice-modal-slide-title"
aria-describedby="notice-modal-slide-description"
>
<DialogTitle id="customized-dialog-title" onClose={handleClose}>
{holidayData.HolidayName ? holidayData.HolidayName : 'Create New Holiday'}
</DialogTitle>
<DialogContent dividers>
<form noValidate autoComplete="off">
<div className="row">
<div className="col">
<TextField required name="HolidayName" id="outlined-basic" label="Holiday Name" variant="outlined" onChange={updateValues} value={holidayData.HolidayName || ''}/>
</div>
<div className="col">
<TextField id="outlined-basic" name="Branch" label="Branch" variant="outlined" onChange={updateValues} value={holidayData.Branch || 'ALL'}/>
</div>
</div>
<div className="row mt-3">
<div className="col">
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
disableToolbar
variant="inline"
format="MM/dd/yyyy"
margin="normal"
id="date-picker-inline"
label="Date picker inline"
value={selectedDate}
onChange={handleDateChange}
KeyboardButtonProps={{
'aria-label': 'change date',
}}
/>
</MuiPickersUtilsProvider>
</div>
<div className="col">
<TextField id="outlined-basic" name="Hours" label="Hours" variant="outlined" onChange={updateValues} value={holidayData.Hours || 'Closed'}/>
</div>
</div>
<div className="row mt-3">
<div className="col d-flex flex-column">
<FormControlLabel
control={
<Checkbox
checked={holidayData.Web || false}
value={holidayData.Web}
onChange={handleChange}
name="Web"
color="primary"
/>
}
label="Show on Web?"
/>
<FormControlLabel
control={
<Checkbox
checked={holidayData.CoOp || false}
value={holidayData.CoOp}
onChange={handleChange}
name="CoOp"
color="primary"
/>
}
label="CoOp Holiday?"
/>
</div>
<div className="col d-flex flex-column">
<FormControlLabel
control={
<Checkbox
checked={holidayData.Phone || false}
value={holidayData.Phone}
onChange={handleChange}
name="Phone"
color="primary"
/>
}
label="Use in IVR?"
/>
<FormControlLabel
control={
<Checkbox
checked={holidayData.Active || true}
value={holidayData.Active}
onChange={handleChange}
disabled
name="Active"
color="primary"
/>
}
label="Active"
/>
</div>
</div>
</form>
</DialogContent>
<DialogActions>
<Button autoFocus onClick={handleClose} color="default">
Cancel
</Button>
<Button autoFocus onClick={handleClose} color="primary">
Create Holiday
</Button>
</DialogActions>
</Dialog>
)
}
export default HolidayDialog;
Could you try this?
I am assuming props.onClose is making dialogOpen to false on parent(holidaySettings)
const handleClose = () => {
props.onClose()
};
If props.onClose is not making dialogOpen to false on parent(holidaySettings).You can add close attribute which sets dialogOpen to false.
<HolidayDialog open={dialogOpen} close={()=>setDialogOpen(false);} onClose={handleDialogClose} data={dialogData}/>
const handleClose = () => {
props.close()
};
And passing props.open to Dialog
<Dialog
open={props.open}
/>
You are not providing any dependency to useEffect so it runs on every re-render. In your useEffect you are toggling the modal and hence the issue.
useEffect(() => {
setNoticeModal(props.open)
});//<---- issue - missing dependency
Solution - pass dependency as props.open. This makes the useEffect to run only when props.open is changed.
useEffect(() => {
setNoticeModal(props.open)
}, [props.open]); //<----- props.open
Inside the useEffect, you are resetting the noticeModal value to props.open which i believe is true?
I believe what you are trying to do is set the initial value of noticeModal.
Try changing to the code below and remove the useEffect
const [noticeModal, setNoticeModal] = useState(props.open);

Categories

Resources