Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML contenteditable with non-editable islands

I have sort of browser based WYSIWYG editor where users can edit documents-templates.

Document-template is an ordinary html with some special "merge code placeholders". Such template gets "instantiated" by replacing these placeholders by data coming from DB. This gives final document - an instance of the template.

My current approach looks like this:

<div contenteditable>   Sample template with <input type=button class="mergecode" value="MergeCode1">. </div> 

(Online sample to play with: http://jsfiddle.net/tFBKN/ )

The input is not editable in such case and behaves as a solid block - exactly what I need. Users can delete such merge codes by clicking DEL or BACKSPACE as any other characters, etc. By having proper CSS for such input.mergecode I am able to achieve look-n-feel I want.

But with such approach I have three different problems in three different UAs:

  • IE - CSS { font:inherit } simply does not work there, so if the input is inside <b> like here <b><input value="test"></b> it does not inherit any font styles.
  • FF - Copy of fragment that contains <input> element removes that input from clipboard content so further paste operation inserts everything but not inputs.
  • GC - Click on {BACKSPACE} immediately after the <input> produces weird results (bug)

So I am looking for other ideas of how to represent non-editable inline-block alike "islands" in HTML.

Other approach that I've tried so far:

  • <span contenteditable="false">MergeCode1</span> - it does not work as most of UAs remove such node from selection. So it is not possible to, say, apply <b> or <i> on top of selection that contains such span.

Any other ideas?

like image 315
c-smile Avatar asked Jan 30 '13 23:01

c-smile


People also ask

How do I make Contenteditable in HTML?

You can set the HTML5 contenteditable attribute with the value true (i.e. contentEditable="true" ) to make an element editable in HTML, such as <div> or <p> element.

What is the HTML attribute Contenteditable used for?

The contenteditable global attribute is an enumerated attribute indicating if the element should be editable by the user. If so, the browser modifies its widget to allow editing.

Should you use Contenteditable?

Would I be shooting myself in the foot by using a div with attribute contentEditable="true" as a text field rather than a textarea? If you want a text field, use a textarea, it's less likely to screw things up. Only use a contentEditable div when you need the ability to format the text. It would not work with forms.

What is false about Contenteditable attribute?

contenteditable="false" Indicates that the element is not editable. contenteditable="inherit" Indicates that the element is editable if its immediate parent element is editable.


2 Answers

I'm a CKEditor developer. We've got some experience with nested readonly elements (i.e. placeholder plugin and the feature we're working on currently #9764) and I don't have good news. You have to handle every behaviour manually if you want to have consistent look&feel. There are no tricks that will fix browsers. And many things (like this with weird things happening around input on GC) seem to be unsolvable.

like image 99
Reinmar Avatar answered Oct 12 '22 12:10

Reinmar


One more idea that looks promising:

To use empty span with ::before { content:"caption"; } that should produce non editable block represented in in DOM as a node having no caret positions inside.

You can try it here http://jsfiddle.net/TwVzt/1/

But this approach is not free of problems (in my case): There is no way to declare ::before inline using style DOM attribute and so the whole set should be declared in CSS upfront. But set of merge codes I have is pretty large, even unknown upfront in full in some use cases. Sigh.

Nevertheless putting this recipe here if someone will have better circumstances (known set of codes).

like image 20
c-smile Avatar answered Oct 12 '22 11:10

c-smile