jQuery, Ajax and getting a complete html structure back - javascript

I'm new to jQuery and to some extent JavaScript programming. I've successfully started to use jQuery for my Ajax calls however I'm stumped and I'm sure this is a newbie question but here goes.
I'm trying to return in an Ajax call a complete html structure, to the point a table structure. However what keeps happening is that jQuery either strips the html tags away and only inserts the deepest level of "text" or the special characters like <,>, etc get replaced with the escaped ones
I need to know how to turn off this processing of the received characters. Using firebug I see the responses going out of my WebServer correctly but the page received by the user and thus processed by jQuery are incorrect. A quick example will so what I mean.
I'm sending something like this
<results><table id="test"><tr>test</tr></table></results>
what shows up on my page if I do a page source view is this.
<results><table....
so you can see the special characters are getting converted and I don't know how to stop it.
The idea is for the <results></results> to be the xml tag and the text of that tag to be what gets placed into an existing <div> on my page.
Here is the JavaScript that I'm using to pull down the response and inserts:
$.post(url, params, function(data)
{
$('#queryresultsblock').text(data)
}, "html");
I've tried various options other than "html" like, "xml", "text" etc. They all do various things, the "html" gets me the closest so far.

The simplest way is just to return your raw HTML and use the html method of jQuery.
Your result:
<table id="test"><tr>test</tr></table>
Your Javascript call:
$.post(url, params, function(data){ $('#queryresultsblock').html(data) })
Another solution with less control — you can only do a GET request — but simpler is to use load:
$("#queryresultsblock").load(url);
If you must return your result in a results XML tag, you can try adding a jQuery selector to your load call:
$("#queryresultsblock").load(url + " #test");

You can't put unescaped HTML inside of XML. There are two options I see as good ways to go.
One way is to send escaped HTML in the XML, then have some JavaScript on the client side unescape that HTML. So you would send
<results><results><table....
And the javascript would convert the < to < and such.
The other option, and what I would do, is to use JSON instead of XML.
{'results': "<table id="test"><tr>test</tr></table>" }
The JavaScript should be able to extract that HTML structure as a string and insert it directly into your page without any sort of escaping or unescaping.

The other thing you could do is create an external .html file with just your HTML code snippet in it. So create include.html with
<results><table id="test"><tr>test</tr></table></results>
As the contents, then use a jquery .load function to get it onto the page. See it in action here.

Related

Programmatically view content of html element loaded from another file

I would like to get the contents of a file on the server into a string. What is the easiest way to do this? Right now I am trying:
<script type="text/template" src="partials/someTemplate.html"
id="someTemplate"></script>
<script>
console.log($('#someTemplate').html()); //nothing comes up
</script>
A hacky way to do this is:
$('<div>').appendTo(document.body)
.load('partials/someTemplate.html', function () {console.log(this.innerHTML);} );
and then get the innerHTML of that, but that's a waste of an HTML element. Any thoughts? I feel like this should be silly easy.
Just use $.get():
var html;
$.get('partials/someTemplate.html', function(res)
{
html = res;
});
You basically need to use an asynchronous server request (ajax) to get the content of a file and process it later.
This can be done in pure JavaScript using XMLHttpRequest but the most popular and easiest way to do this is using jQuery's $.ajax function.
$.ajax({
url: "partials/someTemplate.html"
}).done(function( content ) {
console.log( "Your returned content is " + content );
});
You can configure this ajax call in many ways as described in documentation, you can pass parameters to the file, cache the request or demand a specific content type to be returned if that is necessary, but given example would do just fine for what you are trying to accomplish.
Please note that there are many ways to do an ajax request in jQuery, like .load(), $.post(), $.get(), $.getScript() and $.getJSON() but those are all just shorthand methods for an Ajax request so if you use those you are basically using an $.ajax with some predefined parameters.
Also, make sure that you need to use JavaScript and an async request at all. Getting content of a file inside some other file is mostly often done using some server side processing language like PHP (require() and include()),.NET, Java etc., and while that seems obvious for some people I felt obligated to say that since you didn't provide enaugh information about why you need that content and what you want to do with it.

JQuery.find() on a html string causes the html to be executed

