Painlessly pass HTML to javascript - javascript

I need to pass html to javascript so that I can show the html on demand.
I can do it using textareas by having a textarea tag with the html content on the page, like so: <textarea id="html">{whatever html I want except other textareas}</textarea>
then using jquery I can present it on the page:
$("#target").html($("#html").val());
What I want to know is how to do it properly, without having to use textareas or having the html present in the <body> of the page at all?

You could use jquery templates. It's a bit more complex, but offers lots of other nice features.
https://github.com/codepb/jquery-template

Just save it in a variable:
<script type="text/javascript">
var myHTML = '<div>Foo Bar</div>';
</script>

As far as I know there is no painless way to do this due to the nature of html and javascript.
You can store your html as a string in a javascript variable such as:
var string = '<div class="someClass">your text here</div>';
However you should note that strings are enclosed within ether ' or " and if you use ether in your html you will prematurely end the string and cause errors with invalid javascript.
You can decide to only use one type of quote in your html say " and then ' to hold strings in javascript, but a more concrete way is to escape your quotes in html like so:
<div \"someClass\">your text here</div>
By putting \ before a special character you are telling it that it should ignore this character, however when you go to print it out the character will still print but the \ character won't, giving you functioning html.

Just like remy mentioned, you can use jQuery templates, and it's even cooler if you combine it with mustache! (which supports a lot of platforms)
Plus the mustache jQuery plugin is way more advanced than jQuery templates.
https://github.com/jonnyreeves/jquery-Mustache

Related

Parse HTML string into DOM using JavaScript, but ignore broken tags

I have the following HTML string:
"<div> one is<than three </div>"
is there an elegant way to parse this string to HTML using JavaScript? Every solution tends to create <than tag. Can anyone advise me on this issue, or should I change the solution to avoid this?
(Even StackOverflow has an issue if I put <than as a plain text)
As < shouldn't be part of valid HTML document, you should consider using < character.

How to optimize the creation of long html code to be used in javascript string

I need to define javascript variables containing very long html code.
Here is a short example:
var text = "Select one item:<br>";
text += "<ul class='thumbnails'><li class='span3'><a href='#' class='thumbnail'><img src='http://placehold.it/260x180' alt=''></a></li></ul>";
Since the html is going to be much much longer, I would rather work in pure html rather than append text to a javascript string.
I thought of creating a separate html file, but I guess that would require an Ajax call to fetch its content.
What is the best way to deal with this?
As N.Zakas said on "maintainable javascript" book, you should «keep html out of javascript» to promote high mantainability of the code through loose coupling of UI layers.
Beside the ajax solution you could also place the markup as a comment in the html file and read it via javascript (as a regular DOM node) or you could use some kind of microtemplating system (e.g. handlebars) and place your markup in a script block (the idea is to put markup where is expected to be found and not into javascript logic)
One possible solution is to use templates. There are a few JavaScript libraries that provide templating, underscore.js is one: http://underscorejs.org/#template, or more details on how to use it for templating http://www.headspring.com/blog/developer-deep-dive/an-underscore-templates-primer/
Plus underscore is great for a number of other things.
You could break up the text into actual HTML objects.
var thumbnailsUL = document.createElement('ul');
for (index in {your-thumbnails-list}) {
var thumbnail = document.createElement('li');
thumbnail.innerHTML = {whatever you need, more objects or html as text};
thumbnailsUL.appendChild(thumbnail);
}
Ideally though, there is no reason to build this IN JavaScript - can you not emit it from the server?
Instead of constructing HTML in Javascript as a string, I would rather suggest you to emit those html elements in the page itself and hide while loading. Then in Javascript, you could select that container and display it.

How to have render big chunk of html inside a javascript forloop

I have an html component that makes a variable amount of rows in a table. Inside this component there are several css classes e.g
<div class="row" style="margin-left:0">
How do I embed this big chunk of html in a javascript forloop? The only way I know how is to use document.write("") but the quotation marks in the classes will mess that up.
UPDATE:
Any ideas why the tags and everything inside them is ignored when using innerHTML??
Make a div with an id of someDiv (or whatever you want) for this to work.
document.getElementById("someDiv").innerHTML = '<div class="row" style="margin-left:0">';
I used single quotes to wrap the string in order to avoid conflict with the double quotes in the HTML.
You'll need to escape your quotes in your javascript.
alert('Oh, heya, I didn\'t see you, so "Hello"');
JavaScript isn't great for expressing HTML as, amongst other things, it lacks Heredoc syntax which results in you having to escape any string literals (as suggested by #DavidYell).
It might be worth considering the use of a templating engine such as Mustache.js or Underscore.js

Getting unparsed (raw) HTML with JavaScript

