Closed soodvaibhav closed 7 years ago
Yes, you can add fields dynamically.
On the demo repository, you can find an example, it uses a select input to create new fields, but you can start from that code and change it for your needs:
Thanks for your quick response. :+1:
You are welcome!
Hi, I have a similar question, I need to insert a group of inputs (7 in total) with every onClick event, is this possible with mobx-react-form? and there will be any problem with the values of the repeated inputs?
Hi Guys :)
I'm trying to get the demo working on my end, and I'm having difficulty getting the "dynamic field" populated correctly. I have looked at the documentation and the issues that have been previously closed, but I just can't get why I'm not getting it to populate. From what I can tell the code should be working.
Below is a sample of my code. I have confirmed that the "fieldFactory" values are being populated correctly based on what I type/select on the dropdown; but the "dynamicFields" 'form' is just not being populated. I've also tried adding in fields to the "dynamicFields" but that didn't result in any success. Apologies for having all my code in one place - I find this helps me to understand how the libraries are working, I'll then refactor it on my end :)
Any guidance which can be provided would be appreciated. Please let me know if you need any furter information in order to assist.
Thanks.
`import React, { Component } from 'react';
import MobxReactForm from 'mobx-react-form'; import validatorjs from 'validatorjs'; import { observer } from 'mobx-react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; import getMuiTheme from 'material-ui/styles/getMuiTheme' import TextField from 'material-ui/TextField/TextField';
import { DropdownList } from 'react-widgets'; import 'react-widgets/dist/css/react-widgets.css';
import { Creatable } from 'react-select'; import 'react-select/dist/react-select.css'; import _ from 'lodash';
import { Button } from 'react-bootstrap';
import './Register.css';
//Define a plugins object and pass the installed package to the DVR property
const plugins = {
dvr: {
package: validatorjs,
extend: ($validator) => {
//Here we can access the validatorjs
instance to create custom error messages
var messages = $validator.getMessages('en');
messages.required = 'Please complete this field in order to continue.';
messages.between = ':attribute must be between :min and :max characters long.';
messages.email = 'Please ensure you enter a valid :attribute to continue.'
messages.digits = 'Please ensure you enter a valid number to continue.'
$validator.setMessages('en', messages);
},
},
};//end plugins
//Define dropdown select items const mealOptions = [ 'None', 'Vegan', 'Vegetarian', 'Halal', 'Kosher', 'Gluten-Free', ];//end mealOptions
//Define options for drop down (dynamic) const extra = [ { value: 'foo', label: 'foo' }, { value: 'bar', label: 'bar' }, { value: 'baz', label: 'baz' }, ];
//Define a fields object to describe the form fields which will contain the Inputs Labels and the DVR Rules. const fields = { Name: { rules: 'required|string|between:2,25', },
Surname: {
rules: 'required|string|between:2,25',
},
email: {
type: 'text',
rules: 'required|email|string|between:5,100',
},
phoneNumber: {
rules: 'required|digits:10',
},
numerOfAdults: {
rules: 'required|digits:1',
},
numberOfKids: {
rules: 'required|digits:1',
},
mealOptions: {
label: 'Products - Dropdown (react-widgets)',
value: 'None',
extra: mealOptions, //https://github.com/foxhound87/mobx-react-form-demo/blob/master/src/components/inputs/WidgetDropdownList.jsx
},
fieldFactory: {
onChange: fieldFactory => (values) => {
const dynamicFields = fieldFactory.state.form.$('dynamicFields');
const $values = _.chain(values)
.mapValues('value')
.values()
.value();
// use "extra" field prop to maintain current values
const current = dynamicFields.get('extra') || [];
const diff = _.difference($values, current);
dynamicFields.set('extra', $values);
// add dynamic fields
diff.map((item) => {
dynamicFields.add({ key: item });
dynamicFields.$(item).set('placeholder', item);
return null;
});
// remove unwanted items
const allDynamicFields = dynamicFields.map(field => field.name);
const fieldsToDelete = _.remove(allDynamicFields, item => !_.includes($values, item));
fieldsToDelete.map(field => dynamicFields.del(field));
fieldFactory.set('value', values);
},
},
dynamicFields: [
],
};//end fields
//Validation Hooks which will be executed on submit after the validation is done. This is what the "hooks" object houses.
const hooks = {
onSuccess(form) {
// get field values
console.log('Form Values!', form.values());
},
onError(form) {
// get all form errors
console.log('All form errors', form.errors());
// invalidate the form with a custom error message
form.invalidate('This is a generic error message!');
},
};//end hoooks
//Create a new LoginForm object passing all the previously created objects to it const form = new MobxReactForm({ fields }, { plugins, hooks });
//Define input box theme const muiTheme = getMuiTheme({ // fontFamily: 'CustomCraft-Regular', fontSize: 40, palette: { textColor: '#000000', //text color of input box primary1Color: '#7DA1BF', //floating label and underline color primary2Color: '#7DA1BF', primary3Color: '#FFCA28', // accent1Color: pinkA200, // accent2Color: grey100, // accent3Color: grey500, // alternateTextColor: white, // canvasColor: white, // borderColor: grey300, disabledColor: '#9E9E9E', //Text color when not clicked on pickerHeaderColor: '#7DA1BF', //clockCircleColor: fade(darkBlack, 0.07), //shadowColor: fullBlack, //errorColor: red500, }, });//end muiTheme
//@observer //Added at the bottom with export! class Register extends Component{
constructor (props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}//end constructor
handleChange(event_value) {
//console.log(event_value);
form.$('mealOptions').value = event_value;
}//end handleChange
render () {
return (
<div>
<MuiThemeProvider muiTheme={muiTheme} >
<form className="formClass" noValidate autoComplete="on">
<div className="ListItems">
<Creatable
multi={true}
allowCreate={true}
resetValue={[]}
options={extra}
openOnFocus={false}
placeholder="Type to add fields"
noResultsText="Type to add fields"
onChange={form.$('fieldFactory').onChange}
{...form.$('fieldFactory').bind()}
/>
</div>
<br/><br/><h4>{form.$('dynamicFields').label}</h4>
{form.$('dynamicFields').map(field =>
<TextField
{...field.bind()} />,
)}
<TextField
hintText="Enter your name here..."
floatingLabelText="Name"
type="Name"
autoComplete="Name"
errorText={form.$('Name').error}
{...form.$('Name').bind()} /><br></br>
<TextField
hintText="Enter your surname here..."
floatingLabelText="Last Name"
type="Surname"
autoComplete="Surname"
errorText={form.$('Surname').error}
{...form.$('Surname').bind()} /><br></br>
<TextField
hintText="Enter your email address here..."
floatingLabelText="Email"
type="email"
autoComplete="Email"
errorText={form.$('email').error}
{...form.$('email').bind()}
/><br></br>
<TextField
hintText="Enter your phone number here..."
floatingLabelText="Phone Number"
type="Phone number"
autoComplete="Tel"
errorText={form.$('phoneNumber').error}
{...form.$('phoneNumber').bind()} /><br></br>
<TextField
hintText="Number of adults attending..."
floatingLabelText="Number of Adults"
type="Adult number"
autoComplete="AdultNum"
errorText={form.$('numerOfAdults').error}
{...form.$('numerOfAdults').bind()} /><br></br>
<TextField
hintText="Number of kids attending..."
floatingLabelText="Number of Kids"
type="Kid number"
autoComplete="KidNum"
errorText={form.$('numberOfKids').error}
{...form.$('numberOfKids').bind()} /><br></br>
<div className="ListItems">
<label
className="ListItemsLabel"
>Meal Preference
</label>
<DropdownList
id="meal_list"
defaultValue="None"
value={form.$('mealOptions').value}
onChange={ this.handleChange }
data={mealOptions}
/><br></br>
</div>
<Button
bsStyle="info"
type="submit"
onClick={form.onSubmit}>Submit</Button>
<Button
bsStyle="info"
onClick={form.onClear}>Clear</Button><br></br>
<div className="f6 db red">
{form.error}
</div>
</form>
</MuiThemeProvider>
</div>
);//end return
}//end render
}//end Register Class
export default observer(Register);`
Hi, I am working on a form where the user inputs some set of data and if requires then they can click on add button to create more input fields. Is it possible with mobx-react-form to dynamically add more input fields on click?