Skip to content

Commit 2bbf17d

Browse files
committed
Merge branch 'feature/improve-form-type' into dev
2 parents c6a4172 + 5b5c031 commit 2bbf17d

17 files changed

+1096
-8
lines changed

package.json

+3
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@
113113
"passport-linkedin-oauth2": "^1.4.1",
114114
"pm2": "^2.0.18",
115115
"react": "^15.3.2",
116+
"react-addons-shallow-compare": "^15.3.2",
116117
"react-bootstrap": "^0.30.5",
118+
"react-dates": "^4.0.0",
117119
"react-dom": "^15.0.2",
118120
"react-ga": "^2.1.2",
119121
"react-google-recaptcha": "^0.5.4",
@@ -125,6 +127,7 @@
125127
"react-router": "^2.3.0",
126128
"react-router-active-component": "^4.0.0",
127129
"react-router-redux": "^4.0.6",
130+
"react-slider": "^0.7.0",
128131
"redux": "^3.5.2",
129132
"redux-form": "^6.1.0",
130133
"redux-thunk": "^2.1.0",
+240
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
import React, { Component } from 'react';
2+
import { connect } from 'react-redux';
3+
import { Link } from 'react-router';
4+
import { Field, reduxForm } from 'redux-form';
5+
import Alert from 'react-bootstrap/lib/Alert';
6+
import Button from 'react-bootstrap/lib/Button';
7+
import FormNames from '../../constants/FormNames';
8+
import { Form, FormField, FormFooter } from '../utils/BsForm';
9+
import Head from '../widgets/Head';
10+
11+
class DemoForm extends Component {
12+
constructor() {
13+
super();
14+
this.handleSubmit = this._handleSubmit.bind(this);
15+
}
16+
17+
_handleSubmit(formData) {
18+
console.log('formData', formData);
19+
// let { dispatch, apiEngine } = this.props;
20+
//
21+
// return someAPI(apiEngine)
22+
// .doSomething(formData)
23+
// .catch((err) => {
24+
// dispatch(pushErrors(err));
25+
// throw err;
26+
// })
27+
// .then((json) => {
28+
// console.log('json', json);
29+
// });
30+
}
31+
32+
render() {
33+
let {
34+
handleSubmit,
35+
submitFailed,
36+
error,
37+
pristine,
38+
submitting,
39+
invalid,
40+
demoForm: { values },
41+
} = this.props;
42+
43+
return (
44+
<Form horizontal onSubmit={handleSubmit(this.handleSubmit)}>
45+
<Head
46+
links={[
47+
'/css/react-dates.css',
48+
]}
49+
/>
50+
{submitFailed && error && (<Alert bsStyle="danger">{error}</Alert>)}
51+
<Alert bsStyle="info">
52+
File object is not going to show here.
53+
Please submit the form and check the console.
54+
</Alert>
55+
<pre>{JSON.stringify(values, null, 2)}</pre>
56+
<Field
57+
label="Text"
58+
name="someText"
59+
component={FormField}
60+
type="text"
61+
placeholder="Text"
62+
/>
63+
<Field
64+
label="Password"
65+
name="somePassword"
66+
component={FormField}
67+
type="password"
68+
placeholder="Password"
69+
/>
70+
<Field
71+
label="Number"
72+
name="someNumber"
73+
component={FormField}
74+
type="number"
75+
placeholder="Number"
76+
/>
77+
<Field
78+
label="Date"
79+
name="someDate"
80+
component={FormField}
81+
type="date"
82+
placeholder="Date"
83+
/>
84+
<Field
85+
label="Time"
86+
name="someTime"
87+
component={FormField}
88+
type="time"
89+
placeholder="Time"
90+
/>
91+
<Field
92+
label="File"
93+
name="someFile"
94+
component={FormField}
95+
type="file"
96+
/>
97+
<Field
98+
label="Textarea"
99+
name="someTextarea"
100+
component={FormField}
101+
type="textarea"
102+
rows="6"
103+
/>
104+
<Field
105+
label=" "
106+
name="somePlainText"
107+
component={FormField}
108+
type="plaintext"
109+
text="Plain Text"
110+
/>
111+
<Field
112+
label="Range Slider"
113+
name="someRangeSlider"
114+
component={FormField}
115+
type="rangeSlider"
116+
min={0}
117+
max={100}
118+
step={5}
119+
/>
120+
<Field
121+
label=" "
122+
name="_"
123+
component={FormField}
124+
type="plaintext"
125+
text={
126+
'range slider value is ' +
127+
`${values.someRangeSlider.min} ~ ${values.someRangeSlider.max}`
128+
}
129+
/>
130+
<Field
131+
label="Airbnb Single Date"
132+
name="someAirSingleDate"
133+
component={FormField}
134+
type="airSingleDate"
135+
displayFormat="YYYY/MM/DD"
136+
showClearDate
137+
/>
138+
<Field
139+
label="Airbnb Date Range"
140+
name="someAirDateRange"
141+
component={FormField}
142+
type="airDateRange"
143+
displayFormat="YYYY/MM/DD"
144+
showClearDates
145+
/>
146+
<Field
147+
label="Select"
148+
name="someSelect"
149+
component={FormField}
150+
type="select"
151+
options={[{
152+
label: 'Taiwan',
153+
value: 'TW',
154+
}, {
155+
label: 'Japan',
156+
value: 'JP',
157+
}, {
158+
label: 'United States',
159+
value: 'US',
160+
}]}
161+
/>
162+
<Field
163+
label="Checkbox"
164+
name="someCheckbox"
165+
component={FormField}
166+
type="checkbox"
167+
text="This is a checkbox"
168+
/>
169+
<Field
170+
label="Checkboxes"
171+
name="someInlineCheckboxes"
172+
component={FormField}
173+
type="checkboxes"
174+
style={{float: 'left', paddingRight: 20}}
175+
options={[{
176+
label: 'There',
177+
value: 'VALUE1',
178+
}, {
179+
label: 'are',
180+
value: 'VALUE2',
181+
}, {
182+
label: 'many',
183+
value: 'VALUE3',
184+
}, {
185+
label: 'inline',
186+
value: 'VALUE4',
187+
}, {
188+
label: 'checkboxes',
189+
value: 'VALUE5',
190+
}]}
191+
/>
192+
<Field
193+
label="Radio Button"
194+
name="someRadiobutton"
195+
component={FormField}
196+
type="radiobutton"
197+
options={[{
198+
label: 'some',
199+
value: 'VALUE1',
200+
}, {
201+
label: 'radio',
202+
value: 'VALUE2',
203+
disabled: true,
204+
}, {
205+
label: 'buttons',
206+
value: 'VALUE3',
207+
}]}
208+
/>
209+
<Field
210+
label="Recaptcha"
211+
name="someRecaptcha"
212+
component={FormField}
213+
type="recaptcha"
214+
/>
215+
<FormFooter>
216+
<Button type="submit" disabled={pristine || submitting || invalid}>
217+
Submit
218+
</Button>
219+
<Link to="#">
220+
<Button bsStyle="link">Some link</Button>
221+
</Link>
222+
</FormFooter>
223+
</Form>
224+
);
225+
}
226+
};
227+
228+
export default reduxForm({
229+
form: FormNames.DEMO,
230+
initialValues: {
231+
somePassword: 'xxxxxxxxxx',
232+
someRangeSlider: {
233+
min: 10,
234+
max: 30,
235+
},
236+
},
237+
})(connect(state => ({
238+
apiEngine: state.apiEngine,
239+
demoForm: state.form[FormNames.DEMO],
240+
}))(DemoForm));

