submit form in react with variable set of inputs? - javascript

//form.js
const form=({seg,onSubmit,onChange})=>{
<form id="input_form" onSubmit={onSubmit}>
{seg.map(item=>
<>
<input type="number" onChange={onChange} name={item}
type="number" required className="form-control control" id={item+1} />
</>
)}
</form>}
// app.js
state={array:[0.0,1.0], seg=3}
onSubmit=()=>{
}
onChange=()=>{
// should update the array(as this.state.array=[0.0, inputa,inputb,inputc..., 1.0])}
how do i update the array? what should be the onChange, onSubmit func?
(this.state.seg is variable).

You can use this.setState({ seg : newValue});

You can set the seg state property value like this
onChange=(event)=>{
this.setState({seg: event.target.value});
}
I suppose yo need to update the array with current seg value. If you want to do it using onSubmit, you have to use a button with type of submit. Then the button calls the onSubmit function. Try this.
<form id="input_form" onSubmit={onSubmit}>
{seg.map(item =>
<>
<input type="number" onChange={onChange} name={item} type="number" required className="form-control control" id={item + 1} />
<button type="submit">Submit</button>
</>
)}
</form>
onSubmit=()=>{
this.setState({
array: [...this.state.array, seg]
})
}

Related

How to pass props throught React components without using Redux

Sup guys!
Can I have some help to understood this assessment challenge? I've allready send it, but a horrible doubt keep bouncing on my head:
I was ordered to complete a simple React app, that loads user input in a component, and pass those data as props to another component, rendered from another one. Something like this:
function DataInput(){
const [input, setInput]=useState({
firstName:'',
lastName:'',
phone:'',
)}
function handleChange(e){
setInput({
...input,
[e.target.name]:e.targe.value;
)}
}
function handleSubmit(){
/* dunno if this function is usefull to something. Can't figure out how to pass props from
a child ( DataInput ) to another one ( ContactList)without using Redux to store a Global State.
*/
}
return(
<form>
<input
type="text"
name="firstName"
placeholder="First Name"
value={input.firstName}
onChange={handleChange}
/>
<input
type="text"
name="lastName"
placeholder="Last Name"
value={input.lasttName}
onChange={handleChange}
/>
<input
type="text"
name="phone"
placeholder="Phone Number"
value={input.phone}
onChange={handleChange}
/>
<button onClick={handleSubmit}>Add User</button>
</form>
)}
function ContactList(props){
return(
<div>
<label>{props.firstName}</label>
<label>{props.lastName}</label>
<label>{props.phone}</label>
</div>
)}
function App(){
render(){
<IngresoDatos />
<ContactList />
}
}
ReactDOM.render(<App/>, document.getElementById('root'))

form.validateFields() doesnt work when we have custom antd form component

Considering the following example, this is stopping us to create custom components inside forms using antd4 version.
const handleFormSubmit = () => {
form
.validateFields()
.then((values: any) => {
console.log('success values => ', JSON.stringify(values));
successCallback(values);
})
.catch((errorInfo: any) => {
console.log('failureCallback values => ', JSON.stringify(errorInfo));
failureCallback(errorInfo);
});
};
<Form
form={form}
layout="vertical"
name="normal_login"
className="login-form"
initialValues={store.formData.initialValues}
>
<Form.Item>
<Input placeholder="Name" />
</Form.Item>
<Button type="primary" htmlType="submit" onClick={handleFormSubmit}>
Create
</Button>
</Form>
This works absolutely fine, whereas if the component is custom, then it doesn't work. Example:
function CustomInput(props){
return (
<Form.Item>
<Input placeholder={props.name} />
</Form.Item>
)
}
<Form
form={form}
layout="vertical"
name="normal_login"
className="login-form"
initialValues={store.formData.initialValues}
>
<CustomInput name="Name" />
Will display the field and also validates on change event. HandleFormSubmit is called, but it's not triggering success or failure block.
<Button type="primary" htmlType="submit" onClick={handleFormSubmit}>
Create
</Button>
</Form>
What's wrong here?
Try this instead of your Custom JSX
function CustomInput(props){
return (
<Form.Item name={props.name}> # Update this line only and remove this comment #
<Input placeholder={props.name} />
</Form.Item>
)
}
<Form
form={form}
layout="vertical"
name="normal_login"
className="login-form"
initialValues={store.formData.initialValues}
>
<CustomInput name="Name" />
<Button type="primary" htmlType="submit" onClick={handleFormSubmit}>
Create
</Button>
</Form>
NOTE: In Antd if your using Form.Item then you have to set name there
not on input fields. Form.Item assign its value to its Input.
I hope your doubt is solved comment for more views. I also tired of antd and wasted many days to understand this.

In formik, shorthand input field is not working

In Formik, I try to use {...formik.getFieldProps('email')} on my input field
instead of using value, onChange, and onBlur. But it's not working.
This works :
<input id="email" name="email" type="text" value={formik.values.email} onChange={formik.handleChange} onBlur={formik.handleBlur} />
But this doesn't :
<input id="email" type="text" {...formik.getFieldProps("email")} />
Code is here : https://codesandbox.io/s/formik-pb-with-getfieldprops-83tze?fontsize=14
Any ideas ?
Thanks !
As MiDas said, what you are doing should work if you are on latest version.
I'll mention an even more concise alternative: the Field component.
Field component handles the field property propagation for you.
Simple example:
<Field name="email" type="text" />
Notice that you don't need to do {...formik.getFieldProps("email")}, or any other "boilerplate".
Related to Field is useField, which can be used to make custom form components just as easy to use - no "boilerplate" needed.
A custom component:
function TextInputWithLabel({ label, ...props }) {
// useField() returns [formik.getFieldProps(), formik.getFieldMeta()]
// which we can spread on <input> and also replace ErrorMessage entirely.
const [field, meta] = useField(props);
return (
<>
<label
htmlFor={props.id || props.name}
css={{ backgroundColor: props.backgroundColor }}
>
{label}
</label>
<input className="text-input" {...field} type="text" {...props} />
{meta.touched && meta.error ? (
<div className="error">{meta.error}</div>
) : null}
</>
);
}
Usage:
<TextInputWithLabel name="input1" label="Random comment" />
As seen in code from codesandbox.

React Formik Field onChange event handle

I am trying to handle onChange for Field component in React Formik, but it doesn't work. I also tried to handle it outside Formik component by:
handleChange(e) {
console.log('changing');
}
<Field type="radio" name="players" value="1" onChange={e => this.handleChange(e)}/>
but I am getting the warning:
A component is changing an uncontrolled input of type text to be
controlled. Input elements should not switch from uncontrolled to
controlled (or vice versa).
For now my code looks like this:
<Formik
onChange={() => {
console.log('changing');
}}
onSubmit={(values) => {
console.log('submitted');
}}
>
{({ isSubmitting, handleChange }) => (
<Form>
<InputWrapper>
<span>1</span>
<Field type="radio" name="players" value="1" onChange={handleChange}/>
<span>2</span>
<Field type="radio" name="players" value="2" onChange={handleChange}/>
</InputWrapper>
<button type="submit" disabled={isSubmitting}>
{isSubmitting ? 'Loading..' : 'Start'}
</button>
</Form>
)}
</Formik>
Any tips/ideas?
One issue I have found with introducing the onBlur:handleBlur to your Formik Field is that it overrides the Formik Validation.
Use onKeyUp={handleChange}
This solved said problem
You must to use the InputProps of Field like the following...
import { TextField } from 'formik-material-ui';
<Field
type="radio"
name="players"
value="2"
component={TextField}
InputProps={{ onBlur:handleBlur }}/>
To use the InputProps in the Field you need to use a component TextField from the formik-material-ui lib.
Another way is use the onKeyUp or onKeyDown, that functions work ok with Field and that functions are like onChange
<Field
type="radio"
name="players"
value="2"
onKeyUp =this.handleChange/>
I found one trick which worked well for me, you can use "values" of formik and call a method passing the "values" as parameter and perform the action using new values.
const handleUserChange = (userId: number) => {
//userId is the new selected userId
};
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
enableReinitialize
>
{({ isValid, isSubmitting, values }) => (
<Form>
<table className="table">
<tbody>
<tr>
<td>Users</td>
<td>
<Field name="userId" className="form-control" as="select">
<option value="">--select--</option>
{data.Users.map((user, index) => (
<option key={user.id} value={user.id}>{`User ${index + 1}`}</option>
))}
</Field>
</td>
</tr>
{handleUserChange(values.userId)}
</tbody>
</table>
<div className="row">
<div className="col-sm-12">
<SubmitButton label="Save" submitting={isSubmitting} disabled={!isValid || isSubmitting} />
</div>
</div>
</Form>
)}
</Formik>

Display emoji object to text field or textarea in React

I'm building my app with emoji-mart lib.
I have text input like this:
<FormGroup>
{emoji}
<EmojiMartPicker
set='emojione'
onSelect={(emoji) => console.log(emoji)}
onChange={this.onChange}
>
<Input
type="text"
name="emotion"
bsSize="sm"
autoComplete="off"
value={report.emotion.colons}
onChange={this.onHandleFormChange}
required
/>
</EmojiMartPicker>
</FormGroup>
Now, I wanna display Emoji Object to text input. In value attribute. I want to display emoji, not value text.
How can we do that?
See my detail problem:
https://codesandbox.io/s/646xom9y1z
Sorry, I found that just only add native props to solved my problem.
Like this:
value={report.emotion.native}
That's it..
I solve this problem take a look.
<div className="chatemoji">
<ButtonToolbar >
<div onClick={e => e.preventDefault()}>
{/* <EmojiField
name="textarea"
onChange={this.onChange.bind(this)}
fieldType="input"
/> */}
<EmojiField name="my-textarea" onChange={this.onChange.bind(this)} fieldType="input" />
</div>
</ButtonToolbar>
</div>
In onChange you have to call this code
onChange(e,value) {
this.state.data += value;
this.setState({ data: this.state.data });
}

Categories

Resources