Javascript - using innerHTML to output strings *WITHOUT* HTML-encoded special characters? - javascript

It appears that JavaScript auto-converts certain special characters into HTML entities when outputting content via the innerHTML() function. This is a problem, since I need to be able to output < and > without converting to gt; and lt;
Can this auto-conversion be prevented, reversed, or escaped? So far, no matter what I do, < and > are always automatically encoded into HTML entities.
Example code:
function DisplayQueries() {
var IDs = ['AllOpenedINC','AllOpenedCRQ','AllClosedINC','AllClosedCRQ','SameDayINC','SameDayCRQ','NotSameDayINC','NotSameDayCRQ',
'StillOpenINC','StillOpenCRQ','OpenOldINC','OpenOldCRQ','OtherQueuesINC','OtherQueuesCRQ']
for (var i = 0; i < IDs.length; i++) {
if (eval(IDs[i]))
document.getElementById(IDs[i]).innerHTML = eval(IDs[i]);
}
}
Example query variable:
AllOpenedINC = "('Company*+' = \"test\" OR 'Summary*' = \"%test%\") AND ('Submit Date' >= \"" + theDate +
" 12:00:00 AM\" AND 'Submit Date' <= \"" + theDate + " 11:59:59 PM\")" + nameINC;

You should focus on what you want to accomplish as a result, rather than the way of doing it. innerHTML() does encode, innerText() and textContent() do encoding too. So you should decode your strings if you want them as < or > back.
You can use this unescapeHTML() function to get your results as you want them.
function unescapeHTML() {
return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&');
}
I hope this helps. I've copied it from Prototype.

I think your question is based on a false premise. Just make a very simple test:
document.getElementById("testdiv").innerHTML = '<h1><em>Hello</em></h1>';
if this works fine then the problem is not on the JS side, instead you use some other components in your system which HTML-encode your characters.

I figured out what's going on. There's no easy way to prevent innerHTML from converting special characters to HTML entities, but since the problem was surfacing when copying the content of a DIV to the clipboard (using IE-only JS, which works since this is in a government environment where everyone has to use IE), I just used the replace() function to re-convert the HTML entities back to < and >.

You can use jquery and .append()

Related

Convert php's htmlspecialchars() with javascript

