I want to build a React form with a text field that has very simple syntax highlighting, but I'd like to do it without JSX. Is there a way to use DraftJS without JSX?
-
draftjs not use textfield, but contenteditable dom. – Jiang YD Nov 02 '16 at 06:15
4 Answers
You can do it without Draft.js by using a div
with contenteditable="true"
. Here's what I've worked out so far. For this example, the highlighting rule is that vowels should be highlighted in green.
It works reasonably well, but I still need to add code to keep the selection in the right spot.
Is there a way to use DraftJS instead? Is there an easier way to do this?
var SpanEditor = React.createClass({
handleChange: function(event) {
for (
var i = 0;
i < this.contentSpan.childNodes.length;
i++) {
var child = this.contentSpan.childNodes[i];
if (child.childNodes.length > 1) {
while (child.childNodes.length > 0) {
var grandchild = child.childNodes[0];
child.removeChild(grandchild);
if (grandchild.nodeName == '#text') {
var grandchildText = grandchild;
grandchild = document.createElement(
'span');
grandchild.appendChild(grandchildText);
}
this.contentSpan.insertBefore(
grandchild,
child);
}
this.contentSpan.removeChild(child);
child = this.contentSpan.childNodes[i];
}
if (child.nodeName == 'SPAN') {
var childText = child.textContent,
childClass = child.className;
for (var j = 0; j < childText.length; j++) {
var c = childText.charAt(j),
className = (
'aeiouAEIOU'.indexOf(c) >= 0
? 'vowel'
: '');
if (className != childClass) {
if (j == 0) {
child.className = className;
}
else {
var newChild = document.createElement(
'span');
newChild.className = childClass;
newChild.appendChild(
document.createTextNode(
childText.substring(0, j)));
child.childNodes[0].nodeValue = (
childText.substring(j));
child.className = className;
this.contentSpan.insertBefore(
newChild,
child);
j = childText.length;
}
}
}
}
}
},
mountContentSpan: function(span) {
this.contentSpan = span;
var child = document.createElement('span');
child.appendChild(document.createTextNode(
'Type something.'));
this.contentSpan.appendChild(child);
this.handleChange();
},
render: function() {
return React.createElement(
'span',
{
id: 'z',
onInput: this.handleChange,
contentEditable: true,
suppressContentEditableWarning: true,
ref: this.mountContentSpan
});
}
});
var rootElement =
React.createElement('div', {},
React.createElement(
'p',
{},
'Edit the next paragraph.'),
React.createElement(SpanEditor)
)
ReactDOM.render(
rootElement,
document.getElementById('react-app'))
span.vowel {
background-color: lime;
}
<div id="react-app"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>

- 53,582
- 27
- 205
- 286
Sure there is. Using draft-js makes it much simpler, but I doubt if you need to use such a heavy editor to do this simple job. Take a look at https://facebook.github.io/draft-js/docs/advanced-topics-decorators.html#content

- 687
- 6
- 17
-
Are you saying there is a way to use Draft.js without JSX? The link you provided just tells me how to configure decorators in Draft.js with JSX. I'm trying to write a plain, static Javascript site that includes simple syntax highlighting in a text field. – Don Kirkby Oct 31 '16 at 20:21
-
yes it is possible, we use draftjs at our company and turns out to be pretty good without jsx. You might find something here https://github.com/nikgraf/awesome-draft-js. Also I'm trying to opensource the editor that I'm building right now, lot of code refactoring so I'll let you know when its out. – kaushik94 Nov 01 '16 at 08:47
You can run Babel in the browser plus the ES6 shim. In this approach, you include support scripts that implement JSX and ES6 in the browser. The Draft.js project includes some examples that use this technique. Here are the support scripts that get included:
<script src="../../node_modules/react/dist/react.min.js"></script>
<script src="../../node_modules/react-dom/dist/react-dom.js"></script>
<script src="../../node_modules/immutable/dist/immutable.js"></script>
<script src="../../node_modules/es6-shim/es6-shim.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.js"></script>
<script src="../../dist/Draft.js"></script>
The downside to this approach is that the user's browser has to download a lot of source code, then run the Babylon transpiler before actually running your code.
The upside is that it's easy to configure. You can host the support scripts yourself or link to a CDN version like cdnjs.com. Deploying a new version of your code just means editing your main script and deploying the changed version.

- 53,582
- 27
- 205
- 286
There are some tools to help deploy a static web site based on React-js code. I haven't tried them yet, but they look promising.
These all come from the list of complementary tools for React-js.

- 53,582
- 27
- 205
- 286