How can I add an (otherwise) invalid HTML element into TinyMCE - javascript

My HTML contains elements like this, because it uses inlines from django-basic-apps.
<inline type="myapp.mymodel" id="4" />
I'm trying to use tinymce to insert one of these into the DOM. On the frontend of the site, these are processed into good code.
In tinyMCE I've added the config:
extend_valid_elements: 'inline[id|ids|type|filter|class|template]',
But anytime I try to insert via:
tinyMCE.execCommand('mceInsertRawHtml',false,'<inline type="myapp.mymodel" id="4" />');
nothing happens,
And if I do:
tinyMCE.activeEditor.getContent()
TinyMCE removes any <inline elements that are in my code.
Furthermore, I would like these elements to display in the tinyMCE via CSS or something, but I'll probably have to hack the DTD.
If that doesn't work a possible solution that I've thought of would be to pre-render the content to something that IS valid:
And then before save, convert that back to what it should be.
Please provide any suggestions for things I should look into.

In the source code of tinymce tiny_mce_src.js search for the string valid_elements and add your elements and attributes directly there.

Use mceInsertContent command instead, and don't use self-closing tags:
tinyMCE.execCommand('mceInsertContent', false, '<inline type="myapp.mymodel" id="4"></inline>');

Related

Custom tags in TinyMCE WYSWYG

I have an application which help our user to format the email template. A sample email template looks like this:
Dear <FirstName> <LastName>:
Thank you for your entry <Title> and your order number is <OrderID>....
These are saved in our database as Text. The issue is when i try to load this text in simple Textarea it works fine when i try to display this text in TinyMCE editor textarea it cuts off when it see the first "<" and display something like this:
Dear :
Thank you for your entry and your order number is ....
TinyMCE dose not render the tags. i dont know how to render the custom tags and they are not <abc> </abc> tags. Our system will replace the "<SomeValue>" with the actual value based on the tag and send the email to the client.
I tried replacing the "<" and ">" to "<" and ">" and its not working. I also tried them replacing it to "<code><" and "></code>" before i bind the textarea but that is not working either. I have added "code" plugin while declaring my TinyMCE in javascript. Do i need anything else, any specially "entity_encoding"? I tried "raw" and "html" nothings works.
here is my javascript
<script>
tinymce.init({
selector: '#mytextarea',
entity_encoding: "html",
plugins: "code",
toolbar: 'code'
});
</script>
Any help is appreciated as i have spend two days searching the web and trying bunch of things.
If you want TinyMCE to treat these elements like HTML tags you need to define them as custom tags:
https://www.tiny.cloud/docs/configure/content-filtering/#custom_elements
An alternative which may take less effort to setup is to use another syntax (e.g. {first_name}) along with marking that text as non-editable so that TinyMCE treats the entire string like one "character" in the UI.

need to add contentEditable=false to p tag inside CKEditor

i need inside my CKEditor some boilerplate verbiage that is not editable, then the rest of the my string information. I concatenate the boilerplate verbiage [which is in a p tag], to a string variable that my CKEditor displays inside a certain div. By the time the verbiage, here:
<p id='abc' contentEditable='false'>verbiage</p>
... and the string information is displayed on the page, they are deep inside a number of nested tags - within a body with multiple classes. So both the verbiage, which is now in only a p tag with no attributes[they got stripped out], is nested way inside the original body tag [the first body tag, way up in the page] with lots and lots of divs, then finally comes an iframe, then ... the verbiage and string are like this:
<body contenteditable="true" class="cke_editable cke_editable_themed cke_contents_ltr cke_show_borders" spellcheck="false">
<p>boilerplate verbiage</p>
...then the rest of the information is displayed in the editor, inside various spans, etc. i need to make the boilerplate verbiage readonly, contentEditable='false'. Yet everything I try both from the console in Chrome, and in code.... nothing changes that boilerplate verbiage tag. i have tried various things, including these - perhaps you can see where I need to tweak something; and i hope this will show you things i have tried and that i am run out of options so far:
jQuery("body.cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders").first().contentEditable='false';
jQuery("body.cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders").attr("readonly", "1");
jQuery("body.cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders p:first-child").contentEditable='false';
jQuery("body.cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders").find( "p" ).contentEditable='false';
jQuery("iframe", ".cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders").contents().find("p").contentEditable='false';
jQuery("iframe", "body .cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders").contents().find("p").contentEditable='false';
var editor= jQuery("body", ".cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders");
editor.val(editor.val().replace(/<p>/gi, "<p class='tiny_p'>"))
var editor= jQuery("body.cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders");
editor.val(editor.val().replace(/<p>/gi, "<p class='tiny_p'>"))
yet if i hard code in the Chrome browser, contenteditable="false",
it works perfectly. So, how can i access that p tag and assign it this attribute?
It really depends on moment and how you want to access, one option to access directly from separate script.
CKEDITOR.instances[YOUR_INSTANCE].window.$.document.getElementById("your_p_tag")
Note, that it should be done after CKEDITOR initilized
UPDATE:
CKEDITOR.instances[YOUR_INSTANCE].window.$.document.body.firstChild

