2017-06-06 23:19:12 +02:00
|
|
|
import React from "react";
|
2017-08-07 00:24:55 +02:00
|
|
|
import FormField from "component/formField";
|
2017-09-11 03:25:24 +02:00
|
|
|
import { Icon } from "component/common.js";
|
2016-11-22 21:19:08 +01:00
|
|
|
|
2017-08-07 00:24:55 +02:00
|
|
|
let formFieldCounter = 0;
|
2016-11-22 21:19:08 +01:00
|
|
|
|
2017-08-07 00:24:55 +02:00
|
|
|
export const formFieldNestedLabelTypes = ["radio", "checkbox"];
|
2017-06-06 06:21:55 +02:00
|
|
|
|
2017-08-07 00:24:55 +02:00
|
|
|
export function formFieldId() {
|
|
|
|
return "form-field-" + ++formFieldCounter;
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
2016-11-22 21:19:08 +01:00
|
|
|
|
2017-09-11 03:25:24 +02:00
|
|
|
export class Form extends React.PureComponent {
|
2017-09-19 00:16:00 +02:00
|
|
|
static propTypes = {
|
|
|
|
onSubmit: React.PropTypes.func.isRequired,
|
|
|
|
};
|
|
|
|
|
2017-09-11 03:25:24 +02:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleSubmit(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
this.props.onSubmit();
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<form onSubmit={event => this.handleSubmit(event)}>
|
|
|
|
{this.props.children}
|
|
|
|
</form>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-08 06:42:19 +02:00
|
|
|
export class FormRow extends React.PureComponent {
|
2017-05-17 10:10:25 +02:00
|
|
|
static propTypes = {
|
2017-06-06 23:19:12 +02:00
|
|
|
label: React.PropTypes.oneOfType([
|
|
|
|
React.PropTypes.string,
|
|
|
|
React.PropTypes.element,
|
|
|
|
]),
|
2017-07-19 01:00:13 +02:00
|
|
|
errorMessage: React.PropTypes.oneOfType([
|
|
|
|
React.PropTypes.string,
|
|
|
|
React.PropTypes.object,
|
|
|
|
]),
|
2017-04-10 14:32:40 +02:00
|
|
|
// helper: React.PropTypes.html,
|
2017-06-06 23:19:12 +02:00
|
|
|
};
|
2017-05-17 10:10:25 +02:00
|
|
|
|
2017-10-15 00:03:05 +02:00
|
|
|
static defaultProps = {
|
|
|
|
isFocus: false,
|
|
|
|
};
|
|
|
|
|
2017-05-17 10:10:25 +02:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
2017-08-07 00:24:55 +02:00
|
|
|
this._field = null;
|
|
|
|
|
2017-06-06 23:19:12 +02:00
|
|
|
this._fieldRequiredText = __("This field is required");
|
2017-05-17 10:10:25 +02:00
|
|
|
|
2017-06-08 23:15:34 +02:00
|
|
|
this.state = this.getStateFromProps(props);
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillReceiveProps(nextProps) {
|
|
|
|
this.setState(this.getStateFromProps(nextProps));
|
|
|
|
}
|
|
|
|
|
|
|
|
getStateFromProps(props) {
|
|
|
|
return {
|
2017-06-02 02:51:52 +02:00
|
|
|
isError: !!props.errorMessage,
|
2017-06-08 23:15:34 +02:00
|
|
|
errorMessage: typeof props.errorMessage === "string"
|
|
|
|
? props.errorMessage
|
2017-07-19 01:00:13 +02:00
|
|
|
: props.errorMessage instanceof Error
|
|
|
|
? props.errorMessage.toString()
|
|
|
|
: "",
|
2017-05-17 10:10:25 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
showError(text) {
|
2017-04-10 14:32:40 +02:00
|
|
|
this.setState({
|
|
|
|
isError: true,
|
|
|
|
errorMessage: text,
|
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
showRequiredError() {
|
2017-04-12 16:55:19 +02:00
|
|
|
this.showError(this._fieldRequiredText);
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
clearError(text) {
|
2017-04-12 16:55:19 +02:00
|
|
|
this.setState({
|
|
|
|
isError: false,
|
2017-06-06 23:19:12 +02:00
|
|
|
errorMessage: "",
|
2017-04-12 16:55:19 +02:00
|
|
|
});
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
getValue() {
|
2017-08-07 00:24:55 +02:00
|
|
|
return this._field.getValue();
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
getSelectedElement() {
|
2017-08-07 00:24:55 +02:00
|
|
|
return this._field.getSelectedElement();
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
2017-06-15 21:30:56 +02:00
|
|
|
getOptions() {
|
2017-08-07 00:24:55 +02:00
|
|
|
return this._field.getOptions();
|
2017-06-15 21:30:56 +02:00
|
|
|
}
|
|
|
|
|
2017-10-15 00:03:05 +02:00
|
|
|
onFocus() {
|
|
|
|
this.setState({ isFocus: true });
|
|
|
|
}
|
|
|
|
|
|
|
|
onBlur() {
|
|
|
|
this.setState({ isFocus: false });
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2017-04-10 14:32:40 +02:00
|
|
|
const fieldProps = Object.assign({}, this.props),
|
2017-06-06 23:19:12 +02:00
|
|
|
elementId = formFieldId(),
|
|
|
|
renderLabelInFormField = formFieldNestedLabelTypes.includes(
|
|
|
|
this.props.type
|
|
|
|
);
|
2017-04-10 14:32:40 +02:00
|
|
|
|
|
|
|
if (!renderLabelInFormField) {
|
|
|
|
delete fieldProps.label;
|
|
|
|
}
|
|
|
|
delete fieldProps.helper;
|
2017-06-02 02:51:52 +02:00
|
|
|
delete fieldProps.errorMessage;
|
2017-10-15 00:03:05 +02:00
|
|
|
delete fieldProps.isFocus;
|
2017-04-10 14:32:40 +02:00
|
|
|
|
2017-06-06 23:19:12 +02:00
|
|
|
return (
|
|
|
|
<div className="form-row">
|
|
|
|
{this.props.label && !renderLabelInFormField
|
|
|
|
? <div
|
|
|
|
className={
|
|
|
|
"form-row__label-row " +
|
2017-10-15 00:03:05 +02:00
|
|
|
(this.props.labelPrefix ? "form-row__label-row--prefix" : "") +
|
|
|
|
(this.state.isFocus ? "focus " : "")
|
2017-06-06 23:19:12 +02:00
|
|
|
}
|
|
|
|
>
|
|
|
|
<label
|
|
|
|
htmlFor={elementId}
|
|
|
|
className={
|
|
|
|
"form-field__label " +
|
2017-10-15 00:03:05 +02:00
|
|
|
(this.state.isError ? "form-field__label--error" : " ") +
|
|
|
|
(this.state.isFocus ? "focus" : " ")
|
2017-06-06 23:19:12 +02:00
|
|
|
}
|
|
|
|
>
|
|
|
|
{this.props.label}
|
|
|
|
</label>
|
|
|
|
</div>
|
|
|
|
: ""}
|
2017-08-07 00:24:55 +02:00
|
|
|
<FormField
|
|
|
|
ref={ref => {
|
|
|
|
this._field = ref ? ref.getWrappedInstance() : null;
|
|
|
|
}}
|
|
|
|
hasError={this.state.isError}
|
2017-10-15 00:03:05 +02:00
|
|
|
onFocus={this.onFocus.bind(this)}
|
|
|
|
onBlur={this.onBlur.bind(this)}
|
2017-08-07 00:24:55 +02:00
|
|
|
{...fieldProps}
|
|
|
|
/>
|
2017-06-06 23:19:12 +02:00
|
|
|
{!this.state.isError && this.props.helper
|
|
|
|
? <div className="form-field__helper">{this.props.helper}</div>
|
|
|
|
: ""}
|
|
|
|
{this.state.isError
|
|
|
|
? <div className="form-field__error">{this.state.errorMessage}</div>
|
|
|
|
: ""}
|
|
|
|
</div>
|
|
|
|
);
|
2017-04-10 14:32:40 +02:00
|
|
|
}
|
2017-05-17 10:10:25 +02:00
|
|
|
}
|
2017-09-11 03:25:24 +02:00
|
|
|
|
|
|
|
export const Submit = props => {
|
|
|
|
const { title, label, icon, disabled } = props;
|
|
|
|
|
|
|
|
const className =
|
|
|
|
"button-block" +
|
|
|
|
" button-primary" +
|
|
|
|
" button-set-item" +
|
|
|
|
" button--submit" +
|
|
|
|
(disabled ? " disabled" : "");
|
|
|
|
|
|
|
|
const content = (
|
|
|
|
<span className="button__content">
|
|
|
|
{"icon" in props ? <Icon icon={icon} fixed={true} /> : null}
|
|
|
|
{label ? <span className="button-label">{label}</span> : null}
|
|
|
|
</span>
|
|
|
|
);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<button type="submit" className={className} title={title}>
|
|
|
|
{content}
|
|
|
|
</button>
|
|
|
|
);
|
|
|
|
};
|