
/* Plugin Widgets */ /* +++++++++++++++++++++++++++++++++++++++++++ */ // Plugin for slider control (widgetSlider) (function() { jQuery.widgetSlider = function(settings) { // define defaults and override with options, if available // by extending the default settings, we don't modify the argument settings = jQuery.extend({ viewport: "#widget-slider-viewport", content: "#widget-slider-content", next: "#widget-slider-next", prev: "#widget-slider-prev", item: "div", direction: "vertical", showAmount: 3 }, settings); //if slider exists exist if ( jQuery(settings.viewport).size() > 0 ) { //setup the buttons. jQuery(settings.next).hide().attr("href","#nextItem"); jQuery(settings.prev).hide().attr("href","#prevItem"); if( jQuery(settings.item).size() > settings.showAmount ) { jQuery(settings.next).show(); } if( settings.direction == "vertical" ) {} else { //setup the vars. sliderInfo = new Object(); sliderInfo.start = 0; sliderInfo.end = (jQuery(settings.item).size() - settings.showAmount) * jQuery(settings.item).eq(0).width() * -1; sliderInfo.itemSize = jQuery(settings.item).eq(0).width(); sliderInfo.left = 0; //setup the events for navigation prevButton(settings.prev,settings); nextButton(settings.next,settings); } } }; prevButton = function(prevObj,settings) { $(prevObj).unbind("click"); setTimeout(function() { $(prevObj).click(function(evt) { evt.preventDefault(); sliderInfo.left = parseInt(jQuery(settings.content).css("left").split("px")[0]) + sliderInfo.itemSize; jQuery(settings.content).animate( { left:sliderInfo.left+"px"}, 350 ); if( sliderInfo.left != sliderInfo.end ) { jQuery(settings.next).show(); } if( sliderInfo.left == 0 ) { jQuery(settings.prev).hide(); } prevButton(prevObj,settings); }); }, 351); }; nextButton = function(nextObj,settings) { $(nextObj).unbind("click"); setTimeout(function() { $(nextObj).click(function(evt) { evt.preventDefault(); sliderInfo.left = parseInt(jQuery(settings.content).css("left").split("px")[0]) - sliderInfo.itemSize; jQuery(settings.content).animate( { left:sliderInfo.left+"px"}, 350 ); if( sliderInfo.left == sliderInfo.end ) { jQuery(settings.next).hide(); } if( sliderInfo.left != 0 ) { jQuery(settings.prev).show(); } nextButton(nextObj,settings); }); }, 351); }; })(jQuery); /* ----------------------------------------- */ /* make 2 containers equal */ (function() { jQuery.fn.widgetEqualHeight = function(settings) { settings = jQuery.extend({ toHeight: "#box1" }, settings); return this.each(function(){ if( jQuery(settings.toHeight).size() > 0 ) { jQuery(this).height( jQuery(settings.toHeight).height() ); } }); }; })(jQuery); /* ------------------------------------------ */ /* button widget for buttons with hover states. */ (function() { jQuery.fn.widgetButton = function(settings) { settings = jQuery.extend({ off: "but-off.gif", on: "but-on.gif", hover: "but-hover.gif", hasClick: 0, hasHover: 1, activeId: "but-active", cssButton: 0, cssOff: "glo-but-css-off", cssOn: "glo-but-css-on", cssHover: "glo-but-css-hover", buttonSelector: ".but-class" }, settings); return this.each(function() { if(settings.cssButton) { if( jQuery(this).attr("id") != settings.activeId ) { jQuery(this).addClass(settings.cssOff);} else { jQuery(this).addClass(settings.cssOn); } if(settings.hasHover) { jQuery(this).mouseover(function() { if( jQuery(this).attr("id") != settings.activeId ) { jQuery(this).removeClass(settings.cssOff); jQuery(this).addClass(settings.cssHover); } }); jQuery(this).mouseout(function() { if( jQuery(this).attr("id") != settings.activeId ) { jQuery(this).removeClass(settings.cssHover); jQuery(this).addClass(settings.cssOff); } }); } if(settings.hasClick) { jQuery(this).click(function() { if( jQuery(this).attr("id") != settings.activeId ) { jQuery(settings.buttonSelector).attr("id",""); jQuery(settings.buttonSelector).removeClass(settings.cssHover); jQuery(settings.buttonSelector).removeClass(settings.cssOn); jQuery(this).addClass(settings.cssOn); jQuery(this).attr("id",settings.activeId); } }); } } else { preload(settings.off); // always have the mouseout jQuery(this).mouseout(function() { if( jQuery(this).attr("id") != settings.activeId ) { jQuery(this).attr("src",settings.off); } }); if(settings.hasHover) { preload(settings.hover); jQuery(this).mouseover(function() { if( jQuery(this).attr("id") != settings.activeId ) { jQuery(this).attr("src",settings.hover); } }); } if(settings.hasClick) { preload(settings.on); jQuery(this).click(function() { if( jQuery(this).attr("id") != settings.activeId ) { jQuery(settings.buttonSelector).attr("id",""); jQuery(settings.buttonSelector).mouseout(); jQuery(this).attr("src",settings.on); jQuery(this).attr("id",settings.activeId); } }); } } }); }; function preload(path) { var temp = new Image(); temp.src=path; }; })(jQuery); /* ------------------ */ /* ++++++++++++++++++++++++++++++++++++++++++++ */ // Global Variables (bad) var resizingWidthWindow = 0; // set the express js library, built ontop of Jquery var exp = window.exp = function($) { return { input : { defaultText : function(selector, defaultText) { return $(selector).each(function(){ $(this).focus( function() { if( $(this).val() == defaultText ) { $(this).val(""); } }); $(this).blur(function() { $(this).val( exp.utils.strTrim($(this).val()) ); if( $(this).val() == "" ) { $(this).val( defaultText ); } }); $(this).blur(); }); } }, image : { preload : function(images) { var tImageArr = []; var tImages = images.split(","); $(tImages).each(function(i) { tImageArr[i] = new Image(); tImageArr[i].src = tImages[i]; }); }, rotateImages : function(settings) { exp.image.preload( settings.images ); images = settings.images.split(","); imagesAlt = settings.imagesAlt.split(","); imageIndex = 0; setInterval(function() { $(settings.selector).attr("src", images[imageIndex]); $(settings.selector).attr("alt", imagesAlt[imageIndex]); imageIndex++; if( imageIndex == images.length ) { imageIndex = 0; } }, settings.interval); } }, layer : { setup : function(selector, close) { exp.layer.vCenter(selector); $(close).unbind("click").click(function() { exp.layer.close(selector); }); if( exp.utils.isIE6() ) { exp.utils.iframeFix.add(selector); } }, close : function(selector) { $(selector).remove(); if( exp.utils.isIE6() ) { exp.utils.iframeFix.remove(selector); } }, vCenter : function(selector) { var windowOffsets = exp.utils.getViewportPosition(); var windowViewport = exp.utils.getViewportSize(); var top = ((windowViewport[1] / 2) - ($(selector).height() / 2)) + windowOffsets[1]; top = (top < 0) ? 100 : top; $(selector).css("top",top+"px"); } }, utils: { isIE6 : function() { if( $.browser.msie && (parseFloat($.browser.version) < 7)) { return true;} return false; }, jsLink : function(selector) { $(selector).attr("href","#jsLink"); $(selector).click(function(evt) { evt.preventDefault(); }); }, popupLink : function(selector, settings) { settings = jQuery.extend({ width: 500, height: 500, toolbar: 0, menubar: 0, location: 0, directories: 0, status: 0, scrollbars: 0, resizable: 0, name: "Popup_Window" }, settings); return $(selector).each(function() { this.url = jQuery(this).attr("href"); this.features = "toolbar=" + settings.toolbar + ","; this.features += "menubar=" + settings.menubar + ","; this.features += "location=" + settings.location + ","; this.features += "directories=" + settings.directories + ","; this.features += "status=" + settings.status + ","; this.features += "scrollbars=" + settings.scrollbars + ","; this.features += "resizable=" + settings.resizable; $(this).click(function(evt) { evt.preventDefault(); var newWindow = window.open(this.url, settings.name, 'width=' + settings.width + ',height=' + settings.height + ',"' + this.features + '"'); newWindow.focus(); }); }); }, iframeFix : { add : function(selector) { exp.utils.iframeFix.remove(selector); iframeID = selector.split("#")[1] + "-iframe"; iframeHTML = '
' $("body").append(iframeHTML); $("#" + iframeID).css("position", "absolute"); $("#" + iframeID).css("top", $(selector).css("top")); $("#" + iframeID).css("left", $(selector).css("left")); $("#" + iframeID).css("margin-top", $(selector).css("margin-top")); $("#" + iframeID).css("margin-right", $(selector).css("margin-right")); $("#" + iframeID).css("margin-bottom", $(selector).css("margin-bottom")); $("#" + iframeID).css("margin-left", $(selector).css("margin-left")); $("#" + iframeID).css("height", $(selector).height() + "px" ); $("#" + iframeID).css("width", $(selector).width() + "px" ); $("#" + iframeID).css("z-index", $(selector).css("z-index") - 1); }, remove : function(selector) { $(selector + "-iframe").remove(); } }, getViewportPosition : function() { var scrOfX = 0, scrOfY = 0; if( typeof( window.pageYOffset ) == 'number' ) { //Netscape compliant scrOfY = window.pageYOffset; scrOfX = window.pageXOffset; } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) { //DOM compliant scrOfY = document.body.scrollTop; scrOfX = document.body.scrollLeft; } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) { //IE6 standards compliant mode scrOfY = document.documentElement.scrollTop; scrOfX = document.documentElement.scrollLeft; } return [ scrOfX, scrOfY ]; }, getViewportSize : function() { var vpW = 0, vpH = 0; if (typeof window.innerWidth != 'undefined') { vpW = window.innerWidth, vpH = window.innerHeight } else if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth != 'undefined' && document.documentElement.clientWidth != 0) { vpW = document.documentElement.clientWidth, vpH = document.documentElement.clientHeight } else { vpW = document.getElementsByTagName('body')[0].clientWidth, vpH = document.getElementsByTagName('body')[0].clientHeight } return [ vpW, vpH ]; }, strTrim : function(s) { while (s.substring(0,1) == ' ') { s = s.substring(1, s.length); } while (s.substring(s.length-1, s.length) == ' ') { s = s.substring(0, s.length-1); } return s; } }, func : { sizeChartLayerSetup : function(selector, close, locX, locY) { $(selector).css("margin-left", locX+"px").css("top", locY+"px"); $(close).unbind("click").click(function() { exp.layer.close(selector); }); if( exp.utils.isIE6() ) { exp.utils.iframeFix.add(selector); } }, sizeChartSetup : function(selector) { var sizeChart = []; $(selector).each(function(i) { sizeChart[sizeChart.length] = $(this).attr("href"); $(this).click(function(evt) { evt.preventDefault(); $("#cat-sizechart").remove(); var htmlContainer = '
';
$(".widget-app-quickview").each(function() {
$(this).parent().parent().css("position","relative");
$(this).mouseover(function() {
if( typeof qTimer != undefined )
{
clearTimeout(qTimer);
$("#widget-quickview-but").parent().remove();
}
$(this).parent().parent().append(imgHTML);
$("#widget-quickview-but").css("position","absolute");
$("#widget-quickview-but").css("left", "10px");
qTop = $(".widget-app-quickview", $("#widget-quickview-but").parent().parent()).height() - $("#widget-quickview-but").height() - 2 - 10;
$("#widget-quickview-but").css("top", qTop+"px");
$("#widget-quickview-but").widgetButton({
cssButton: 1,
cssOff: "glo-but-css-off2",
cssHover: "glo-but-css-hover2"
});
$("#widget-quickview-but").mouseover(function() {
if(typeof qTimer != undefined)
{ clearTimeout(qTimer); }
});
$("#widget-quickview-but").parent().click(function(ev) {
type = $(this).parent().attr("id").split("-")[0];
id = $(this).parent().attr("id").split("-")[1];
if( type == "p" )
{ params = "productId="+id;}
else
{ params = "ensembleId="+id; }
//if on basket page
if ( $(".che-bas-also-like-item").size() > 0 )
{ params = params + "&onBasketPage=1"; }
loadQuickView(params, $("body"));
});
exp.utils.jsLink( $("#widget-quickview-but").parent() );
});
$(this).mouseout(function() {
qTimer = setTimeout(function() { $("#widget-quickview-but").parent().remove(); }, 100);
});
});
})
}(),
setupQuickview2 : function() {
$(function() {
//quickview.
$(".widget-quickview-but2").each(function() {
$(this).parent().click(function() {
type = $(this).attr("id").split("-")[0];
id = $(this).attr("id").split("-")[1];
if( type == "p" )
{ params = "productId="+id;}
else
{ params = "ensembleId="+id; }
//if on basket page
if ( $(".che-bas-also-like-item").size() > 0 )
{ params = params + "&onBasketPage=1"; }
loadQuickView(params, $("body"));
});
$(this).widgetButton({
cssButton: 1,
cssOff: "glo-but-css-off2",
cssHover: "glo-but-css-hover2"
});
exp.utils.jsLink( $(this).parent() );
});
});
}(),
setupRecentlyViewed : function() {
// on load
$(function() {
var recentlyViewedTimer;
$("#glo-recently-viewed-cont #glo-recently-viewed-products-cont").bind("mouseover.recently_viewed",function(evt){
if( $(evt.target).is("img") )
{
if( typeof recentlyViewedTimer != "undefined")
{ clearTimeout(recentlyViewedTimer); }
$("#glo-recently-viewed-cont #glo-recently-viewed-products-cont img").addClass("hover");
$(evt.target).removeClass("hover");
nameStr = $(evt.target).attr("alt");
if( nameStr.length > 15 )
{
nameStr = nameStr.substring(0,15);
nameStr += "...";
}
$("#glo-recently-viewed-prod-name").html( nameStr );
$("#glo-recently-viewed-prod-name").css("visibility","visible");
}
});
$("#glo-recently-viewed-cont #glo-recently-viewed-products-cont").bind("mouseout.recently_viewed",function(evt){
if( $(evt.target).is("img") )
{
if( typeof recentlyViewedTimer != "undefined")
{ clearTimeout(recentlyViewedTimer); }
recentlyViewedTimer = setTimeout( function() {
$("#glo-recently-viewed-cont #glo-recently-viewed-products-cont img").removeClass("hover");
$("#glo-recently-viewed-prod-name").css("visibility","hidden");
}, 50 );
}
});
});
}(),
setupGlobalNav : function() {
// onload
$(function() {
globalNav_setup();
});
}()
}
};
}(jQuery)
function pageResize_noflash(withWidth) {
if(withWidth)
{
w = ($("body").width() - 110) < 950 ? 950 : ($("body").width() - 110);
$("#glo-container").width(w);
resizingWidthWindow = 1;
}
wContent = $("#glo-body-leftnav").size() > 0 ? $("#glo-body-container").width() - $("#glo-body-leftnav").width() : $("#glo-body-container").width();
$("#glo-body-content").width( wContent );
};
function pageResize_flash() {
resizingWidthWindow = 1;
w = ($("body").width() - 110) < 950 ? 950 : ($("body").width() - 110);
$("#glo-container").width(w);
resizingWidthWindow = 1;
wContent = $("#glo-body-leftnav").size() > 0 ? $("#glo-body-container").width() - $("#glo-body-leftnav").width() : $("#glo-body-container").width();
$("#glo-body-content").width( wContent );
if( $("#movie").size() > 0 )
{ flashResize(wContent); }
};
function flashResize(w) {
if($.browser.msie)
{ document.movie.sendToFlash(w); }
else
{ window.document["movie"].sendToFlash(w); }
};
function globalNav_setup() {
var ucartTimer;
// Universal Cart Button setup
$("#widget-ucart-but").hover(function(ev) {
if( !ucartActive ) { ucartTimer = setTimeout(function() { showBasket('show',''); }, 500); }
},function(ev) {
if( typeof ucartTimer != undefined ) { clearTimeout(ucartTimer); }
});
// events for search box.
exp.input.defaultText("#glo-header-search-component-input", "keyword or style #");
$("#searchForm").submit(function() {
searchVal = $("#glo-header-search-component-input").val();
if( (searchVal == "keyword or style #") || (searchVal == "") )
{
alert("Please enter a search term and try your search again");
return false;
}
});
//setup the express radio but
$("#glo-header-express-radio img").widgetButton({
off: "/assets/images/tex/tex-header-express-radio.gif",
hover: "/assets/images/tex/tex-header-express-radio-hover.gif"
});
//setup the express tabs
$(".glo-header-tab-span").each(function(i) {
if( i == 0 ) //whats new
{
offPath = "/assets/images/tex/tex-header-whats-new.gif";
hoverPath = "/assets/images/tex/tex-header-whats-new-hover.gif";
}
if( i == 1 ) // for her
{
offPath = "/assets/images/tex/tex-header-for-her.gif";
hoverPath = "/assets/images/tex/tex-header-for-her-hover.gif";
}
if( i == 2 ) // for him
{
offPath = "/assets/images/tex/tex-header-for-him.gif";
hoverPath = "/assets/images/tex/tex-header-for-him-hover.gif";
}
if( i == 3 ) // sale
{
offPath = "/assets/images/tex/tex-header-sale.gif";
hoverPath = "/assets/images/tex/tex-header-sale-hover.gif";
}
$("img",this).widgetButton({
off: offPath,
hover: hoverPath,
activeId: "widget-header-active-tab",
buttonSelector: "#glo-header-tab-span img"
});
});
$(".glo-header-link-span").each(function(i) {
if( i == 2 )
{
if( $("img", this).attr("class") == "widget-sign-out" )
{
onPath = "/assets/images/tex/tex-header-sign-out-active.gif";
offPath = "/assets/images/tex/tex-header-sign-out.gif";
hoverPath = "/assets/images/tex/tex-header-sign-out-hover.gif";
}
else
{
onPath = "/assets/images/tex/tex-header-sign-in-active.gif";
offPath = "/assets/images/tex/tex-header-sign-in.gif";
hoverPath = "/assets/images/tex/tex-header-sign-in-hover.gif";
}
}
//else if( i == 2 )
//{
// onPath = "/assets/images/tex/tex-header-gift-cards-active.gif";
// offPath = "/assets/images/tex/tex-header-gift-cards.gif";
// hoverPath = "/assets/images/tex/tex-header-gift-cards-hover.gif";
//}
else if( i == 1 )
{
onPath = "/assets/images/tex/tex-header-my-account-active.gif";
offPath = "/assets/images/tex/tex-header-my-account.gif";
hoverPath = "/assets/images/tex/tex-header-my-account-hover.gif";
}
else if( i == 0 )
{
onPath = "/assets/images/tex/tex-header-shopping-bag-active.gif";
offPath = "/assets/images/tex/tex-header-shopping-bag.gif";
hoverPath = "/assets/images/tex/tex-header-shopping-bag-hover.gif";
}
$("img",this).widgetButton({
on: onPath,
off: offPath,
hover: hoverPath,
hasClick: 1,
activeId: "widget-header-active-link",
buttonSelector: "#glo-header-link-span img"
});
});
//setup the footer navigation.
$("#glo-footer-nav-cont1 img").each(function(i) {
if( i == 0 )
{
onPath = "/assets/images/tex/tex-footer-help-active.gif";
offPath = "/assets/images/tex/tex-footer-help.gif";
hoverPath = "/assets/images/tex/tex-footer-help-hover.gif";
}
else if( i == 1 )
{
offPath = "/assets/images/tex/tex-footer-gift-cards.gif";
hoverPath = "/assets/images/tex/tex-footer-gift-cards-hover.gif";
}
else if( i == 2 )
{
offPath = "/assets/images/tex/tex-footer-club-express.gif";
hoverPath = "/assets/images/tex/tex-footer-club-express-hover.gif";
}
else if( i == 3 )
{
offPath = "/assets/images/tex/tex-footer-email-signup.gif";
hoverPath = "/assets/images/tex/tex-footer-email-signup-hover.gif";
}
else if( i == 4 )
{
offPath = "/assets/images/tex/tex-footer-store-locator.gif";
hoverPath = "/assets/images/tex/tex-footer-store-locator-hover.gif";
}
else if( i == 5 )
{
offPath = "/assets/images/tex/tex-footer-contactus.gif";
hoverPath = "/assets/images/tex/tex-footer-contactus-hover.gif";
}
else if( i == 6 )
{
offPath = "/assets/images/tex/tex-footer-order-status.gif";
hoverPath = "/assets/images/tex/tex-footer-order-status-hover.gif";
}
if( i == 0)
{
$(this).widgetButton({
on: onPath,
off: offPath,
hover: hoverPath,
hasClick: 1,
activeId: "widget-footer-active-link",
buttonSelector: "#glo-footer-nav-cont .glo-fl"
});
}
else
{
$(this).widgetButton({
off: offPath,
hover: hoverPath,
buttonSelector: "#glo-footer-nav-cont .glo-fl"
});
}
});
// popup links in footer
exp.utils.popupLink("#glo-footer-nav-cont2 .widget-popup-window", {
width: 485,
height: 660,
scrollbars: 1
});
// popup link for shipping info
exp.utils.popupLink("#use-ship-info-link .widget-popup-window", {
width: 485,
height: 605,
scrollbars: 0
});
// Express Radio Pop-up
exp.utils.popupLink("#glo-header-express-radio .widget-popup-window",{
width: 504,
height: 219,
scrollbars: 0,
name: "Express_Radio"
});
};
/* OCP FRAMEWORK FILES */
/* +++++++++++++++++++++++++++++++++++++++++++++ */
//---------------------------------------------
// OCP Framework
// Corresponding Javascript Object Lib
//
// Convention: __[name] == private variable or
// method of class.
//---------------------------------------------
// Product variant attribute object
function VariantAttribute(attribName, attribValue, /*optional*/ variant)
{
// Store name and value pair
this.name = attribName.toUpperCase();
this.value = attribValue;
this.matched = false;
// This is the variant that this
// attribute belongs to
if (arguments.length == 3)
this.__variant = variant;
else
this.__variant = null;
}
function varattr_getVariant()
{
return this.__variant;
}
function varattr_equals(attrib)
{
return ((this.name == attrib.name) && (this.value == attrib.value));
}
VariantAttribute.prototype.getVariant = varattr_getVariant;
VariantAttribute.prototype.equals = varattr_equals;
//----------------------------------------------------------------------------------
// Product variant
function Variant(/*optional*/ prodVarGroup)
{
// This will be the VariantAttribute(s)
// for a product
this.__attributes = new Array();
// This is the unique ID for this variant
this.__id = null;
// When editing an item, this will be set to true
// if this is the variant that was selected
this.__selected = false;
// The product variant group object
// this variant belongs to
if (arguments.length == 1)
this.__productVariantGroup = prodVarGroup;
else
this.__productVariantGroup = null;
}
function variant_setSelected()
{
this.__selected = true;
}
function variant_isSelected()
{
return this.__selected;
}
function variant_getAttribute(attrib_1)
{
// If they pass a string, it must be an attribute name
// otherwise it's an index. In the first case, return
// the value. For the second, return the entire attribute.
if (typeof attrib_1 == "string")
{
for (var idx = 0; idx < this.__attributes.length; idx++)
if (attrib_1.toUpperCase() == this.__attributes[idx].name)
return this.__attributes[idx];
}
else if ((typeof attrib_1 == "number") &&
(attrib_1 >= 0 && attrib_1 < this.__attributes.length))
return this.__attributes[attrib_1];
// If we didn't find an attribute
// just return null
return null;
}
function variant_getAllAttributes()
{
return this.__attributes;
}
function variant_getAttributeValue(attribName)
{
var attrib = this.getAttribute(attribName);
if (attrib != null)
return attrib.value;
else
return undefined;
}
function variant_addAttribute(attribName, attribValue)
{
// We only set attributes that don't exist
if (this.getAttribute(attribName) == null)
this.__attributes[this.__attributes.length] = new VariantAttribute(attribName, attribValue, this);
else
{
// Throw an exception
var err = new Error("Attribute " + attribName + " already exists in Variant");
throw err;
}
}
function variant_size()
{
return this.__attributes.length;
}
function variant_setId(varID)
{
this.__id = varID;
}
function variant_getId()
{
return this.__id;
}
function variant_equals(variant)
{
function keyMatch(keyArr, key)
{
for (var z = 0; z < keyArr.length; z++)
if (keyArr[z] == key)
return true;
return false;
}
var matchKeys = new Array();
var matchSize = this.__attributes.length;
for (var x = 0; x < this.size(); x++)
for (var y = 0; y < variant.size(); y++)
if (this.getAttribute(x).equals(variant.getAttribute(y)) && !keyMatch(matchKeys, this.getAttribute(x).name))
matchKeys[matchKeys.length] = this.getAttribute(x).name;
return (matchKeys.length == this.__attributes.length);
}
function variant_getProductVariantGroup()
{
return this.__productVariantGroup;
}
Variant.prototype.setSelected = variant_setSelected;
Variant.prototype.isSelected = variant_isSelected;
Variant.prototype.getAttribute = variant_getAttribute;
Variant.prototype.getAllAttributes = variant_getAllAttributes;
Variant.prototype.addAttribute = variant_addAttribute;
Variant.prototype.getAttributeValue = variant_getAttributeValue;
Variant.prototype.setId = variant_setId;
Variant.prototype.getId = variant_getId;
Variant.prototype.size = variant_size;
Variant.prototype.equals = variant_equals;
Variant.prototype.getProductVariantGroup = variant_getProductVariantGroup;
//----------------------------------------------------------------------------------
// Product variant grouping
function ProductVariantGroup()
{
this.__variants = new Array();
this.__formField = null;
this.__variantGroup = null;
}
function pvgroup_setVariantGroup(variantGroupList)
{
this.__variantGroup = variantGroupList.split(",");
}
function pvgroup_getVariantGroup()
{
return this.__variantGroup;
}
function pvgroup_setFormField(fieldName)
{
this.__formField = fieldName;
}
function pvgroup_getFormField()
{
return this.__formField;
}
function pvgroup_getVariant(arg1)
{
if (typeof arg1 == "number")
{
// Find variant by index number
if (arg1 >= 0 && arg1 < this.__variants.length)
return this.__variants[arg1];
else
return null;
}
else if (typeof arg1 == "object") // We're in control, so we'll assume Array...
{
// Find variant by attribute combination
var vTest = new Variant();
for (var x = 0; x < arg1.length; x++)
vTest.addAttribute(arg1[x].name, arg1[x].value);
return this.variantExists(vTest);
}
}
function pvgroup_getAllVariants()
{
return this.__variants;
}
function pvgroup_variantExists(variant)
{
// See if we already have this variant
for (var idx = 0; idx < this.__variants.length; idx++)
{
var v = this.getVariant(idx);
if (v != null)
if (v.equals(variant))
return v;
}
return null;
}
function pvgroup_addVariant(variant)
{
// Add the variant as long as it doesn't
// already exist for this product
if (this.variantExists(variant) == null && variant instanceof Variant)
{
// Assign the productVariantGroup back to the variant
// so the end user can access it.
variant.__productVariantGroup = this;
// Store the variant
this.__variants[this.__variants.length] = variant;
}
else if (!variant instanceof Variant)
{
// Throw an exception
var err = new Error("Cannot add objects not of type Variant to ProductVariantGroup");
throw err;
}
}
function pvgroup_getAttributesWithName(attrName)
{
function isInList(arAttribs, attrValue)
{
for (var idx = 0; idx < arAttribs.length; idx++)
if (arAttribs[idx].value == attrValue)
return true;
return false;
}
var matchingAttributes = new Array();
for (var idx=0; idx < this.__variants.length; idx++)
if (!isInList(matchingAttributes, this.__variants[idx].getAttributeValue(attrName)))
matchingAttributes[matchingAttributes.length] = this.__variants[idx].getAttribute(attrName);
return matchingAttributes;
}
function pvgroup_getVariantsMatching(attrName, attrValue)
{
var matchingVariants = new Array();
// Find every variant that contains the
// matching attribute name/value pair
for (var idx = 0; idx < this.__variants.length; idx++)
if (this.__variants[idx].getAttribute(attrName).value != null &&
this.__variants[idx].getAttribute(attrName).value == attrValue)
matchingVariants[matchingVariants.length] = this.__variants[idx];
// return the matching variants array
return matchingVariants;
}
function pvgroup_getSelectedVariant()
{
for (var idx = 0; idx < this.__variants.length; idx++)
if (this.__variants[idx].isSelected())
return this.__variants[idx];
// Nothing is selected
return null;
}
function pvgroup_size()
{
return this.__variants.length;
}
ProductVariantGroup.prototype.getFormField = pvgroup_getFormField;
ProductVariantGroup.prototype.setFormField = pvgroup_setFormField;
ProductVariantGroup.prototype.getVariant = pvgroup_getVariant;
ProductVariantGroup.prototype.getAllVariants = pvgroup_getAllVariants;
ProductVariantGroup.prototype.variantExists = pvgroup_variantExists;
ProductVariantGroup.prototype.addVariant = pvgroup_addVariant;
ProductVariantGroup.prototype.getVariantsMatching = pvgroup_getVariantsMatching;
ProductVariantGroup.prototype.getSelectedVariant = pvgroup_getSelectedVariant;
ProductVariantGroup.prototype.getAttributesWithName = pvgroup_getAttributesWithName;
ProductVariantGroup.prototype.getVariantGroup = pvgroup_getVariantGroup;
ProductVariantGroup.prototype.setVariantGroup = pvgroup_setVariantGroup;
ProductVariantGroup.prototype.size = pvgroup_size;
//----------------------------------------------------------------------------------
// HELPER METHODS
// Returns an array of unique VariantAttribute objects from
// an array of Variant objects
function getAttributesWithNameFromVariants(varArray, attrName)
{
function isInList(arAttribs, attrValue)
{
for (var idx = 0; idx < arAttribs.length; idx++)
if (arAttribs[idx].value == attrValue)
return true;
return false;
}
var matchingAttributes = new Array();
for (var idx=0; idx < varArray.length; idx++)
if (!isInList(matchingAttributes, varArray[idx].getAttributeValue(attrName)))
matchingAttributes[matchingAttributes.length] = varArray[idx].getAttribute(attrName);
return matchingAttributes;
}
//---------------------------------------------
// OCP Framework
//
// Dropdown maintenance functions for multi-
// variant display.
//
//--------------------------------------------------------------------------
var __pvdsArray = new Array();
function __getDropdownSupport(listObj)
{
var idx = 0;
while (idx < __pvdsArray.length)
{
if (__pvdsArray[idx].__list == listObj)
return __pvdsArray[idx];
idx++;
}
return null;
}
//--------------------------------------------------------------------------
// Creating the support structure for a variant dropdown,
// specify the name of the dropdown, not the actual object
function ProductVariantDropdownSupport(listName, productID, complimentaryLists, productVariants, callbackFunc, primary, selectedValue, defaultText, defaultValue)
{
// Private fields
this.__attribCallback = null;
this.__arDefOpts = new Array();
this.__attributeName = listName;
this.__list = document.getElementById(listName + productID + "Variants");
this.__complimentaryLists = complimentaryLists;
this.__productVariants = productVariants;
this.__selectedValue = selectedValue;
this.__defaultText = (arguments.length > 7 ? defaultText : "Select One");
this.__defaultValue = (arguments.length > 8 ? defaultValue : "");
// Public fields
this.isPrimary = primary;
this.productID = productID;
// Add this directly to the list
this.__list.productVariantDropdownSupport = this;
// We use this global array because we need to find
// the primary list for complimentary/dependent lists
__pvdsArray[__pvdsArray.length] = this;
// Register a formatter callback
if (callbackFunc != "")
this.setAttributeFormatCallback(callbackFunc);
// Get the selected value for this dropdown
var selVariant = this.__productVariants.getSelectedVariant();
if (selVariant != null)
this.__selectedValue = selVariant.getAttributeValue(this.__attributeName);
// Load the data if this is the primary
this.loadDropdown();
// Register the event we want to respond to
if (this.__list.attachEvent)
{
// This is Internet Explorer
this.__list.attachEvent("onchange", this.updateLists);
}
else if (this.__list.addEventListener)
{
// This is Mozilla/Firefox
this.__list.addEventListener("change", this.updateLists, true);
}
}
// Callback function when dropdowns are loaded
// The callback function should be in the form:
//
// function cbFuncName(list, attribute, optionObj)
//
// When adding attributes to a dropdown, this method
// will pass to the callback the list object that is being
// modified, the VariantAttribute object, and the Option
// object that will be appended to the list
// The callback should return an Option object that
// will be added to the dropdown list.
function pvds_setAttributeFormatCallback(cbFuncPointer)
{
if (cbFuncPointer == null)
return;
// Determine that the object pass in is a function
if (typeof cbFuncPointer != "function")
{
// Throw an exception
var err = new Error("The attribute format callback must be a function pointer");
throw err;
}
// Check it's length (should be 3 parameters)
if (cbFuncPointer.length != 3)
{
// Throw an exception
var err = new Error("The attribute format callback must take 3 parameters");
throw err;
}
// Function ok, set it
this.__attribCallback = cbFuncPointer;
}
//--------------------------------------------------------------------------
// Clear a dropdown's options
function pvds_clearDropdown()
{
while (this.__list.options.length > 0)
this.__list.remove(0);
}
function pvds_addDefault()
{
var dOpt = document.createElement("option");
dOpt.text = this.__defaultText;
dOpt.value = this.__defaultValue;
try
{
// IE likes it this way
this.__list.add(dOpt);
}
catch (ex)
{
// The W3C DOM specifies the second parameter is required
this.__list.add(dOpt, null);
}
}
// Returns the primary drop-down for any list provided
function pvds_getPrimary()
{
if (this.isPrimary)
return this;
else
{
for (var x = 0; x < __pvdsArray.length; x++)
if ((__pvdsArray[x].productID == this.productID) &&
(__pvdsArray[x].isPrimary))
return __pvdsArray[x];
}
return null;
}
function pvds_getPrimarySelectedValue()
{
var primary = this.getPrimary();
return primary.__selectedValue;
}
// Load all of the unique attributes of a
// particular name into a dropdown list
var arrColors = null; //hoang add
var arrColorsCopy = null; //hoang add
function pvds_loadDropdown()
{
// Clear the dropdown
this.clearDropdown();
// Add the default option
this.addDefault();
// All lists start out as disabled
this.__list.disabled = true;
// Primary lists are never disabled
if (this.isPrimary)
this.__list.disabled = false;
// Enable a list that has a value selected
if (this.__selectedValue != "")
this.__list.disabled = false;
var primarySelOpt = (this.getPrimarySelectedValue() != "");
if (!this.isPrimary && primarySelOpt)
this.__list.disabled = false;
// Don't need to load the list if nothing selected and not primary and primary has no selected options
if (!this.isPrimary && !primarySelOpt && (this.__selectedValue == ""))
return;
// Get all of the unique values
var arAttributeList = null;
if (!this.isPrimary && this.getPrimarySelectedValue() != "")
{
var arMatchingVariants = this.__productVariants.getVariantsMatching(this.getPrimary().__attributeName, this.getPrimarySelectedValue());
arAttributeList = getAttributesWithNameFromVariants(arMatchingVariants, this.__attributeName);
}
else {
arAttributeList = this.__productVariants.getAttributesWithName(this.__attributeName); }
//if( arAttributeList.length > 1 )
//{ this.addDefault(); }
arrColors = new Array();
arrColorsCopy = new Array();
// Load the array of values
for (var idx = 0; idx < arAttributeList.length; idx++)
{
// Create new element
var opt = document.createElement("option");
opt.text = arAttributeList[idx].value;
opt.value = arAttributeList[idx].value;
arrColors.push(arAttributeList[idx].value);
// Give them a chance to modify the option object
if (this.__attribCallback != null)
opt = this.__attribCallback(this.__list, arAttributeList[idx], opt);
try
{
// IE likes it this way
this.__list.add(opt);
}
catch (ex)
{
// The W3C DOM specifies the second parameter is required (mozilla/firefox)
this.__list.add(opt, null);
}
// Is this a selected option?
if (this.__selectedValue == opt.value)
opt.selected = true;
}
// Set the variant form field to the selected value
this.setVariantField();
}
// Update dropdown lists, relative to a changed element
// in another list. ie:
// Change size from small to medium and update the
// color dropdown to show all of the colors for
// that size.
function pvds_updateLists(evt)
{
arrColors = new Array();
arrColorsCopy = new Array();
if (evt == "")
{ alert("Nothing") }
else
{
var dropdown = (evt.target) ? evt.target : evt.srcElement;
}
var thisObj = __getDropdownSupport(dropdown);
var arDependentAttribs = thisObj.__complimentaryLists.split(",");
// Anything to update??
if (!(arDependentAttribs.length == 1 && arDependentAttribs[0] == ""))
{
// Get the variants which match the selected attribute
var sAttribValue = thisObj.__list.options[thisObj.__list.selectedIndex].value;
var arMatchingVariants = thisObj.__productVariants.getVariantsMatching(thisObj.__attributeName, sAttribValue);
for (var lIdx = 0; lIdx < arDependentAttribs.length; lIdx++)
{
// The name of the list = [name]Variants
var listName = arDependentAttribs[lIdx] + thisObj.productID + "Variants";
// Refresh the proper list(s)
var compList = document.getElementById(listName);
// Get the ProductVariantDropdownSupport object
var pvdsObj = __getDropdownSupport(compList);
var sSelection = "";
// 1) Enable list
// -or-
// If enabled, grab the selected option's name so we
// can retain that selection if possible
if (compList.disabled)
compList.disabled = false;
else
sSelection = compList.options[compList.selectedIndex].value;
// 2) Clear the list
pvdsObj.clearDropdown();
// 3) Add default option
//pvdsObj.addDefault();
// 4) Load the values
var arAttribs = getAttributesWithNameFromVariants(arMatchingVariants, arDependentAttribs[lIdx]);
if( arAttribs.length != 1 )
{ pvdsObj.addDefault(); }
for (var idx = 0; idx < arAttribs.length; idx++)
{
// Create new element
var opt = document.createElement("option");
opt.text = arAttribs[idx].value;
opt.value = arAttribs[idx].value;
// Give them a chance to modify the option object
if (pvdsObj.__attribCallback != null)
opt = pvdsObj.__attribCallback(compList, arAttribs[idx], opt);
if (sSelection == arAttribs[idx].value)
opt.selected = true;
try
{
// IE likes it this way
compList.add(opt);
}
catch (ex)
{
// The W3C DOM specifies the second parameter is required
compList.add(opt, null);
}
}
// Disable this list if there are no elements in the dropdown
if (arAttribs.length == 0)
pvdsObj.__list.disabled = true;
}
}
// Set the variant form field to the selected value
thisObj.setVariantField();
}
function pvds_updateListsNew(dropdown)
{
arrColors = new Array();
arrColorsCopy = new Array();
var thisObj = __getDropdownSupport(dropdown);
var arDependentAttribs = thisObj.__complimentaryLists.split(",");
// Anything to update??
if (!(arDependentAttribs.length == 1 && arDependentAttribs[0] == ""))
{
// Get the variants which match the selected attribute
var sAttribValue = thisObj.__list.options[thisObj.__list.selectedIndex].value;
var arMatchingVariants = thisObj.__productVariants.getVariantsMatching(thisObj.__attributeName, sAttribValue);
for (var lIdx = 0; lIdx < arDependentAttribs.length; lIdx++)
{
// The name of the list = [name]Variants
var listName = arDependentAttribs[lIdx] + thisObj.productID + "Variants";
// Refresh the proper list(s)
var compList = document.getElementById(listName);
// Get the ProductVariantDropdownSupport object
var pvdsObj = __getDropdownSupport(compList);
var sSelection = "";
// 1) Enable list
// -or-
// If enabled, grab the selected option's name so we
// can retain that selection if possible
if (compList.disabled)
compList.disabled = false;
else
sSelection = compList.options[compList.selectedIndex].value;
// 2) Clear the list
pvdsObj.clearDropdown();
// 3) Add default option
//pvdsObj.addDefault();
// 4) Load the values
var arAttribs = getAttributesWithNameFromVariants(arMatchingVariants, arDependentAttribs[lIdx]);
if( arAttribs.length != 1 )
{ pvdsObj.addDefault(); }
for (var idx = 0; idx < arAttribs.length; idx++)
{
// Create new element
var opt = document.createElement("option");
opt.text = arAttribs[idx].value;
opt.value = arAttribs[idx].value;
// Give them a chance to modify the option object
if (pvdsObj.__attribCallback != null)
opt = pvdsObj.__attribCallback(compList, arAttribs[idx], opt);
if (sSelection == arAttribs[idx].value)
opt.selected = true;
try
{
// IE likes it this way
compList.add(opt);
}
catch (ex)
{
// The W3C DOM specifies the second parameter is required
compList.add(opt, null);
}
}
// Disable this list if there are no elements in the dropdown
if (arAttribs.length == 0)
pvdsObj.__list.disabled = true;
}
}
// Set the variant form field to the selected value
thisObj.setVariantField();
}
// Set the hidden form field that is tied to this variant with
// the value of the combined variant attributes.
function pvds_setVariantField()
{
// Find the variant that matches this type
var variantArray = this.__productVariants.getVariantGroup();
var attribs = new Array();
for (var x = 0; x < variantArray.length; x++)
{
var pvds = document.getElementById(variantArray[x] + this.productID + "Variants").productVariantDropdownSupport;
if (pvds)
attribs[attribs.length] = new VariantAttribute(variantArray[x], pvds.getSelectedOption().value);
}
var selVariant = this.__productVariants.getVariant(attribs);
// Set the form field
try
{
document.getElementById(this.__productVariants.getFormField()).value = selVariant.getId();
}
catch (ex)
{
// They've probably selected something invalid...
document.getElementById(this.__productVariants.getFormField()).value = "";
}
}
function pvds_getSelectedOption()
{
return this.__list.options[this.__list.selectedIndex];
}
function pvds_getProductVariants()
{
return this.__productVariants;
}
ProductVariantDropdownSupport.prototype.setAttributeFormatCallback = pvds_setAttributeFormatCallback;
ProductVariantDropdownSupport.prototype.clearDropdown = pvds_clearDropdown;
ProductVariantDropdownSupport.prototype.addDefault = pvds_addDefault;
ProductVariantDropdownSupport.prototype.loadDropdown = pvds_loadDropdown;
ProductVariantDropdownSupport.prototype.updateLists = pvds_updateLists;
ProductVariantDropdownSupport.prototype.updateListsNew = pvds_updateListsNew;
ProductVariantDropdownSupport.prototype.getSelectedOption = pvds_getSelectedOption;
ProductVariantDropdownSupport.prototype.getPrimary = pvds_getPrimary;
ProductVariantDropdownSupport.prototype.getPrimarySelectedValue = pvds_getPrimarySelectedValue;
ProductVariantDropdownSupport.prototype.getProductVariants = pvds_getProductVariants;
ProductVariantDropdownSupport.prototype.setVariantField = pvds_setVariantField;
// This is an example of sending product data from the server
// to the client, then formatting the variants on the client-side
// based on certain criteria.
function cbFormatter(list, attribute, opt)
{
// Get the price for this variant.. If this is the primary list, get all related
// variants from the group and get their prices as well so we can build a range.
var pvds = list.productVariantDropdownSupport;
// Get all of the product variants for this attribute
var variantGroup = attribute.getVariant().getProductVariantGroup();
var groupVariants = variantGroup.getAllVariants()
// Are all of the prices the same within the group?
var lowGroupPrice = 999999.00;
var highGroupPrice = -1.00;
for (var idx = 0; idx < groupVariants.length; idx++)
{
lowGroupPrice = groupVariants[idx].numericPrice < lowGroupPrice ? groupVariants[idx].numericPrice : lowGroupPrice;
highGroupPrice = groupVariants[idx].numericPrice > highGroupPrice ? groupVariants[idx].numericPrice : highGroupPrice;
}
// Are all of the prices the same within the variant?
var variants = variantGroup.getVariantsMatching(attribute.name, attribute.value);
var lowVariantPrice = 999999.00;
var highVariantPrice = -1.00;
var lowVariantDisplay = variants[0].displayPrice;
var highVariantDisplay = variants[0].displayPrice;
for (var idx = 0; idx < variants.length; idx++)
{
// Display really needs to be done before the re-assignment...
lowVariantDisplay = parseFloat(variants[idx].numericPrice) < lowVariantPrice ? variants[idx].displayPrice : lowVariantDisplay;
lowVariantPrice = parseFloat(variants[idx].numericPrice) < lowVariantPrice ? parseFloat(variants[idx].numericPrice) : lowVariantPrice;
highVariantDisplay = parseFloat(variants[idx].numericPrice) > highVariantPrice ? variants[idx].displayPrice : highVariantDisplay;
highVariantPrice = parseFloat(variants[idx].numericPrice) > highVariantPrice ? parseFloat(variants[idx].numericPrice) : highVariantPrice;
}
if (lowGroupPrice != highGroupPrice)
{
// Primary list should display a range
if (pvds.isPrimary)
if (lowVariantPrice != highVariantPrice)
opt.text = opt.text + " " + lowVariantDisplay + " - " + highVariantDisplay;
else
opt.text = opt.text + " " + attribute.getVariant().displayPrice;
else // Secondary lists should show exact price
opt.text = opt.text + " " + attribute.getVariant().displayPrice;
}
return opt;
}
/* ++++++++++++++++++++++++++++++++++++++++++++++++++ */