I need to get the actual html code of an element in a web page.
For example if the actual html code inside the element is "How to fix"
Running this JavaScript:
getElementById('myE').innerHTML
Gives me "How to fix" which is the parsed HTML.
How can I get the unparsed "How to fix" using JavaScript?
You cannot get the actual HTML source of part of your web page.
When you give a web browser an HTML page, it parses the HTML into some DOM nodes that are the definitive version of your document as far as the browser is concerned. The DOM keeps the significant information from the HTML—like that you used the Unicode character U+00A0 Non-Breaking Space before the word fix—but not the irrelevent information that you used it by means of an entity reference rather than just typing it raw ( ).
When you ask the browser for an element node's innerHTML, it doesn't give you the original HTML source that was parsed to produce that node, because it no longer has that information. Instead, it generates new HTML from the data stored in the DOM. The browser decides on how to format that HTML serialisation; different browsers produce different HTML, and chances are it won't be the same way you formatted it originally.
In particular,
element names may be upper- or lower-cased;
attributes may not be in the same order as you stated them in the HTML;
attribute quoting may not be the same as in your source. IE often generates unquoted attributes that aren't even valid HTML; all you can be sure of is that the innerHTML generated will be safe to use in the same browser by writing it to another element's innerHTML;
it may not use entity references for anything but characters that would otherwise be impossible to include directly in text content: ampersands, less-thans and attribute-value-quotes. Instead of returning it may simply give you the raw   character.
You may not be able to see that that's a non-breaking space, but it still is one and if you insert that HTML into another element it will act as one. You shouldn't need to rely anywhere on a non-breaking space character being entity-escaped to ... if you do, for some reason, you can get that by doing:
x= el.innerHTML.replace(/\xA0/g, ' ')
but that's only escaping U+00A0 and not any of the other thousands of possible Unicode characters, so it's a bit questionable.
If you really really need to get your page's actual source HTML, you can make an XMLHttpRequest to your own URL (location.href) and get the full, unparsed HTML source in the responseText. There is almost never a good reason to do this.
What you have should work:
Element test:
<div id="myE">How to fix</div>​
JavaScript test:
alert(document.getElementById("myE​​​​​​​​").innerHTML); //alerts "How to fix"
You can try it out here. Make sure that wherever you're using the result isn't show as a space, which is likely the case. If you want to show it somewhere that's designed for HTML, you'll need to escape it.
You can use a script tag instead, which will not parse the HTML. This is more relevant when there are angle brackets, like loading a lodash or underscore template.
document.getElementById("asDiv").value = document.getElementById("myDiv").innerHTML;
document.getElementById("asScript").value = document.getElementById("myScript").innerHTML;
<div id="myDiv">
<h1>
<%= ${var} %> %>
How to fix
</h1>
</div>
<script id="myScript" type="text/template">
<h1>
<%= ${var} %>
How to fix
</h1>
</script>
<textarea rows="10" cols="40" id="asDiv"></textarea>
<textarea rows="10" cols="40" id="asScript"></textarea>
Because the HTML in a div is parsed, the inner HTML for brackets comes back as
<
, but as a script it does not.

Regex replace string but not inside html tag

I want to replace a string in HTML page using JavaScript but ignore it, if it is in an HTML tag, for example:
visit google search engine
you can search on google tatatata...
I want to replace google by <b>google</b>, but not here:
visit google search engine
you can search on <b>google</b> tatatata...
I tried with this one:
regex = new RegExp(">([^<]*)?(google)([^>]*)?<", 'i');
el.innerHTML = el.innerHTML.replace(regex,'>$1<b>$2</b>$3<');
but the problem: I got <b>google</b> inside the <a> tag:
visit <b>google</b> search engine
you can search on <b>google</b> tatatata...
How can fix this?
You'd be better using an html parser for this, rather than regex. I'm not sure it can be done 100% reliably.
You may or may not be able to do with with a regexp. It depends on how precisely you can define the conditions. Saying you want the string replaced except if it's in an HTML tag is not narrow enough, since everything on the page is presumably within some HTML tag (BODY if nothing else).
It would probably work better to traverse the DOM tree for this instead of trying to use a regexp on the HTML.
Parsing HTML with a regular expression is not going to be easy for anything other than trivial cases, since HTML isn't regular.
For more details see this Stackoverflow question (and answers).
I think you're all missing the question here...
When he says inside the tag, he means inside the opening tag, as in the <a href="google.com"> tag...This is something quite different than text, say, inside a <p> </p> tag pair or <body> </body>. While I don't have the answer yet, I'm struggling with this same problem and I know it has to be solvable using regex. Once I figure it out, i'll come back and post.
WORKAROUND
If You can't use a html parser or are quite confident about Your html structure try this:
do the "bad" changing
repeat replace (<[^>]*)(<[^>]+>) to $1 a few times (as much as You need)
It's a simple workaround, but works for me.
Cons?
Well... You have to do the replace twice for the case ... ...> as it removes only first unwanted tag from every tag on the page
[edit:]
SOLUTION
Why not use jQuery, put the html code into the page and do something like this:
$(containerOrSth).find('a').each(function(){
if($(this).children().length==0){
$(this).text($(this).text().replace('google','evil'));
}else{
//here You have to care about children tags, but You have to know where to expect them - before or after text. comment for more help
}
});
I'm using
regex = new RegExp("(?=[^>]*<)google", 'i');
you can't really do that, your "google" is always in some tag, either replace all or none
Well, since everything is part of a tag, your request makes no real sense. If it's just the <a /> tag, you might just check for that part. Mainly by making sure you don't have a tailing </a> tag before a fresh <a>
You can do that using REGEX, but filtering blocks like STYLE, SCRIPT and CDATA will need more work, and not implemented in the following solution.
Most of the answers state that 'your data is always in some tags' but they are missing the point, the data is always 'between' some tags, and you want to filter where it is 'in' a tag.
Note that tag characters in inline scripts will likely break this, so if they exist, they should be processed seperately with this method. Take a look at here :
complex html string.replace function
I can give you a hacky solution…
Pick a non printable character that’s not in your string…. Dup your buffer… now overwrite the tags in your dup buffer using the non printable character… perform regex to find position and length of match on dup buffer … Now you know where to perform replace in original buffer

Categories

Resources