Comments (11)
(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.
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.
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.
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.
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.
@mattgi dumb question, is your sample code ES6 or Babel?
from contenttools.
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.
@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.
Any news on this topic? It's been some years...
from contenttools.
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.
@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)
- Save issue - saves fine, but won't allow a second "save" HOT 5
- Making CT compatible with CSP style-src set to 'self'
- Can't edit files that were included or read by php HOT 17
- Edit multiple paragraphs at once. HOT 2
- Is there a way to change the default tag output for normal html tags HOT 2
- Missing translation in /src/scripts/ui/dialogs/table.coffee
- Problem update image classes HOT 5
- Build files to use dynamic import in pure javascript HOT 1
- How to use assign ? HOT 2
- Hot to keep style attributes on save.
- Support for Sass >= 1.33 HOT 11
- npm install failed HOT 2
- Feature: Support drag & drop of images
- The image uploader HOT 2
- Inspector bar doesn't show embedded HTML elements when wrapped with paragraph HOT 1
- Line breaks not saving
- Add class to a link
- Lazy loading of images
- Source code edit? Insert <script> tag HOT 3
- The part in italics is not the right one HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from contenttools.