Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React = require("react");
- import Promise = require("bluebird");
- import {FormEvent, HTMLProps, FocusEvent, CSSProperties} from "react";
- import {IEventTargetInput} from "../../interfaces/IEventTargetInput";
- import {json_merge_recursive} from "../../../utils/utils";
- import {IOptionsAttribute} from "../../../data/AttributeGroup";
- import {OptionBool} from "../../controlPanel/controlOfPanel/OptionBool";
- import {OptionNumber} from "../../controlPanel/controlOfPanel/OptionNumber";
- import {IGenericControlProps} from "../../controls/GenericControlProps";
- import {autobind} from "core-decorators";
- import * as autosize from "autosize";
- import {If} from "../../utils/If";
- import {ObservableComponent} from "../../../utils/mobx/ObservableComponent";
- import {observable} from "mobx";
- import {lazyInject} from "../../../core/dependency-container/decorators";
- import {SettingsServiceIdentifier} from "../../../core/dependency-container/identifiers";
- import {SettingsServiceInterface} from "../../../services/settings/SettingsServiceInterface";
- const styles = require("./TextAreaControl.less");
- export interface ITextAreaControlProps extends IGenericControlProps {
- value?: string;
- placeholder?: string;
- onChange?: (value: string) => Promise<any>;
- errorMessage?: string;
- disableResize?: boolean;
- realtime?: boolean;
- style?: CSSProperties;
- showLabel?: boolean;
- maxSize?: number;
- }
- export interface ITextAreaControlState {
- }
- export class TextAreaControl<P extends ITextAreaControlProps = ITextAreaControlProps, S extends ITextAreaControlState = ITextAreaControlState> extends ObservableComponent<P, S> {
- @observable
- private valueSize: number = 0;
- @observable
- private showCountIndicatorSetting: boolean = false;
- @lazyInject(SettingsServiceIdentifier)
- private settingService: SettingsServiceInterface;
- componentWillReceiveProps(props: Readonly<P>) {
- if (this.props.value !== props.value) {
- this.valueSize = (props.value || "").length;
- this.setValue(props.value);
- }
- }
- private getTextArea(): HTMLTextAreaElement {
- return this.refs["textarea"] as HTMLTextAreaElement;
- }
- private get$TextArea(): JQuery {
- return $(this.getTextArea());
- }
- @autobind
- protected handleBlur(event: FocusEvent<HTMLTextAreaElement> | FormEvent<HTMLTextAreaElement>) {
- const target: IEventTargetInput = event.target;
- let value = target.value;
- if (value === "") {
- value = null;
- }
- if (this.props.onChange && this.props.value !== value) {
- this.props.onChange(value);
- }
- }
- protected get visible(): boolean {
- return true;
- }
- protected get header(): JSX.Element {
- if (!this.props.showLabel) {
- return null;
- }
- let headerContent = this.props.labelContent;
- if (typeof headerContent === "string") {
- return <span>{headerContent}</span>;
- } else if (React.isValidElement(headerContent)) {
- return headerContent;
- } else {
- return null;
- }
- }
- protected get value() {
- return (this.props.value != null) ? this.props.value : "";
- }
- protected get errorMessage(): string {
- return this.props.errorMessage;
- }
- public static get defaultOptions(): IOptionsAttribute {
- return {
- visualSettingsButtons: {
- reSize: {
- component: OptionBool,
- value: false,
- content: "glyphicon glyphicon-pushpin",
- tooltip: "Разрешить изменение размера поля",
- ident: "reSize"
- },
- ColRow: {
- component: OptionNumber,
- value: 5,
- content: "glyphicon glyphicon-resize-vertical",
- tooltip: "Количество строк в текстовом поле",
- ident: "ColRow"
- },
- AutoHeight: {
- component: OptionBool,
- value: true,
- content: "glyphicon glyphicon-sort-by-attributes",
- tooltip: "Автоподбор высоты по содержимому",
- ident: "AutoHeight"
- },
- countIndicator: {
- component: OptionBool,
- value: false,
- content: "glyphicon glyphicon-font",
- tooltip: "Индикация количества символов в многострочных полях",
- ident: "countIndicator"
- }
- }
- };
- }
- protected get options() {
- if (!this.props.options) {
- return TextAreaControl.defaultOptions;
- } else {
- const jsonDef = TextAreaControl.defaultOptions;
- const jsonOpt = this.props.options;
- return json_merge_recursive(jsonOpt, jsonDef);
- }
- }
- protected get placeholder() {
- return (this.props.placeholder) ? this.props.placeholder : "";
- }
- protected get readonly() {
- return (this.props.readonly !== undefined) ? this.props.readonly : false;
- }
- setValue(value: string) {
- this.get$TextArea().val(value);
- autosize.update(this.getTextArea());
- }
- private get styles(): CSSProperties {
- const options = this.options;
- let styles: CSSProperties = {};
- let resizeStyle = options.visualSettingsButtons.reSize.value ? "vertical" : "none";
- if (this.props.disableResize === true) {
- resizeStyle = "none";
- }
- if (this.readonly) {
- styles.backgroundColor = "#eee";
- styles.cursor = "not-allowed";
- }
- const inputFieldSettingsStyles = options.OptionsOfAttr && options.OptionsOfAttr.inputFieldSettings || {};
- return $.extend({resize: resizeStyle}, inputFieldSettingsStyles, this.props.style, {...styles});
- }
- @autobind
- protected onBlur(event: FocusEvent<HTMLTextAreaElement> | FormEvent<HTMLTextAreaElement>) {
- if (this.props.onBlur) {
- this.props.onBlur();
- }
- this.handleBlur(event);
- }
- @autobind
- protected onFocus() {
- if (this.props.onFocus) {
- this.props.onFocus();
- }
- }
- onDidMount(): void {
- this.settingService.showCountIndicator().then(res => {
- this.showCountIndicatorSetting = res;
- });
- this.valueSize = (this.props.value || "").length;
- if (this.options.visualSettingsButtons.AutoHeight.value) {
- autosize(this.getTextArea());
- }
- }
- onWillUnmount(): void {
- autosize.destroy(this.getTextArea());
- }
- private get size() {
- return this.props.maxSize || this.props.typeAttr && this.props.typeAttr.size;
- }
- private get showCountIndicator() {
- const visualSettingsButtons = this.options && this.options.visualSettingsButtons;
- const optionsIndicatorValue = visualSettingsButtons && visualSettingsButtons.countIndicator.value;
- return this.showCountIndicatorSetting || optionsIndicatorValue;
- }
- @autobind
- private valueChange(event) {
- let value = event.target.value;
- this.valueSize = value.length;
- this.props.realtime && this.handleBlur(event);
- }
- render() {
- const value = this.value || "";
- const placeholder: string = this.placeholder;
- const readonly: boolean = this.readonly;
- const tabIndex: number = readonly ? -1 : null;
- const error: string = this.errorMessage;
- const options = this.options;
- let textAriaControl: HTMLProps<HTMLTextAreaElement>;
- if (this.props.realtime) {
- textAriaControl = {
- value: value
- };
- } else {
- textAriaControl = {
- defaultValue: value
- };
- }
- let containerStyles: CSSProperties = {
- display: this.visible ? "block" : "none"
- };
- if (this.props.style && this.props.style.height) {
- containerStyles.height = this.props.style.height;
- }
- return (
- <span style={containerStyles} title={error ? error : "текстовое поле"}
- className={error ? "error" : ""}>
- {this.header}
- <textarea ref="textarea"
- className={"form-control " + (this.props.errorHighlight ? " text-control-error" : " text-control") + (this.props.className || "")}
- rows={options.visualSettingsButtons.ColRow.value}
- placeholder={placeholder}
- readOnly={readonly}
- tabIndex={tabIndex}
- style={this.styles} {...textAriaControl}
- onFocus={this.onFocus}
- onBlur={this.onBlur}
- maxLength={this.size}
- onChange={this.valueChange}/>
- <If cond={this.showCountIndicator && this.size != null}>
- <div className={styles["countIndicator"]}><span>{this.valueSize}/{this.size}</span></div>
- </If>
- </span>
- );
- }
- }
- export {TextAreaControl as Control};
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement