mirror of
https://github.com/opensupports/opensupports.git
synced 2025-07-31 01:35:15 +02:00
Ivan - Create Ticket Form - Fix TextEditor issues [skip ci]
This commit is contained in:
parent
99e9392c45
commit
9813dd0ebd
@ -56,6 +56,7 @@
|
|||||||
"app-module-path": "^1.0.3",
|
"app-module-path": "^1.0.3",
|
||||||
"classnames": "^2.1.3",
|
"classnames": "^2.1.3",
|
||||||
"draft-js": "^0.8.1",
|
"draft-js": "^0.8.1",
|
||||||
|
"draft-js-export-html": "^0.4.0",
|
||||||
"jquery": "^2.1.4",
|
"jquery": "^2.1.4",
|
||||||
"keycode": "^2.1.4",
|
"keycode": "^2.1.4",
|
||||||
"localStorage": "^1.0.3",
|
"localStorage": "^1.0.3",
|
||||||
|
@ -23,7 +23,8 @@ class CreateTicketForm extends React.Component {
|
|||||||
{content: 'Department3'}
|
{content: 'Department3'}
|
||||||
]} />
|
]} />
|
||||||
<Input label="Title" name="title" required />
|
<Input label="Title" name="title" required />
|
||||||
<TextArea label="Content" name="content" required />
|
<TextArea label="Content" name="content" required validation="TEXT_AREA" />
|
||||||
|
<SubmitButton>Sumibtea ameo</SubmitButton>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -50,6 +50,7 @@ class Button extends React.Component {
|
|||||||
props.className = this.getClass();
|
props.className = this.getClass();
|
||||||
|
|
||||||
delete props.route;
|
delete props.route;
|
||||||
|
delete props.iconName;
|
||||||
delete props.type;
|
delete props.type;
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import {EditorState} from 'draft-js';
|
||||||
|
import {stateToHTML} from 'draft-js-export-html';
|
||||||
|
|
||||||
import {reactDFS, renderChildrenWithProps} from 'lib-core/react-dfs';
|
import {reactDFS, renderChildrenWithProps} from 'lib-core/react-dfs';
|
||||||
import ValidationFactory from 'lib-app/validations/validations-factory';
|
import ValidationFactory from 'lib-app/validations/validations-factory';
|
||||||
|
|
||||||
import Input from 'core-components/input';
|
import Input from 'core-components/input';
|
||||||
import Checkbox from 'core-components/checkbox';
|
import Checkbox from 'core-components/checkbox';
|
||||||
//import TextArea from 'core-components/text-area';
|
import TextArea from 'core-components/text-area';
|
||||||
|
|
||||||
const validFieldTypes = [
|
const validFieldTypes = [
|
||||||
Input,
|
Input,
|
||||||
CheckBox
|
TextArea,
|
||||||
|
Checkbox
|
||||||
];
|
];
|
||||||
|
|
||||||
class Form extends React.Component {
|
class Form extends React.Component {
|
||||||
@ -151,9 +154,9 @@ class Form extends React.Component {
|
|||||||
else if (child.type === Checkbox) {
|
else if (child.type === Checkbox) {
|
||||||
form[child.props.name] = child.props.checked || false;
|
form[child.props.name] = child.props.checked || false;
|
||||||
}
|
}
|
||||||
// else if (child.type === TextArea) {
|
else if (child.type === TextArea) {
|
||||||
// DO SOMETHING
|
form[child.props.name] = child.props.value || EditorState.createEmpty();
|
||||||
// }
|
}
|
||||||
|
|
||||||
if (child.props.required) {
|
if (child.props.required) {
|
||||||
validations[child.props.name] = ValidationFactory.getValidator(child.props.validation || 'DEFAULT');
|
validations[child.props.name] = ValidationFactory.getValidator(child.props.validation || 'DEFAULT');
|
||||||
@ -170,10 +173,18 @@ class Form extends React.Component {
|
|||||||
handleSubmit(event) {
|
handleSubmit(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
const form = _.mapValues(this.state.form, (field) => {
|
||||||
|
if (field instanceof EditorState) {
|
||||||
|
return stateToHTML(field.getCurrentContent());
|
||||||
|
} else {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (this.hasFormErrors()) {
|
if (this.hasFormErrors()) {
|
||||||
this.updateErrors(this.getAllFieldErrors(), this.focusFirstErrorField.bind(this));
|
this.updateErrors(this.getAllFieldErrors(), this.focusFirstErrorField.bind(this));
|
||||||
} else if (this.props.onSubmit) {
|
} else if (this.props.onSubmit) {
|
||||||
this.props.onSubmit(this.state.form);
|
this.props.onSubmit(form);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ class TextArea extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: React.PropTypes.string,
|
value: React.PropTypes.object,
|
||||||
validation: React.PropTypes.string,
|
validation: React.PropTypes.string,
|
||||||
onChange: React.PropTypes.func,
|
onChange: React.PropTypes.func,
|
||||||
required: React.PropTypes.bool,
|
required: React.PropTypes.bool,
|
||||||
@ -45,6 +45,9 @@ class TextArea extends React.Component {
|
|||||||
props.className = 'text-area__input';
|
props.className = 'text-area__input';
|
||||||
props.ref = 'nativeTextArea';
|
props.ref = 'nativeTextArea';
|
||||||
props.disabled = this.context.loading;
|
props.disabled = this.context.loading;
|
||||||
|
props.value = this.props.value;
|
||||||
|
props.onChange = this.props.onChange;
|
||||||
|
props.errored = !!this.props.error;
|
||||||
|
|
||||||
delete props.required;
|
delete props.required;
|
||||||
delete props.validation;
|
delete props.validation;
|
||||||
|
@ -7,7 +7,9 @@ import Button from 'core-components/button';
|
|||||||
|
|
||||||
class TextEditor extends React.Component {
|
class TextEditor extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
error: React.PropTypes.bool
|
errored: React.PropTypes.bool,
|
||||||
|
onChange: React.PropTypes.func,
|
||||||
|
value: React.PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -23,8 +25,10 @@ class TextEditor extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div className={this.getClass()}>
|
<div className={this.getClass()}>
|
||||||
{this.renderEditOptions()}
|
{this.renderEditOptions()}
|
||||||
<div className="text-editor__editor" onClick={this.focus.bind(this)}>
|
<div className="text-editor__editor" onClick={this.focus.bind(this)} onMouseDown={(event) => event.preventDefault()}>
|
||||||
<Editor {...this.getEditorProps()} />
|
<span onMouseDown={(event) => event.stopPropagation()}>
|
||||||
|
<Editor {...this.getEditorProps()} />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -37,7 +41,7 @@ class TextEditor extends React.Component {
|
|||||||
};
|
};
|
||||||
const onItalicsClick = (event) => {
|
const onItalicsClick = (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.onEditorChange(RichUtils.toggleInlineStyle(this.state.editorState, 'ITALICS'));
|
this.onEditorChange(RichUtils.toggleInlineStyle(this.state.editorState, 'ITALIC'));
|
||||||
};
|
};
|
||||||
const onUnderlineClick = (event) => {
|
const onUnderlineClick = (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -68,7 +72,7 @@ class TextEditor extends React.Component {
|
|||||||
|
|
||||||
getEditorProps() {
|
getEditorProps() {
|
||||||
return {
|
return {
|
||||||
editorState: this.state.editorState,
|
editorState: this.props.value || this.state.editorState,
|
||||||
ref: 'editor',
|
ref: 'editor',
|
||||||
onChange: this.onEditorChange.bind(this),
|
onChange: this.onEditorChange.bind(this),
|
||||||
onFocus: this.onEditorFocus.bind(this),
|
onFocus: this.onEditorFocus.bind(this),
|
||||||
@ -78,14 +82,30 @@ class TextEditor extends React.Component {
|
|||||||
|
|
||||||
onEditorChange(editorState) {
|
onEditorChange(editorState) {
|
||||||
this.setState({editorState});
|
this.setState({editorState});
|
||||||
|
|
||||||
|
if (this.props.onChange) {
|
||||||
|
this.props.onChange({
|
||||||
|
target: {
|
||||||
|
value: editorState
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onEditorFocus() {
|
onEditorFocus(event) {
|
||||||
this.setState({focused: true});
|
this.setState({focused: true});
|
||||||
|
|
||||||
|
if(this.props.onFocus) {
|
||||||
|
this.props.onFocus(event)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onBlur() {
|
onBlur(event) {
|
||||||
this.setState({focused: false});
|
this.setState({focused: false});
|
||||||
|
|
||||||
|
if(this.props.onBlur) {
|
||||||
|
this.props.onBlur(event)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
|
@ -21,6 +21,7 @@ export default {
|
|||||||
'ERROR_PASSWORD': 'Invalid password',
|
'ERROR_PASSWORD': 'Invalid password',
|
||||||
'ERROR_NAME': 'Invalid name',
|
'ERROR_NAME': 'Invalid name',
|
||||||
'ERROR_EMAIL': 'Invalid email',
|
'ERROR_EMAIL': 'Invalid email',
|
||||||
|
'ERROR_CONTENT_SHORT': 'Content too short',
|
||||||
'PASSWORD_NOT_MATCH': 'Password does not match',
|
'PASSWORD_NOT_MATCH': 'Password does not match',
|
||||||
'INVALID_RECOVER': 'Invalid recover data',
|
'INVALID_RECOVER': 'Invalid recover data',
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import {EditorState} from 'draft-js';
|
||||||
|
|
||||||
import Validator from 'lib-app/validations/validator';
|
import Validator from 'lib-app/validations/validator';
|
||||||
|
|
||||||
class LengthValidator extends Validator {
|
class LengthValidator extends Validator {
|
||||||
@ -9,6 +11,10 @@ class LengthValidator extends Validator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validate(value, form) {
|
validate(value, form) {
|
||||||
|
if (value instanceof EditorState) {
|
||||||
|
value = value.getCurrentContent().getPlainText();
|
||||||
|
}
|
||||||
|
|
||||||
if (value.length < this.minlength) return this.getError(this.errorKey);
|
if (value.length < this.minlength) return this.getError(this.errorKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ let validators = {
|
|||||||
'DEFAULT': new Validator(),
|
'DEFAULT': new Validator(),
|
||||||
'NAME': new AlphaNumericValidator('ERROR_NAME', new LengthValidator(2, 'ERROR_NAME')),
|
'NAME': new AlphaNumericValidator('ERROR_NAME', new LengthValidator(2, 'ERROR_NAME')),
|
||||||
'EMAIL': new EmailValidator(),
|
'EMAIL': new EmailValidator(),
|
||||||
|
'TEXT_AREA': new LengthValidator(10, 'ERROR_CONTENT_SHORT'),
|
||||||
'PASSWORD': new LengthValidator(6, 'ERROR_PASSWORD'),
|
'PASSWORD': new LengthValidator(6, 'ERROR_PASSWORD'),
|
||||||
'REPEAT_PASSWORD': new RepeatPasswordValidator()
|
'REPEAT_PASSWORD': new RepeatPasswordValidator()
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
const i18n = require('lib-app/i18n');
|
import {EditorState} from 'draft-js';
|
||||||
|
|
||||||
|
import i18n from 'lib-app/i18n';
|
||||||
|
|
||||||
class Validator {
|
class Validator {
|
||||||
constructor(validator = null) {
|
constructor(validator = null) {
|
||||||
@ -18,7 +20,11 @@ class Validator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validate(value, form) {
|
validate(value, form) {
|
||||||
if (!value.length) return this.getError('ERROR_EMPTY');
|
if (value instanceof EditorState) {
|
||||||
|
value = value.getCurrentContent().getPlainText()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.length === 0) return this.getError('ERROR_EMPTY');
|
||||||
}
|
}
|
||||||
|
|
||||||
getError(errorKey) {
|
getError(errorKey) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user