Often times on an eCommerce or product information web site, you will need to display product images that your client's potential customers will be able click and zoom into. People typically prefer to view multiple images of a product prior to buying that product. This demo solves that problem using the following technologies:
ACME Landscaping Products have the finest gasses and hostas available!
View LargerLooking for succulents? Then look no further! We have the widest variety of succulents available.
View LargerI typically use Microsoft SQL Server for all of my client's databases, but you could really use any type of database, including mySQL, Oracle, Apache Derby, etc. This demo uses 3 tables: one for product information, one for product image information, and one for product categories.
Included below are details for each of these tables:
Create a Microsoft SQL Server ColdFusion datasource titled cubeportfolioCFDemo_RO in the ColdFusion Administrator. QuackIt has a good tutorial that describes how to do this at https://www.quackit.com/coldfusion/tutorial/coldfusion_datasource.cfm. This datasource should map to a user in your database that is in the db_datareader role (and no others). This account will just let ColdFusion read data from the database.
I know that most of us don't like ponying up cash for...well...anything code-related, but at $16.00 (as of June 5th, 2018) this is very much worth it. BUY THE PLUG-IN. It will save you a ton of time and it will make you look like a rock star. You can purchase a copy of the plug-in at https://codecanyon.net/item/cube-portfolio-responsive-jquery-grid-plugin/6372959.
Cube Portfolio is dependent upon jQuery to run. You can obtain code that references latest version of jQuery that is compatible with your web site or web application at https://code.jquery.com/. Add jQuery code similar to what is listed below just above the closing BODY tag.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
This folder in the Cube Portfolio download includes the css, js and img files you need to implement CubePortfolio. I typically put this folder in my assets folder off of the root of the web server share. Add a reference to the CSS in the HEAD section of your site and the JS code for Cube Portfolio below the code that refrences jQuery.
Add the CubePortfolio CSS code into the HEAD section
<link rel="stylesheet" type="text/css" href="/demos/cubePortfolio-ColdFusion-SQL/assets/cubeportfolio/css/cubeportfolio.min.css">
Add the following CubePortfolio code in a script block below the jQuery reference.
<script type="text/javascript" src="/demos/cubePortfolio-ColdFusion-SQL/assets/cubeportfolio/js/jquery.cubeportfolio.min.js"></script>
<script>
(function($, window, document, undefined) {
'use strict';
// init cubeportfolio
$('.grid-container').cubeportfolio({
layoutMode: 'slider',
defaultFilter: '*',
gapHorizontal: 10,
gapVertical: 10,
gridAdjustment: 'responsive',
caption: 'overlayBottomAlong',
displayType: 'bottomToTop',
displayTypeSpeed: 100,
showNavigation: false,
showPagination: false,
auto: true,
// lightbox
lightboxDelegate: '.cbp-lightbox',
lightboxGallery: true,
lightboxTitleSrc: 'data-title',
lightboxCounter: '<div class="cbp-popup-lightbox-counter">{{current}} of {{total}}</div>',
});
})(jQuery, window, document);
</script>
I typically keep the code to actually retrieve information from a database in method for a ColdFusion Component (CFC). In this example I have separate components Products and for Product Images: one titled ProductService.cfc, and the other titled ProductImageService.cfc. I store these in a components folder off of the root for the site, but depending upon the framework you might be using these would be stored in a separate location. I created these as "service" CFCs, because each of these extend functionality from existing CFCs for Products and Product Images (to be explained more in a future demo)
Create a ProductService.cfc with the following code and save it in your components folder
Create the ProductService.cfc by adding the following CubePortfolio code from script block below, then save it to your components folder.
<cfcomponent>
<cffunction name="getProductsByCategory" access="public" returntype="query" hint="This method returns products by category">
<cfargument name="CategoryId" type="numeric" required="yes" hint="This argument expects a numeric CategoryId">
<cfscript>
var gi = "";
</cfscript>
<cfquery datasource="cubeportfolioCFDemo_RO" name="gi">
SELECT *
FROM Product
WHERE CategoryId = <cfqueryparam cfsqltype="cf_sql_tinyint" value="#ARGUMENTS.CategoryId#">
ORDER BY Title
</cfquery>
<cfreturn gi>
</cffunction>
</cfcomponent>
Create the ProductImageService.cfc by adding the following CubePortfolio code from script block below, then save it to your components folder.
<cfcomponent>
<cffunction name="getImagesForCategory" access="public" returntype="query" hint="This method returns a query of images for a product category">
<cfargument name="CategoryId" type="numeric" required="yes" hint="This argument expects a numeric CategoryId">
<cfquery datasource="cubeportfolioCFDemo_RO" name="gi">
SELECT a.ProductId,
CASE WHEN a.Caption IS NOT NULL then a.Caption
ELSE b.Title
END AS Caption,
a.Thumbnail,
a.ThumbnailW,
a.ThumbnailH,
a.FullImage
FROM ProductImage a
INNER JOIN Product b ON a.ProductId = b.ProductId
INNER JOIN Category c ON b.CategoryId = c.CategoryId
WHERE b.CategoryId = <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#ARGUMENTS.CategoryId#">
AND a.IsVisible = 1
ORDER BY ProductId, DisplayOrder
</cfquery>
<cfreturn gi>
</cffunction>
</cfcomponent>
NOTE: I typically will store a reference to my service CFCs in the Application.cfc file as an Application variable, which makes it easier to reference on other parts of the site, but in this example, we will reference it locally.
Place the following code at the top of your ColdFusion Product page.
<cfscript>
// Identify the Category of Products to Retrieve
VARIABLES.CategoryId = 27;
// Get Product and Photo Data for the Product Category
VARIABLES.pi = CreateObject("component","demos.cubePortfolio-ColdFusion-SQL.components.ProductService").getProductsByCategory(VARIABLES.CategoryId);
VARIABLES.images = CreateObject("component","demos.cubePortfolio-ColdFusion-SQL.components.ProductImageService").getImagesForCategory(VARIABLES.CategoryId);
</cfscript>
Place the following code in the area of your Product page that you would like to display product and product image data.
<section id="livedemo" class="container" style="margin-bottom:40px;">
<div class="row">
<div class="col-xs-12">
<h2>Live Demo</h2>
<cfloop query="VARIABLES.pi">
<cfquery dbtype="query" name="VARIABLES.tpp">
SELECT *
FROM VARIABLES.images
WHERE ProductId = #ProductId#
</cfquery>
<cfscript>
VARIABLES.displayZoom = 0;
</cfscript>
<cfif VARIABLES.tpp.recordCount GT 0>
<cfloop query="VARIABLES.tpp" startrow="1" endrow="1">
<cftry>
<cfscript>
VARIABLES.thisImage = ExpandPath('\demos\cubePortfolio-ColdFusion-SQL\assets\productPhotos\') & fullimage;
</cfscript>
<cfimage source="#VARIABLES.thisImage#" name="VARIABLES.thisImage">
<cfscript>
VARIABLES.tiw = ImageGetWidth(VARIABLES.thisImage);
if (VARIABLES.tiw > 360) {
VARIABLES.displayZoom = 1;
}
</cfscript>
<cfcatch type="Any"></cfcatch>
</cftry>
</cfloop>
</cfif>
<div class="row" style="margin-bottom:20px;">
<div class="col-xs-12 col-sm-3" style="margin-bottom:20px;">
<cfif VARIABLES.tpp.recordCount GT 0>
<div class="grid-container cbp-slider">
<cfoutput query="VARIABLES.tpp">
<div class="cbp-slider-item cbp-item">
<a class="cbp-lightbox" data-title="#EncodeForHTMLAttribute(Caption)#" href="assets/productPhotos/#EncodeForHTMLAttribute(fullimage)#" data-cbp-lightbox="productLightbox#EncodeForHTMLAttribute(VARIABLES.pi.currentrow)#">
<img src="assets/productPhotos/#EncodeForHTMLAttribute(fullimage)#" class="img-responsive" alt="#EncodeForHTMLAttribute(Caption)#" width="100%">
</a>
</div>
</cfoutput>
</div>
<cfelse>
<div class="grid-container cbp-slider">
<div class="cbp-slider-item cbp-item">
<cfoutput>
<a class="cbp-lightbox" data-title="#EncodeForHTMLAttribute(Title)#" href="assets/productPhotos/ImageUnavailable.png" data-cbp-lightbox="productLightbox#EncodeForHTMLAttribute(VARIABLES.pi.currentrow)#">
<img src="assets/productPhotos/ImageUnavailable.png" class="img-responsive" alt="#EncodeForHTMLAttribute(Title)#" width="100%">
</a>
</cfoutput>
</div>
</div>
</cfif>
</div>
<div class="col-xs-12 col-sm-9" style="margin-bottom:20px;">
<cfoutput><h2 style="margin-top:0px;">#EncodeForHTML(Title)#</h2></cfoutput>
<cfoutput><p>#GetSafeHTML(Description)#</p></cfoutput>
<button type="button" class="btn btn-normal btnLearnMore btn-sm rounded"><span class="glyphicon glyphicon-leaf" style="margin-right:10px;"></span>Learn More</button>
<cfif VARIABLES.displayZoom EQ 1>
<cfoutput query="VARIABLES.tpp" maxrows="1">
<a class="cbp-lightbox btn btn-normal btn-sm rounded" data-title="#EncodeForHTMLAttribute(Caption)#" href="assets/productPhotos/#EncodeForHTMLAttribute(fullimage)#" data-cbp-lightbox="productLightbox#EncodeForHTMLAttribute(VARIABLES.pi.currentrow)#"><span class="glyphicon glyphicon-zoom-in" style="margin-right:10px;"></span> View Larger</a>
</cfoutput>
</cfif>
</div>
</div>
</cfloop>
</div>
</div>
</section>