Update to use ReactInput
This commit is contained in:
parent
5ff8fdc86b
commit
0ac08c8ce0
9 changed files with 55 additions and 70 deletions
|
@ -5,15 +5,16 @@ import {Field} from "../../../../types/mobx-react-form";
|
||||||
import LabeledFieldComponent from "./LabeledFieldComponent";
|
import LabeledFieldComponent from "./LabeledFieldComponent";
|
||||||
import {injectIntl, InjectedIntl} from 'react-intl';
|
import {injectIntl, InjectedIntl} from 'react-intl';
|
||||||
import {HoudiniField} from "../../lib/houdini_form";
|
import {HoudiniField} from "../../lib/houdini_form";
|
||||||
|
import ReactInput from "./form/ReactInput";
|
||||||
|
|
||||||
|
|
||||||
export const BasicField = injectIntl(observer((props:{field:Field, intl?:InjectedIntl, wrapperClassName?:string}) =>{
|
export const BasicField = observer((props:{field:Field, placeholder?:string, label?:string, wrapperClassName?:string}) =>{
|
||||||
let field = props.field as HoudiniField
|
let field = props.field as HoudiniField
|
||||||
return <LabeledFieldComponent
|
return <LabeledFieldComponent
|
||||||
inputId={props.field.id} labelText={field.label} inError={field.hasError} error={field.error}
|
inputId={props.field.id} labelText={field.label} inError={field.hasError} error={field.error}
|
||||||
inStickyError={field.hasServerError} stickyError={field.serverError}
|
inStickyError={field.hasServerError} stickyError={field.serverError}
|
||||||
className={props.wrapperClassName} >
|
className={props.wrapperClassName} >
|
||||||
|
|
||||||
<input {...props.field.bind()} placeholder={field.placeholder ? props.intl.formatMessage({id:field.placeholder}) : undefined} className="form-control"/>
|
<ReactInput field={field} label={props.label} placeholder={props.placeholder} className="form-control"/>
|
||||||
</LabeledFieldComponent>
|
</LabeledFieldComponent>
|
||||||
}))
|
})
|
|
@ -10,7 +10,8 @@ export interface ReactFormProps
|
||||||
}
|
}
|
||||||
|
|
||||||
///Mostly useless class but, at some point, will replace all our form elements
|
///Mostly useless class but, at some point, will replace all our form elements
|
||||||
class ReactForm extends React.Component<ReactFormProps, {}> {
|
@observer
|
||||||
|
export class ReactForm extends React.Component<ReactFormProps, {}> {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@ class ReactForm extends React.Component<ReactFormProps, {}> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default observer(ReactForm)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,11 @@ import * as React from 'react';
|
||||||
import 'jest';
|
import 'jest';
|
||||||
import ReactInput from './ReactInput'
|
import ReactInput from './ReactInput'
|
||||||
import {Form} from "mobx-react-form";
|
import {Form} from "mobx-react-form";
|
||||||
import ReactForm from "./ReactForm";
|
|
||||||
import {mount} from 'enzyme';
|
import {mount} from 'enzyme';
|
||||||
import {toJS, observable, action, runInAction} from 'mobx';
|
import {toJS, observable, action, runInAction} from 'mobx';
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
import {InputHTMLAttributes} from 'react';
|
import {InputHTMLAttributes} from 'react';
|
||||||
|
import {ReactForm} from "./ReactForm";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,7 +99,9 @@ describe('ReactInput', () => {
|
||||||
|
|
||||||
let res = mount(<TestChange/>)
|
let res = mount(<TestChange/>)
|
||||||
|
|
||||||
let f = res.find('ReactForm').instance() as ReactForm
|
// The two casts are needed because Typescript was going blowing up without the 'any' first.
|
||||||
|
// Why was it? *shrugs*
|
||||||
|
let f = res.find('ReactForm').instance() as any as ReactForm
|
||||||
expect(f.form.size).toEqual(1)
|
expect(f.form.size).toEqual(1)
|
||||||
|
|
||||||
res.find('input').simulate('change', {target: { value: 'something' } })
|
res.find('input').simulate('change', {target: { value: 'something' } })
|
||||||
|
@ -146,7 +148,7 @@ describe('ReactInput', () => {
|
||||||
let res = mount(<TestChange>
|
let res = mount(<TestChange>
|
||||||
<WrappedInput/>
|
<WrappedInput/>
|
||||||
</TestChange>)
|
</TestChange>)
|
||||||
let f = res.find('ReactForm').instance() as ReactForm
|
let f = res.find('ReactForm').instance() as any as ReactForm
|
||||||
res.find('input').simulate('change', {target: { value: 'something' } })
|
res.find('input').simulate('change', {target: { value: 'something' } })
|
||||||
|
|
||||||
expect(f.form.$('name').value).toEqual('something')
|
expect(f.form.$('name').value).toEqual('something')
|
||||||
|
|
|
@ -6,12 +6,13 @@ import {Field} from "mobx-react-form";
|
||||||
import {observable, action, toJS, runInAction} from 'mobx';
|
import {observable, action, toJS, runInAction} from 'mobx';
|
||||||
import {InputHTMLAttributes} from 'react';
|
import {InputHTMLAttributes} from 'react';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export interface ReactInputProps
|
export interface ReactInputProps
|
||||||
{
|
{
|
||||||
field:Field
|
field:Field
|
||||||
label?:string
|
label?:string
|
||||||
placeholder?:string
|
placeholder?:string
|
||||||
children: React.ReactElement<InputHTMLAttributes<HTMLInputElement>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function castToNullIfUndef(i:any){
|
function castToNullIfUndef(i:any){
|
||||||
|
|
|
@ -17,47 +17,31 @@ export interface NonprofitInfoFormProps
|
||||||
export const FieldDefinitions : Array<FieldDefinition> = [
|
export const FieldDefinitions : Array<FieldDefinition> = [
|
||||||
{
|
{
|
||||||
name: 'organization_name',
|
name: 'organization_name',
|
||||||
label: 'registration.wizard.nonprofit.name.label',
|
|
||||||
placeholder: 'registration.wizard.nonprofit.name.placeholder',
|
|
||||||
type: 'text',
|
|
||||||
validators: [Validations.isFilled]
|
validators: [Validations.isFilled]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'website',
|
name: 'website',
|
||||||
label: 'registration.wizard.nonprofit.website.label',
|
|
||||||
placeholder: 'registration.wizard.nonprofit.website.placeholder',
|
|
||||||
validators: [Validations.optional(Validations.isUrl)]
|
validators: [Validations.optional(Validations.isUrl)]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'org_email',
|
name: 'org_email',
|
||||||
label: 'registration.wizard.nonprofit.email.label',
|
|
||||||
placeholder: 'registration.wizard.nonprofit.email.placeholder',
|
|
||||||
validators: [Validations.optional(Validations.isEmail)]
|
validators: [Validations.optional(Validations.isEmail)]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'org_phone',
|
name: 'org_phone',
|
||||||
label: 'registration.wizard.nonprofit.phone.label',
|
|
||||||
placeholder: 'registration.wizard.nonprofit.phone.placeholder',
|
|
||||||
type: "tel"
|
type: "tel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'city',
|
name: 'city',
|
||||||
label: 'registration.wizard.nonprofit.city.label',
|
|
||||||
placeholder: 'registration.wizard.nonprofit.city.placeholder',
|
|
||||||
validators: [Validations.isFilled]
|
validators: [Validations.isFilled]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'state',
|
name: 'state',
|
||||||
label: 'registration.wizard.nonprofit.state.label',
|
|
||||||
placeholder: 'registration.wizard.nonprofit.state.placeholder',
|
|
||||||
type: 'text',
|
|
||||||
validators: [Validations.isFilled]
|
validators: [Validations.isFilled]
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'zip',
|
name: 'zip',
|
||||||
label: 'registration.wizard.nonprofit.zip.label',
|
|
||||||
placeholder: 'registration.wizard.nonprofit.zip.placeholder',
|
|
||||||
validators: [Validations.isFilled]
|
validators: [Validations.isFilled]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -67,17 +51,33 @@ class NonprofitInfoForm extends React.Component<NonprofitInfoFormProps & Injecte
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <fieldset >
|
return <fieldset >
|
||||||
<BasicField field={this.props.form.$("organization_name")}/>
|
<BasicField field={this.props.form.$("organization_name")}
|
||||||
<BasicField field={this.props.form.$('website')}/>
|
label={this.props.intl.formatMessage({id:'registration.wizard.nonprofit.name.label' })}
|
||||||
|
placeholder={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.name.placeholder'})}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<BasicField field={this.props.form.$('website')}
|
||||||
|
label={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.website.label'})}
|
||||||
|
placeholder={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.website.placeholder'})}/>
|
||||||
<TwoColumnFields>
|
<TwoColumnFields>
|
||||||
<BasicField field={this.props.form.$('org_email')}/>
|
<BasicField field={this.props.form.$('org_email')}
|
||||||
<BasicField field={this.props.form.$('org_phone')}/>
|
label={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.email.label'})}
|
||||||
|
placeholder={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.email.placeholder'})}/>
|
||||||
|
<BasicField field={this.props.form.$('org_phone')}
|
||||||
|
label={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.phone.label'})}
|
||||||
|
placeholder={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.phone.placeholder'})}/>
|
||||||
</TwoColumnFields>
|
</TwoColumnFields>
|
||||||
|
|
||||||
<ThreeColumnFields>
|
<ThreeColumnFields>
|
||||||
<BasicField field={this.props.form.$('city')}/>
|
<BasicField field={this.props.form.$('city')}
|
||||||
<BasicField field={this.props.form.$('state')}/>
|
label={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.city.label'})}
|
||||||
<BasicField field={this.props.form.$('zip')}/>
|
placeholder={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.city.placeholder'})}/>
|
||||||
|
<BasicField field={this.props.form.$('state')}
|
||||||
|
label={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.state.label'})}
|
||||||
|
placeholder={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.state.placeholder'})}/>
|
||||||
|
<BasicField field={this.props.form.$('zip')}
|
||||||
|
label={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.zip.label' })}
|
||||||
|
placeholder={this.props.intl.formatMessage({id: 'registration.wizard.nonprofit.zip.placeholder'})}/>
|
||||||
</ThreeColumnFields>
|
</ThreeColumnFields>
|
||||||
<ProgressableButton onClick={this.props.form.onSubmit} className="button" disabled={!this.props.form.isValid} buttonText={this.props.intl.formatMessage({id: this.props.buttonText})}
|
<ProgressableButton onClick={this.props.form.onSubmit} className="button" disabled={!this.props.form.isValid} buttonText={this.props.intl.formatMessage({id: this.props.buttonText})}
|
||||||
inProgress={this.props.form.submitting || this.props.form.container().submitting} disableOnProgress={true}/>
|
inProgress={this.props.form.submitting || this.props.form.container().submitting} disableOnProgress={true}/>
|
||||||
|
|
|
@ -175,24 +175,6 @@ export class InnerRegistrationWizard extends React.Component<RegistrationWizardP
|
||||||
this.form.signinApi = this.props.ApiManager.get(WebUserSignInOut)
|
this.form.signinApi = this.props.ApiManager.get(WebUserSignInOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
//set up labels
|
|
||||||
let label: {[props:string]: string} = {
|
|
||||||
'nonprofitTab[organization_name]': "registration.wizard.nonprofit.name.label",
|
|
||||||
"nonprofitTab[website]": 'registration.wizard.nonprofit.website.label',
|
|
||||||
"nonprofitTab[org_email]": 'registration.wizard.nonprofit.email.label',
|
|
||||||
'nonprofitTab[org_phone]': 'registration.wizard.nonprofit.phone.label',
|
|
||||||
'nonprofitTab[city]': 'registration.wizard.nonprofit.city.label',
|
|
||||||
'nonprofitTab[state]': 'registration.wizard.nonprofit.state.label',
|
|
||||||
'nonprofitTab[zip]': 'registration.wizard.nonprofit.zip.label',
|
|
||||||
'userTab[name]': 'registration.wizard.contact.name.label',
|
|
||||||
'userTab[email]': 'registration.wizard.contact.email.label',
|
|
||||||
'userTab[password]': 'registration.wizard.contact.password.label',
|
|
||||||
'userTab[password_confirmation]': 'registration.wizard.contact.password_confirmation.label'
|
|
||||||
}
|
|
||||||
for (let key in label){
|
|
||||||
this.form.$(key).set('label', this.props.intl.formatMessage({id: label[key]}))
|
|
||||||
}
|
|
||||||
|
|
||||||
return <Wizard wizardState={this.registrationWizardState} disableTabs={this.form.submitting}>
|
return <Wizard wizardState={this.registrationWizardState} disableTabs={this.form.submitting}>
|
||||||
<NonprofitInfoPanel tab={this.registrationWizardState.tabsByName['nonprofitTab']}
|
<NonprofitInfoPanel tab={this.registrationWizardState.tabsByName['nonprofitTab']}
|
||||||
buttonText="registration.wizard.next"/>
|
buttonText="registration.wizard.next"/>
|
||||||
|
|
|
@ -12,8 +12,6 @@ import {areWeOrAnyParentSubmitting} from "../../lib/houdini_form";
|
||||||
export const FieldDefinitions : Array<FieldDefinition> = [
|
export const FieldDefinitions : Array<FieldDefinition> = [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
label: 'registration.wizard.contact.name.label',
|
|
||||||
placeholder: 'registration.wizard.contact.name.placeholder',
|
|
||||||
validators: [Validations.isFilled]
|
validators: [Validations.isFilled]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -24,14 +22,12 @@ export const FieldDefinitions : Array<FieldDefinition> = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'password',
|
name: 'password',
|
||||||
label: 'registration.wizard.contact.password.label',
|
|
||||||
type: 'password',
|
type: 'password',
|
||||||
validators: [Validations.isFilled],
|
validators: [Validations.isFilled],
|
||||||
related: ['userTab.password_confirmation']
|
related: ['userTab.password_confirmation']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'password_confirmation',
|
name: 'password_confirmation',
|
||||||
label: 'registration.wizard.contact.password_confirmation.label',
|
|
||||||
type: 'password',
|
type: 'password',
|
||||||
validators: [Validations.shouldBeEqualTo("userTab.password")]
|
validators: [Validations.shouldBeEqualTo("userTab.password")]
|
||||||
}
|
}
|
||||||
|
@ -50,12 +46,22 @@ class UserInfoForm extends React.Component<UserInfoFormProps & InjectedIntlProps
|
||||||
render() {
|
render() {
|
||||||
return <fieldset>
|
return <fieldset>
|
||||||
<TwoColumnFields>
|
<TwoColumnFields>
|
||||||
<BasicField field={this.props.form.$("name")}/>
|
<BasicField field={this.props.form.$("name")}
|
||||||
<BasicField field={this.props.form.$('email')}/>
|
label={
|
||||||
|
this.props.intl.formatMessage({id: "registration.wizard.contact.name.label"})}
|
||||||
|
placeholder={this.props.intl.formatMessage({id: "registration.wizard.contact.name.placeholder"})}/>
|
||||||
|
<BasicField field={this.props.form.$('email')}
|
||||||
|
label={this.props.intl.formatMessage({id: "registration.wizard.contact.email.label"})}
|
||||||
|
placeholder={this.props.intl.formatMessage({id: "registration.wizard.contact.email.placeholder"})}
|
||||||
|
/>
|
||||||
</TwoColumnFields>
|
</TwoColumnFields>
|
||||||
|
|
||||||
<BasicField field={this.props.form.$('password')}/>
|
<BasicField field={this.props.form.$('password')}
|
||||||
<BasicField field={this.props.form.$('password_confirmation')}/>
|
label={this.props.intl.formatMessage({id:'registration.wizard.contact.password.label'})}
|
||||||
|
/>
|
||||||
|
<BasicField field={this.props.form.$('password_confirmation')}
|
||||||
|
label={this.props.intl.formatMessage({id:'registration.wizard.contact.password_confirmation.label'})}
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
<ProgressableButton onClick={this.props.form.onSubmit}
|
<ProgressableButton onClick={this.props.form.onSubmit}
|
||||||
|
|
|
@ -23,13 +23,11 @@ export interface SessionLoginFormProps
|
||||||
export const FieldDefinitions : Array<FieldDefinition> = [
|
export const FieldDefinitions : Array<FieldDefinition> = [
|
||||||
{
|
{
|
||||||
name: 'email',
|
name: 'email',
|
||||||
label: 'email',
|
|
||||||
type: 'text',
|
type: 'text',
|
||||||
validators: [Validations.isFilled]
|
validators: [Validations.isFilled]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'password',
|
name: 'password',
|
||||||
label: 'password',
|
|
||||||
type: 'password',
|
type: 'password',
|
||||||
validators: [Validations.isFilled]
|
validators: [Validations.isFilled]
|
||||||
}
|
}
|
||||||
|
@ -100,20 +98,14 @@ class InnerSessionLoginForm extends React.Component<SessionLoginFormProps & Inje
|
||||||
if(!this.form.signinApi){
|
if(!this.form.signinApi){
|
||||||
this.form.signinApi = this.props.ApiManager.get(WebUserSignInOut)
|
this.form.signinApi = this.props.ApiManager.get(WebUserSignInOut)
|
||||||
}
|
}
|
||||||
let label: {[props:string]: string} = {
|
|
||||||
'email': "login.email",
|
|
||||||
"password": 'login.password',
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let key in label){
|
|
||||||
this.form.$(key).set('label', this.props.intl.formatMessage({id: label[key]}))
|
|
||||||
}
|
|
||||||
|
|
||||||
let errorDiv = !this.form.isValid ? <div className="form-group has-error"><div className="help-block" role="alert">{(this.form as any).error}</div></div> : ''
|
let errorDiv = !this.form.isValid ? <div className="form-group has-error"><div className="help-block" role="alert">{(this.form as any).error}</div></div> : ''
|
||||||
|
|
||||||
return <form onSubmit={this.form.onSubmit}>
|
return <form onSubmit={this.form.onSubmit}>
|
||||||
<BasicField field={this.form.$('email')}/>
|
<BasicField field={this.form.$('email')}
|
||||||
<BasicField field={this.form.$('password')}/>
|
label={this.props.intl.formatMessage({id: 'login.email'})}/>
|
||||||
|
<BasicField field={this.form.$('password')}
|
||||||
|
label={this.props.intl.formatMessage({id: 'login.password'})}/>
|
||||||
{errorDiv}
|
{errorDiv}
|
||||||
<div className={'form-group'}>
|
<div className={'form-group'}>
|
||||||
<ProgressableButton onClick={this.form.onSubmit} className="button" disabled={!this.form.isValid || this.form.submitting} inProgress={this.form.submitting}
|
<ProgressableButton onClick={this.form.onSubmit} className="button" disabled={!this.form.isValid || this.form.submitting} inProgress={this.form.submitting}
|
||||||
|
|
1
types/mobx-react-form/index.d.ts
vendored
1
types/mobx-react-form/index.d.ts
vendored
|
@ -311,6 +311,7 @@ export class Form implements Base {
|
||||||
protected validator :any
|
protected validator :any
|
||||||
|
|
||||||
readonly isValid :boolean;
|
readonly isValid :boolean;
|
||||||
|
readonly size:number
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue