How to make a template content non editable in tinymce - javascript

I've crated html template file, I put some elements inside that template are non editable.
template.html contains
<body>
<div>This is a sample template </div>
<div contenteditable="false" style="color:red">Read Only Text</div>
</body>
on inserting this template file into the textarea the second div is editable, while inspecting over that div I've seen that the attribute contenteditable="false" is not there on insert, but its there on the preview before the insert of template.
Any help gratefully received!

From this page: http://www.tinymce.com/tryit/noneditable_content.php
Its using a textarea:
<textarea name="content" style="width:100%">
<p>Text with a <span class="mceNonEditable">[non editable]</span> inline element.</p>
<p class="mceNonEditable">Noneditable text block with <span class="mceEditable">[editable]</span> items within.</p>
<p>Text with tokens that isn't [[editable]] since they match the noneditabe_regexp.</p>
</textarea>
The key here is putting a class of mceNonEditable in your element:
span class="mceNonEditable"
Then whatever non-editable content you have, wrap it in greater than and less than:
>You cannot edit me<
Then finally close the element:
/span
I think you can also change the mode (in the example they're using textareas, so I guess you can also use divs or spans) when initializing tinymce:
tinyMCE.init({
mode : "textareas",
noneditable_regexp: /\[\[[^\]]+\]\]/g
});
There's also noneditable_regexp which lets you specify a regular expression of non-editable contents.
I think this is easier than using html entities.
I haven't actually tried it but that's the way I interpret the example in the page.

Related

Why is a <div> tag or <form> tag written as a child to a <p> tag in an HTML code rendered by Chrome as not a child, but a sibling of the <p> tag? [duplicate]

As far as I know, this is right:
<div>
<p>some words</p>
</div>
But this is wrong:
<p>
<div>some words</div>
</p>
The first one can pass the W3C validator (XHTML 1.0), but the second can't. I know that nobody will write code like the second one. I just want know why.
And what about other tags' containment relationship?
An authoritative place to look for allowed containment relations is the HTML spec. See, for example, http://www.w3.org/TR/html4/sgml/dtd.html. It specifies which elements are block elements and which are inline. For those lists, search for the section marked "HTML content models".
For the P element, it specifies the following, which indicates that P elements are only allowed to contain inline elements.
<!ELEMENT P - O (%inline;)* -- paragraph -->
This is consistent with http://www.w3.org/TR/html401/struct/text.html#h-9.3.1, which says that the P element "cannot contain block-level elements (including P itself)."
In short, it is impossible to place a <div> element inside a <p> in the DOM because the opening <div> tag will automatically close the <p> element.
According to HTML5, the content model of div elements is flow content
Most elements that are used in the body of documents and applications are categorized as flow content.
That includes p elements, which can only be used where flow content is expected.
Therefore, div elements can contain p elements.
However, the content model of p elements is Phrasing content
Phrasing content is the text of the document, as well as elements that
mark up that text at the intra-paragraph level. Runs of phrasing
content form paragraphs.
That doesn't include div elements, which can only be used where flow content is expected.
Therefore, p elements can't contain div elements.
Since the end tag of p elements can be omitted when the p element is immediately followed by a div element (among others), the following
<p>
<div>some words</div>
</p>
is parsed as
<p></p>
<div>some words</div>
</p>
and the last </p> is an error.
Look at this example from the HTML spec
<!-- Example of data from the client database: -->
<!-- Name: Stephane Boyera, Tel: (212) 555-1212, Email: sb#foo.org -->
<DIV id="client-boyera" class="client">
<P><SPAN class="client-title">Client information:</SPAN>
<TABLE class="client-data">
<TR><TH>Last name:<TD>Boyera</TR>
<TR><TH>First name:<TD>Stephane</TR>
<TR><TH>Tel:<TD>(212) 555-1212</TR>
<TR><TH>Email:<TD>sb#foo.org</TR>
</TABLE>
</DIV>
Did you notice something? : There was no closing tag of the <p> element. a mistake in the specs ? No.
Tip #1: The closing tag of <p> is OPTIONAL
You may ask: But then how would a <p> element knows where to stop?
From w3docs:
If the closing tag is omitted, it is considered that the end of the paragraph matches with the start of the next block-level element.
In simple words: a <div> is a block element and its opening tag will cause the parent <p> to be closed, thus <div> can never be nested inside <p>.
BUT what about the inverse situation ? you may ask
well ...
Tip #2: The closing tag of the <div> element is REQUIRED
According to O’Reilly HTML and XHTML Pocket Reference, Fourth Edition (page 50)
<div> . . . </div>
Start/End Tags
Required/Required
That is, the <div> element's end will only be determined by its closing tag </div> hence a <p> element inside is will NOT break it.
After the X HTML, the conventions has been changed, and now it's a mixture of conventions of XML and HTML, so that is why the second approach is wrong and the W3C validator accepts the things correct that are according to the standards and conventions.
Because the div tag has higher precedence than the p tag. The p tag represents a paragraph tag whereas the div tag represents a document tag.
You can write many paragraphs in a document tag, but you can't write a document in a paragraph. The same as a DOC file.

