Getting the value from a TinyMCE textarea - javascript

I have a news editor for my site with which I am using TinyMCE. What I would like to be able to do is have a button (outside of the TinyMCE editor itself) that I can click to scan the textarea for any images, then list those images as options to use for a thumbnail image for said news article.
For an idea of what I mean, please see this link here: https://docs.google.com/leaf?id=0B05m73kzudwPNzUwZjkyNmItYjZkMy00NTdlLTlkNDctOGRhYThjMzNjNTM5&hl=en_US
My problem is that document.getElementById('NewsArticle').value is not returning anything when there is text in the textarea
The other potential problem is that whats shown in the textarea is not actual code, but images etc too so I wasn't sure it would even work in the first place, but since when the form is submitted the data[News][article] value is back into text, I thought there might be a chance.
If anyone knows how to get either the content or code for the tinyMCE textarea, or has a better solution, I'd be interested to hear

TinyMce has an api for accessing content from the editor.
This code will grab the html from the active editor:
// Get the HTML contents of the currently active editor
tinyMCE.activeEditor.getContent();
// Get the raw contents of the currently active editor
tinyMCE.activeEditor.getContent({format : 'raw'});
// Get content of a specific editor:
tinyMCE.get('content id').getContent()

Use below syntax, which will remove unwanted character from your input textarea....
(((tinyMCE.get('YourTextAreaId').getContent()).replace(/( )*/g, "")).replace(/(<p>)*/g, "")).replace(/<(\/)?p[^>]*>/g, "");

Try
window.parent.tinymce.get('contentID').getContent();
For some reason, the stock-standard tinymce.get() call didn't work for me, so I tried this and it works. :)

var temp = tinymce.get('textAreaName').save();
console.log(temp);
OR
var temp =tinymce.get('textAreaName').getContent();
console.log(temp);

Probably you have something like
<form>
<textarea id="myArea">Hello, World!</textarea>
</form>
you should simply add as follows
<form method="post">
<textarea id="myArea" name="value">Hello, World!</textarea>
<input type="submit">
</form>
and you can catch the data with PHP under myArea var.

Related

How can some HTML code be isolated from the rest of the webpage?

