I would like to style json feed output. I want to be able to arrange it as I want. So far this is my javascript code. I would like to achieve something like this IMG, information's such as age number etc would be possible to change location etc. I want this to work on jquery mobile as i am building an application.
function listPosts(data) {
var output = '<ul data-role="listview" data-filter="true">';
$.each(data.posts, function(key, val)
{
var tempDiv = document.createElement("tempDiv");
tempDiv.innerHTML = val.excerpt;
$("a", tempDiv).remove();
var excerpt = tempDiv.innerHTML;
output += '<li>';
output += '<a href="#blogpost" onclick = "showPost('+ val.id +') ">';
output += '<h3>' + val.title + "</h3>";
output += (val.thumbnail) ?
'<img src="' + val.thumbnail + '" alt="' + val.title + '">':
'<img src="images/itblogo.png" alt="ITB Logo">';
output += '<h3>' + val.custom_fields.gender + "</h3>";
output += '<h3>' + val.custom_fields.age + "</h3>";
output += '</a>';
output += '</li>';
}); //go through each post
output += "</ul>";
$('#postlist').html(output);
} //listPosts
function showPost(id) {
$.getJSON('http://www.pawmatch.info?json=get_post&post_id=' + id + '&callback=?', function(data) {
var
output ='<img src="'+data.post.thumbnail + '">'
output += '<h3>' + data.post.custom_fields.dogs_name + '</h3>'
output +='<h3>'+data.post.custom_fields.dog_size + '</h3>'
output +='<h3>'+data.post.custom_fields.age + '</h3>'
output +='<h3>'+data.post.custom_fields.gender + '</h3>'
output +='<h3>'+data.post.custom_fields.breed + '</h3>'
output +='<h3>'+data.post.custom_fields.extra_information + '</h3>'
$('#mypost').html(output);
});
}
I'm trying to use JSON to print content to the screen. I'm trying to print out as two different sections so the "albumData" displays as columns in the "albumData" div and the audio equipment goes in a div further down the page. I have tried having {audio: [ ...]} in the JSON array but that never seems to work. The issue right now is the JS file is outputting too munch data and is not stopping when the the object is not in the array. Ideally, it would put out a 4x4 layout for the albums, and a 4x3 layout for devices but instead both sections are outputting 4x7 and many of the text is 'undefined'.
Do you guys have any tips on targeting specific JSON data? Thanks for your help
HTML Code:
<h1 class="headText">Wall of Fame</h1>
<hr class="style14"></hr>
</br></br>
<h2>Albums: </h2>
<div id="albumData" class="row"></div>
</br></br>
<h2>Equipment: </h2>
<div id="deviceData" class="row"></div>
<script src="js/wall.js"></script>
JS Code:
$.getJSON("jsonDatabase/wall.json",function(data){
console.dir(data);
var html = "";
$.each(data, function(index, item){
html += '<div class="col-md-3">'+
'<img class="albumImage" src=""' + item.albumImage + '"/>' + "<br>" +
'<div class="albumArtist">' + "<strong>Artist: </strong>" + item.artist + '</div>'+
'<div class="albumTitle">' + "<strong>Album: </strong>" + item.albumTitle + '</div>'+
'<div class="albumYear">' + "<strong>Year: </strong>" + item.year + '</div>'+
'<div class="albumGenre">' + "<strong>Genre: </strong>" + item.genre + '</div>'
html += '</div>'; //col-md-3
})//each album
$("#albumData").append(html);
//end record data
var device = "";
$.each(data, function(ind, item){
device += '<div class="col-md-3">'+
'<img class="deviceImage" src=""' + item.deviceImage + '"/>' + "<br>" +
'<div class="deviceName">' + "<strong>Name: </strong>" + item.device + '</div>'+
'<div class="deviceType">' + "<strong>Device: </strong>" + item.type + '</div>'+
'<div class="deviceCompany">' + "<strong>Company: </strong>" + item.comapny + '</div>'+
'<div class="devicePrice">' + "<strong>Price: </strong>" + item.price + '</div>'
device += '</div>'; //col-md-3
})//each device
$("#deviceData").append(device);
})
// closes getJSON
})
JSON Array:
[{"albumImage":"","artist":"Bruce","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"Tom Waits","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"Alison Krauss","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"Pink Floyd","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"Rage Against the Machine","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"deviceImage":"","device":"E12","type":"Portable amp","company":"FiiO","price":"$130"},
{"deviceImage":"","device":"GS1000e","type":"Headphone","company":"Grado","price":"$1300"},
{"deviceImage":"","device":"RS1i","type":"Headphone","company":"Grado","price":"$850"},
{"deviceImage":"","device":"SR60e","type":"Headphone","company":"Grado","price":"$80"},
{"deviceImage":"","device":"HD 650","type":"Headphone","company":"Sennheiser","price":"$500"},
{"deviceImage":"","device":"SRH 860","type":"Headphones","company":"Samson","price":"$60"},
{"deviceImage":"","device":"MA750i","type":"In-ear monitors","company":"RHA","price":"$130"},
{"deviceImage":"","device":"Play: 1","type":"WiFi connected speaker","company":"Sonos","price":"$229"},
{"deviceImage":"","device":"Walsh 3","type":"Speakers (passive)","company":"Ohm","price":"$2,000"},
{"deviceImage":"","device":"Evo 2/8","type":"Speakers (passive)","company":"Wharfedale","price":"$400"},
{"deviceImage":"","device":"Asgard 2","type":"Amplifier","company":"Schiit","price":"$299"},
{"deviceImage":"","device":"Modi","type":"DAC","company":"Schiit","price":"$99"}]
Since it's one array don't parse it 2x, use variables instead.
var deviceHtml = "";
var albumHtml = "";
$.each(data, function(index, item){
if(typeof(item.albumImage) != "undefined" && typeof(item.deviceImage == 'undefined')
{
albumHtml += '<div class="col-md-3">'+
'<img class="albumImage" src=""' + item.albumImage + '"/>' + "<br>" +
'<div class="albumArtist">' + "<strong>Artist: </strong>" + item.artist + '</div>'+
'<div class="albumTitle">' + "<strong>Album: </strong>" + item.albumTitle + '</div>'+
'<div class="albumYear">' + "<strong>Year: </strong>" + item.year + '</div>'+
'<div class="albumGenre">' + "<strong>Genre: </strong>" + item.genre + '</div></div>';
}
else if(typeof(item.deviceImage) != "undefined" && typeof(item.albumImage) == 'undefined')
{
deviceHtml += '<div class="col-md-3">'+
'<img class="deviceImage" src=""' + item.deviceImage + '"/>' + "<br>" +
'<div class="deviceName">' + "<strong>Name: </strong>" + item.device + '</div>'+
'<div class="deviceType">' + "<strong>Device: </strong>" + item.type + '</div>'+
'<div class="deviceCompany">' + "<strong>Company: </strong>" + item.comapny + '</div>'+
'<div class="devicePrice">' + "<strong>Price: </strong>" + item.price + '</div>';
deviceHtml += '</div>'; //col-md-3
}
})//each album
$("#albumData").append(albumHtml);
$("#deviceData").append(device);
You will also want to skip records that have no values for any of them so you will need to add an additional if block in there to test that the string isn't empty, else skip that iteration of the loop.
If, as in your comments you change the format of your object to {albums:[ { } ], devices:[ { }] } you can then just use dot notation to access the key you wish to loop through.
$.each(data.albums,function(index, item){})
and
$.each(data.devices,function(index, item){})
I have some content being added to a page via an AJAX call, and all of my styles are working, except one:
.bld-txt {
font-weight: bold;
}
The call itself looks like this:
$('#quick-search').submit(function(evt) {
evt.preventDefault();
$('.quick-search-info').empty();
var artistName = $(this).serialize();
$.post('/', artistName, function(data) {
var parsedInfo = $.parseJSON(data);
var tourDetails = '';
$.each(parsedInfo, function(i, val) {
tourDetails += '<li class="tour-date">';
tourDetails += '<ul class="show-details">';
tourDetails += '<li class="show-date"><span class="bld-txt">Date: </span>' + parsedInfo[i].formatted_datetime + '</li>';
tourDetails += '<li class="show-venue"><span class="bld-txt">Venue: </span>' + parsedInfo[i].venue.name + '</li>';
tourDetails += '<li class="show-location"><span class="bld-txt">Location: </span>' + parsedInfo[i].venue.city + ", " + parsedInfo[i].venue.region + '</li>';
tourDetails += '<li class="show-tickets"><span class="bld-txt">Tickets: </span>' + parsedInfo[i].ticket_status + '</li>';
tourDetails += '</ul>';
tourDetails += '</li>';
});
$('.quick-search-info').append(tourDetails);
});
});
All other classes that have styles assigned to them thus far are working, but for some reason "bld-txt" will not take effect.
I'm using a reset (normalize.css), but there's nothing in it that should be causing this.
Any guidance is greatly appreciated.
I am trying to render a catalog from an XML document and everything works, although when trying to show a default image if there is no image present in the XML node, it disables the parent node therefore forcing it not to show any of it and it reads me an error in my console saying:
Uncaught TypeError: Cannot read property 'getElementsByTagName' of
undefined
Which is pointing to this part of the code:
if (records[i].getElementsByTagName("IMAGE")[0].childNodes.length > 0)
{
So my question is where in my code below is my error causing it to not load the XML node?
PS: If anybody needs more of my code please let me know, and I would be happy to post it.
for (var i = fromItem; i < nextMaxItem; i++) {
if (records[i].getElementsByTagName("IMAGE")[0].childNodes.length > 0) {
xmlContent += '<article class="post all ' + records[i].getElementsByTagName("CATEGORY")[0].childNodes[0].nodeValue + '" id="">'
+ '<div class="col-sm-4 col-lg-4 col-md-4"><div class="thumbnail img-hover">'
+ '<a class="fancybox" rel="group" href="' + records[i].getElementsByTagName("BIGIMAGE")[0].childNodes[0].nodeValue + '" title="'+ records[i].getElementsByTagName("SHORTDESCRIPTION")[0].childNodes[0].nodeValue +'">'
+ '<img class="product-image" src="' + records[i].getElementsByTagName("IMAGE")[0].childNodes[0].nodeValue + '" alt="' + records[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue + '" />'
+ '<div class="caption">'
+ '<h4>' + records[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue + '</h4>'
+ '<p>' + records[i].getElementsByTagName("SHORTDESCRIPTION")[0].childNodes[0].nodeValue + '</p>'
+ '</div>'
+ "</a></div></div></article>";
} else {
xmlContent += '<article class="post all ' + records[i].getElementsByTagName("CATEGORY")[0].childNodes[0].nodeValue + '" id="">'
+ '<div class="col-sm-4 col-lg-4 col-md-4"><div class="thumbnail img-hover">'
+ '<a class="fancybox" rel="group" href="' + records[i].getElementsByTagName("BIGIMAGE")[0].childNodes[0].nodeValue + '" title="'+ records[i].getElementsByTagName("SHORTDESCRIPTION")[0].childNodes[0].nodeValue +'">'
+ '<img class="product-image" src="/images/Products/no-preview.jpg" alt="No Preview Available" />'
+ '<div class="caption">'
+ '<h4>' + records[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue + '</h4>'
+ '<p>' + records[i].getElementsByTagName("SHORTDESCRIPTION")[0].childNodes[0].nodeValue + '</p>'
+ '</div>'
+ "</a></div></div></article>";
}
}
Here is the whole JavaScript code:
var page = 1, perPage = 12, content = document.getElementById('content'),
pagination = document.getElementById('pagination'), records;
function paganation(page) {
var nextMaxItem = perPage * page,
fromItem = (page - 1) * perPage,
maxPages = Math.ceil(records.length / perPage);
var xmlContent = '<div class="row">';
for (var i = fromItem; i < nextMaxItem; i++) {
if (records[i].getElementsByTagName("IMAGE")[0].childNodes.length > 0) {
xmlContent += '<article class="post all ' + records[i].getElementsByTagName("CATEGORY")[0].childNodes[0].nodeValue + '" id="">'
+ '<div class="col-sm-4 col-lg-4 col-md-4"><div class="thumbnail img-hover">'
+ '<a class="fancybox" rel="group" href="' + records[i].getElementsByTagName("BIGIMAGE")[0].childNodes[0].nodeValue + '" title="' + records[i].getElementsByTagName("SHORTDESCRIPTION")[0].childNodes[0].nodeValue + '">'
+ '<img class="product-image" src="' + records[i].getElementsByTagName("IMAGE")[0].childNodes[0].nodeValue + '" alt="' + records[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue + '" />'
+ '<div class="caption">'
+ '<h4>' + records[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue + '</h4>'
+ '<p>' + records[i].getElementsByTagName("SHORTDESCRIPTION")[0].childNodes[0].nodeValue + '</p>'
+ '</div>'
+ "</a></div></div></article>";
} else {
xmlContent += '<article class="post all ' + records[i].getElementsByTagName("CATEGORY")[0].childNodes[0].nodeValue + '" id="">'
+ '<div class="col-sm-4 col-lg-4 col-md-4"><div class="thumbnail img-hover">'
+ '<a class="fancybox" rel="group" href="' + records[i].getElementsByTagName("BIGIMAGE")[0].childNodes[0].nodeValue + '" title="' + records[i].getElementsByTagName("SHORTDESCRIPTION")[0].childNodes[0].nodeValue + '">'
+ '<img class="product-image" src="/images/Products/no-preview.jpg" alt="No Preview Available" />'
+ '<div class="caption">'
+ '<h4>' + records[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue + '</h4>'
+ '<p>' + records[i].getElementsByTagName("SHORTDESCRIPTION")[0].childNodes[0].nodeValue + '</p>'
+ '</div>'
+ "</a></div></div></article>";
}
}
xmlContent += "</div>";
content.innerHTML = xmlContent;
var paginationContent = '<nav><ul class="pagination">';
if (page > 1) {
paginationContent += '<li>';
paginationContent += '<span aria-hidden="true">«</span>';
paginationContent += '</li>';
} else {
paginationContent += '<li class="disabled">';
paginationContent += '<span aria-hidden="true">«</span>';
paginationContent += '</li>'
}
var prevPosition = page - 3;
var nextPosition = page + 3;
for (var i = 1; i <= maxPages; i++) {
if (i != page) {
if (i >= prevPosition && i <= nextPosition) {
var linkToPage = i == prevPosition ? 1 : i == nextPosition ? maxPages : i;
var linkText = i == prevPosition ? "..." : i == nextPosition ? "..." : i;
paginationContent += "<li>";
paginationContent += '' + linkText + '';
paginationContent += "</li>";
}
} else {
paginationContent += "<li class='active'>";
paginationContent += '' + i + '';
paginationContent += "</li>";
}
}
var next = page + 1;
if (next <= maxPages) {
paginationContent += '<li>';
paginationContent += '<span aria-hidden="true">»</span>';
paginationContent += '</li>';
} else {
paginationContent += '<li class="disabled">';
paginationContent += '<span aria-hidden="true">»</span>';
paginationContent += '</li>';
}
paginationContent += '</ul></nav>';
pagination.innerHTML = paginationContent;
}
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET", xmlUrl, false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML;
records = xmlDoc.getElementsByTagName(xmlNode);
records = Array.prototype.slice.call(records).sort(function () {
return Math.random() > 0.5 ? 1 : -1
});
paganation(1);
If we imagine that records was of length 18, then for the second page, you would have:
fromItem - 12
nextMaxItem - 24
You are iterating i from fromItem to nextMaxItem, but as soon as you go past i = 18, you've gone past the end of records. You need to make sure that doesn't happen. You need to ensure that you don't iterate past the end of your array:
var max = Math.min(nextMaxItem, records.length);
for (var i = fromItem; i < max; i++) {
....
}
Wondering if anyone can help me. I'm trying to put together a weekly photo competition page by pulling in photos from a Flickr gallery, but I can't get the images to display. It works OK for groups, but having some problems with the gallery code. Getting the correct JSON response, but can't get the results to display on the page as good as the group images do.
Here's my Javascript:
$(function() {
var map;
var markers = [];
var infowindow;
// Get gallery photos
var visibleGallery;
$.getJSON("http://api.flickr.com/services/rest/" +
"?method=flickr.galleries.getPhotos" +
"&api_key=XXXX" +
"&photoset_id=XXXX" +
"&extras=geo,tags,url_sq,url_t,url_s,url_m,url_o" +
"&format=json&jsoncallback=?", function(data, textStatus) {
var htmlString = '<div id="weekContainer">';
var weeks = sortIntoWeekArrays(data.photos.photo);
$.each(weeks, function(i, week)
{
var weekNumber = i + 1;
var numberOfWeeks = weeks.length - 1;
htmlString += '<div id="week' + weekNumber + '">';
htmlString += '<ul class="weeks">';
if(i < numberOfWeeks)
{
htmlString += '<li><a class="weekLinksNext" href="#"><span>Next</span></a></li>';
}
var sunday = new Date(week.monday.toUTCString());
sunday.setDate(week.monday.getDate() + 6);
htmlString += '<li class="weekTitle">Week ' + weekNumber + ':</li><li class="weekDate"> ' + week.monday.format("ddd d mmm") + ' — ' + sunday.format("ddd d mmm") + '</li>';
if(i > 0)
{
htmlString += '<li><a class="weekLinksPrev" href="#"><span>Previous</span></a></li>';
}
htmlString += '</ul>';
if(week.winner !== undefined)
{
htmlString += '<p class="galleryTitleFirst">Photo of the Week</p>';
htmlString += '<ul class="imagesWinners">';
htmlString += '<li class="winner"><a href="http://www.flickr.com/photos/' + week.winner.owner + '/' + week.winner.id + '" target="_blank">';
htmlString += '<img title="' + week.winner.title + '" src="' + week.winner.url_m + '" alt="' + week.winner.title + '" />';
htmlString += '</a></li>';
htmlString += '<li class="name">' + week.winner.title + '</li>';
htmlString += '<li class="owner">' + 'by ' + week.winner.ownername + '</li>';
htmlString += '</ul>';
}
htmlString += '<p class="galleryTitle">Our other favourites this week</p>';
htmlString += '<ul class="imagesRunnersUp">';
$.each(week.images, function(i, item)
{
htmlString += '<li><a href="http://www.flickr.com/photos/' + item.owner + '/' + item.id + '" target="_blank">';
htmlString += '<img title="' + item.title + '" src="' + item.url_sq + '" alt="' + item.title + '" />';
htmlString += '</a></li>';
if(item.longitude == "0" && item.latitude == "0")
{
return true;
}
var latlng = new google.maps.LatLng(item.latitude, item.longitude);
var marker = new google.maps.Marker(
{
position: latlng,
map: map,
title:item.title
});
marker.content = '<img title="' + item.title + '" src="' + item.url_s + '" alt="' + item.title + '" />';
markers.push(marker);
});
htmlString += '</ul>';
htmlString += '</div>';
});
htmlString += '</div>';
$('div#weekViewer').append(htmlString);
$('div#weekContainer > div').css('float', 'left').css('margin-right', '30px');
$('div#weekContainer').width(weeks.length * 450);
$('div#weekContainer .weekLinksPrev')
.click(function(){
$('div#weekViewer').animate({scrollLeft: '-=450'}, 'slow');
return false;
});
$('div#weekContainer .weekLinksNext')
.click(function(){
$('div#weekViewer').animate({scrollLeft: '+=450'}, 'slow');
return false;
});
});
});
function sortIntoWeekArrays(items)
{
var weeks = [];
// Returns single dimension array containing single dimension arrays
$(items).each(function(i, item)
{
var monday = new Date(item.dateadded * 1000);
monday.setDate(monday.getDate() - monday.getDay() + 1);
monday.setHours(0,0,0,0);
var week, thisWeek;
for (i in weeks)
{
week = weeks[i];
if(week.monday - monday == 0)
{
thisWeek = week;
break;
}
}
if(thisWeek === undefined)
{
thisWeek =
{
monday: monday,
images: []
};
weeks.push(thisWeek);
}
if($.inArray('winner', item.tags.split(" ")) > -1)
{
thisWeek.winner = item;
}
else
{
thisWeek.images.push(item);
}
});
return weeks.sort(function(first, second)
{
return (first.monday > second.monday) - (first.monday < second.monday);
});
}
Any help would be fantastic :)
Regards,
David
Worked it out after some help from a friend. I was missing the date_upload value in the extras argument and item.dateadded needed to change to item.upload.