I am designing a website for a company that manages buildings/real estate. I did not have much use for a CSS library like Bootstrap or Foundation, except on one page of the website. This page contains a list of selected buildings. When a user clicks on the name of a building, the building's information appears and images of the building appear in a Bootstrap image carousel. I used AJAX to GET the images of a property and then prototyped an object for each property on the list-- easy way to replace the text on-screen.
Below is the JavaScript & jQuery code that makes this happen:
//for bootstrap carousel
$('.carousel').carousel();
//stores the building currently displayed, for swap function below.
var currentBuilding;
//constructor for Building
function Building(title, background, story, images, stats){
this.title = title;
this.background = background;
this.story = story;
//images references directory where this building's images are located:
this.images = images;
this.stats = stats;
}
//example object
var azusa = new Building(
"Azusa, CA",
"The company purchased a building in 2006 with a 20-year loan at 2% interest.",
"The lot used to be the site of a mini-mall with tenants such as McDonalds and Costco",
"azusa-california",
"10,000 sqft");
//bind to onclick for list items. Given a Building (e.g. azusa above),
//place the most recently clicked Building's information on the page.
function swap(building){
event.preventDefault();
if(currentBuilding != building) {
currentBuilding = building;
$("h3:first").fadeOut(400,function(){
$("h3:first").html(building.title);
$("h3:first").fadeIn(400,function(){});
});
$("#background p:first").fadeOut(400,function(){
$("#background p:first").html(building.background);
$("#background p:first").fadeIn(400,function(){});
});
$('#carousel-container').fadeOut(400,function(){
grabImages(building.images); //see function below
$('#carousel-container').fadeIn(400,function(){});
});
$("#story p:first").fadeOut(400,function(){
$("#story p:first").html(building.story);
$("#story p:first").fadeIn(400,function(){});
});
$("#stats p:first").fadeOut(400,function(){
$("#stats p:first").html(building.stats);
$("#stats p:first").fadeIn(400,function(){});
});
}
}
function grabImages(folder){
var dir = "img/selected-buildings-slides/"+folder;
var fileextension = ".jpg";
$.ajax({
//This will retrieve the contents of the folder if the folder is configured as 'browsable'
url: dir,
type: "GET",
success: function (data) {
var nth = 0;
var active=" active";
$('.carousel-inner').html("");
//Lsit all png file names in the page
$(data).find("a:contains(" + fileextension + ")").each(function () {
if(nth>0){
$('.carousel-indicators').append("<li data-target='#property-carousel' data-slide-to='"+nth+"'></li>")
active=""
}
else{
$('.carousel-indicators').html("<li class='active' data-target='#property-carousel' data-slide-to='0'></li>");
}
var filename = this.href.replace(window.location.host, "").replace("http://", "");
$('.carousel-inner').append("<div class='item"+active+"'> <img src ='"+dir+filename+"' alt='property photo'></div>");
nth++;
});
}
});
}
Now, I am sure you are looking at that grabImages()
function and cringing. I know it looks messy, but it works. Really I am looking to see if there is a way to sidestep AJAX without having to reference the explicit path to each individual image, because the image files have arbitrary names.
Also, if there is a way to wait for the images to fully load in grabImages()
before displaying them, that would be cool too.
-
1\$\begingroup\$ I can't see what's kicking this all off. What is calling swap? \$\endgroup\$Jivings– Jivings2014年04月16日 17:55:06 +00:00Commented Apr 16, 2014 at 17:55
-
\$\begingroup\$ i did the binding in the HTML, sorry! just an <a href="#" onclick="swap(azusa)"> tag \$\endgroup\$user3267289– user32672892014年04月16日 18:55:40 +00:00Commented Apr 16, 2014 at 18:55
1 Answer 1
Let's start by removing that inline JS call. Let's use the href
to indicate the building. We'll remove the hash later. We also add a class to find these links to attach event handlers:
<a href="#azusa" class="swap-trigger">Azusa</a>
As for the script:
;(function ($) {
// Cache the fetched elements. Unless they are dynamic, they're better off fetched
// once and reused rather than fetching them from the DOM every function call.
var header = $("h3:first");
var background = $("#background p:first");
var carouselContainer = $('#carousel-container');
var story = $("#story p:first");
var stats = $("#stats p:first");
var carousel = $('.carousel').carousel();
var carouselInner = $('.carousel-inner');
var carouselIndicators = $('.carousel-indicators');
var fileextension = ".jpg";
// We store building data here in a hash. The key will match the href that we placed
// in the links.
var buildings = {
'azusa': {
title: 'Azusa, CA',
background: 'The company purchased a building in 2006 with a 20-year loan at 2% interest.',
story: 'The lot used to be the site of a mini-mall with tenants such as McDonalds and Costco',
images: 'azusa-california',
stats: '10,000 sqft'
},
...
};
// Now we attach a click handler to the links
$('.swap-trigger').on('click', function (event) {
event.preventDefault();
var building = $(this).attr('href').slice(1); //chop of the hash
swap(building);
});
// Your swap function
function swap(building) {
// We can store state data into the element itself using .data()
// That way, we avoid creating a variable for it. The data is saved in the
// respective element.
var currentBuilding = carousel.data('currentBuilding');
if (currentBuilding === building) return;
carousel.data('currentBuilding', currentBuilding);
// Using the cached elements
header.fadeOut(400, function () {
header.html(building.title).fadeIn(400)
});
background.fadeOut(400, function () {
background.html(building.background).fadeIn(400)
});
carouselContainer.fadeOut(400, function () {
grabImages(building.images);
carouselContainer.fadeIn(400)
});
story.fadeOut(400, function () {
story.html(building.story).fadeIn(400)
});
stats.fadeOut(400, function () {
stats.html(building.stats).fadeIn(400)
})
}
function grabImages(folder) {
var dir = "img/selected-buildings-slides/" + folder;
// Shorthand AJAX GET
$.get(dir, function (data) {
var active = " active";
carouselInner.html('');
$(data).find("a:contains(" + fileextension + ")").each(function (index,element) {
//nth was of no use since .each() provides an index on every iteration.
if (index === 0) {
carouselIndicators.html("<li class='active' data-target='#property-carousel' data-slide-to='0'></li>");
} else {
carouselIndicators.append("<li data-target='#property-carousel' data-slide-to='" + index + "'></li>");
active = "";
}
var filename = this.href.replace(window.location.host, "").replace("http://", "");
carouselInner.append("<div class='item" + active + "'> <img src ='" + dir + filename + "' alt='property photo'></div>");
});
// jQuery sometimes fails to parse correctly, so we make sure
}, 'html');
}
}(jQuery));
Can't verify if this actually works, but the mentioned changes should help the code. Also, I can see that the code you have only works for a single link-carousel combination. If there were more than one, then I can sense that it will break. Consider scenarios where there's more than one set.
Explore related questions
See similar questions with these tags.