I'm currently messing around with Reactjs and don't know where exactly my problem lays. I wan't to render an input field if a certain chekbox is selected (requiredRoleResponsible in this case). If i check it first time to true it works fine, but if I deselect it, it won't disappear. Maybe i missing something?
class ProccessForm extends React.Component {
constructor(props) {
super(props)
this.state = { name: '', description: '', requireSupervisor: false, requireRoleResponsible: false, roleResponsible: '' }
this.handleNameChange = this.handleNameChange.bind(this);
this.handleDescriptionChange = this.handleDescriptionChange.bind(this);
this.handleSupervisorCheckbox = this.handleSupervisorCheckbox.bind(this);
this.handleRoleResponsibleCheckbox = this.handleRoleResponsibleCheckbox.bind(this);
this.handleRoleResponsibleChange = this.handleRoleResponsibleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e, data) {
e.preventDefault();
const name = this.state.name.trim();
const description = this.state.description.trim();
if (!name || !description)
return;
this.props.onProcessSubmit({ name: name, description: description });
this.setState({ name: '', description: '' });
}
handleSupervisorCheckbox(e) {
this.setState({requireSupervisor: Boolean(e.target.value)});
}
handleRoleResponsibleCheckbox(e) {
this.setState({requireRoleResponsible: Boolean(e.target.value)});
}
handleRoleResponsibleChange(e) {
this.setState({roleResponsible: e.target.value});
}
handleNameChange(e) {
this.setState({ name: e.target.value })
}
handleDescriptionChange(e) {
this.setState({ description: e.target.value })
}
render() {
return (
<div className="panel-body">
<form className="processForm" onSubmit={this.handleSubmit}>
<div className="form-group">
<label htmlFor="inputName">Name</label>
<input className="form-control" id="inputName" type="text" placeholder="Prozessname" value={this.state.name} onChange={this.handleNameChange} />
</div>
<div className="form-group">
<label htmlFor="inputDescription">Beschreibung</label>
<textarea className="form-control" id="inputDescription" type="text" placeholder="Prozessbeschreibung" value={this.state.description} onChange={this.handleDescriptionChange} />
</div>
<span>Welche Genehmigungen werden benötigt?</span>
<div className="checkbox">
<label><input type="checkbox" value={this.state.requireSupervisor} onChange={this.handleRoleResponsibleCheckbox}/>Vorgesetzer</label>
</div>
<div className="checkbox">
<label><input type="checkbox" value={this.state.requireRoleResponsible} onChange={this.handleRoleResponsibleCheckbox}/>Rollenverantwortlicher</label>
</div>
{this.state.requireRoleResponsible ?
<div className="form-group">
<label htmlFor="inputRoleResp">Name</label>
<input className="form-control" id="inputRoleResp" type="text" placeholder="Rollenverantwortlicher" value={this.state.roleResponsible} onChange={this.handleRoleResponsibleChange} />
</div> : null}
<div>
<input type="submit" value="erstellen" />
</div>
</form>
</div>
);
}
}
I tried different approaches I seen online so far. Making the second part of the if to null like currently in my code. Just to use this.state.requireRoleResponsible && the to render part and in the handler to make explicitely a boolean out of the value
Thanks for your help
For checkbox you need to use checked instead of value.
Checked will determined if the checkbox is checked or not. Value is just a property to hold.
In this case you need to change:
<input type="checkbox" value={this.state.requireRoleResponsible}
onChange={this.handleRoleResponsibleCheckbox}/>Rollenverantwortlicher</label>
To:
<input type="checkbox" checked={this.state.requireRoleResponsible}
onChange={this.handleRoleResponsibleCheckbox}/>Rollenverantwortlicher</label>
And change the handler to:
handleRoleResponsibleCheckbox(e) {
this.setState({requireRoleResponsible: e.target.checked});
}
With checkbox you should use checked instead of value ( should use value attr for type: text , select , ... )
And in 2 function handler for your checkbox , i think you can use like this :
handleRoleResponsibleCheckbox(e) {
//this.setState({requireRoleResponsible: Boolean(e.target.value)});
this.setState((prevState)=>{
return {
requireRoleResponsible: !prevState.requireRoleResponsible
}
})
}
with prevState is current state before you update
Related
function App() {
let [account, setAccount] = React.useState({
startdate: "",
enddate: "",
reason: "",
leavetype: "",
});
function handleChange(e) {
let name = e.target.name;
let value = e.target.value;
account[name] = value;
setAccount(account);
}
function Submit(e) {
e.preventDefault();
console.log(account);
}
return (
<div>
<fieldset>
<form className="" method="post" onSubmit={Submit}>
Start Date:
<input
type="date"
name="startdate"
min={new Date().toISOString().split("T")[0]}
onChange={handleChange}
required
/>
End Date:
<input
type="date"
name="enddate"
// min={}
onChange={handleChange}
required
/>
</form>
</fieldset>
</div>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
You need to use the state that you have.
function App() {
const [account, setAccount] = React.useState({
startdate: "",
enddate: "",
reason: "",
leavetype: "",
});
function handleChange(e) {
const name = e.target.name;
const value = e.target.value;
// treat state as immutable!
// you need to creaet a new object here
// See https://stackoverflow.com/a/25333702/17487348 for how to create a property from a string in ES6
setAccount({...account, [name]: value});
}
function Submit(e) {
e.preventDefault();
console.log(account);
}
return (
<div>
<fieldset>
<form className="" method="post" onSubmit={Submit}>
<legend>Your trip</legend>
<label for="startdate">Start Date:</label>
<input
type="date"
name="startdate"
min={new Date().toISOString().split("T")[0]}
onChange={handleChange}
required
/>
<label for="enddate">End Date:</label>
<input
type="date"
name="enddate"
disabled={account.startdate === "" ? true: false}
min={account.startdate ? new Date(account.startdate).toISOString().split("T")[0]: ""}
onChange={handleChange}
required
/>
</form>
</fieldset>
</div>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
When you look at the code there are some other changes which you should consider.
I would disable the end date date picker as long as there is no start date selected or set sensible default values for start end end date (e.g. today for both) and set those when defining the state.
More important: You should treat state as immutable that means you need to create a new object every time the state changes as React only does a shallow comparison. Otherwise the component won't re-render. So use setAccount({...account, [name]: value}); to update your state. You need to use [] here so the variable content is interpreted as the name of the property. See this thread.
You also probably want to use <label> and maybe <legend>. See the MDN docs for <fieldset>.
For more options to control the datepicker see MDN docs for <input type="date">.
I'm trying to set up react-fook-form to validate my forms, but when I use the register function on a text input (in my case the username input), this input is no longer editable, I can't type anything inside.
const {register, handleSubmit, formState: { errors }} = useForm();
const [username, setUsername] = useState('');
.....
<form onSubmit={handleSubmit(onSubmit)}>
<label htmlFor="username">Username : </label>
<input type="text" value={username}
onChange={e => setUsername(e.target.value)}
{...register('username', { required: 'Please, type in your username' })}
/>
{errors.username && <span style={{color: 'red'}}><br/>{errors.username.message}</span>}
<br/>
<label htmlFor="password">Password : </label>
<input type="password" value={password} onChange={e => setPassword(e.target.value)}/>
<br/>
<button type="submit">Login</button>
</form>
Ok I finally found the solution myself.
Since the version 7 of react-hook-form library, we have to place "onChange" inside the register function like so :
<input type="text" value={username} {...register('username', {
required: 'Please, type in your username',
onChange: e => setUsername(e.target.value)
})}/>
I am trying to use Formik in React for a dummy app. I am not being able to type anything in either of the input boxes if I give value as a prop. On the other hand, if I skip the value props, then I can type in the boxes but the same is not reflected as the value while submitting.
Here's the code:
export default class DashboardPage extends React.Component {
render() {
return (
<Formik
initialValues={{ fname: "", lname: "" }}
onSubmit={(values) => {
alert(values.fname);
}}
render={({ values, handleChange, handleSubmit }) => (
<form onSubmit={handleSubmit}>
<input type="text" placeholder="First Name" name="fname" onChange={handleChange} value={values.fname} />
<input type="text" placeholder="Last Name" name="lname" onChange={handleChange} value={values.lname} />
<button type="submit>ADD<button/>
</form>
)}
/>
);
}
}
I may be very wrong here and might be over-looking a minor error, but any help/suggestion is appreciated!
export default class DashboardPage extends React.Component {
render() {
return (
<Formik
initialValues={{ fname: "", lname: "" }}
onSubmit={ (values) => alert(values.fname) }
>
{ props => (
<React.Fragment>
<form onSubmit={handleSubmit}>
<input type="text" placeholder="First Name" name="fname" onChangeText={props.handleChange('fname')} />
<input type="text" placeholder="Last Name" name="lname" onChangeText={props.handleChange('lname')} />
<button type="submit>ADD<button/>
</form>
</React.Fragment>
)}
</Formik>
)
}
}
Hi mate can you please try this?
Another possibility for this weird behavior is putting your component inside a function and sending the props as function parameters instead of using a functional component with props as parameters.
When a component is inside a function you lose react component lifecycle and the parameters will not refresh even when its values change.
Make sure your form elements are properly configured as react elements.
Mine was also not working, I gave id prop in my TextField and now it works
const formik = useFormik({
initialValues: {
username: "",
password: "",
},
onSubmit: (values) => {
console.log(values);
// onLogin(values.username, values.password);
},
});
<form onSubmit={formik.handleSubmit}>
<TextField
value={formik.values.username}
onChange={formik.handleChange}
id="username"
name="username"
variant="outlined"
style={TextField1style}
placeholder="Enter username"
fullWidth
required
//.
// .
// .
// other code
enter image description here
I have this simple piece of code in my ReactJs app:
import React from 'react'
import '../../../assets/styles/authentication/login.css'
import '../../../assets/bootstrap/css/bootstrap.min.css'
import { login } from './login_form_actions.js'
export default class LoginForm extends React.Component {
constructor(props) {
super(props)
this.state = {
email : { email: "" },
password : { password: "" }
}
this.handle_sign_in_click = this.handle_sign_in_click.bind(this)
}
handle_sign_in_click(e) {
console.log(e, this.state.email, this.state.password)
login(this.state.email, this.state.password)
}
render() {
return (
<div className="col-sm-6 col-sm-offset-3 form-box">
<div className="form-auth">
<form className="login-form">
<div className="form-group">
<label className="sr-only" htmlFor="form-username">Email</label>
<input type="text" name="form-username" placeholder="Email..."
className="form-username form-control" id="form-username"
onChange={(event) => this.setState({email:event.target.value})}/>
</div>
<div className="form-group">
<label className="sr-only" htmlFor="form-password">Password</label>
<input type="password" name="form-password" placeholder="Password..."
className="form-password form-control" id="form-password"
onChange={(event) => this.setState({password:event.target.value})}/>
</div>
<button className="btn" onClick={this.handle_sign_in_click}>Sign in!</button>
</form>
</div>
</div>
)
}
}
When I click the Sign In button, nothing happens for some reason.
I tried to bind the handle_sign_in_click as proposed in some other reactjs question (from StackOverflow) but still nothing.. What am I missing here? (next step is to use redux to store the result of the auth on success)
Thanks for any help
Edit1: Console and proposition
console:
react-dom.development.js:22287 Download the React DevTools for a better development experience: react-devtools
authentication:1 [DOM] Input elements should have autocomplete attributes (suggested: "current-password"):
However, when I use an <a/> instead of <button/>, it does work but my design is broken (it's the same at all as when it's a button)
Here is how to properly handle basic forms in React (without libs like Formik etc...):
import React from 'react';
export default class Form extends React.Component {
state = { email: '', password: '' };
handleChange = event => {
this.setState({ [event.target.name]: event.target.value });
};
handleSubmit = event => {
event.preventDefault();
// login logic here ususally passed down as props from the parent (if not using redux...) so it will be something like this.props.login(...)
this.setState({ email: '', password: '' });
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<input
name="email"
type="text"
onChange={this.handleChange}
placeholder="email"
value={this.state.email}
/>
<input
name="password"
type="text"
onChange={this.handleChange}
placeholder="password"
value={this.state.password}
/>
<input type="submit" />
</form>
);
}
}
You are missing a e.preventDefault in your signin handler, check this working sample
i am new to angularjs and javascript,I am having a list of radio buttons and have to make some of them selected,so can anybuddy please tell me how to achieve this?I tried ng-value=true with no luck,my code is as below:
<ons-list-item modifier="tappable" ng-repeat="area in vm.AreaList" >
<label class="radio-button radio-button--list-item line-h45">
<input type="radio" ng-bind="area.name" ng-model="vm.selectedArea" name="area" ng-value="area.code" >
<div class="radio-button__checkmark radio-button--list-item__checkmark">
</div>
{{area.name}}
</label>
</ons-list-item>
you can do something like this in your controller:
$scope.results = {
favorites: [{
id: "WatchList1",
title: "WatchList1"
}, {
id: "WatchList2",
title: "WatchList2"
}, {
id: "WatchList3",
title: "WatchList3"
}]
};
$scope.selectedRow = {
id: 'WatchList2'
};
$scope.event = {
type: {
checked: true
}
}
and your html:
<div>
<div ng-repeat="row in results.favorites">
<input type="radio" ng-model="selectedRow.id" value="{{ row.id }}" style="opacity: 1;" class="pointer" />
<span>{{ row.title }}</span>
</div>
</div>
Single box
You should use ngChecked for that.
https://docs.angularjs.org/api/ng/directive/ngChecked
<ons-list-item modifier="tappable" ng-repeat="area in vm.AreaList" >
<label class="radio-button radio-button--list-item line-h45">
<input type="radio" ng-bind="area.name" ng-model="vm.selectedArea" name="area" ng-value="area.code"
ng-checked="true">
<div class="radio-button__checkmark radio-button--list-item__checkmark">
</div>
{{area.name}}
</label>
</ons-list-item>
Only one radio button can be selected at a time.
If you want multiple selected items, then use checkbox and to select, make model value equal to value attribute.