Escaping html entities in textarea - javascript

I have a textarea used for comments that loads the contents of a div when a link is pressed, putting those contents in the displayed textarea.
Everything worked fine until I introduced a way to display interpoints (I'm talking about the · entity). These display fine in the div, but the problem is they also display as dots in the actual textarea, which I don't want. I want them to display as {*} in the textarea, since this is the string that gets converted to · on the server side.
This is the function I use to handle the display of tags:
function HtmlDecode(str)
{
var ta = document.createElement("textarea");
ta.innerHTML = str.replace(/</g, "<").replace(/>/g, ">").replace(/·/g, "{*}");
toReturn = ta.value;
ta = null;
return toReturn.replace(/<br\s*\/?>/mg, "\n");
}
I output the textarea like this:
anotherDiv.innerHTML = '<textarea ...>' + HtmlDecode(div.innerHTML) + '</textarea>';
What I don't understand is why if I change the /·/g replace with /asdf/g for example, any asdf will get replaced just fine.
Bottom line: how can I make my textarea display {*} instead of an actual interpoint?

What about .replace(/·/g, "{*}") instead of .replace(/·/g, "{*}");?

Related

How to get the whole HTML value from Dijit Editor

Hello Experts I need help
I'm using dojo Dijit Editor "rich text editor" field in my widget, on page load I fetch HTML text from database and I set the rich text editor with the HTML normally, Then user can edit the displayed text and on page close I have to set the field in database with the source HTML of the edited text by user
the problem is when I do the following "myDB_txt=myEditor.getValue();" getValue() doesn't return the complete HTML code it removes HTML tag and header tag and body tag which causes me troubles.
Simply use myEditorWidget.get("Value") where myEditorWidget refer to your dijit/Editor indtance
To wrap this result you can define a function that return result wraped by html tags
wrapResult(myEditor.get("value")));
function wrapResult(html) {
return "<html> <head></head> <body>"+html+"</body></html>";
}
Here is a Sample with wraped result Fiddle .
Otherwise If you want to get the whole HTML enclosing the content dijit ,
you will get access to it's Iframe ( that has the id="editor_iframe")
and then get get the html document of this last like bellow (here you should import dojo/query package)
query("#editor_iframe")[0].contentDocument.documentElement.outerHTML
Here is another Fiddle .
You could try the following to retrieve the value from your dijit/Editor instance.
var content = myEditor.attr("value");
var openTags = '<html><head></head><body>';
var closeTags = '</body></html>';
var html = openTags + content + closeTags; // use this
or
var htmlWrapper = function(content){
return '<html><head></head><body>' + content + '</body></html>';
};
var html = htmlWrapper(myEditor.attr("value"));

Javascript not being called from hyperlink

I am using Google Apps Script to create a web app that contains several hyperlinks. When a hyperlink is clicked, it is supposed to trigger an alert box (just filler code to see if JS function is being called). My hyperlinks are being generated using this javascript function:
function updateAlertList(results) {
var div = document.getElementById('output');
div.innerHTML = '';
for (var i=0;i<results.length;i++)
{
div.innerHTML += '<p><a class="ra-button" href="javascript:void(0)" onclick="myJsFunc()">' + results[i].alertName + '</a></p>';
}
}
and the JS function that generates the alert is:
function myJsFunc(){
alert('this function was called');
}
For some reason, only the LAST hyperlink in the list of hyperlinks will trigger the JS function called myJsFunc. Whenever I click on any of the other hyperlinks that are earlier in the list, the JS function is not called. When I look in the console in Chrome Developer tools, I see the error "Cannot read property 'plugin_dispatchEvent___' of undefined"
Anybody know why the very last hyperlink in my list of hyperlinks works.. but the earlier ones don't?
I would change your code to this:
function updateAlertList(results) {
var div = document.getElementById('output');
div.innerHTML = '';
var alrtInnrHTML = '';
for (var i=0;i<results.length;i++) {
alrtInnrHTML += '<p><a class="ra-button" href="javascript:void(0)" onclick="myJsFunc()">' + results[i].alertName + '</a></p>';
console.log('alrtInnrHTML: ' + alrtInnrHTML);
}
}
div.innerHTML = alrtInnrHTML;
Please note that I created a variable alrtInnrHTML, and using += on the variable, not the innerHTML.
You are trying to use += on DOM manipulation instead of a variable. Set the HTML text string first, then inject the entire string just one time. Right now you are injecting HTML into the same DIV over and over and over again. Do all the links show up? In any case, even if your logic is working, I would change the logic to what I am suggesting, check that the final HTML content is correct with a console.log() output, and then inject the HTML all at once.
You would actually be better off adding individual <p> and <a> tags in each loop, and adding HTML in each loop rather than trying to construct a string of HTML.
You might want to do some reading about:
insertRow
insertCell
setAttribute
textContent
createTextNode
appendChild
createElement
With those methods you could avoid writing long HTML strings for the most part.
For example, you could create a table, with a new row for every result.
for (var i=0;i<results.length;i++) {
window.row1 = tblAlertList.insertRow(-1);
window.cell1 = row1.insertCell(0);
row1.setAttribute("class", "ra-button");
row1.innerHTML = <p><a class="ra-button" href="javascript:void(0)" onclick="myJsFunc()">' + results[i].alertName + '</a></p>';
}
That above code is just to give you an idea of what you might do, it's not working code.
Instead of creating a table, you could create an unordered list: <ul>
div.innerHTML = "<ul><a></a></ul>";
Then append a child to the last node in the list:
var node=document.createElement("LI");
var textnode=document.createTextNode("New Alert");
node.appendChild(textnode);
document.getElementById("myList").appendChild(node);

Programmatically select text (like as done with a mouse) that matches string in a textarea element