How to replace a <p> tag in an html file using Javascript

In an Html file that I have, there is a paragraph tag that basically looks like this:
<p class="col-sm-8 form-control-static wordwrap">
Hey
What's
Up
</p>
The contents of this paragraph are grabbed from a textarea that a user fills out and the value of this textarea is grabbed via jquery and filled into this element.
The output looks like this: Hey What's Up
This paragraph tag ignores the newlines within the paragraph, so the paragraph displays all on one line. Due to the format and layout of the project, I can't necessarily change the html source. I was wondering if there was a way to change this exact element to be:
<pre class="col-sm-8 form-control-static wordwrap">
Hey
What's
Up
</pre>
using only javascript. Is this possible? This is so my output will keep the newlines.
I think you are looking for something like this. you tagged jquery so I used that but this could be done in vanilla js too.
I linked to a onkeyup event if you wanted to change to use the button only if you wanted
$(document).ready(function(){
function updateContent() {
$('#p1').html($('#source').val());
}
$('#update').on('click', function(e){
updateContent();
// add other stuff here
// for only the click event
})
$('#source').on('keyup', updateContent);
})
button {
display:block;
}
#source {
height:100px;
}
#p1{
white-space:pre;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="source" placeholder="Update content and click 'update'">new content
add line breaks and <p>html markup</p>
</textarea>
<button id="update" >Update</button>
<p id="p1">THIS WILL CHANGE!</p>
It is very simple and has been asked before... BUT here it is, using DOM:
document.getElementById("p1").innerHTML = "<p>This</p><p>Has</p><p>Changed!</p>";
<p id="p1">THIS WILL CHANGE!</p>
So your piece of code you need is:
document.getElementById("p1").innerHTML = "New text!";
EDIT
This is simpler, easier and more browser friendly than using <pre> tags. Therefore, I would highly recommend you to use this instead.

JQuery replace all contents in a div except tags

