I have a cfm (ColdFusion) page where I display a #userHTML# variable's content inside my div.
<cfoutput>
<div class="panel panel-default" style="margin-left: 20px; margin-right: 20px;">
<div id="myDiv" class="panel-body">
#userHTML#
</div>
</div>
<br/><br/>
<div class="col-sm-8 col-sm-offset-2">
<!-- Some Code Here -->
</div>
</cfoutput>
Sometimes the #userHTML# variable has invalid HTML. It may contain open <div> tags that are not closed which makes the rest of the code where I have <div class="col-sm-8 col-sm-offset-2"> be inside the top div (id="myDiv")
Is there a way to make this work so that it doesn't matter what the #userHTML# variable contains, it will always have it's content inside the div "myDiv"?
The browser is designed to parse that HTML natively. If you require XML it will apply XML rules and importing incorrectly formated XML will error. If you use HTML, it will automatically correct the errors to the best of its ability (as is the case with all HTML documents.
To achive this you can do (please see comments in code):
// Create a new HTML Document (DOM)
var doc = document.implementation.createHTMLDocument ('', 'html', null);
// Add the body
var body = document.createElementNS('', 'body');
// Place the body into the DOM
doc.documentElement.appendChild(body);
// Get body parsed / corrected
body.innerHTML = "<div>This is a test";
// Now place that content into your existing DOM
document.getElementById('test').innerHTML = body.innerHTML;
// Get rid of the extra DOM
doc = null;
<div id="test">Test Div</div>
If you inspect the output HTML you will see the closing </div> has been added automatically.
You can use JSOUP to clean that HTML.
Get the relevant JAR file from either https://jsoup.org or http://central.maven.org/maven2/org/jsoup/jsoup/ and put it in you lib folder.
Then use JSOUP like
<cfset oJSOUP = CreateObject("java", "org.jsoup.Jsoup" )>
<cfset oJSOUPWL = CreateObject("java", "org.jsoup.safety.Whitelist" ).init()>
#oJsoup.clean(
javaCast( "string", userHTML ),
"http://example.com/",
oJSOUPWL.relaxed().preserveRelativeLinks( true )
)#
This removes unwanted HTML like unclosed DIVs.
Related
I found a code for real time markup for HTML and CSS in different textareas using a jQuery function that outputs in an iframe:
HTML
<div class="container grid">
<form>
<h3>HTML</h3>
<textarea id="html" class="edit"></textarea> // TEXTAREA FOR HTML
<h3>CSS</h3>
<textarea id="css" class="edit"></textarea> // TEXTAREA FOR CSS
</form>
</div>
<div class="output grid">
<iframe></iframe>
</div>
JQUERY for markup
function() {
$(".grid").height($(window).height());
var contents = $("iframe").contents(),
body = contents.find("body"),
styleTag = $("<style></style>").appendTo(contents.find("head"));
$("textarea.edit").keyup(function() {
var $this = $(this);
if ($this.attr("id") === "html") {
body.html($this.val());
} else {
// it had to be css
styleTag.text($this.val());
}
});
})();
What if I wanted another textarea for javascript? I'm guessing you can't execute it in real time so I have to include a button to to run an eval()
But how?
In your HTML you can have another textarea for the javascript code.
In your textarea.edit event handler, you can add another check for javascript and use something like this -
$iframeEl.append(`<script>${textarea.val()}</script>`);
This line would execute your script as well because the browser re parses the document whenever it encounters a DOM change and it would also execute the script tag.
We should anyways refrain on using the eval keyword because it is an expensive operation and is advised not to be used.
I have a javascript variable that contains a part of html code.
I need to get in this part of html code a div html content.
How can i do it ?
This is an example:
var code = '<style type="text/css">
#example{
border:1px;
font-size:20px;
}
</style>
<div id="ex"> Some Content </div>
<div id="ex2"> Some Content <span> Another Content</span></div>
<div id="my_code">This Is My Code.</div><div id="ex3> Etc Etc </div>';
I'd like get content of div "my_code" with Jquery .html();
How can i do it ?
Thanks
code variable it's just a string for your document. If you have parsed this HTML code inside the body then you can use $('#my_code'), otherwise it's still just a string so.. that's another story.
Check the other story here: http://jsfiddle.net/NSCQh/1/
I strongly suggest you have a look at jQuery's selector overview. They are the most important part of the jQuery magic, and without understanding them you'll get nowhere in the long run.
var html = $('#my_code').html()
or because that div containts text only
var txt = $('#my_code').text()
You've got a string, you need a DOM element. From that, you can get the jQuery object.
var el = document.createElement('div');
el.innerHTML = code;
console.log($(el));
pass the string to jquery and it works
var foo = '<div id="foo"> <span class="bar">fooBar</span> </div>';
var inside = $(foo).find('.bar').text();
alert(inside);
Create an ELEMENT, say p.
Use the following
$('<p>').append(code).find('div#my_code').html();
It create a p element, then append the content of variable code, then find div with id=my_code and select it's innerHTML.
Working model in the snippet.
var code = `<style type="text/css">
#example{
border:1px;
font-size:20px;
}
</style>
<div id="ex"> Some Content </div>
<div id="ex2"> Some Content <span> Another Content</span></div>
<div id="my_code">This Is My Code.</div><div id="ex3> Etc Etc </div>`;
var elm=$('<p>').append(code).find('div#my_code').html();
console.log(elm);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I just started using Mustache and I like it so far, but this has me perplexed.
I am using the GitHub gist API to pull down my gists, and part of what I want to do is include the embedding functionality into my page. The problem is Mustache seems to not want to have anything to do with my dynamic script tag.
For example, this works fine:
<div class="gist-detail">
{{id}} <!-- This produces a valid Gist ID -->
</div>
Additionally, this works perfect:
<div class="gist-detail">
<script src='http://gist.github.com/1.js'></script> <!-- Produces the correct embed markup with Gist ID #1 -->
</div>
If I try to pull these together, something goes terribly wrong:
<div class="gist-detail">
<script src='http://gist.github.com/{{id}}.js'></script> <!-- Blows up! -->
</div>
Chrome Inspector shows this:
GET https://gist.github.com/%7B%7Bid%7D%7D.js 404 (Not Found)
... which looks like to me something is weird with escapes or whatnot, so I switch over to the raw syntax:
<div class="gist-detail">
<script src='http://gist.github.com/{{{id}}}.js'></script> <!-- Blows again! -->
</div>
And I get the same result in Inspector:
GET https://gist.github.com/%7B%7B%7Bid%7D%7D%7D.js 404 (Not Found)
How do I get the correct values to embed in the script tag?
EDIT
I am injecting the template as follows (in document.ready:
function LoadGists() {
var gistApi = "https://api.github.com/users/<myuser>/gists";
$.getJSON(gistApi, function (data) {
var html, template;
template = $('#mustache_gist').html();
html = Mustache.to_html(template, {gists: data}).replace(/^\s*/mg, '');
$('.gist').html(html);
});
}
The actually template is inside of a ruby partial, but it is wrapped in a div (not a script tag, is that a problem?) (that's hidden):
<div id="mustache_gist" style="display: none;">
{{#gists}}
<!-- see above -->
{{/gists}}
</div>
I assume a div is ok rather than a script because in either case, I'm pulling the .html(). Is this a bad assumption?
To avoid automatic escaping in Mustache use {{{token}}} instead of {{token}}.
It seems like your template is in HTML and trying to retrieve the template using html() results in a pre-URL-escaped template to be returned. Try placing your template inside a <script type="text/html"> tag instead.
When you embed your template inside an HTML element that excepts more HTML elements as children, it may get processed by the browser as HTML. Escaping may occur. By using a <script> tag with a non-script content type, you're basically telling the browser not to touch your template.
It looks like your script is getting requested before Mustache has a chance to update the src property. What you want to do is define the template in a way that it's not parsed as part of the DOM. A common approach is to define your template inside of a <textarea> tag. This will preserve formatting and prevent character escaping.
<textarea id="gist-detail-template" style="display:none">
<script src='http://gist.github.com/{{id}}.js'></script>
</textarea>
Now, to instantiate the template:
var template = $('#gist-detail-template').val();
var html = Mustache.to_html(template, yourTemplateData);
Here's an official example: http://mustache.github.com/#demo
(I ask my question again after the first one was terribly formulated)
I face the following problem:
<div class="testA" id="test1"></div>
The above written element is predefined. I now load a xml tree via XMLHttpRequest & Co. delivering the following response:
<response>
<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>
</response>
I now append the first div using
request.responseXML.getElementsByTagName("response")[0]
.getElementsByTagName("div")[0]
into the predefined div
<div class="testA" id="test1">
The final document looks like this (checked using development tools):
<div class="testA" id="test1">
<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>
</div>
When I now try to get the element <div class="colorSelector" id="0-0"> using getElementById("0-0") I get the expected result.
But using getElementsByClassName("colorSelector") returns [].
Did I miss something? Is it probably a leftover of the fact the nodes were of type Element and not HTMLElement?
colorSelector is commented out. JavaScript only works within the DOM, and commented out portions aren't in the DOM.
Since you said that your getElementById("0-0") is successful, then clearly you don't actually have the nodes commented out.
I'm guessing you're doing:
document.getElementById("0-0").getElementsByClassName('colorSelector');
...which will not work because the element selected by ID does not have any descendants with that class.
Since you show HTML comments in the markup, I'd also wonder if you have some different element on the page with the ID "0-0". Take a look for that.
If your nodes are actually commented out, you'll need to first select the comment, and replace it with the markup contained inside:
var container = document.getElementById('test1'),
comment = container.firstChild;
while( comment && comment.nodeType !== 8 ) {
comment = comment.nextSibling;
}
if( comment ) {
container.innerHTML = comment.nodeValue;
}
...resulting in:
<div class="testA" id="test1">
<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>
</div>
...but there again, this doesn't seem likely since your getElementsById does work.
Here's a way to do it for Firefox, Opera, Chrome and Safari. Basically, you just do div.innerHTML = div.innerHTML to reinterpret its content as HTML, which will make that class attribute from the XML file be treated as an HTML class name.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<script>
window.addEventListener("DOMContentLoaded", function() {
var div = document.getElementsByTagName("div")[0];
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
var doc = this.responseXML;
div.appendChild(document.importNode(doc.getElementsByTagName("response")[0].getElementsByTagName("div")[0], true));
div.innerHTML = div.innerHTML;
alert(document.getElementsByClassName("colorSelector").length);
}
};
req.open("GET", "div.xml");
req.send();
}, false);
</script>
</head>
<body>
<div class="testA"></div>
</body>
</html>
Remove the this.status === 200 if you're testing locally in browsers that support xhr locally.
The importNode() function doesn't seem to work in IE (9 for example). I get a vague "interface not supported" error.
You could also do it this way:
var doc = this.responseXML;
var markup = (new XMLSerializer()).serializeToString(doc.getElementsByTagName("response")[0].getElementsByTagName("div")[0]);
div.innerHTML = markup;
as long as the markup is HTML-friendly as far as end tags for empty elements are concerned.
<!--<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>-->
The above code is gray for a reason: it's a comment. Comments aren't parsed by the browser at all and have no influence on the page whatsoever.
You'll have to parse the HTML, read the comments, and make a new DOM object with the contents of the comment.
Please describe what you are doing with the returned results. There is a significant difference between a nodeList and a node, nodeLists are LIVE.
So if you assign a nodeList returned by getElementsByClassName() (or similar) to a variable, this variable will change when you remove the nodes inside the nodeList from the DOM.
I now append the first div
How do you do that? What you have in the responseXML are XML elements, and not HTML elements.
You shouldn't be able to appendChild them into a non-XHTML HTML document;
actually you shouldn't be able to appendChild them into another document at all, you're supposed to use importNode to get elements from one document to another, otherwise you should get WRONG_DOCUMENT_ERR;
even if you managed to insert them into an HTML due to browser laxness, they're still XML elements and are not semantically HTML elements. Consequently there is nothing special about the class attributes; just having that name doesn't make the attribute actually represent a class. getElementsByClassName won't return elements just because they have attributes with the name class; they have to be elements whose language definition associates the attributes with the concept of classness (which in general means HTML, XHTML or SVG).
(The same should be true of the id attributes; just having an attribute called id doesn't make it conceptually an ID. So getElementById shouldn't be working. There is a way to associate arbitrary XML attributes with ID-ness, which you don't get with class-ness, by using an <!ATTLIST declaration in the doctype. Not usually worth bothering with though. Also xml:id is a special case, in implementations that support XML ID.)
You could potentially make it work if you were using a native-XHTML page by putting suitable xmlns attributes on the content to make it actual-XHTML and not just arbitrary-XML, and then using importNode. But in general this isn't worth it; it tends to be simpler to return HTML markup strings (typically in JSON), or raw XML data from which the client-side script can construct the HTML elements itself.
I have several templates for faceboxes (lightbox) that I need at different points of the application. These are stored in different partials and files.
I will initialize different javascript functions in accordance to which ones I need. The question is, what is the best way to append the external HTML page into my body using javascript?
Since you tagged the question with it, here's a jQuery solution.
$("body").append("text");
Remember that the parameter can also be a DOM element. So you can do this :
var p = $("<p/>").text("a paragraph");
$("body").append(p);
the easy way with jQuery is:
$('#result').load('test.html');
<div id="result"><!--/ Hold My Data! /--></div>
obviously you can change #result with body
Also you can try some templates library..
Like handlebar and underscore..
and append in the el provided by backbone.js
Suppose you want to append this html in your template, then you can use the below code according to your application
Consider the code
Example 1:
rowData += '<div style="width: 130px;">'+param1+'</div>';
rowData += '<div style="width: 130px;">'+param2+'</div>';
$('#ID').html(rowData);
and please make sure that the js should be include in that file.
Here is the information of variable used above:
row data - the html that you want to append,
param- if you want to show the value of java script variable on browser dynamically,
#ID- ID of the div in which you want to append this html
example 2:
Consider the following HTML:
<h2>Hello World</h2>
<div class="user">
<div class="inner">Hi</div>
<div class="inner">Bye</div>
</div>
You can create content and insert it into several elements at once:
$( ".inner" ).append( "<p>Lorem Ipsum</p>" );