instructure-react / react-tinymce

React TinyMCE component
181 stars 115 forks source link

Is react-tinymce supported by redux-form? #22

Closed tingwei628 closed 8 years ago

tingwei628 commented 8 years ago

According to docs by redux-form, content is the fields to be passed... but it turned out redux-form get "undefined" in content... Thanks in advance~
Here is my code

{ <TinyMCE
        config={{
        menubar: false,
        plugins: 'autolink link image lists print preview',
        toolbar: 'styleselect | bold italic | alignleft aligncenter alignright | link ',
        height: 150,
        width: 450,
        statusbar: false,
}} {...content} />}
jonathaningram commented 8 years ago

@tingwei628 for use with redux-form, you need to set the content prop:

<TinyMCE
  {...content}
  content={content.value}
  config={{
    menubar: false,
    plugins: 'autolink link image lists print preview',
    toolbar: 'styleselect | bold italic | alignleft aligncenter alignright | link ',
    height: 150,
    width: 450,
    statusbar: false,
  }} />
tingwei628 commented 8 years ago

@jonathaningram, really appreciated!

andrewmclagan commented 7 years ago

Just note you really want to only call onChange when a user clicks outside the editor otherise inserting HUGE amounts of HTML content int othe store is a performance nightmare

e.g.

import React, { Component, PropTypes } from 'react';
import TinyMCE from 'react-tinymce';

/**
 * WYSIWYG editor field
 *
 * @author Andrew McLagan <andrewmclagan@gmail.com>
 */

export default class EditableField extends Component {

  static propTypes = {
    value: PropTypes.any,
    id: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired,
    onBlur: PropTypes.func.isRequired,
  }

  componentWillReceiveProps() {
    // we dont ever need to update this, manages the dom itself
    return false;
  }

  editorConfig = {
    plugins: 'link,image,lists,paste,code',
    toolbar: 'undo redo | formatselect bullist numlist | bold italic link | image code paste',
    block_formats: 'Paragraph=p;Heading 3=h3',
    menubar: false,
    statusbar: false,
    body_class: 'editable-field-content',
    paste_word_valid_elements: 'b,strong,i,em,h1,h2,h3,p,li,ul,ol,a',
    paste_retain_style_properties: 'none',
    paste_strip_class_attributes: 'none',
    paste_remove_styles: true,
  }

  editorContent = () => {
    return tinyMCE.get(this.props.id) ? tinyMCE.get(this.props.id).getContent() : '';
  }

  render() {

    const { value, id } = this.props;

    return (
      <TinyMCE
        id={id}
        content={value}
        config={this.editorConfig}
        onBlur={() => {
          this.props.onBlur();
          this.props.onChange(this.editorContent());
        }}
      />
    );
  }
}

is my redux-form component

robhadfield commented 7 years ago

Just thought I'd share my component when using the Field helper... sorry the layout is a bit derp.

import React, { Component } from 'react';
import { Field } from 'redux-form';
import TinyMCE from 'react-tinymce';

class RichTextArea extends Component {

    constructor(props) {
        super(props);
    }

    editorConfig = {
        plugins: 'link,image,lists,paste,code',
        toolbar: 'undo redo | formatselect bullist numlist | bold italic link | code paste',
        block_formats: 'Paragraph=p;Heading 3=h3',
        menubar: false,
        statusbar: false,
        body_class: 'editable-field-content',
        paste_word_valid_elements: 'b,strong,i,em,h1,h2,h3,p,li,ul,ol,a',
        paste_retain_style_properties: 'none',
        paste_strip_class_attributes: 'none',
        paste_remove_styles: true,
    }

    renderTinyMCE(field){

        let props = Object.assign({}, field);
        delete props.input;
        delete props.meta;

        return <TinyMCE
            {...props}
            value={field.input.content !== '' ? field.input.content : null}
            onBlur={(event, value) => { field.input.onChange(event.target.getContent()) }}
            />
    }

    render(){

        const { handleSubmit, value, pristine, reset, submitting } = this.props;

        return (
            <Field
                component={ this.renderTinyMCE }
                name={ this.props.id.toString() }
                ref={ this.props.id }
                id={ this.props.id }
                disabled={ this.props.readonly }
                autoComplete="off"
                config={ this.editorConfig }
            />
        );
    }

};

RichTextArea.propTypes = {
    id:             React.PropTypes.string.isRequired,
    show_label:     React.PropTypes.bool,
    label:          React.PropTypes.string,
    className:      React.PropTypes.string
};

export default RichTextArea;
gugadev commented 6 years ago

@robhadfield does your component reset it's values? I can't achieve this.

/* eslint no-unused-vars: off, max-len: off */
import React from 'react';
import PropTypes from 'prop-types';
import TinyMCE from 'react-tinymce';

const Editor = ({ id, label, input, meta: { touched, error } }) => (
  <div className="form-group">
    <label
      htmlFor={id}
      style={{ marginBottom: '5px' }}
    >
      {label}
    </label>
    <TinyMCE
      {...input}
      content={input.value}
      config={{
        plugins: [
          'advlist autolink lists link image charmap print preview anchor',
          'searchreplace visualblocks code fullscreen',
          'insertdatetime media table contextmenu paste code',
        ].join(' '),
        toolbar: 'undo redo | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
        menubar: false,
        statusbar: false,
        height: 250,
      }}
      onChange={e => input.onChange(e.target.getContent())}
    />
  </div>
);

Editor.propTypes = {
  id: PropTypes.string.isRequired,
  label: PropTypes.string.isRequired,
  input: PropTypes.object.isRequired,
  meta: PropTypes.object.isRequired,
};

export default Editor;
robhadfield commented 6 years ago

Sorry, I'm not sure what you mean - do you mean to clear the editor or initial value?

wysdi commented 6 years ago

@gugadev I experienced the same issue, and this is a workaround:

{ input.value ? <TinyMCE content={input.value} /> : null}

it makes sure your data is available before rendering your TinyMCE