I have a variable written from PHP into my javascript (using json_encode), that looks a little like this:
mappoints[x]['about'] = 'Administrator: Foo Barlt;br />Telephone: 555-4202<br />Email: bert#hotmail.com<br />Website: www.domain.com'
That I am using for a google maps map point. Using the json_encode seems to be very picky about what characters I can and cannot enter into it, so i am wondering how I can convert those special html characters into real html characters using javascript?
update
The way i am building my variable is:
var description = "<h3 style='margin: 0; padding: 0;'>" + mappoints[x]['name'] + "</h3><b>Director:</b> " + mappoints[x]['director'] + "<br/>" + mappoints[x]['about'];
The HTML in the varaible is all fine, until I add the about index. No function I have attached or tried yet seems to give me proper HTML.
You can use the dom to decode those entities for you.
mappoints[x]['about'] = 'Administrator: Foo Barlt;br />Telephone: 555-4202<br />Email: bert#hotmail.com<br />Website: www.domain.com'
mappoints[x]['about'] = $('<div/>').append(mappoints[x]['about']).text();
http://jsfiddle.net/5FTCX/
Basically when you add the html to the dom it will show the entities as the characters they represent, using .text() you can receive the data back as you'd see it in the browser as text, not html with the entities. If you want back the html you can use .html() e.g..
Would it be okay with :
return mystring.replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, """);
From here : Convert special characters to HTML in Javascript
Just because #Musa's idea was great but needed some re-interpreting on my side, I wish to post a quick function here, that will handle htmlspecialchars great, based on #Musa's design :
function htmlspecialchars_decode(string) {
$('body').append("<span style='display:none;visibility:hidden;' id='tempText'>" + string + "</span>");
var result = $('#tempText').text();
$('#tempText').remove();
return result;
};
try this
decodeURIComponent(str) or `unescape(str)` or `decodeURI(str)`

How to convert unicode in JavaScript?

I'm using the Google Maps API. Please see this JSON response.
The HTML instructions is written like this:
"html_instructions" : "Turn \u003cb\u003eleft\u003c/b\u003e onto \u003cb\u003eEnggårdsgade\u003c/b\u003e"
How can I convert the unicodes \u003c, \u003e etc. in JavaScript?
Those are Unicode character escape sequences in a JavaScript string. As far as JavaScript is concerned, they are the same character.
'\u003cb\u003eleft\u003c/b\u003e' == '<b>left</b>'; // true
So, you don’t need to do any conversion at all.
Below is a simpler way thanks to modern JS .
ES6 / ES2015 introduced the normalize() method on the String prototype, so we can do:
var directions = "Turn \u003cb\u003eleft\u003c/b\u003e onto \u003cb\u003eEnggårdsgade\u003c/b\u003e";
directions.normalize();
//it will return : "Turn <b>left</b> onto <b>Enggårdsgade</b>"
Refer to this article : https://flaviocopes.com/javascript-unicode/
you can use JSON.parse directly on JSON response then the unicode characters will automatically converted to its html counter parts (\u003c will be converted to < sign in html)
JSON.parse(JSON.stringify({a : 'Turn \u003cb\u003eleft\u003c/b\u003e onto \u003cb\u003eEnggårdsgade\u003c/b\u003e'}));
This small function may help
String.prototype.toUnicode = function(){
var hex, i;
var result = "";
for (i=0; i<this.length; i++) {
hex = this.charCodeAt(i).toString(16);
result += ("\\u00"+hex).slice(-7);
}
return result;
};

CSS Style property names -- going from the regular version to the JS property camelCase version and vice versa

Does there exist a provision for obtaining the corresponding names?
A function I'm writing has to both set the style via element.style[propnameCamelCase] and retrieve the existing rendered value via document.defaultView.getComputedStyle(element,'').getPropertyValue(propname-regular), and I can hardly justify having to pass two separate but semantically identical arguments to this function.
I know that for most of them it's a fairly straightforward transcription between camelCase and hyphen-delimited with the same words, so I can use regexes to convert them. But maybe there are a few that are not like this?
Off the top of my head I'm having a hard time figuring out how to deal with the capitalized letters for camel case with regular expressions.
edit: Ah, I could use a function for regex replace, each time I see a hyphen, convert next letter to upper case.
So you're basically reinventing jQuery.css(). Maybe a look at how jQuery solved the camelCase problem might help: https://github.com/jquery/jquery/blob/master/src/core.js#L600
I was about to ask question about the same thing (and I intended to name it "Translate css names to\from javascript counterparts"). Somehow I ended up writing my own solution.
function cssNameToJsName(name)
{
var split = name.split("-");
var output = "";
for(var i = 0; i < split.length; i++)
{
if (i > 0 && split[i].length > 0 && !(i == 1 && split[i] == "ms"))
{
split[i] = split[i].substr(0, 1).toUpperCase() + split[i].substr(1);
}
output += split[i];
}
return output;
}
function jsNameToCssName(name)
{
return name.replace(/([A-Z])/g, "-$1").toLowerCase();
}
I'd like to mention that CSSStyleDeclaration.style.setProperty accepts css/hyphen type property names without conversion, as documented here
Try this hyphenated property, for example:
document.body.style.setProperty("background-color", "red");
You can also do this:
document.body.style["background-color"] = "silver";
These approaches - if you can use them - may be simpler.

HTML Passing Link information through to javascript method

I am setting up some basic pagination of a table, and I have the following JS function:
function AddPagination() {
var paginationDiv = document.getElementById("pagination");
for (i = 0; i < 3; ++i) {
var page = document.createElement("a");
page.innerHTML = i + 1;
page.setAttribute("title", i + 1);
page.setAttribute("href", "javascript:RenderResultTable(this.innerHTML)");
paginationDiv.appendChild(page);
}
}
What I want to do is pass page number clicked on to the RenderResultTable method. I have this number stored as the innerHTML and title for the link element, how can I get this passed through using the above code?
Thanks.
Personally, I wouldn't use JavaScript for pagination but if that's the way you want to go, you need to use some string concatenation. I'm not sure what RenderResultTable() does but you can set that line up like this:
page.setAttribute("href", "javascript:RenderResultTable('" + page.innerHTML + "')");
I believe that should do the trick.
EDIT: Shouldn't you be using i++ in your loop instead of ++i? I think what you have right now will give 2 as the first page number. Please correct me if I am wrong.
EDIT: page.innerHTML will need to be escaped by this functions and then unescaped the in the RenderResultTable() function. escape() and unescape(). This is to prevent JavaScript injections and/or accidental bugs.

innerHTML removes attribute quotes in Internet Explorer

When you get the innerHTML of a DOM node in IE, if there are no spaces in an attribute value, IE will remove the quotes around it, as demonstrated below:
<html>
<head>
<title></title>
</head>
<body>
<div id="div1"><div id="div2"></div></div>
<script type="text/javascript">
alert(document.getElementById("div1").innerHTML);
</script>
</body>
</html>
In IE, the alert will read:
<DIV id=div2></DIV>
This is a problem, because I am passing this on to a processor that requires valid XHTML, and all attribute values must be quoted. Does anyone know of an easy way to work around this behavior in IE?
IE innerHTML is very annoying indeed. I wrote this function for it, which may be helpfull? It quotes attributes and sets tagnames to lowercase. By the way, to make it even more annoying, IE's innerHTML doesn't remove quotes from non standard attributes.
Edit based on comments
The function now processes more characters in attribute values and optionally converts attribute values to lower case. The function looks even more ugly now ;~). If you want to add or remove characters to the equation, edit the [a-zA-Z\.\:\[\]_\(\)\&\$\%#\#\!0-9]+[?\s+|?>] part of the regular expressions.
function ieInnerHTML(obj, convertToLowerCase) {
var zz = obj.innerHTML ? String(obj.innerHTML) : obj
,z = zz.match(/(<.+[^>])/g);
if (z) {
for ( var i=0;i<z.length;(i=i+1) ){
var y
,zSaved = z[i]
,attrRE = /\=[a-zA-Z\.\:\[\]_\(\)\&\$\%#\#\!0-9\/]+[?\s+|?>]/g
;
z[i] = z[i]
.replace(/([<|<\/].+?\w+).+[^>]/,
function(a){return a.toLowerCase();
});
y = z[i].match(attrRE);
if (y){
var j = 0
,len = y.length
while(j<len){
var replaceRE =
/(\=)([a-zA-Z\.\:\[\]_\(\)\&\$\%#\#\!0-9\/]+)?([\s+|?>])/g
,replacer = function(){
var args = Array.prototype.slice.call(arguments);
return '="'+(convertToLowerCase
? args[2].toLowerCase()
: args[2])+'"'+args[3];
};
z[i] = z[i].replace(y[j],y[j].replace(replaceRE,replacer));
j+=1;
}
}
zz = zz.replace(zSaved,z[i]);
}
}
return zz;
}
Example key-value pairs that should work
data-mydata=return[somevalue] => data-mydata="return[somevalue]"
id=DEBUGGED:true => id="DEBUGGED:true" (or id="debugged:true" if you use the convertToLowerCase parameter)
someAttribute=Any.Thing.Goes => someAttribute="Any.Thing.Goes"
Ah, the joy of trying to use XHTML in a browser that doesn't support it.
I'd just accept that you are going to get HTML back from the browser and put something in front of your XML processor that can input tag soup and output XHTML — HTML Tidy for example.
I ran into this exact same problem just over a year ago, and solved it using InnerXHTML, a custom script written by someone far smarter than I am. It's basically a custom version of innerHTML that returns standard markup.
I might be couple year too late but here goes. Accepted answer might do what it promises but it's already Friday afternoon and I need something simpler nor I have time go it through. So here's my version which will just quote attribute values w/o quotes and it should be pretty trivial to extend it.
var t = "<svg id=foobar height=\"200\" width=\"746\"><g class=rules>";
t.replace(/([\w-]+)=([\w-]+)([ >])/g, function(str, $n, $v, $e, offset, s) {
return $n + '="' + $v + '"' + $e;
});
I've tested this, and it works for most attributes, except those that are hyphenated, such as class=day-month-title. It ignores those attributes, and does not quote them.
There is a quick and dirty workaround for this issue. I used it when working with jQuery templates. Just add a trailing space to the value of the attribute.
Of course this does not make much sense with id that is used in the example, so here is another example involving jQuery, and jQuery templates:
http://jsfiddle.net/amamaenko/dW7Wh/5/
Note the trailing space in the line <input value="${x} "/> without it, the example won't work on IE.
did you tried with jquery ?
alert($('#div1').html());

Categories