src/common/components/forms/user/AvatarForm.js

+7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import userAPI from '../../../api/user';
1010
import { pushErrors } from '../../../actions/errorActions';
1111
import { setCookies } from '../../../actions/cookieActions';
1212
import { Form, FormField, FormFooter } from '../../utils/BsForm';
13+
import Head from '../../widgets/Head';
1314
import toRefreshURL from '../../../utils/toRefreshURL';
1415

1516
const initialValues = {
@@ -196,6 +197,11 @@ class AvatarForm extends Component {
196197

197198
return (
198199
<Form onSubmit={handleSubmit(this.handleSubmit)}>
200+
<Head
201+
scripts={[
202+
'https://www.gstatic.com/firebasejs/live/3.0/firebase.js',
203+
]}
204+
/>
199205
{avatarURL && <Image thumbnail src={avatarURL} />}
200206
<Field
201207
name="avatar"
@@ -206,6 +212,7 @@ class AvatarForm extends Component {
206212
label="Store avatar into"
207213
name="storage"
208214
component={FormField}
215+
type="radiobutton"
209216
options={[{
210217
label: 'Firebase',
211218
value: 'firebase',

src/common/components/forms/user/RegisterForm.js

+19
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ const validate = (values) => {
2727
errors.password = 'Required';
2828
}
2929

30+
if (!values.isAgreeTerms) {
31+
errors.isAgreeTerms = 'Required';
32+
}
33+
3034
if (configs.recaptcha && !values.recaptcha) {
3135
errors.recaptcha = 'Required';
3236
}
@@ -74,6 +78,7 @@ class RegisterForm extends Component {
7478
asyncValidating,
7579
submitting,
7680
invalid,
81+
registerForm: { values },
7782
} = this.props;
7883

7984
return (
@@ -100,6 +105,13 @@ class RegisterForm extends Component {
100105
type="password"
101106
placeholder="Password"
102107
/>
108+
<Field
109+
label=" "
110+
name="isAgreeTerms"
111+
component={FormField}
112+
type="checkbox"
113+
text={<span>I agree the <a href="#">terms</a></span>}
114+
/>
103115
<Field
104116
label=" "
105117
name="recaptcha"
@@ -121,9 +133,16 @@ class RegisterForm extends Component {
121133

122134
export default reduxForm({
123135
form: FormNames.USER_REGISTER,
136+
initialValues: {
137+
slide: {
138+
min: 30,
139+
max: 40,
140+
},
141+
},
124142
validate,
125143
asyncValidate,
126144
asyncBlurFields: ['email'],
127145
})(connect(state => ({
128146
apiEngine: state.apiEngine,
147+
registerForm: state.form[FormNames.USER_REGISTER],
129148
}))(RegisterForm));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from 'react';
2+
import PageHeader from 'react-bootstrap/lib/PageHeader';
3+
import PageLayout from '../../layouts/PageLayout';
4+
import DemoForm from '../../forms/DemoForm';
5+
6+
let FormElementPage = (props) => (
7+
<PageLayout>
8+
<PageHeader>Form Elements</PageHeader>
9+
<p>
10+
There are a rich amount of field types built inside the boilerplate.
11+
You can reuse them to prototype your custom form.
12+
</p>
13+
<DemoForm />
14+
</PageLayout>
15+
);
16+
17+
export default FormElementPage;

src/common/components/pages/user/ShowPage.js

-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import Button from 'react-bootstrap/lib/Button';
99
import Image from 'react-bootstrap/lib/Image';
1010
import userAPI from '../../../api/user';
1111
import { pushErrors } from '../../../actions/errorActions';
12-
import Head from '../../widgets/Head';
1312
import PageLayout from '../../layouts/PageLayout';
1413
import Time from '../../widgets/Time';
1514
import VerifyEmailForm from '../../forms/user/VerifyEmailForm';
@@ -76,11 +75,6 @@ class ShowPage extends Component {
7675
const { user } = this.state;
7776
return (
7877
<PageLayout>
79-
<Head
80-
scripts={[
81-
'https://www.gstatic.com/firebasejs/live/3.0/firebase.js',
82-
]}
83-
/>
8478
{this.renderModal()}
8579
<Row>
8680
<Col md={12}>

0 commit comments

Comments
 (0)