Jquery masonary formatting changes after ajax update - javascript

I'm using the masonary jquery plugin to format images loaded into my page via ajax.
It's all working perfectly except for when images are loaded in through ajax, they seem to gain extra margin/padding values from nowhere and do not fit seamlessly like the images already on the page. I've tried adding margin:0; padding:0; but nothing seems to work
All my code is currently live here:
http://1hype.me/
Any ideas are greatly appreciated!
EDIT:
The problem is occurring on everything i've tested, Safari, Chrome & FF (mac)
Here's a screenshot that explains it a bit more: http://cl.ly/0d0q37290W1r0j0X2g0c

This is due to whitespace.
You could just return the image from the ajax call (without any script)
and just run
function fetch() {
//autoupdater
$.ajax({
type: "POST",
url: "ajax/fetch_image.php",
cache: false,
data: "after=000000",
success: function(results){
var imgHolder = $('#image_holder');
/* prepend the results
results is just the image (without whitespace around it) */
imgHolder.prepend(results);
/* fade in the first image (the one we just prepended)*/
imgHolder.find('img:first').fadeIn(1100);
/* do the masonry thing.. */
imgHolder.masonry({ singleMode: true });
}
});
}
if that is not an option (altering the fetch_image.php) then you can use
function fetch() {
//autoupdater
$.ajax({
type: "POST",
url: "ajax/fetch_image.php",
cache: false,
data: "after=000000",
success: function(results){
var imgHolder = $('#image_holder');
/* exclude text whitespace nodes (not included in a tag).*/
var $results = $(results).filter(function(){return this.nodeType != 3});
imgHolder.prepend( $results.eq(0) );
$('body').append( $results.eq(1) );
}
});
}

Related

JQuery's ajax function stripping HTML tags from XML