setting content between div tags using javascript

I'm trying to set some content in between some div tags on a JSP page using javascript.
currently the div tag on the JSP page looks like this:
<div id="successAndErrorMessages"></div>
I want to fill the content in those div tags using some javascript method so that it will look like so:
<div id="successAndErrorMessages"><div class="portlet-msg-error">This is an error message</div></div>
I know you can go like this:
document.getElementById("successAndErrorMessages").value="someContent";
But that just changes the value of the 'value' attribute. It doesn't fill in content between those div tags. Anyone out there that can point me in the right direction?
Try the following:
document.getElementById("successAndErrorMessages").innerHTML="someContent";
msdn link for detail : innerHTML Property
See Creating and modifying HTML at what used to be called the Web Standards Curriculum.
Use the createElement, createTextNode and appendChild methods.
If the number of your messages is limited then the following may help. I used jQuery for the following example, but it works with plain js too.
The innerHtml property did not work for me. So I experimented with ...
<div id=successAndErrorMessages-1>100% OK</div>
<div id=successAndErrorMessages-2>This is an error mssg!</div>
and toggled one of the two on/off ...
$("#successAndErrorMessages-1").css('display', 'none')
$("#successAndErrorMessages-2").css('display', '')
For some reason I had to fiddle around with the ordering before it worked in all types of browsers.

Create new (not change) stylesheets using jQuery