I'd like to allow the user to customize their user name using HTML tags, without restrictions.
The only problem I've found is they not closing tags...
Ex: (a user name with not closed tag: my<b>nick)
mynick: comment textinnocent user: comment text
I searched for a tag like <sandbox> my <b>nick </sandbox> or any way to force closing every open tag, but I have not been lucky.
Desired result:
mynick: comment textinnocent user: comment text
Is there any smart way to achieve this? (Only using HTML or JS/JQuery)
If you have any incomplete tags, the browser automatically tries to close it(doesn't seem to happen if you have an HTML code following).
If you look at this fiddle https://jsfiddle.net/hwpLyow0/1/
I have the HTML inside the DIV asHello <b><i>World!
But when I alert the HTML from the DIV I get
Hello <b><i>World!</i></b>
I would suggest using jQuery's .html() function or JavaScript's .innerHTML to get the HTML with tags closed.
EDIT:
If users are typing it in textbox, creating a new element(not appending it to document) will do the work for you.
var fix = document.createElement("div");
fix.innerHTML=document.getElementById("test").value;
Fiddle: https://jsfiddle.net/hwpLyow0/3/

How to make a live HTML preview textarea safe against HTML/Script Injection

I'm turning here as a last resort. I've scoured google and I'm having troubles coming to a solution. I have a form with a textarea element that allows you to type html in the area and it will render the HTML markup live as you type if you have the preview mode active. Not too different from the way StackOverflow shows the preview below a new post.
However, I have recently discovered that my functionality has a vulnerability. All I got to do is type something like:
</textarea>
<script>alert("Hello World!");</script>
<textarea style="display: none;">
And not only does this run from within the textarea live, if you save the form and reload said data on a different page this code still executes within the textarea on said different page but unbeknownst to the user; to them all the see is a textarea (if there is no alert obviously).
I found this post; Live preview of textarea input with javascript html, and attempted to refactor my JS to the accepted answer there, because I noticed I couldn't write a script tag in the JSFiddle example, though maybe that's some JSFiddle blocking that behaviour, but I couldn't get it working within my JS file.
These few lines is what I use to live render HTML markup:
$(".main").on("keyup", "#actualTextArea", function () {
$('#previewTextArea').html($('#actualTextArea').val());
});
$(".main").on("keydown", "#actualTextArea", function () {
$('#previewTextArea').html($('#actualTextArea').val());
});
Is there a way this can be refactored so it's safe? My only idea at the moment is to wipe the live preview and use a toggle on/off and encode it, but I really think this is a cool feature and would like to keep it live instead of toggle. Is there a way to "live encode" it or escape certain tags or something?
In order to sanitise your text area preview simply replace all the < and > with their html character code equivalents:
function showPreview()
{
var value = $('#writer').val().trim();
value = value.replace("<", "<");
value = value.replace(">", ">");
$('#preview').html(value);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="writer" onInput="showPreview();">
</textarea>
<br/>
<hr/>
<div id="preview">
</div>
Edit: Actually, I think this solution is a little cleaner, and makes the below code unnecessary. In the velocity page all that is needed is to take advantage of the Spring framework. So I replace the textarea with this like so:
#springBindEscaped("myJavaObj.textAreaText" true)
<textarea id="actualTextArea" name="${status.expression}" class="myClass" rows="10" cols="120">$!status.value</textarea>
This paired with some backend Java validation and it ends up being a much cleaner solution.
But if you want a non-spring/ velocity solution, then this below works just fine
I cobbled together a quick fix as my main purpose is to eliminate the ability for others to execute scripts easily. It's not ideal, and I"m not claiming it to be the best answer, so if someone finds a better solution, please do share. I created a "sanitize" function like so:
function sanitize(text){
var sanitized = text.replace("<script>", "");
sanitized = sanitized.replace("</script>", "");
return sanitized;
}
Then the previous two event handlers now look like:
$(".main").on("keyup", "#actualTextArea", function () {
var textAreaMarkup = $('#actualTextArea').val();
var sanitizedMarkup = sanitize(textAreaMarkup );
$('#actualTextArea').val(sanitizedMarkup);
$('#previewTextArea').html(sanitizedMarkup);
});
// This one can remain unchanged and infact needs to be
// If it's the same as above it will wipe the text area
// on a highlight-backspace
$(".main").on("keydown", "#actualTextArea", function () {
$('#previewTextArea').html($('#actualTextArea').val());
});
Along with Java side sanitation to prevent anything harmful being stored in the DB, this serves my purpose, but I'm very open to a better solution if it exists.

Replace parts of string (attributes) in textarea using input boxes

Main Target :
To create a website that will have a live preview of an HTML/CSS code.
More specifically :
The HTML/CSS code will be editable form the user in some specific parts. So, the code in the live preview will not derive from text areas but from divs.
Image of what I am trying to do :
So, in my Previous Question I tried to find a way to make the live preview box work after getting the code from the black boxes. It did not work because the code was given in a div tag and not a textarea. I would like to add that the code in the div tags use xmp tags because some parts are editable from the user.
Now, I have replaced the divs with textarea tags but the EDIT function does not work.
Main Question :
How do I edit parts of a textarea text? Below, I made it work for a div tag but not a textarea. How can I make the following work for a textarea?
$('input#thebox1').keypress(function(e) {
console.log($(this).val());
if(e.which == 13 && $(this).val().length > 0) {
var c = $(this).val();
$('.popup1').removeClass().addClass(c).text(c);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Replace Title Background Color: </div><input type="text" id='thebox1'>
<div id="copyTarget1" class="innerbox css">
<blockquote>
<pre>
<code>
.title
{
background: #<b class="popup1" style="color:#FF0000;">value </b>;
vertical-align: middle;
}
</code>
</pre>
</blockquote>
</div>
<br><br><br><br><br><br>
I thought about taking another approach to make your life easier using Ace (Cloud9 Editor). It is an awesome solution to get code editors for different languages. All built in JavaScript. It is quite easy to integrate. I just downloaded it to create the case you are trying to build.
You can find the example I have just made here: https://dubaloop.io/dev/html_css_js_editor/
Basically, you load the library for ace:
<script src="src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
Then you create a "pre" container for your HTML, CSS, JavaScript editor:
<pre class="editor" id="editor_js">
function foo(items) {
alert('works');
}</pre>
You will be able to convert them into code editor by using the function:
var editor_js = ace.edit("editor_js");
editor_js.setTheme("ace/theme/monokai");
editor_js.session.setMode("ace/mode/javascript");
It will generate a nice code editor that can through error, warnings, etc. You also have different themes. It is very user friendly as you could see. In my example I just get the content of each code container and send it to an blank iframe that. In order to retrieve the content you can use:
editor_js.getValue();
Check the source code for example I sent you above. I also created .zip with the example here: https://dubaloop.io/dev/html_css_js_editor/example.zip
Have a look to see if this would work for you.
GitHub repo for ACE: https://github.com/ajaxorg/ace-builds
I hope it helps.
UPDATE:
I decided to update the response to replay to your last comment. A few things about it:
First, I updated the code in the link I sent you previously: https://dubaloop.io/dev/html_css_js_editor/
The idea was to check the guide to see how you can manipulate the input and adjust it to what you need. They have great manipulation options. This is the guide: https://ace.c9.io/#nav=howto&api=editor
I just made a short version of what you are trying to do: I am replacing the content for the <h1> in HTML editor, by entering it in a textfield input; similar to what you are trying to achieve. I set the html code editor as a readonly so you cant edit on it. Have a look and let me know.
Second, I created another example using your code. You can check it here: https://dubaloop.io/dev/html_css_js_editor/example.html
I noticed that the first problem you were having was related to how you were triggering the preview update ($('.innerbox').on("keyup"...)). There was not keyup event there. For now I set it on any input when you hit enter. The other big problem, and probably the main one you had was how you were accessing the iframes through jQuery. You need to use $('selector').contents().find('selector2'). Finally another problem was the you were retrieving the data getting the attribute value from your code wrapper. What you need to get is the actual content as flat text in order to avoid other html content. In order to do that you need to use .text() (Please check the updated GetHtml() and GetCss() functions).
I hope you can make it work from here. Still, I like option 1 :P
I hope it helps.

Changing textContent using javascript, Cushy CMS

OK, I'm going to get a bad rep here for asking too many questions. I have some javascript that dynamically changes content on my page. This works just fine. My issue is that I need to be able to tag all text with 'class="CushyCms"' in order to allow access to the site owner for easy content changes. Here is the basic code for the script, there is more than just the one set but this will give you an idea of what I'm doing. I tried adding the class tag inside the innerHTML, but Cushy couldn't see it.
<script language="javascript" type="text/javascript">
function changeText(idElement) {
if(idElement==0){
document.getElementById('tagmain').innerHTML ='<class="cushycms">Default text to display on page load.';
document.getElementById('tagtext').innerHTML ='<class="cushycms">More default body text on page load.';
}
</script>
I am looking for a way to put these text fields in a hidden div and pull the textContent from there. This is an example of a section that works with Cushy
<h2 class="cushycms">Preventative Maintanence</h2>
I'm beginning to get the hang of javascript, though Java is my primary language. I want to be more rounded i my langauge skills so I am trying to leanr as much as I can. Thanks in advance for the help.
Cushy CMS requires an actual HTML in order to edit. You could use the following:
HTML
<p id="tagmain-replace" class="cushycms" style="display:none;"></p>
<p id="tagmain">Default Text</p>
JS
var newText = document.getElementById('tagmain-replace').innerText;
if( newText != ''){
document.getElementById('tagmain').innerText = newText;
}
I would suggest changing the IDs to better work with your project.

can't get textarea field using jquery rte lwrte?( issues of plugin behaviour I think)

I am using this plugin http://code.google.com/p/lwrte/, but I can not select the textarea or the id with jquery, I know it creates an iframe, but I read the docs and It does not mention anything about this issue, I just want to count the characters in the textarea and then that the user can not type, but I dont find a solution for this, has someone has a solution? what can I do?
<textarea id="message" rows="10" cols="120" class="rte1"></textarea>
$('#message').keyup(function(){ //tried with this does not work
});
any more help??
LWRTE takes textAreas and turns them into <iframe>s. So you need to use something like Google Chrome or Firebug to identify the new name of the object, then reference that directly. Something like this:
$('body iframe').contents().find('body').html()
Replace $('message') with $('#message') to get the actual element.

Categories

Resources