Okay, I'm pulling data from an XML file to populate my elements of my webpage dynamically. My problem is that when I use JQuery .ajax to pull the xml file, it strips my HTML tags.
For example,
Data in XML file:
<transcript><p>Hello, world</p></transcript>
Desired output on webpage:
<p>Hello, world</p>
Actual output:
Hello World
Here is my code inside of my ajax function:
$(xmlData).find('item').each(function() {
var n = $(this).find('transcript').text();
I've tried to use JQuery's '.html()' but it returns null. What is the simplest way I can fix this? Preferably without changing too much of what I've already done.
Thanks in advance.
Using text will strip the tags as you experienced. You can instead use the jQuery children method (reference) on the transcript node to get the HTML. Here is a working example: http://jsfiddle.net/gjwyd/
$(document).ready(function() {
$.ajax({
type: "POST",
url: "/echo/xml/",
dataType: "xml",
data: {
xml: "<transcript><p>Hello, world</p></transcript>"
},
success: function(xml) {
var container = $('#content');
var html = $(xml).find('transcript').children();
container.html(html);
}
});
});​
The key is this line:
var html = $(xml).find('transcript').children();
And being sure to set the dateType as xml.
Issues
When taking HTML from an XML response it may be missing the default styles. For example, a paragraph tag may not have display: block. Resetting the styles may be one way around this issue. A more correct and probably easier way would be to put the HTML content inside of CDATA within the XML as one of the other commenters suggested.
http://jsfiddle.net/tZJQp/
$(document).ready(function() {
$.ajax({
type: "POST",
url: "/echo/xml/",
dataType: "xml",
data: {
xml: "<transcript><![CDATA[<p>Hello, world</p><p>Bye</p>]]></transcript>"
},
success: function(xml) {
var container = $('#content');
var html = $(xml).find('transcript').text();
container.html(html);
}
});
});
As others note, html won't work on XML.

Why .html() method does not load data in the element?

$.get("progress.txt", null, function(data_aj){
if(data_aj.substr(0,14) == "<!-- MSG:: -->"){
$("#list").html("<li>"+data_aj+"</li>");
window.clearTimeout(timeOutId);
}else{
$("#list").html(data_aj);
}
});
I really have tried everything but can't figure out whats wrong. If I use alert(data_aj); it gives the desired output and just works fine but HTML(data_aj) just doesnt loads into a <ul> element #list using .html(). Can anyone tell me why?
Have you tried putting your code in a document ready, as your alert will fire fine but if your dom is not loaded then you cannot append to it. Also use .append() for lists not html
$(document).ready(function() {
$.get("progress.txt", null, function(data_aj){
if(data_aj.substr(0,14) == "<!-- MSG:: -->"){
$("#list").append("<li>"+data_aj+"</li>");
window.clearTimeout(timeOutId);
}else{
$("#list").append(data_aj);
}
});
});
Listen up...
$.get() is a shorthand for $.ajax().
So when you do this
$.get(uri, function(data){
//Your functionality
});
You're really doing this
$.ajax({
url: uri,
type: "GET",
success: function(data) {
//Your functionality
}
});
By default this returns the page as HTML. Or rather, by default, it first checks the MIME-type on the page, and if none is found, it returns HTML. As you are requesting a .txt file it will interpret it as a simple textfile. If you want to tell it what you would like to return (HTML), you can either do it in the MIME-type on the server page, or you could use $.getJSON().
An easy way to solve this is thus doing:
$.get(uri, function(data) {
//Your functionality
},
"html");
Which is the same as doing:
$.ajax({
url: uri,
type: "GET",
dataType: "HTML",
success: function(data) {
//Your functionality
}
});
Also it is not a good idea to use html() because you are replacing the existing html inside of your ul element every time you want to add an additional new node.
Try making use of:
$('#list').append('<li>' + data_aj + '</li>');
Basically you can just append the <li> to the <ul> itself.
Lastly make sure your dom has already been loaded by placing all your JQuery code into the
$(document).ready(function() {
//Your code...
});
Otherwise if your HTML is not fully loaded yet, your list might not exist yet so there is no way for JQuery to put some values into unexisting HTML.

Jquery selector validity/scope

New to JQuery but want to use it to prefetch html pages in the background (about four # about 4kb each) but I am not quite sure I am doing this right.
Here is the code I have come up with:
$(document).ready(function() {
var my_url;
$('[rel=prefetch][href$=.html]')
.each(function() {
my_url = $(this).attr('href')
$.ajax({
url: my_url,
dataType: 'text',
headers:{'X-Moz': 'prefetch'}
});
});
});
Basically, I have some links with 'rel=prefetch' in the head of the document and the code snippet above is inserted when the browser is not Firefox. My application renders things differently when the 'X-Moz: prefetch' header is detected so this is sent here as it is needed.
The code is supposed to just get the html and cache without processing scripts which I believe 'dataType: text' should take care of.
Will appreciate some eyes on this and suggestions. Queries are:
Is the code above valid? If not what is the fix?
What do I need to change to limit the selector's scope to the < head > ... < /head > section?
$(document).ready(function() {
$('[rel=prefetch][href$=.html]')
.each(function() {
var my_url = $(this).attr('href')
$.ajax({
url: my_url,
dataType: 'text',
headers:{'X-Moz': 'prefetch'}
});
});
});
Got it working. The issue was because the jquery snippet was not running when I linked to JQuery using the google api. When I serve it directly from my site, in which case all the js is combined into one file, it works.
I noticed this when I used the developer tool in Safari.
The full code is:
(function ($) {
$(document).ready(function() {
var this_browser, my_url;
// Prefetch pages for non Firefox browsers
this_browser = new Browser();
if ( this_browser.getBrowserName() != this_browser.BROWSER_FIREFOX ) {
// Asynchronously prefetch html as text strings
// I.E., do not process scripts in incoming html
// See: http://ernstdehaan.blogspot.com/2009/08/prefetching-files-using-jquery.html
$('link[rel="prefetch"][href$=".html"]')
.each(function() {
my_url = $(this).attr('href');
$.ajax({
url: my_url,
dataType: 'text',
headers: {'X-Moz': 'prefetch'}
});
});
}
});
}(jQuery));
Safari alerted me that the "(jQuery)" bit was generating an error.
It turned out that this was because the code was fired before JQuery was loaded.
Also forgot to mention that
$('head link[rel="prefetch"][href$=".html"]')
Limits the selector.
I have also removed the browser detection and just use this for all browsers.

jQuery selectors on an ajax response string that is a full html page

I'm trying to get some page details (page title, images on the page, etc.) of an arbitrarily entered URL/page. I have a back-end proxy script that I use via an ajax GET in order to return the full HTML of the remote page. Once I get the ajax response back, I'm trying to run several jQuery selectors on it to extract the page details. Here's the general idea:
$.ajax({
type: "GET",
url: base_url + "/Services/Proxy.aspx?url=" + url,
success: function (data) {
//data is now the full html string contained at the url
//generally works for images
var potential_images = $("img", data);
//doesn't seem to work even if there is a title in the HTML string
var name = $(data).filter("title").first().text();
var description = $(data).filter("meta[name='description']").attr("content");
}
});
Sometimes using $("selector", data) seems to work while other times $(data).filter("selector") seems to work. Sometimes, neither works. When I just inspect the contents of $(data), it seems that some nodes make it through, but some just disappear. Does anyone know a consistent way to run selectors on a full HTML string?
Your question is kind of vague, especially w/r/t what input causes what code to fail, and how. It could be malformed HTML that's mucking things up - but I can only guess.
That said, your best bet is to work with $(data) rather than data:
$.ajax({
type: "GET",
url: base_url + "/Services/Proxy.aspx?url=" + url,
success: function(data) {
var $data = $(data);
//data is now the full html string contained at the url
//generally works for images
var potential_images = $("img", $data);
//doesn't seem to work even if there is a title in the HTML string
var name = $data.filter("title").first().text();
var description = $data.filter("meta[name='description']").attr("content");
}
});

JQuery Treeview not working with Ajax

I'm new to JQuery and web development in general. I'm trying to load some data from an XML file and build an unordered list. I've got that part working, now I'm trying to use the TreeView plugin so I can collapse/expand the data. The data is loaded like this:
$(document).ready(function(){
$.ajax({
type: "GET",
url: "solutions.xml",
dataType: ($.browser.msie) ? "text" : "xml",
success: function(data) {
var xml;
if (typeof data == "string") {
// Work around IE6 lameness
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(data);
} else {
xml = data;
}
list = ""
$(xml).find("Group").each(function() {
group = $(this).attr("name");
list += "<li><span>" + group + "</span><ul>";
$(this).find("Solution").each(function() {
solution = $(this).attr("name");
list += "<li><span>" + solution + "</span></li>";
});
list += "</ul></li>";
});
$("#groups").html(list);
},
error: function(x) {
alert("Error processing solutions.xml.");
}
});
$("#groups").treeview({
toggle: function() {
console.log("%s was toggled.", $(this).find(">span").text());
}
});
});
and the HTML looks like this:
<html>
...
<body>
<ul id="groups">
</ul>
</body>
</html>
The unordered list shows correctly, but the little [+] and [-] signs don't show up and the sections aren't collapsible/expandable. If I get rid of my Ajax loading and insert an unordered list inside of #groups manually it works as expected.
What am I doing wrong? Is there any other plugins or Javascript libs that could make this easier? The solution needs to work on IE6 locally (i.e. webserver).
Update: I found a work-around: If I define my treeview stuff like this it works:
function makeTreeview() {
$("#container").treeview({
toggle: function() {
console.log("%s was toggled.", $(this).find(">span").text());
}
});
}
setTimeout('makeTreeview();', 50);
I think the problem is, when I create the treeview, the ajax stuff hasn't done it's work yet, so when treeview() is called, the unordered list hasn't been created yet. I haven't tested this with IE6 yet. Is there a nicer way to do this, without using SetTimeout()?
I made the same type of call for another project.
For other reasons you will probably want to wrap your ajax call in an anonymous function to create a closure so that your variables remain what you expect them to...
The success method is a callback function that happens after your call is complete , just create your treeview inside that method, or break it out into a seperate fumction if you need to for clarity.
in the example that you show - your treeview will still fail if the ajax call takes longer than 50ms - which could easily happen during initial load if more than two objects are being loaded from that same server.
This example used JSON, and concurrently loaded html data from a page method into a series of divs.
$(document).ready(function() {
for (i= 1;i<=4;i++)
{
(function (){
var divname ="#queuediv"+i;
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "test12.aspx/GetHtmlTest",
data: "{}",
error: function(xhr, status, error) {
alert("AJAX Error!");
},
success: function(msg) {
$(divname).removeClass('isequeue_updating');
$(divname).html(msg);
$("#somethingfromthemsg").treeview();
}
});
})();
}
});
Hope that helps!
You need to get FireBug (Firefox add-in) and then you can see in the console what is being returned, and make sure it matches what you expect (And that it is actually doing the request..).
Once you get it working in FF, you can support the ancient 10-year old IE6 browser.
There's also some other things you may want to consider:
The whole ActiveXObject("Microsoft.XMLDOM") jumps out as me as unnecessary. If you pass XML in a string to $(), jQuery turns it into a DOM object.
Additionally, .Find can be replaced by:
$('Element', this);
So for example:
var xmlDoc = '<Group><Solution name="foo" /><Solution name="bar" /></Group>';
$('Solution', xmlDoc).each(function() {
document.write( $(this).attr('name') );
});
would spit out:
foo
bar
Also, with firebug, stick a console.log(list); at the end, to be sure you're generating the HTML you think you are. If you're really stuck in IE6, alert(list) somewhat works as a poor man's equivalent (as long as your file isn't too big).
In short, I think you're on the right track, you just need the tools to debug properly.
For anyone who also finds their way to this post. I had this trouble with an ajax call.
If you want to wait for the ajax call to be returned, you need to set async as false.
$.ajax({
type: 'POST',
async: false,
........

Categories