We've got a little tool that I built where you can edit a jQuery template in one field and JSON data in another and then hit a button to see the results immediately within the browser.
I really need to expand this though so the designer can edit a full CSS stylesheet within another field and when we render the template, it will have the CSS applied to it. The idea being that once we've got good results we can take the contents of these three fields, put them in files and use them in our project.
I found the jQuery.cssRule plugin but it looks like it's basically abandoned (all the links go nowhere and there's been no development in three years). Is there something better or is it the only game in town?
Note: We're looking for something where someone types traditional CSS stylesheet data in here and that is used immediately for rendering within the page and that can be edited and changed at will with the old rules going away and new ones used in their stead. I'm not looking for something where the designer has to learn jQuery syntax and enter in individual .css("attribute", "value") type calls to jQuery.
Sure, just append a style tag to the head:
$("head").append("<style>p { color: blue; }</style>");
See it in action here.
You can replace the text in a dynamically added style tag using something like this:
$("head").append("<style id='dynamicStylesheet'></style>");
$("#dynamicStylesheet").text(newStyleTextGoesHere);
See this in action here.
The cleanest way to achieve this is by sandboxing your user-generated content into an <iframe>. This way, changes to the CSS won't affect the editor. (For example, input { display:none; } can't break your page.)
Just render out your HTML (including the CSS in the document's <head>, and write it into the <iframe>.
Example:
<iframe id="preview" src="about:blank">
var i = $('#preview')[0];
var doc = i.contentWindow || i.contentDocument;
if (doc.document) doc = doc.document;
doc.open('text/html',true);
doc.write('<!DOCTYPE html><html>...</html>');
doc.close();
If the user should be able to edit a whole stylesheet, not only single style attributes, then you can store the entered stylesheet in a temporary file and load it into your html document using
$('head').append('<link rel="stylesheet" href="temp.css" type="text/css" />');
sounds like you want to write an interpreter for the css? if it is entered by hand in text, then using it later would be as simple as copy and pasting it into a css file.
so if you have a textarea on your page to type in css and want to apply those rules when you press the button, you could use something like this (only pseudocode, needs work):
//for each css id in the text area
$.each($('textarea[name=cssTextArea]').html().split('#'), function({
//now get each property
$.each($(this).split(';'), function(){
$(elem).css({property:value});
});
});
then you could write something to go through each element that your designer typed in, and get the current css rules for it (including those that you applied using some code like the snippet above) and create a css string from that which could then be output or saved in a db. It's a pain and much faffing around with substrings but unfortunately I don't know of a faster or more efficient way.
Hope this atleast gives you some ideas

jQuery appended text is invisible

I'm trying to create a couple of buttons above a textarea to insert some HTML code -- a VERY poor-man's HTML editor. I have a couple of INPUT elements, and I'm using jQuery to set a click handler that will call's jQuery's append() or html() or text() functions.
The handler fires, it shows a debug alert(), but the text I'm trying to append doesn't show up in the textarea. When I inspect the textarea in Firebug, I see the text I'm appending as a child of the textarea -- but it's dimmed, as when an element's style is set to display:none. But Firebug's CSS inspector doesn't show any change to the display or visibility properties.
When I set the click handler to 'append()', and then click multiple times, in Firebug I see the text being added over and over again -- but each new chunk is still invisible. If I choose 'Edit HTML' in Firebug and then type some chars next to the appended text, the entire text block -- the text added by jQuery and the stuff I added in Firebug -- suddenly appear.
This also happens if I don't use a click handler, but call my append function using an inline handler like onclick="javascript:insert('bold');"
Anyone have any idea why the appended text is not displayed?
Here's the relevant code:
The HTML:
<input type='button' id='bold' value='B' onclick='javascript:insert("bold")' />
<textarea name='PersonalGreeting' id='PersonalGreeting'>default text</textarea>
The Javascript:
function insert( cmd ) {
switch ( cmd ) {
case 'bold':
$('#PersonalGreeting').append('<b>bold text here</b>');
break;
}
}
I would guess that jQuery is trying to append HTML DOM elements to the textarea.
Try using the val method to get and set the textarea's value, like this:
$('#PersonalGreeting').val($('#PersonalGreeting').val() + '<b>bold text here</b>');
The basic problem is that you can't put HTML inside a <textarea>. In fact, you can't append HTML elements to one at all. You could use the .val() method to change the text shown inside, but that won't make it bold. That will just make it have <b> showing as part of the text.
An off-the-shelf WYSIWYG editor like TinyMCE is free and easy to implement. Rather than reinvent the wheel (which is a lot harder than it might look), try an existing wheel out.
SLaks and VoteyDisciple are correct. You're usage of append is faulty as you are perceiving it as a string function.
From http://docs.jquery.com/Manipulation/append
Append content to the inside of every
matched element. This operation is the
best way to insert elements inside, at
the end, of all matched elements. It
is similar to doing an appendChild to
all the specified elements, adding
them into the document.
Reinventing the wheel on this one is likely more headache than its worth unless this is an attempt to create a superior, competing product or for your own experimentation.
Also, I would shy away from use of obtrusive JavaScript as you have shown in your example with onclick='javascript:insert("bold")' embedded in the input element. Instead, you'll have a more elegant solution with something like the following:
HTML
<input type="button" value="B" class="editor-command" >
<input type="button" value="I" class="editor-command" >
<input type="button" value="U" class="editor-command" >
JavaScript (not tested)
$(document).ready(function() {
var textarea = $('#PersonalGreeting')
$(".editor-command").each(function(i, node) {
textarea.val(textarea.val() + '<$>text here</$>'.replace(/\$/g, node.value);
});
});
If the main issue is the textarea not being visible, I would try this:
$('#PersonalGreeting').append('<b>bold text here</b>').show();
Might be worth a shot.
edit: In the vain of not trying to reinvent the wheel, I've had success with WYMEditor
You could do this:
$('#PersonalGreeting').append('[b]bold text here[/b]');
But that won't actually render the text as bold. To be honest I'm not actually sure how to render text as bold inside a textarea, I imainge some js trickery.

Categories