5

I have a contenteditable tag, and I want my users to be able to type code into it. However, when I type into the contenteditable tag, my code shows up as text rather than an actual element. Is there a way for a user to create a full, working HTML element in a contenteditable box? I know it is possible for the client to insert code using javascript, but what about users who do not have access to javascript? How could users get code such as buttons inside a contenteditable box?

<p contenteditable="true">Try typing code in here as user, code will only be text...</p>

Is there a javascript way to accomplish this without JQUERY?

EDIT

I spent a long time searching for answers on Google, but nothing came up. The best solution I've gotten at this point has been @Dekel's comment on CKEditor. If there is another solution, I want to hear it. If there isn't, I'm sticking to CKEditor. I don't have much time, so I need a solution fast.

MORE EDIT =D

I recently developed my own answer to my question by looking at @Brandon's .replace answer (which only worked for client-coding, not user-coding) and modifying it to work with user-coding.

asked Jan 2, 2017 at 22:01
9
  • I'm trying not to take "no" as an answer, as well. Commented Jan 2, 2017 at 22:03
  • You are probably looking for a wysiwyg editor (and not a contenteditable element, unless you want to write all the functionality yourself). Commented Jan 2, 2017 at 22:03
  • By code do you mean a <code> element or do you mean JavaScript? (that would be executed?) Commented Jan 2, 2017 at 22:04
  • In that case, what editor do you recommend I use, @Dekel? I do not want to use an editor, but it seems I may have to. Commented Jan 2, 2017 at 22:04
  • 1
    Don't do this. The user experience would be awful. Provide a field for the HTML source and render it in another place. Commented Jan 2, 2017 at 23:21

3 Answers 3

5

This isn't pretty, but you could make it work if you are looking to add HTML only. Otherwise an inline editor might work best.

var el = document.querySelector('p')
el.addEventListener('blur', function() {
 var map = {amp: '&', lt: '<', gt: '>', quot: '"', '#039': "'"}
 var html = this.innerHTML.replace(/&([^;]+);/g, (m, c) => map[c]);
 this.innerHTML = html;
});
<p contenteditable="true">Try typing <b>code</b> in here as user, code will only be text...</p>

answered Jan 2, 2017 at 22:55
Sign up to request clarification or add additional context in comments.

5 Comments

This just converts the entities produced by the contenteditable back the HTML characters once you stop editing.
also, when user types something in after page has loaded, that doesn't change into element.
@IamGuest, actually it does, at least in the latest version of chrome... make sure to hit tab, or something else to cause the paragraph to lose focus.
oh, yeah. This is the answer!
Just make sure to use a more specific selector! Otherwise, all your paragraphs will have this event listener. Use an id, class or data attribute instead. Before you get too invested in this idea... how do your users now "undo" or change the code?
2

This answer is similar to @Brandon's idea, but is much more simple.

https://jsfiddle.net/azopqLe4/

<iframe width="100%" height="300" src="//jsfiddle.net/azopqLe4/embedded/js,html,result/dark/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>

function convertit() {
	var convet = document.getElementById("convet");
 var text = convet.innerHTML;
 var newtext;
 newtext = text.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
 
 convet.innerHTML = newtext;
}
//this version runs onrightclick =D
<p contenteditable="true" oncontextmenu="convertit();" id="convet">
Type some code here, then right-click... =D
</p>
In the second snippet, I typed <b>Test</b>, right-clicked it, and it became Test! My answer works through simple array replacement methods, although it is frustrating and time-wasting to keep right-clicking all the time. To prevent the actual contextmenu from popping up, just add .preventDefault().

answered Jan 2, 2017 at 23:17

4 Comments

Also, FYI, you can use ctrl/cmd+b and ctrl/cmd+i while editing text in this type of tag, if that is all you are looking to do. You could just add a tooltip or similar to inform users on this functionality.
Note that this is just an example, I am not trying to get bold and italic text in my contenteditable. Instead of doing this example for my actual projectm I'll be making a seperate textbox where a user inputs their code, and my code will take the user's inputted code and insert it into the contenteditable... Phew! =D
Not sure. Looks like they all are.
well, maybe there is no great answer yet... ;)
2

You can't insert code, but you can insert DOMElements with JS. No need for jQuery.

var element=document.createElement("button");
element.innerHTML="Hello";
document.getElementById("yourContentEditable").append(element);

The idea with this would be to have a button to prompt for the code and insert it. Something like this:

(It is very ugly and buggy but it's just an example I just wrote)

var editorSelection=null;
function openCodePopup() {
 //Store cursor position before editor loses focus
 editorSelection=getEditorSelection();
 
 //Open the popup
 document.querySelector("#codePopup").style.display="block";
 var ta=document.querySelector("#userCode");
 ta.value="";
 ta.focus();
}
function closeCodePopup() {
 document.querySelector("#codePopup").style.display="none";
}
function insertCode() {
 var code=document.querySelector("#userCode").value;
 closeCodePopup();
 if(code=="") return;
 insertIntoEditor(html2dom(code));
}
function getEditorSelection() {
 //TODO make crossbrowser
 //TODO (VERY IMPORTANT) validate if selection is whitin the editor
 var sel=window.getSelection();
 if(sel.rangeCount) return sel.getRangeAt(0);
 return null;
}
function insertIntoEditor(dom) {
 if(editorSelection) {
 editorSelection.deleteContents();
 editorSelection.insertNode(dom);
 } else {
 //Insert at the end
 document.querySelector("#editor").append(dom);
 }
}
function html2dom(code) {
 //A lazy way to convert html to DOMElements, you can use jQuery or any other 
 var foo=document.createElement('div'); //or you could use an inline element
 foo.contentEditable=false;
 foo.innerHTML=code;
 return foo;
}
#editor {
 height: 180px;
 overflow: auto;
 border: 1px solid #ccc;
}
#toolbar {
 position: relative;
}
#codePopup {
 position: absolute;
 left: 10px;
 top: 15px;
 background-color: #fff;
 border: 1px solid #ccc;
 padding: 5px;
 display: none;
}
#userCode {
 display: block;
 width: 200px;
 height: 100px;
}
<div id="toolbar">
 <button onclick="openCodePopup()">&lt;/&gt;</button>
 <div id="codePopup">
 <textarea id="userCode" placeholder="Type code here"></textarea>
 <button onclick="insertCode()">Ok</button>
 <button onclick="closeCodePopup()">Cancel</button>
 </div>
</div>
<div contenteditable="true" id="editor"></div>

With the same idea you could create other options to convert element (example, text->link, etc.).

answered Jan 2, 2017 at 22:36

4 Comments

however, with this only the client can insert DOM elements, not the user...
Yes he can. You could add a button (like a toolbar) that the user can click to insert code. The user insert his code in a textarea or something, then it converts the code to a DOM element and inserts it at cursor position.
Then the user would only be able to create specific elements, @Gabriel. It would become difficult as users would have to add any amount of attributes and elements without innerHTMLs. Could you edit your answer to show an example of how this could be done? Thanks :)
I've added the example. If you want the code to be converted as the user writes, the accepted answer is the solution. But the user won't be able to enter code to be shown as code or even < and >, evaluate if that may be an issue.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.