question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add more useful options and documentation

See original GitHub issue

Nice to have this project published as ContentEditables are hard to deal with.

You should probably document that the implementation is “uncontrolled” and that the div content changes before the state is updated.

Also there are some useful options. Here is the full implementation I use in my project, to give you some insights of features I need:

  • Possibility to post-process the div DOM on change before emitting the change (permits to “format” the DOM, like removing inline styles, html comments, classes or things like that.
  • Possibility to “lock” the contenteditable without unmounting/remounting, to avoid flickering effects
  • Possibility to use a placeholder easily
  • Possibility to disable the listening of changes, to allow integration of side effect libraries like AnnotationJS to update the DIV content without triggering the callback/parser
var UncontrolledContentEditable = React.createClass({

    propTypes: {
        // The HTML to set in this content editable
        html: React.PropTypes.string.isRequired,

        // What to do on changes (key input,paste...)
        onChange: React.PropTypes.func.isRequired,

        // Gives the possibility to "reformat" the dom tree before emitting the change
        parser: React.PropTypes.func,

        // Adds a placeholder attribute to the div.
        // Notice that it requires some CSS to work:
        // [contenteditable][placeholder]:empty:not(:focus):before { content: attr(placeholder); }
        placeholder: React.PropTypes.string,

        // Permits to eventually "lock" the contenteditable. It means that the contenteditable will not be editable anymore
        // This is useful to change from edition to read-only mode
        locked: React.PropTypes.bool,

        // This can be useful to be able to disable the listening of changes
        // This allow external libraries to be able to manipulate the content without triggering parsing/change callback
        // This was primarily done to be able to display annotations on text, using AnnotatorJS
        disableChangeListener: React.PropTypes.bool

    },

    shouldComponentUpdate: function(nextProps) {
        // Special case to avoid cursor jumps
        // See http://stackoverflow.com/a/27255103/82609
        var htmlChanged = nextProps.html !== this.getDOMNode().innerHTML;
        //
        var lockedChanged = this.props.locked !== nextProps.locked;
        var onChangeChanged = this.props.onChange !== nextProps.onChange;
        var parserChanged = this.props.parser !== nextProps.parser;
        var placeholderChanged = this.props.placeholder !== nextProps.placeholder;
        var shouldUpdate = htmlChanged || lockedChanged || onChangeChanged || parserChanged || placeholderChanged;
        if ( shouldUpdate ) {
            console.debug("UncontrolledContentEditable -> should update");
        }
        return shouldUpdate;
    },
    componentDidUpdate: function() {
        // Bypass VDOM diff by React and updates the dom if it is not correct
        // See http://stackoverflow.com/a/27255103/82609
        if ( this.props.html !== this.getDOMNode().innerHTML ) {
            this.getDOMNode().innerHTML = this.props.html;
        }
    },

    emitChange: function(e) {
        if ( this.props.disableChangeListener ) {
            return;
        }
        if ( this.props.parser ) {
            this.props.parser(this.getDOMNode());
        }
        var html = this.getDOMNode().innerHTML;
        if ( html !== this.lastHtml) {
            this.props.onChange(html);
        }
        this.lastHtml = html;
    },

    render: function() {
        return <div {...this.props}
            onInput={this.emitChange}
            placeholder={this.props.placeholder}
            contentEditable={!this.props.locked}
            dangerouslySetInnerHTML={{__html: this.props.html}}></div>;
    }

});

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

5reactions
monolithedcommented, Jan 22, 2017

+1 to add another option placeholder

0reactions
lovasoacommented, Aug 5, 2018

I am closing this issue as it covers several independent feature requests, some of which were implemented. Feel free to open new issues if you have a feature request for which there is no open issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

options - Vim documentation
More precise: For options that expect a file name (those where environment ... This is useful to start the Vim in native mode...
Read more >
View or change the properties for an Office file
View and update properties and metadata for your documents.
Read more >
optparse — Parser for command line options — Python 3.11.1 ...
This tutorial section only covers the four most important option attributes: action , type , dest (destination), and help . Of these, action...
Read more >
git-add Documentation - Git
Update the index by adding new files that are unknown to the index and files modified in the working tree, but ignore files...
Read more >
Best practices for writing Dockerfiles - Docker Documentation
When you run an image and generate a container, you add a new writable layer ... Piping a Dockerfile through stdin can be...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found