I have to replace some characters in all a div, but when I run the code, the function replaces me also the html tags characters
my code is:
$("#main").children().each(function() {
$(this).html($(this).html().replace(/s/g, "K"));
})
<div id="main">
<p>Some contents that will be replaced... <span>this will not be in a span tag :(</span></p>
</div>
result:
<div id="main">
<p>Kome contentK that will be replaced... <Kpan>this will not be in a Kpan tag :(</Kpan></p>
</div>
If your goal is to preserve all the markup within the div but replace text within all those tags, that's difficult. You need to find just the text nodes and no other nodes and do the replacement within each of the text nodes individually.
This question may help: How do I select text nodes with jQuery?

JQuery - Paste event, stripping rich text

I have a contentEditable field where I'd like to do the following. When a user pastse rich text into the field (microsoft word, or otherwise) I'd like to strip all the rich text, but retain the line breaks.
My thinking was: If you paste rich text into a plain <texarea>, it removes all the formatting and retains the breaks (created by explicit new lines, as well as block level elements). I'd like to somehow simulate this. In other words, create a temporary textarea, intercept the paste event, apply it to the Textarea, retrieve the results, and insert them back into the original Content Editable field.
However, i haven't found a way to simulate this. If I paste the contents into a textarea via jquery, it seems to retan all the rich text formatting when I try and copy it from there, back to the original fields
You could achieve something like this without needing a textarea, just processing the code in the content editable div every time that there is a change in its value, and removing all the tags but the paragraphs and line breaks.
The idea would be that every time that the content changes in the div (listen to the input event):
Replace in the inner HTML all </p> and <br> for non-HTML tokens (e.g.: [p] and [br] respectively).
Remove all HTML tags (you can do it with .text())
Replace the tokens that you used for their equivalents (and their openings!)
Wrap everything between <p> and </p>.
Here a simple demo:
$("#editable").on("input", function() {
$this = $(this);
// replace all br and closing p tags with special tokens
$this.html($this.html().replace(/\<\/p\>/g,"[p]").replace(/\<br\>/g,"[br]"));
// remove all the tags, and then replace the tokens for their original values
$this.html("<p>" + $this.text().replace(/\[p\]/g, "</p><p>").replace(/\[br\]/g,"<br>") + "</p>");
});
div#editable, div#demo {
border:1px solid gray;
padding:6px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div contenteditable="true" id="editable"></div>
<h3>Demo</h3>
<p>Copy this code and paste it on the editable div above:</p>
<div id="demo">
<p>This <b>is</b> <i>a</i> styled paragraph.</p>
<p> </p>
<p>The <span style="font-weight:bold">above paragraph</span> is empty.</p>
<p>And this is a new paragraph…<br>with a line break!</p>
</div>
You can also see it running on this JSFiddle: http://jsfiddle.net/v5rae96w/
I tried this solution with MS Word and HTML and it works fine. But it has one issue: it only does line breaks with p and br (that works nicely with MS Word and other word processors). If the user copies HTML like div (or other block elements that cause a line break), it won't work as nicely. If you need to break with all block elements, this solution may require some changes.
To fix that, you could replace all the block tags with p (or div or the element that you want), by indicating it on the regular expression:
$this.html().replace(/(\<\/p\>|\<\/h1\>|\<\/h2\>|\<\/div\>)/gi,"[p]")
As you can see here:
$("#editable").on("input", function() {
$this = $(this);
// replace all closing block tags with special token
$this.html($this.html().replace(/(\<\/p\>|\<\/h1\>|\<\/h2\>|\<\/h3\>|\<\/h4\>|\<\/h5\>|\<\/h6\>|\<\/div\>)/gi,"[p]").replace(/\<br\>/gi,"[br]"));
// remove all the tags
$this.html("<p>" + $this.text().replace(/\[p\]/g,"</div><p>").replace(/\[br\]/g,"<br>") + "</p>");
});
div#editable, div#demo {
border:1px solid gray;
padding:6px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div contenteditable="true" id="editable"></div>
<div>
<h3>Demo</h3>
<p>Copy this code and paste it on the editable div above:</p>
<div id="demo">
<p>This <b>is</b> <i>a</i> styled paragraph.</p>
<p> </p>
<p>The <span style="font-weight:bold">above paragraph</span> is empty.</p>
<p>And this is a new paragraph…<br>with a line break!</p>
</div>
</div>
Or on this JSFiddle: http://jsfiddle.net/v5rae96w/1/

Tinymce editor text alignment in noneditable contet

I've created a custom tinymce plugin to Add Headers,
(this plugin used to add readonly text into the editor)
these headers are inserted into a div with attribute
contenteditable="false"
Like <div class="headerDiv" contenteditable="false">Marks</div>
(headerDiv is used to set the div as inline)
I havn't use the tinymce noneditable plugin regex , for me it's not working on inserting from a listbox. (please check the images)
The problem arises when i try to align the selected content with noneditable headers,
the headers will displayed on next line. (please check the image)
I've checked the tinymce_src.js, from that i understand how alignment works,
they get the content from the editor and wrap a div around it,
and align that div using text-align property.
In wrapping section they check the selected content has a html tag,
if the tag was found then they split the content into 3
i.e
content before the tag
content with html tag
content after the tag
and wrap this 3 part with a div
Example for tinymce selected content : raw tepmlate Marks
part 1 : <div style="text-align:center">raw tepmlate</div>
part 2 : <div style="text-align:center"><div class="headerDiv" contenteditable="false">Marks</div></div>
part 3 : <div style="text-align:center"> </div>
Any guidance and help is appreciated..!
style="display: inline-block;"
?

Categories

Resources