Fix merge conflicts
This commit is contained in:
@@ -24,6 +24,7 @@ class Button extends Component {
|
||||
this.buttonProps = {
|
||||
className: classes,
|
||||
onClick: this.props.onClick,
|
||||
disabled: this.props.disabled,
|
||||
...this.props
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Tooltip } from 'payload/components';
|
||||
import { Tooltip, FormContext } from 'payload/components';
|
||||
|
||||
import './index.css';
|
||||
|
||||
@@ -12,21 +12,26 @@ class Input extends Component {
|
||||
email: 'Please enter a valid email'
|
||||
};
|
||||
|
||||
this.state = {
|
||||
init: false
|
||||
};
|
||||
|
||||
this.validate = this.validate.bind(this);
|
||||
this.sendField = this.sendField.bind(this);
|
||||
}
|
||||
|
||||
validate() {
|
||||
validate(value) {
|
||||
let emailTest = /\S+@\S+\.\S+/;
|
||||
|
||||
switch (this.props.type) {
|
||||
case 'text':
|
||||
return this.el.value.length > 0;
|
||||
return value.length > 0;
|
||||
|
||||
case 'password':
|
||||
return this.el.value.length > 0;
|
||||
return value.length > 0;
|
||||
|
||||
case 'email':
|
||||
return emailTest.test(this.el.value);
|
||||
return emailTest.test(value);
|
||||
|
||||
case 'hidden':
|
||||
return true;
|
||||
@@ -36,18 +41,40 @@ class Input extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (this.props.autoFocus) {
|
||||
this.el.focus();
|
||||
}
|
||||
sendField(value) {
|
||||
|
||||
return {
|
||||
name: this.props.name,
|
||||
value: value,
|
||||
valid: this.props.required
|
||||
? this.validate(value)
|
||||
: true
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.context.setValue(
|
||||
this.sendField(
|
||||
this.props.value ? this.props.value : ''
|
||||
)
|
||||
);
|
||||
|
||||
this.setState({
|
||||
init: true
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const valid = this.props.context.fields[this.props.name]
|
||||
? this.props.context.fields[this.props.name].valid
|
||||
: true;
|
||||
|
||||
const Required = this.props.required
|
||||
? () => <span className="required">*</span>
|
||||
: () => null;
|
||||
|
||||
const Error = this.props.valid === false
|
||||
const Error = valid === false && this.props.context.submitted
|
||||
? () => <Tooltip className="error-message">{this.errors[this.props.type]}</Tooltip>
|
||||
: () => null;
|
||||
|
||||
@@ -60,23 +87,37 @@ class Input extends Component {
|
||||
? className
|
||||
: `${className} error`;
|
||||
|
||||
const initialValue = this.props.value ? this.props.value : '';
|
||||
|
||||
return (
|
||||
<div className={className} style={this.props.style}>
|
||||
<Error />
|
||||
<Label />
|
||||
<input
|
||||
ref={el => { this.el = el; } }
|
||||
value={
|
||||
this.props.context.fields[this.props.name]
|
||||
? this.props.context.fields[this.props.name].value
|
||||
: initialValue
|
||||
}
|
||||
onChange={
|
||||
(e) => {
|
||||
this.props.context.setValue(this.sendField(e.target.value))
|
||||
}
|
||||
}
|
||||
disabled={this.props.disabled}
|
||||
placeholder={this.props.placeholder}
|
||||
onChange={this.props.change}
|
||||
onFocus={this.props.onFocus}
|
||||
type={this.props.type}
|
||||
id={this.props.id ? this.props.id : this.props.name}
|
||||
name={this.props.name}
|
||||
value={this.props.value} />
|
||||
name={this.props.name} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Input;
|
||||
export default props => {
|
||||
return (
|
||||
<FormContext.Consumer>
|
||||
{context => <Input {...props} context={context} />}
|
||||
</FormContext.Consumer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Tooltip } from 'payload/components';
|
||||
import { FormContext, Tooltip } from 'payload/components';
|
||||
|
||||
import './index.css';
|
||||
|
||||
@@ -11,24 +11,56 @@ class Textarea extends Component {
|
||||
text: 'Please fill in the field'
|
||||
};
|
||||
|
||||
this.state = {
|
||||
init: false
|
||||
};
|
||||
|
||||
this.validate = this.validate.bind(this);
|
||||
this.sendField = this.sendField.bind(this);
|
||||
}
|
||||
|
||||
validate() {
|
||||
validate(value) {
|
||||
switch (this.props.type) {
|
||||
case 'honeypot':
|
||||
return this.el.value.length === 0;
|
||||
return value.length === 0;
|
||||
default:
|
||||
return this.el.value.length > 0;
|
||||
return value.length > 0;
|
||||
}
|
||||
}
|
||||
|
||||
sendField(value) {
|
||||
return {
|
||||
name: this.props.name,
|
||||
value: value,
|
||||
valid: this.props.required
|
||||
? this.validate(value)
|
||||
: true
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.context.setValue(
|
||||
this.sendField(
|
||||
this.props.value ? this.props.value : ''
|
||||
)
|
||||
);
|
||||
|
||||
this.setState({
|
||||
init: true
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const valid = this.props.context.fields[this.props.name]
|
||||
? this.props.context.fields[this.props.name].valid
|
||||
: true;
|
||||
|
||||
const Required = this.props.required
|
||||
? () => <span className="required">*</span>
|
||||
: () => null;
|
||||
|
||||
const Error = this.props.valid === false
|
||||
const Error = valid === false && this.props.context.submitted
|
||||
? () => <Tooltip className="error-message">{this.errors.text}</Tooltip>
|
||||
: () => null;
|
||||
|
||||
@@ -49,23 +81,38 @@ class Textarea extends Component {
|
||||
className = 'interact';
|
||||
}
|
||||
|
||||
const initialValue = this.props.value ? this.props.value : '';
|
||||
|
||||
return (
|
||||
<div className={className} style={style}>
|
||||
<Error />
|
||||
<Label />
|
||||
<textarea
|
||||
ref={el => { this.el = el; } }
|
||||
onBlur={this.validate}
|
||||
onFocus={this.props.onFocus}
|
||||
onChange={this.props.change}
|
||||
value={
|
||||
this.props.context.fields[this.props.name]
|
||||
? this.props.context.fields[this.props.name].value
|
||||
: initialValue
|
||||
}
|
||||
onChange={
|
||||
(e) => {
|
||||
this.props.context.setValue(this.sendField(e.target.value))
|
||||
}
|
||||
}
|
||||
disabled={this.props.disabled}
|
||||
placeholder={this.props.placeholder}
|
||||
type={this.props.type}
|
||||
id={this.props.id ? this.props.id : this.props.name}
|
||||
name={this.props.name}
|
||||
rows={this.props.rows ? this.props.rows : '5'}
|
||||
value={this.props.value}>
|
||||
name={this.props.name}>
|
||||
</textarea>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Textarea;
|
||||
export default props => {
|
||||
return (
|
||||
<FormContext.Consumer>
|
||||
{context => <Textarea {...props} context={context} />}
|
||||
</FormContext.Consumer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,70 +1,51 @@
|
||||
import React, { Component } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
import React, { Component, createContext } from 'react';
|
||||
import { ajax } from 'payload';
|
||||
|
||||
import './index.css';
|
||||
|
||||
export const FormContext = createContext({});
|
||||
|
||||
class Form extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
fields: this.buildFields(),
|
||||
fields: {},
|
||||
status: undefined,
|
||||
submitted: false,
|
||||
processing: false
|
||||
};
|
||||
|
||||
// Fill from renderChildren
|
||||
this.childRefs = {};
|
||||
|
||||
this.buildFields = this.buildFields.bind(this);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.submit = this.submit.bind(this);
|
||||
this.renderChildren = this.renderChildren.bind(this);
|
||||
this.setValue = this.setValue.bind(this);
|
||||
}
|
||||
|
||||
buildFields() {
|
||||
let fields = {};
|
||||
|
||||
React.Children.map(this.props.children, (child) => {
|
||||
if (child.props.name) {
|
||||
fields[child.props.name] = {
|
||||
value: child.props.value ? child.props.value : '',
|
||||
required: child.props.required
|
||||
};
|
||||
setValue(field) {
|
||||
this.setState(prevState => ({
|
||||
...prevState,
|
||||
fields: {
|
||||
...prevState.fields,
|
||||
[field.name]: {
|
||||
value: field.value,
|
||||
valid: field.valid
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
handleChange(e) {
|
||||
let newState = { ...this.state };
|
||||
newState.fields[e.target.name].value = e.target.value;
|
||||
this.setState(newState);
|
||||
}));
|
||||
}
|
||||
|
||||
submit(e) {
|
||||
let isValid = true;
|
||||
let newState = { ...this.state };
|
||||
|
||||
Object.keys(this.childRefs).forEach((field) => {
|
||||
if (this.childRefs[field].props.required) {
|
||||
let current = this.childRefs[field];
|
||||
|
||||
let validated = current.validate();
|
||||
|
||||
newState.fields[field].valid = validated;
|
||||
|
||||
if (!validated) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
submitted: true
|
||||
});
|
||||
|
||||
// Update validated fields
|
||||
this.setState(newState);
|
||||
let isValid = true;
|
||||
|
||||
Object.keys(this.state.fields).forEach((field) => {
|
||||
if (!this.state.fields[field].valid) {
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
// If not valid, prevent submission
|
||||
if (!isValid) {
|
||||
@@ -76,7 +57,7 @@ class Form extends Component {
|
||||
this.props.onSubmit(this.state.fields);
|
||||
|
||||
// If form is AJAX, fetch data
|
||||
} else if (this.props.ajax) {
|
||||
} else if (this.props.ajax !== false) {
|
||||
e.preventDefault();
|
||||
let data = {};
|
||||
|
||||
@@ -118,52 +99,10 @@ class Form extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.clearAfterSubmit && isValid) {
|
||||
// Loop through fields - if not valid, set to invalid, rerender with error
|
||||
Object.keys(this.state.fields).forEach((field) => {
|
||||
newState.fields[field].value = '';
|
||||
});
|
||||
}
|
||||
|
||||
// If valid and not AJAX submit as usual
|
||||
return;
|
||||
}
|
||||
|
||||
renderChildren() {
|
||||
let children = React.Children.map(this.props.children, (child) => {
|
||||
if (child.props.name) {
|
||||
// Initialize validation as true - only show error class if error after blur
|
||||
let valid = true;
|
||||
|
||||
// If a valid value has been passed from field, set valid equal to that
|
||||
if (typeof this.state.fields[child.props.name].valid !== 'undefined') {
|
||||
valid = this.state.fields[child.props.name].valid;
|
||||
}
|
||||
|
||||
return React.cloneElement(child, {
|
||||
ref: (el) => {
|
||||
this.childRefs[child.props.name] = el;
|
||||
},
|
||||
change: this.handleChange,
|
||||
validate: this.validate,
|
||||
valid: valid,
|
||||
value: this.state.fields[child.props.name].value
|
||||
});
|
||||
}
|
||||
|
||||
if (child.props.type === 'submit') {
|
||||
return React.cloneElement(child, {
|
||||
disabled: this.state.processing || child.props.disabled === 'disabled' ? 'disabled' : false,
|
||||
children: this.state.processing ? 'Processing...' : child.props.children
|
||||
});
|
||||
}
|
||||
|
||||
return child;
|
||||
});
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
render() {
|
||||
let Status = () => {
|
||||
return null;
|
||||
@@ -186,10 +125,17 @@ class Form extends Component {
|
||||
action={this.props.action}
|
||||
className={this.props.className}>
|
||||
<Status />
|
||||
{this.renderChildren()}
|
||||
<FormContext.Provider value={{
|
||||
setValue: this.setValue.bind(this),
|
||||
fields: this.state.fields,
|
||||
processing: this.state.processing,
|
||||
submitted: this.state.submitted
|
||||
}}>
|
||||
{this.props.children}
|
||||
</FormContext.Provider>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(Form);
|
||||
export default Form;
|
||||
|
||||
21
src/client/components/forms/Submit/index.js
Normal file
21
src/client/components/forms/Submit/index.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import React, { Component } from 'react';
|
||||
import { FormContext, Button } from 'payload/components';
|
||||
|
||||
class FormSubmit extends Component {
|
||||
render() {
|
||||
return (
|
||||
<Button disabled={this.props.context.processing ? 'disabled' : ''}>
|
||||
{this.props.children}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default props => {
|
||||
return (
|
||||
<FormContext.Consumer>
|
||||
{context => <FormSubmit {...props} context={context} />}
|
||||
</FormContext.Consumer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Input } from 'payload/components';
|
||||
import { Form, Input } from 'payload/components';
|
||||
|
||||
class Filter extends Component {
|
||||
render() {
|
||||
return (
|
||||
<Input data-fillable placeholder="Search" type="text" id="keywords" />
|
||||
<Form>
|
||||
<Input placeholder="Search" type="text" name="keywords" />
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
.tooltip {
|
||||
@extend %uppercase-label;
|
||||
background-color: $green;
|
||||
position: absolute;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: - rem(.5);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
Reference in New Issue
Block a user