I encountered the strangest thing today while I was trying to filter image data from a string of html that I download through an AJAX request (I use https://github.com/padolsey/jQuery-Plugins/blob/master/cross-domain-ajax/jquery.xdomainajax.js to do so).
I noticed that I was getting a 404 on an image that it was trying to download. After looking at the initialiser stack, it appears that the image is inside the html that my AJAX pulls back. Here is the relevant stack:
b.extend.buildFragment # jquery-1.9.1.min.js:4
b.extend.parseHTML # jquery-1.9.1.min.js:3
b.fn.b.init # jquery-1.9.1.min.js:3
b # jquery-1.9.1.min.js:3
$.ajax.success # main.js:86
My code in main.js looks like this:
function generateAlbumHTML(album)
{
$.ajax({
url: album.data.url,
type: 'GET',
success: function(data)
{
var albumHtmlStr = "";
var images = $(data.responseText).find('#image-container .zoom');
$.each(images, function(i, item)
{
album.data.url = $(item).attr('href');
albumHtmlStr += generateHTML(album);
});
return albumHtmlStr;
}
});
}
It appears that the culprit is line 86 where I do:
var images = $(data.responseText).find('#image-container .zoom');
This causes JQuery to parse the HTML and start loading unwanted images and data from the HTML.
Here is a link to the html that gets pulled back by the ajax request as data.responseText: http://pastebin.com/hn4jEgAA
Anyway, am I doing something wrong here? How can I filter and find the data I want from this string without loading things such as unwanted images and other data?
What causes the "parsing" is this:
$(data.responseText)
This is actually you, telling jQuery to create HTML structure using the string you provided in data.responseText.
If you want to find things in this string, which is the HTML in response to your GET request, then you have to use one of the corresponding String methods:
String instances methods
It should be noted, however, that what you are trying to do is quite unorthodox, since parsing HTML on the client to retrieve information is not the best of approaches.
The better way would be to either use the receieved HTML as is (provided it is from a trusted source or you sanitize it properly), or to receive raw data in JSON form and process that data (while creating corresponding HTML by yourself) in your code.
UPDATE
Additional ways are presented in jQuery ajax method
For instance, you can use dataFilter setting or some such to sanitize your response.

How to include a file OR PHP code with JS?

How can I include code, for example using Javascript? Or if that can't be done, how can I include a whole PHP file?
P.S. Found some script called "require" or "include," but I prefer two lines of code instead of a huge library (using jQuery though). If that can't be done, let me know, I will try to think of something else.
EDIT:
Okay, an example of what I want to do:
function foo() { if(x = 1) return 1; else return 0; }
Then if the function returns 1, I want to either add HTML/PHP code to DIV tags OR I want to include a PHP file containing that code.
EDIT #2:
What about only HTML?
document.getElementById('test').innerHTML = 'a cool link';
That doesn't seem to work either.
I have an empty div tag with id="test" in my code.
function foo() {
if(x = 1) {$("#divid").load("somephp.php");return 1;}
else return 0;
}
Or
if (foo()) $("#divid").load("somephp.php");
The only files could Javascript includes is Javascript files, what ever the extension is. and the only way to do it is using
<script src="path/to some/file.ext"></script>
You should note that the file should be javascript text contents, else errors may be generated.
Javascript can call any file as long as it is on your server.It can't call files on the user's local files, for obvious security reasons.
However, javascript cannot, and will never be able to call PHP code, as in it cannot execute php code. This is because since javascript is client side, users can call their own javascript on your page, and execute PHP code, and potentially mess up your site or browse your backend.
You can, however add HTML code to your page using javascript, fairly simply using the innerHTML property of DOM elements or JQuery.
Javascript can also call more javascript code if you wanted, using eval()
If you wanted to call files off your server onto the page using javascript, you'd have to use AJAX
Google it up, and you can code it from scratch, or use JQuery's convenient AJAX handler.
Let's say you had a php file myfile.php that had some html/php, and you wanted to insert it into a div with the id "mydiv", or in css, "#mydiv"
If you just want to quickly load the html/php and push it into the div:
$("#mydiv").load("myfile.php");
If you want to have maximum control of the response from the html/php file:
$.ajax({
url: "myfile.php", // url to load
success : function(data) { // on success function
// data is the response of the ajax request, the response text
// you can manipulate it here
manipulateData(data);
$('#mydiv').html(data); // set the html of the div
}
});

How do I use jQuery to extract part of a dynamically loaded mustache template

In an attempt to avoid repetition, I am trying to use mustache for templating on both the server and client side. I have a template something like the following:
<html>
<head>...</head>
<body>
<table>
<tbody id="#this">
{{rows}}
<tr>{{row}}<tr>
{{/rows}}
</tbody>
</table>
</body>
</html>
This works great for my server side templating. On the client side however, I'm having some trouble. I can successfully load the template using ajax, but I don't need the whole thing to update the rows of the table.
$(function () {
var template;
$.ajax('templates/thetemplate.mustache', {
success : function (data) {
template = $('#this', data).html();
},
dataType : 'html'
});
});
When I use the above jQuery to get at the contents of the #this element however, the {{rows}} and {{/rows}} lines are stripped from the result, while the <tr>{{row}}</tr> between them are returned successfully. How can I get the entire contents?
I've tried $('#this', data).contents(); which gives the same results, and $('#this', data).val(); which returns an empty string. Using $(data).find('#this') instead has the same three results. I've also tried setting the dataType of the ajax call to 'text' with no apparent effect.
I realize that I could probably accomplish what I want (not duplicating parts of my templates for client vs server side use) by using partials, and that it would have the added bonus of avoiding the transfer of more template than I actually need to the client just to have it thrown away, but that doesn't answer my question. (tho slick solutions are appreciated)
Thanks
The problem has already occurred at $('#this', data), which sends data via the browser's HTML parser to convert it to a DOM fragment. Being error tolerant, the HTML parser does what it can with the template but it's not what you want because the template itself is not valid HTML. For this reason $('#this', data).anythingYouLike() or $(data).anythingYouLike() will not work.
As the HTML must be valid before submitting to the browser's HTML parser, there's no other choice than to perform Mustache rendering before submitting valid HTML to the browser with a $(renderedHTML) expression.
With that constraint in mind, there are two realistic options regarding the order of events :
strip down data to just <tbody ...>...</tbody> (with
a regular expression), then Mustache render, then $tbody = $(renderedHTML).
Mustache render data in full, then $tbody = $(renderedHTML).find('tbody')
As far as I'm aware, either approach will work. In both cases, you end up with a jQuery object, $tbody, containing a populated tbody node, which can then be inserted into the DOM with $tbody.appendTo($('#myTable')) or similar.
first, your template is not a good structure of table (of couse, it's template), it will become an good table after you do $(data), something like this:
[" {{rows}} {{row}} {{/rows}} ", <table>​…​</table>​]
{{rows}} are not in table element, so you can not get what you want by $('#this', data).html();
My solution:
data.replace(/\n/g, '').match(/<tbody id="#this">(.*)<\/tbody>/g)[0]

Using jQuery on a string containing HTML

I'm trying to make a field similar to the facebook share box where you can enter a url and it gives you data about the page, title, pictures, etc. I have set up a server side service to get the html from the page as a string and am trying to just get the page title. I tried this:
function getLinkData(link) {
link = '/Home/GetStringFromURL?url=' + link;
$.ajax({
url: link,
success: function (data) {
$('#result').html($(data).find('title').html());
$('#result').fadeIn('slow');
}
});
}
which doesn't work, however the following does:
$(data).appendTo('#result')
var title = $('#result').find('title').html();
$('#result').html(title);
$('#result').fadeIn('slow');
but I don't want to write all the HTML to the page as in some case it redirects and does all sorts of nasty things. Any ideas?
Thanks
Ben
Try using filter rather than find:
$('#result').html($(data).filter('title').html());
To do this with jQuery, .filter is what you need (as lonesomeday pointed out):
$("#result").text($(data).filter("title").text());
However do not insert the HTML of the foreign document into your page. This will leave your site open to XSS attacks.
As has been pointed out, this depends on the browser's innerHTML implementation, so it does not work consistently.
Even better is to do all the relevant HTML processing on the server. Sending only the relevant information to your JS will make the client code vastly simpler and faster. You can whitelist safe/desired tags/attributes without ever worrying about dangerous ish getting sent to your users. Processing the HTML on the server will not slow down your site. Your language already has excellent HTML parsers, why not use them?.
When you place an entire HTML document into a jQuery object, all but the content of the <body> gets stripped away.
If all you need is the content of the <title>, you could try a simple regex:
var title = /<title>([^<]+)<\/title>/.exec(dat)[ 1 ];
alert(title);
Or using .split():
var title = dat.split( '<title>' )[1].split( '</title>' )[0];
alert(title);
The alternative is to look for the title yourself. Fortunately, unlike most parse your own html questions, finding the title is very easy because it doesn;t allow any nested elements. Look in the string for something like <title>(.*)</title> and you should be set.
(yes yes yes I know never use regex on html, but this is an exceptionally simple case)

Categories