Code Monkey home page Code Monkey logo

Comments (11)

anthonyjb avatar anthonyjb commented on August 18, 2024 3

(Very) Minimal React component example:

<!DOCTYPE HTML>
<html>
    <head>
        <title>ContentTools react</title>
        <link rel="stylesheet" type="text/css" href="../build/content-tools.min.css">
    </head>
    <body>
        <article id="react-mount"></article>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react-with-addons.js"></script>
        <script type="text/javascript" src="../build/content-tools.js"></script>
        <script type="text/javascript">
window.onload = function () {

    // Setup editable React component
    var EditableComponent = React.createClass({

        getInitialState: function () {
            return {content: this.props.content}
        },

        componentDidMount: function () {
            var _this, editor;
            _this = this;

            // When the react component is mounted initialize the ContentTools
            // editor.
            editor = new ContentTools.EditorApp.get();
            editor.init('[data-editable]', 'data-editable');

            // Capture save events and update the react component
            editor.bind('save', function (regions) {
                // Update the state of the component
                _this.setState({content: regions['my-region']},
                    function () {
                        // HACK: Reselect the region DOM elements for the
                        // editor (required because React will re-render the
                        // contents of the component).
                        editor._domRegions = document.querySelectorAll(
                                '[data-editable]');
                    });
            });
        },

        render: function () {
            console.log(this.state.content);
            return React.createElement(
                'div',
                {
                    key: 'my-region',
                    dangerouslySetInnerHTML: {__html:
                        '<div data-editable="my-region">' +
                            this.state.content +
                        '</div>'
                    }
                });
        }

    });

    // Mount the react component on the DOM
    React.render(
        React.createElement(EditableComponent, {content: '<p>Edit me</p>'}),
        document.getElementById('react-mount')
    );

}
        </script>
    </body>
</html>

Whenever the user saves their changes the editor updates the content member of the React component's state, if the user cancels the state stays as it was. Hopefully this is a good starting point if you're looking to integrate the editor into React.

from contenttools.

anthonyjb avatar anthonyjb commented on August 18, 2024

Good question. I've worked on a couple of pretty large React projects in the last 12 months but I'm still not confident I'm qualified to answer.

The basic UI for ContentTools attaches itself to the body of the document as a single element <div class="ct-app">...</div> and the editor that's provided as part of the library in turn uses the UI. It's probable that the editor could run alongside other react components without conflict. Alternatively a React based UI for the editor could be created (but that would be quite a bit of work).

As for making a child of a React component editable you'd probably have to use something along the lines of <div key="..." dangerouslySetInnerHTML={{__html: '<div data-editable=\"region-name\">...</div>'}} /> where the key is used to prevent the child component from being replaced on updates and the contents is set as raw HTML. The editor start/stop methods could be modified to trigger an update of the component when the user finishes editing the component(s).

If you have something specific in mind I'll happily attempt to put together an example to see what's possible?

from contenttools.

mattgi avatar mattgi commented on August 18, 2024

Thanks for the quick response. I guess the editor is the first step and the tools come second. It would be awesome to have an example React component (in ES6, not coffee : P).

Essentially just a way to set some state to display in a view and then flick between editing and viewing (as per your current demo) with perhaps some comments/console logging around when/why things are happening where they do.

I'm yet to spend too much time looking, but your structuring at first glance looks very OO and like it was written as a React component so the thought to port to React has also crossed my mind - but what you have is already rock solid so, if it's simple to integrate, seems like a no brainer to just use it as-is.

from contenttools.

mattgi avatar mattgi commented on August 18, 2024

Awesome, thanks!

I added the editor to state so that I could also destroy it on Unmount; otherwise, your sample code worked on my first attempt, so good!

Now to hook it up with data and look at how to save things :)

Thanks again

from contenttools.

mattgi avatar mattgi commented on August 18, 2024

For the sake of completeness:

'use strict';

import React    from 'react';
import Reach    from 'reach-react';
import Snackbar from '../snackbar';
import './style.scss';

export default class Content extends React.Component {

  /**
   * @constructor
   */
  constructor(...args) {
    super(...args);
    this.state = {
      record : null,
      editor : null
    };
  }

  /**
   * @method componentDidMount
   */
  componentDidMount() {
    this.setState({
      record : this.props.record || {},
      editor : new ContentTools.EditorApp.get()
    }, () => {
      this.state.editor.init('[data-editable]', 'data-editable');
      this.state.editor.bind('save', (regions) => {
        this.editorChange(regions['text-component']);
      });
    });
  }

  /**
   * @method componentWillUnmount
   */
  componentWillUnmount() {
    this.state.editor.destroy();
  }

  /**
   * @method editorChange
   * @param  {Object} event
   */
  editorChange(value) {
    let record = this.state.record;
    record.html = value;
    this.setState({
      record : record
    }, () => {
      this.submit();
      // HACK: Reselect the region DOM elements for the editor after state change.
      this.state.editor._domRegions = document.querySelectorAll('[data-editable]');
    });
  }

  /**
   * @method submit
   */
  submit() {
    Reach.API[this.props.method](this.props.action, this.state.record, function (err, res) {
      if (err) {
        if (this.props.onError) {
          return this.props.onError(err, res);
        }
        return Snackbar.notify({ type : 'danger', message : err.message });
      }
      if (this.props.onSuccess) {
        return this.props.onSuccess(res);
      }
      return Snackbar.notify({ message : 'Success' });
    }.bind(this));
  }

  /**
   * @method render
   */
  render() {
    let innerHtml = {
      __html : `<div data-editable="text-component">${ this.state.record ? this.state.record.html : '' }</div>`
    };

    return (
      <div
        key                     = 'text-component'
        className               = 'text-component'
        dangerouslySetInnerHTML = { innerHtml }
      >
      </div>
    );
  }
}

from contenttools.

guillaumepiot avatar guillaumepiot commented on August 18, 2024

@mattgi dumb question, is your sample code ES6 or Babel?

from contenttools.

mattgi avatar mattgi commented on August 18, 2024

We are running on Babel Stage 0.. may drop back to 1 or 2 when we revisit potential issues... not sure we actually make use of anything from Stage 0 tbh.

from contenttools.

oyeanuj avatar oyeanuj commented on August 18, 2024

@mattgi @anthonyjb Glad to have found this! I considering using this for my React project as well and I was wondering if either of you could share your experience with this example or projects and any learnings before I embark on my journey?

@anthonyjb Any plans by any chance to create a React wrapper for this library?

from contenttools.

needfulthing avatar needfulthing commented on August 18, 2024

Any news on this topic? It's been some years...

from contenttools.

anthonyjb avatar anthonyjb commented on August 18, 2024

Hi @needfulthing I'm afraid I'm no longer involved in any react projects and we dropped it as a framework from our stack sometime ago now. So realistically React integration isn't something we have plans to introduce.

Of course if others with relevant knowledge and experience want to add support for it then I'd help in any limited capacity I can.

from contenttools.

needfulthing avatar needfulthing commented on August 18, 2024

@anthonyjb Thanks for the answer, our team will have a look on it and it would be great to be able to get back to you in case any questions might come up :)

from contenttools.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.