Consider the following problem:
Have a textarea like so:
<textarea id="body" name="body"></textarea>
Also have some simple JavaScript (jQuery) that inserts some new text into the textarea so a user can embed an image:
$('textarea').val($('textarea').val() + '[img]path to image file[/img]');
The trick is to automatically highlight the text in between the [img][/img] tags after that text is inserted so the user can just copy and paste their image URL in quickly, instead of manually selecting, then copy and pasting.
I've racked my brain and gone all over the internet trying to figure this out, and the best I could do was this popular StackOverflow question Selecting text in an element (akin to highlighting with your mouse) which only addresses the problem of selecting the text inside an ENTIRE element, which is not what is desired here. The problem is to select text that matches a certain string, in this case path to image file, so the user can just copy/paste. (not sure if this is the best way to do it, but that's what I thought of...).
Is this possible? I'm guessing we're going to need getSelection() and createRange() but other than that I have no idea where to go... any JavaScript wizards figured this one out already? I feel like this could be a popular question. Using jQuery is fine, as I'm already using it on the rest of the document.
You could use my jQuery plug-in. It works around browser differences in textarea selection manipulation and has some convenience methods:
https://code.google.com/p/rangyinputs/
For your example, the code would be
var $textarea = $("#body");
var text = "path to image file"
$textarea.replaceSelectedText(text, "select");
$textarea.surroundSelectedText("[img]", "[/img]");
Demo: http://jsfiddle.net/P8Jrh/1/
I actually figured this one out myself... I used the Rangy library https://code.google.com/p/rangy/ and code like this:
// Add text to the reply area at the very end, and move the cursor to the very end.
function insertText(textarea, text) {
textarea = $(textarea);
textarea.focus();
textarea.val(textarea.val() + text);
textarea.focus();
// Trigger the textarea's keyup to emulate typing.
textarea.trigger("keyup");
}
// Add text to the reply area, with the options of wrapping it around a selection and selecting a part of it when it's inserted.
function wrapText(textarea, tagStart, tagEnd, selectArgument, defaultArgumentValue) {
textarea = $(textarea);
// Save the scroll position of the textarea.
var scrollTop = textarea.scrollTop();
// Work out what text is currently selected.
var selectionInfo = textarea.getSelection();
if (textarea.val().substring(selectionInfo.start, selectionInfo.start + 1).match(/ /)) selectionInfo.start++;
if (textarea.val().substring(selectionInfo.end - 1, selectionInfo.end).match(/ /)) selectionInfo.end--;
var selection = textarea.val().substring(selectionInfo.start, selectionInfo.end);
// Work out the text to insert over the selection.
selection = selection ? selection : (defaultArgumentValue ? defaultArgumentValue : "");
var text = tagStart + selection + (typeof tagEnd != "undefined" ? tagEnd : tagStart);
// Replace the textarea's value.
textarea.val(textarea.val().substr(0, selectionInfo.start) + text + textarea.val().substr(selectionInfo.end));
// Scroll back down and refocus on the textarea.
textarea.focus();
// If a selectArgument was passed, work out where it is and select it. Otherwise, select the text that was selected
// before this function was called.
if (selectArgument) {
var newStart = selectionInfo.start + tagStart.indexOf(selectArgument);
var newEnd = newStart + selectArgument.length;
} else {
var newStart = selectionInfo.start + tagStart.length;
var newEnd = newStart + selection.length;
}
textarea.selectRange(newStart, newEnd);
// Trigger the textarea's keyup to emulate typing.
textarea.trigger("keyup");
}
var bbcode = {
bold: function(id) {wrapText($("textarea"), "[b]", "[/b]", "", "bolded text");},
};
Example usage:
bbcode.bold();
Full code (in a larger project I did): https://github.com/wnajar/textarea

How to prevent script tags in text from executing?

I had a text box in my browser. Whatever you typed in the text box and clicked on okay button, the text submitted server through a AJAX request and then spread that message to remaining people, including to me also.
The message is appeared on a <div>.
What's my problem is if I typed html or script tags in that message they are not appearing in the message <div> and they are executing .
If I typed like tags opened and end with script in that middle code is executing on client side, how can I prevent executing and I am able to spread <script> tags also in the messages spreading to all.
If you want the text to always be text, treat is as text and don't use it to set innerHTML property for example.
Update text nodes instead.
Update
For example, if you had user input in userInput, and you wanted to display it, you would treat it as text, not HTML.
var element = document.body,
// For example
userInput = "Alex <script>alert('xss')</script>";
// Don't do this! Your input is text, not HTML.
// element.innerHTML = userInput;
// Use this instead
if ('textContent' in element) {
element.textContent = userInput;
} else {
element.innerText = userInput;
}
jsFiddle.
Have you tried replacing with html character entities? For example replacing all < with <.

Javascript replacing HTML char code with actual character

I have a HTML input text, and its values are populated from a related div. My problem is that the div contains characters like & which will display correcly as '&' sign in div but when copied to text box the text '&' will be dispalyed
How can i convert & to & and '<' to '<', ' ' to ' ' ???
You thus want to unescape HTML entities. With plain JS you can use this snippet:
function unescapeHTML(html) {
var div = document.createElement("DIV");
div.innerHTML = html;
return ("innerText" in div) ? div.innerText : div.textContent; // IE | FF
}
And with jQuery the following one:
function unescapeHTML(html) {
return $("<div />").html(html).text();
}
But you can also just fix this problem during the step that you "copy" the div's content into the input element's value. Instead of grabbing HTML, just grab text. Instead of element.innerHTML, that'll be element.innerText for IE or element.textContent for real browsers.
No, you can't and shouldn't do this (reliably) with regex.
I am not sure how you are accessing data but a possible solution could be use of innerText property instead on innerHtml

Categories

Resources