Clone HTML and remove some nodes using jQuery - javascript

I'm developing a little tool for live editing using Chrome DevTools, and I have a little button "Save" which grabs the HTML and sends it to server to update the static file (.html) using Ajax. Very simple indeed.
My problem is that I need to filter the HTML code before sending it to the server, I need to remove some nodes and I'm trying to achive this using jQuery, something like this:
// I grab all the HTML code
var html = $('<div>').append($('html').clone()).html();
// Now I need to remove some nodes using jQuery
$(html).find('#some-node').remove();
// Send the filtered HTML to server
$.post('url/to/server/blahblahblah');
I already tried this Using jQuery to search a string of HTML with no success. I can't achieve to use jQuery on my cloned HTML code.
Any idea about how to do this?

The DOM is not a string of HTML. With jQuery, you do DOM manipulation, not string manipulation.
What you're doing is
cloning the document (unnecessary because you convert it to HTML anyway),
appending that cloned document to a new div for some reason
converting the content of that div to an HTML string
converting that HTML back to DOM nodes $(html) (so we're back to the first point above)
finding and removing an element in those nodes
presumably posting the html variable to the server.
Unfortunately, the html string has not changed because you manipulated DOM nodes, not the string.
Hopefully you can see above that you're doing all sorts of conversions that have little to do with what you ultimately want.
I don't know wny you'd need to do this, but all you need is to do a .clone(), then the .find().remove(), then .html()
var result = $("html").clone(false);
result.find("#some-node").remove();
var html = result.html();

Maybe like this?
var html = $('html').clone();
html.find('#some-node').remove();

Related

generate HTML from a set of jQuery objects?

I am trying to modify an HTML string (things like adding class to one of its children). In my code I have to used a container as a midway to ouput $html as a string. Does jQuery provide any function to do this?
html = "<p>title</p><div><ul class='www'></ul>something</div>";
$html = $(html);
$html.filter('div').find('ul').addClass('xxx');
container = $('<div></div>');
html = container.html($html)[0].innerHTML; //output "<p>title</p><div><ul class='www xxx'></ul>something</div>"
Nope.
There is no escape to interacting with the DOM (this is creating or selecting an existing element), the best you can try is to document.write your string but you'll need to scape the HTML so it doesn't gets interpreted as HTML but text. Notice that document.write only works before the document finishes loading.
I don't know your needs but I can't think of a good use case for this, your jQuery should be better for most cases.

jQuery get html in div without any markup

I have some script written using the jQuery framework.
var site = {
link: $('#site-link').html()
}
This gets the html in the div site-link and assigns it to link. I later save link to the DB.
My issue is I don't want the html as I see this as being to dangerous, maybe?
I have tried:
link: $('#site-link').val()
... but this just gives me a blank value.
How can I get the value inside the div without any markup?
Try doing this:
$('#site-link').text()
From the jQuery API Documentation:
Get the combined text contents of each element in the set of matched
elements, including their descendants, or set the text contents of the
matched elements.
Use the .text() jquery method like this:
var site = {
link: $('#site-link').text()
}
Here is an example of what .val(), .html() and .text() do: jsfiddle example
Use the text() method.
Get the combined text contents of each element in the set of matched elements, including their descendants, or set the text contents of the matched elements.
Use the .text() function of jQuery to get the only text.
var site = {
link: $('#site-link').text()
}
to avoid html, you will be required to use text() method of jquery.
var site = {
link: $('#site-link').text()
}
http://api.jquery.com/text/
If you are planning to store the result in the database and you are concerned about HTML, than using something like .text() rather than .html() is just an illusion of security.
NEVER EVER trust anything that comes from the client side!
Everything on the client side is replaceble, hijackable by the client rather easily. With the Tamper Data firefox plugin for example, even my mother could change the data sent to the server. She could send in anything in place of the link. Like malicious scripts, whole websites, etc...
It is important that before saving the "link" to the database you validate it on the server side. You can write a regex to check if a string is a valid url, or just replace everything that is html.
It's also a good idea to html encode it before outputting. This way even if html gets into your database, after encoding it will be just a harmless string (well there are other stuff to be aware of like UTF-7, but the web is a dangerous place).

Could be jquery used to modify html strings?

I have for example such piece of html:
var html = '<p>Title</p><b>edit me</b><i>remove me</i>';
I want to change title in it, but do not want to use regexp or string replace
functions for this, because if title would match tag name, then html could be corrupted.
I now trying to adopt jQuery for this, because it seems capable, but in reality things not so easy. Here is code:
$( $(html)[0] ).text('New title');
console.log(html); // --> prints out original html with old title
Any idea how to make this code work if it is at all possible ?
html = $('<div/>').html(html).find('p').text('New title').end().html();
http://jsfiddle.net/bEUHN/
Note: There are 3 wrapper elements in the created jQuery object using $(html), for selecting the p element you should use filter method.
$(html).filter('p').text('New title');

Static Data to be displayed using XML

I modify my XML now, I have a parent element <imgRes> in my XML in that I am having two different child nodes <images> and <rightContent>.
In earlier I wont have <imgRes> and <rightContent>, As i added it my code then its not adding in the div. I dont know whether my XML structure is wrong or something is missing.
So the <rightContent> having a div which is static which should be outside of the image sliding functionlity. I holds a link and a data.
I need some help where I am going wrong.
This is what I have tried.
http://jsfiddle.net/QNZDX/13/
It looks like you were never retrieving the data from the xml to set it into your new DOM elements. I updated the jsfiddle to alter the css and dom a bit so that the rightContent div wouldn't contain the link itself but the main piece you needed was this:
$("#rightContent").text( $xmldata.find('rightData').find('data').text());
$("#rightLink").prop('href',$xmldata.find('rightData').find('link').text());
prevIndex++;
The updated fiddle will show the minor changes.
If you want to update not only the URL of the link but also the link text then you can add something like this to set that value.
$("#rightLink").text($xmldata.find('rightData').find('link').text());
Note that the hardcoded values in the jsfiddle are just for demonstration. You can define whatever elements you like in the xml and then parse then into dom element values through jquery.

javascript innerHTML without childNodes?

im having a firefox issue where i dont see the wood for the trees
using ajax i get html source from a php script
this html code contains a tag and within the tbody some more tr/td's
now i want to append this tbody plaincode to an existing table. but there is one more condition: the table is part of a form and thus contains checkboxe's and drop down's. if i would use table.innerHTML += content; firefox reloads the table and reset's all elements within it which isnt very userfriendly as id like to have
what i have is this
// content equals transport.responseText from ajax request
function appendToTable(content){
var wrapper = document.createElement('table');
wrapper.innerHTML = content;
wrapper.setAttribute('id', 'wrappid');
wrapper.style.display = 'none';
document.body.appendChild(wrapper);
// get the parsed element - well it should be
wrapper = document.getElementById('wrappid');
// the destination table
table = document.getElementById('tableid');
// firebug prints a table element - seems right
console.log(wrapper);
// firebug prints the content ive inserted - seems right
console.log(wrapper.innerHTML);
var i = 0;
// childNodes is iterated 2 times, both are textnode's
// the second one seems to be a simple '\n'
for(i=0;i<wrapper.childNodes.length;i++){
// firebug prints 'undefined' - wth!??
console.log(wrapper.childNodes[i].innerHTML);
// firebug prints a textnode element - <TextNode textContent=" ">
console.log(wrapper.childNodes[i]);
table.appendChild(wrapper.childNodes[i]);
}
// WEIRD: firebug has no problems showing the 'wrappid' table and its contents in the html view - which seems there are the elements i want and not textelements
}
either this is so trivial that i dont see the problem OR
its a corner case and i hope someone here has that much of expirience to give an advice on this - anyone can imagine why i get textnodes and not the finally parsed dom elements i expect?
btw: btw i cant give a full example cause i cant write a smaller non working piece of code
its one of those bugs that occure in the wild and not in my testset
thx all
You are probably running into a Firefox quirk of following the W3C spec. In the spec the whitespace between tags are "text" nodes instead of elements. These TextNodes are returned in childNodes. This other answer describes a workaround. Also Using something like JQuery makes this much easier.
I would expect this behavior in any browser as the += operand overwrites what is already in the table by definition. Two solutions:
Instead of receiving HTML code from your PHP file, have the PHP generate a list of items to add to the table. Comma/tab separated, whatever. Then use Table.addRow(), Row.addCell() and cell.innerHTML to add the items to the table. This is the way I would suggest doing it, no point in creating GUI elements in two separate files.
The other solution is to save all the form data that's already been entered to local JavaScript variables, append the table, and then reload the data into the form fields.
Well, returning a JSON object with the new data seems like the best option. Then, you can synthesize the extra table elements by using it.
In case one is forced to get plain HTML as response, it is possible to use var foo = document.createElement('div');, for example, and then do foo.innerHTML = responseText;. This creates an element that is not appended to anything, yet hosts the parsed HTML response.
Then, you can drill down the foo element, get the elements that you need and append them to the table in a DOM-friendly fashion.
Edit:
Well, I think I see your point now.
wrapper is a table element itself. The nodes reside under the tbody, a child of wrapper which is its lastChild (or you can access it via its tBodies[0] member, in Firefox).
Then, using the tBody element, I think that you would be able to get what you want.
BTW, You do not need to append the wrapper to the document before appending its children to the table, so no need to hide it etc.

Categories