Show form errors

This commit is contained in:
Manuel Bouza
2019-02-13 14:22:50 +01:00
parent eb154be04a
commit 4d77ddb2aa
6 changed files with 48 additions and 12 deletions

View File

@@ -147,6 +147,7 @@ class Bubble extends Component {
.createActivity(this.changesetWithDefaults)
.then(() => {
this.close()
this.changeset = {}
this.formErrors = {}
})
.catch(this.handleSubmitError)
@@ -173,6 +174,7 @@ class Bubble extends Component {
<Form
projects={this.projects}
changeset={this.changesetWithDefaults}
errors={this.formErrors}
isLoading={this.isLoading}
onChange={this.handleChange}
onSubmit={this.handleSubmit}

View File

@@ -1,6 +1,7 @@
import React, { Component } from "react"
import PropTypes from "prop-types"
import Select from "components/Select"
import cn from "classnames"
class Form extends Component {
static propTypes = {
@@ -10,6 +11,7 @@ class Form extends Component {
task: PropTypes.object,
hours: PropTypes.string
}).isRequired,
errors: PropTypes.object,
projects: PropTypes.array.isRequired,
onChange: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired
@@ -33,29 +35,39 @@ class Form extends Component {
return null
}
const { projects, changeset, onChange, onSubmit } = this.props
const { projects, changeset, errors, onChange, onSubmit } = this.props
const project = Select.findOptionByValue(projects, changeset.assignment_id)
return (
<form onSubmit={onSubmit}>
<div className="form-group">
<div
className={cn("form-group", { "has-error": errors.assignment_id })}
>
<Select
name="assignment_id"
options={projects}
value={changeset.assignment_id}
hasError={!!errors.assignment_id}
onChange={onChange}
/>
{errors.assignment_id ? (
<div className="form-error">{errors.assignment_id.join('; ')}</div>
) : null}
</div>
<div className="form-group">
<div className={cn("form-group", { "has-error": errors.task_id })}>
<Select
name="task_id"
options={project?.tasks || []}
value={changeset.task_id}
onChange={onChange}
hasError={!!errors.task_id}
noOptionsMessage={() => "Zuerst Projekt wählen"}
/>
{errors.task_id ? (
<div className="form-error">{errors.task_id.join('; ')}</div>
) : null}
</div>
<div className="form-group">
<div className={cn("form-group", { "has-error": errors.hours })}>
<input
name="hours"
className="form-control"
@@ -65,8 +77,11 @@ class Form extends Component {
autoComplete="off"
autoFocus
/>
{errors.hours ? (
<div className="form-error">{errors.hours.join('; ')}</div>
) : null}
</div>
<div className="form-group">
<div className={cn("form-group", { "has-error": errors.description })}>
<textarea
name="description"
onChange={onChange}
@@ -74,6 +89,9 @@ class Form extends Component {
placeholder="Beschreibung der Tätigkeit - mind. 3 Zeichen"
rows={4}
/>
{errors.description ? (
<div className="form-error">{errors.description.join('; ')}</div>
) : null}
</div>
<button disabled={!this.isValid()}>Speichern</button>

View File

@@ -12,6 +12,7 @@ import {
flatMap,
pathEq
} from "lodash/fp"
import { trace } from "utils"
const customTheme = theme => ({
...theme,
@@ -23,7 +24,11 @@ const customTheme = theme => ({
}
})
const customStyles = {
const customStyles = props => ({
control: (base, _state) => ({
...base,
borderColor: props.hasError ? "#FB3A2F" : base.borderColor
}),
groupHeading: (base, _state) => ({
...base,
color: "black",
@@ -31,7 +36,7 @@ const customStyles = {
fontWeight: "bold",
fontSize: "100%"
})
}
})
const filterOption = createFilter({
stringify: compose(
@@ -47,10 +52,10 @@ export default class Select extends Component {
name: PropTypes.string.isRequired,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
options: PropTypes.array,
hasError: PropTypes.bool,
onChange: PropTypes.func.isRequired
};
static findOptionByValue = (selectOptions, value) => {
const options = flatMap(
option => (option.options ? option.options : option),
@@ -58,7 +63,7 @@ export default class Select extends Component {
)
return options.find(pathEq("value", value))
}
};
handleChange = option => {
const { name, onChange } = this.props
@@ -67,7 +72,7 @@ export default class Select extends Component {
};
render() {
const { value, ...passThroughProps } = this.props
const { value, hasError, ...passThroughProps } = this.props
return (
<ReactSelect
{...passThroughProps}
@@ -75,7 +80,7 @@ export default class Select extends Component {
onChange={this.handleChange}
filterOption={filterOption}
theme={customTheme}
styles={customStyles}
styles={customStyles(this.props)}
/>
)
}