Form component for React-Native
- 0.0.6 Allow customizing the required and not valid messages on submit button - PR @graywolf336 - See https://github.com/FaridSafi/react-native-gifted-form/commit/a82b3d3508153465e9adbd1b4a6e0ef01e1767e3
- 0.0.5 Fix ScrollTo for RN 0.20.0
- 0.0.4 Fix ScrollWithoutAnimationTo for RN 0.19.0
- 0.0.3 Adds activityIndicatorColor prop to SubmitWidget and Ability to disable the submit widget using onValidation prop - PR @danielweinmann - See FaridSafi#17
- 0.0.2 Add support of react-native-vector-icons - PR @danielweinmann - See FaridSafi#9
- 0.0.1 Initial
var{GiftedForm, GiftedFormManager}=require('react-native-gifted-form');varComponent=React.createClass({render(){return(<GiftedFormformName='signupForm'// GiftedForm instances that use the same name will also share the same statesopenModal={(route)=>{navigator.push(route);// The ModalWidget will be opened using this method. Tested with ExNavigator}}clearOnClose={false}// delete the values of the form when unmounteddefaults={{/* username: 'Farid', 'gender{M}': true, password: 'abcdefg', country: 'FR', birthday: new Date(((new Date()).getFullYear() - 18)+''), */}}validators={{fullName: {title: 'Full name',validate: [{validator: 'isLength',arguments: [1,23],message: '{TITLE} must be between {ARGS[0]} and {ARGS[1]} characters'}]},username: {title: 'Username',validate: [{validator: 'isLength',arguments: [3,16],message: '{TITLE} must be between {ARGS[0]} and {ARGS[1]} characters'},{validator: 'matches',arguments: /^[a-zA-Z0-9]*$/,message: '{TITLE} can contains only alphanumeric characters'}]},password: {title: 'Password',validate: [{validator: 'isLength',arguments: [6,16],message: '{TITLE} must be between {ARGS[0]} and {ARGS[1]} characters'}]},emailAddress: {title: 'Email address',validate: [{validator: 'isLength',arguments: [6,255],},{validator: 'isEmail',}]},bio: {title: 'Biography',validate: [{validator: 'isLength',arguments: [0,512],message: '{TITLE} must be between {ARGS[0]} and {ARGS[1]} characters'}]},gender: {title: 'Gender',validate: [{validator: (...args)=>{if(args[0]===undefined){returnfalse;}returntrue;},message: '{TITLE} is required',}]},birthday: {title: 'Birthday',validate: [{validator: 'isBefore',arguments: [moment().utc().subtract(18,'years').format('YYYY-MM-DD')],message: 'You must be at least 18 years old'},{validator: 'isAfter',arguments: [moment().utc().subtract(100,'years').format('YYYY-MM-DD')],message: '{TITLE} is not valid'}]},country: {title: 'Country',validate: [{validator: 'isLength',arguments: [2],message: '{TITLE} is required'}]},}}><GiftedForm.SeparatorWidget/><GiftedForm.TextInputWidgetname='fullName'// mandatorytitle='Full name'image={require('../../assets/icons/color/user.png')}placeholder='Marco Polo'clearButtonMode='while-editing'/><GiftedForm.TextInputWidgetname='username'title='Username'image={require('../../assets/icons/color/contact_card.png')}placeholder='MarcoPolo'clearButtonMode='while-editing'onTextInputFocus={(currentText='')=>{if(!currentText){letfullName=GiftedFormManager.getValue('signupForm','fullName');if(fullName){returnfullName.replace(/[^a-zA-Z0-9-_]/g,'');}}returncurrentText;}}/><GiftedForm.TextInputWidgetname='password'// mandatorytitle='Password'placeholder='******'clearButtonMode='while-editing'secureTextEntry={true}image={require('../../assets/icons/color/lock.png')}/><GiftedForm.TextInputWidgetname='emailAddress'// mandatorytitle='Email address'placeholder='example@nomads.ly'keyboardType='email-address'clearButtonMode='while-editing'image={require('../../assets/icons/color/email.png')}/><GiftedForm.SeparatorWidget/><GiftedForm.ModalWidgettitle='Gender'displayValue='gender'image={require('../../assets/icons/color/gender.png')}><GiftedForm.SeparatorWidget/><GiftedForm.SelectWidgetname='gender'title='Gender'multiple={false}><GiftedForm.OptionWidgetimage={require('../../assets/icons/color/female.png')}title='Female'value='F'/><GiftedForm.OptionWidgetimage={require('../../assets/icons/color/male.png')}title='Male'value='M'/></GiftedForm.SelectWidget></GiftedForm.ModalWidget><GiftedForm.ModalWidgettitle='Birthday'displayValue='birthday'image={require('../../assets/icons/color/birthday.png')}scrollEnabled={false}><GiftedForm.SeparatorWidget/><GiftedForm.DatePickerIOSWidgetname='birthday'mode='date'getDefaultDate={()=>{returnnewDate(((newDate()).getFullYear()-18)+'');}}/></GiftedForm.ModalWidget><GiftedForm.ModalWidgettitle='Country'displayValue='country'image={require('../../assets/icons/color/passport.png')}scrollEnabled={false}><GiftedForm.SelectCountryWidgetcode='alpha2'name='country'title='Country'autoFocus={true}/></GiftedForm.ModalWidget><GiftedForm.ModalWidgettitle='Biography'displayValue='bio'image={require('../../assets/icons/color/book.png')}scrollEnabled={true}// true by default><GiftedForm.SeparatorWidget/><GiftedForm.TextAreaWidgetname='bio'autoFocus={true}placeholder='Something interesting about yourself'/></GiftedForm.ModalWidget><GiftedForm.SubmitWidgettitle='Sign up'widgetStyles={{submitButton: {backgroundColor: themes.mainColor,}}}onSubmit={(isValid,values,validationResults,postSubmit=null,modalNavigator=null)=>{if(isValid===true){// prepare objectvalues.gender=values.gender[0];values.birthday=moment(values.birthday).format('YYYY-MM-DD');/* Implement the request to your server using values variable ** then you can do: ** postSubmit(); // disable the loader ** postSubmit(['An error occurred, please try again']); // disable the loader and display an error message ** postSubmit(['Username already taken', 'Email already taken']); // disable the loader and display an error message ** GiftedFormManager.reset('signupForm'); // clear the states of the form manually. 'signupForm' is the formName used */}}}/><GiftedForm.NoticeWidgettitle='By signing up, you agree to the Terms of Service and Privacy Policity.'/><GiftedForm.HiddenWidgetname='tos'value={true}/></GiftedForm>);}});Pass value prop to your widgets and onValueChange to your GiftedForm to store your state outside of GiftedFormManager's store.
IMPORTANT: currently only TextInputWidget and HiddenWidget support this feature. PR's are welcome for the other widgets ;)
importReact,{AppRegistry,Component}from'react-native'import{GiftedForm,GiftedFormManager}from'react-native-gifted-form'classFormextendsComponent{constructor(props,context){super(props,context)this.state={form: {fullName: 'Marco Polo',tos: false,}}}handleValueChange(values){console.log('handleValueChange',values)this.setState({form: values})}render(){const{ fullName, tos, gender }=this.state.formconsole.log('render',this.state.form)return(<GiftedFormformName='signupForm'openModal={(route)=>{this.props.navigator.push(route)}}onValueChange={this.handleValueChange.bind(this)}><GiftedForm.TextInputWidgetname='fullName'title='Full name'placeholder='Marco Polo'clearButtonMode='while-editing'value={fullName}/><GiftedForm.HiddenWidgetname='tos'value={tos}/></GiftedForm>)}}AppRegistry.registerComponent('Form',()=>Form)npm install react-native-gifted-form --save
- TextInputWidget - A text input
- TextAreaWidget - A text area
- GooglePlacesWidget - A Google Places picker based on react-native-google-places-autocomplete
- ModalWidget - A route opener for nested forms
- GroupWidget - A widgets container with a title
- HiddenWidget - A non-displayed widget. The value will be passed to SubmitWidget
- LoadingWidget - A loader
- RowWidget - A touchable row with title/image
- SelectCountryWidget - A country picker. Flags made by www.IconDrawer.com
- SelectWidget - A select menu
- SeparatorWidget - A 10px widgets separator
- SubmitWidget - A submit button that trigger form validators and error displaying
- SwitchWidget - A switch
- DatePickerIOSWidget - Date picker for iOS
- NoticeWidget - A notice information - PR wanted for onPress handler
- DayPickerWidget (Not ready for production) - A cross platform date picker. If you want to use it please submit a PR with ISO weeks support (weeks starting on monday) and a prop to set the years range
See the sources for props details
Widgets must implement the mixin GiftedForm.WidgetMixin - See /widgets/TextAreaWidget.js for example
Pull requests are welcome
Feel free to ask me questions on Twitter @FaridSafi !
