WIDGET_ERROR_CLASS = "validation-error"; // For **DEVELOPMENT** server //IMAGE_REPOSITORY = "/VenetianMaskStore_Images/"; //For **WEB** server IMAGE_REPOSITORY = "mask_app_images/"; // create one event manager to be used by the entire page. //EVENT_MANAGER = new EventManager(); GALLERY_MENU = null; // runs the defaull page javescipt, sets the on doucment ready JQUERY function. $(document).ready(function(){ try { // // create and initialize the main page manager // var mainPageManager = new MainPageManager(); // mainPageManager.initialize(); // find out the name of the current page. var mainPageUtility = new MainPageUtility(); var pageName = mainPageUtility.getPageName(); var pageManager = null; // generate the specific page manager depending on the page name switch(pageName) { case "search.html": // starting the search page pageManager = new SearchPageManager(); break; case "contact_us.html": // starting the contact up page pageManager = new ContactUsPageManager(); break; case "checkout.html": // starting the checkout page pageManager = new CheckoutPageManager(); break; case "inventory_count_search.html": // starting the inventory search page pageManager = new InventoryCountSearchPageManager(); break; case "inventory_count_checkout.html": // starting the inventory search page pageManager = new InventoryCountCheckoutPageManager(); break; case "product_list.html": // starting the product list page pageManager = new ProductListPageManager(); break; default: // no specific default page generation is required. Start the default page manager. pageManager = new MainPageManager(); } // initialize the page manager to support the loading of the a new page. pageManager.initializePage(); } catch (e) { alert("stack details:\n" + e.stack); } }); // the class manages the HTML width functionliaty implementation for the page. // selectionId: an Jquery object used to limit the scope of the html widget manager, if null, the whole page is the scope function HtmlWidgetPageManager (selectorId) { this.selectorId = selectorId; if (empty(this.selectorId)) { this.selectorId = "body"; // default to the whole page. } // iniatlize the html widget page manager. this.initialize = function () { $(this.selectorId).find(".widget-input-field").change(function () { validateInput(this); }); }; } /*// update the display by adding some rounded coners. function updateDisplaySearchPage () { $(".gallery-text").corner("5px"); $("#search-menu .menu-option").corner("5px"); $("#item-list-heading").corner("5px"); }*/ //performs the input validation for the specified input node. //returns a value of TRUE if the input value is valid //inputNode: Jquery equivalant representing the input node of the widget to be validation. function validateInput (inputNode) { // made sure the node value is defined. checkParamSet(inputNode); // get the widget type. var widgetNode = $(inputNode).parent(); var widgetType = $(widgetNode).attr("data-widget-type"); // create an object for the input widget using the widget faction. // pass in the parent of the input node which is the widget container var htmlWidget = new HtmlWidget(); var htmlWidget = htmlWidget.htmlWidgetFactory(widgetType, widgetNode); // var htmlWidget = HtmlWidget.htmlWidgetFactory(widgetType, widgetNode); // validate the widget value. var isValid = htmlWidget.validateWidgetValue($(inputNode).val()); // update the display of the widget htmlWidget.display(); return isValid; } // perform all the required form validation before submitting data to the server. // returns a value of TRUE if all the validation passed. // sectionID: jquery object or equivalent, if set, will limit validation to the specified section. function submitValidation(sectionID) { var isValid = true; var selector = ".widget-input-field"; if (!empty(sectionID)) { // the selector ID was set, preprepend to the selector. selector = sectionID + " " + selector; } // the each function itterates over each item synchronously, like a loop. $(selector).each(function () { var isInputValid = validateInput(this); if (!isInputValid) { isValid = false; } }); if (!isValid) { // find the first error as use bring it into focus. selector = sectionID + " " + ".validation-error"; var errorElement = $(selector).first(); if (!empty(errorElement)) { scrollWindowToTopOfElement(errorElement, "#main-menu-box"); } } return isValid; } // submit the form on the page to be processed, the form takes up the page so the results // are displayed in the main display of the page // formId = jquery object, the form name is the same name as the server side activity. // activity = the activity to passed to server ajax routine as the operation to invoke on the server // targetElement : the elemnt use to display the html retult returned, a jquery object // targetInsertionType : 1 (default) - overwrite content of element; // 2 - append as a sibling of the target element // waitType : the way to display the wait icon when the request is loading // 1 (default) - inactivate the entire page until the request is complete // 2 - the wait icon is append to the end of the target element showing that // more data is being loaded. function submitFormPage(formId, activity, targetElement, targetInsertionType, waitType) { try { checkParamSet (2, formId, activity); if (empty(targetElement)) { // default the target element to the page-main id if not specefied. targetElement = "#page-main"; } // create the submit form object to submit the request to the server. pageFormSubmitRequest = new PageFormSubmitRequest(); // create an event instance to be called after the page loads. var eventManager = new EventManager("page-loaded", function () { // scroll to the top of the page scrollWindowToTop(); }); var eventInstance = new EventInstance (eventManager, "page-loaded"); pageFormSubmitRequest.setRequestSucessEvent (eventInstance); pageFormSubmitRequest.submit(formId, activity, targetElement, targetInsertionType, waitType); } catch (e) { alert("stack details:\n" + e.stack); } return false; // to stop multiple events being fired. } // add the wait item html snipit to the end of the target element and show it. // a unique ID is generated to track the wait icon inserted in the element // waitType : the way to display the wait icon when the request is loading // 1 (default) - inactivate the entire page until the request is complete // 2 - the wait icon is append to the end of the target element showing that // more data is being loaded. function showWaitIcon (targetElement, waitType) { checkParamSet (1, targetElement); if (empty(waitType)) { // default the wait type value. waitType = 1; } var className = ""; if (waitType == 1) { className = "wait-loading"; } else if (waitType == 2) { className = "wait-loading-element"; } else { throw new Error("Wait type "+waitType+" is not defined.") } var waitTemplate = "
- element that displays the current quantity associated with control element
// Class item-remove-from-cart - element clicked whent item remove
//
// The item-in-cart or item-not-in-cart class is added to the control element for CSS control of an empty cotrol versus
// one with some quantity.
//
// Parameters:
// itemId - the ID of the items the quantity control is assoicated with
// quantityControlElement - the quantity control element, containing the control elements
// shoppingCartActionActivity - the activity to use when calling the shopping cart action service.
function SearchItemQuantityControl (itemId, quantityControlElement, shoppingCartActionActivity) {
checkParamSet (3, itemId, quantityControlElement, shoppingCartActionActivity);
this.itemId = itemId;
this.quantityControlElement = quantityControlElement;
this.shoppingCartActionActivity = shoppingCartActionActivity;
// initialize the current item quantity, based on what is current displayed in the items gallery.
this.itemQuantity = Number($(this.quantityControlElement).find(".item-count-cart p").text());
this.isAnimateAddToCart = false; // updated to control that only one cart is animated at a time.
this.addToCartTimer = null; // used to save the timer used to buffer/accumulate add/remove item clicks
this.addToCartBuffering = false; // an indication if the add to cart clicks are being buffered and the add to cart timer was started.
this.eventInstance = null; // an event instance to fire controlled quantity changes.
// initialize the list by adding the click event to any next page buttons.
this.initializeWidget = function () {
// add the click event to the add to cart button to add the clicked item to the
// shopping cart.
var callbackData = {'thisObject': this}; // callback data
$(this.quantityControlElement).find(".item-add-to-cart").off("click").click( callbackData, function (event) {
// animate the cart button when pressed.
event.data.thisObject.animateAddToCart(this);
// add one item to the cart.
event.data.thisObject.addToCart(this, 1);
});
// add the click event to the remove from cart button to add the remove item from the
// shopping cart.
$(this.quantityControlElement).find(".item-remove-from-cart").off("click").click( callbackData, function (event) {
// animate the cart button when pressed.
event.data.thisObject.animateAddToCart(this);
// remove one item from the cart.
event.data.thisObject.addToCart(this, -1);
});
// initialize the page display look controlled by JS.
this.initializeDisplay();
}
this.initializeDisplay = function () {
// round the coners elements
$(this.quantityControlElement).corner("30px");
}
// add the given item to the sytem shopping cart.
// element : the shopping cart image.
// quantity: The amount to change the cart by, usually +1, -1
this.addToCart = function (element, quantity) {
checkParamSet (2, element, quantity);
// increase/decrease the current item quantity.
this.itemQuantity = this.itemQuantity + quantity;
// the minumum item quantity can be is zero.
if (this.itemQuantity < 0) {
this.itemQuantity = 0;
}
// update the display of the item quantity.
this.updateCartQuantity ();
// update the server cart quantity.
this.updateShoppingCartUpdate();
}
// annimate the cart button when it is pressed.
// element : the shopping cart image.
this.animateAddToCart = function (element) {
if (!this.isAnimateAddToCart) {
// cart animation is not running so we can start it.
// set flag to indicate the cart animation is running.
this.isAnimateAddToCart = true;
$(element).find("img").effect("scale", {percent: "125"}, 300, function () {
$(element).find("img").effect("scale", {percent: "80"}, 300, function () {
// set the flag to indicate the cart animation has stopped.
this.isAnimateAddToCart = false;
}.bind(this));
}.bind(this));
}
}
// updated the item quantity
// element : the shopping cart image.
// cartQuantity: cart quantity to be displayed.
this.updateCartQuantity = function (cartQuantity) {
// kept this here but it is not enough so control both together, using a combine status.
if (this.itemQuantity > 0) {
// display the all cart controls and the counter.
$(this.quantityControlElement).parent().addClass("item-in-cart").removeClass("item-not-in-cart");
} else {
// only display the add cart button since no items are in the cart for the item.
$(this.quantityControlElement).parent().addClass("item-not-in-cart").removeClass("item-in-cart");
}
$(this.quantityControlElement).find(".item-count-cart p").text(this.itemQuantity);
if (!empty(this.eventInstance)) {
// return some even data with the item Id new quantity set.
var eventData = {itemId: this.itemId, itemQuantity: this.itemQuantity}
this.eventInstance.triggerEvent(eventData);
}
}
// implements the buffering of the server call. The server data will be updated 1 second after the last time
// the quantity of the item changed..
this.updateShoppingCartUpdate = function () {
if (this.addToCartBuffering) {
// we currently buffering the server side call. Remove the old timer on delay call and start a new one.
if (this.addToCartTimer != "") {
// stop any previous calculation timer started
clearTimeout(this.addToCartTimer);
}
}
// wait second till after the last update item being added to the shopping cart.
// the bind is used set the htis scope of hte function call and pass parameters.
this.addToCartBuffering = true;
this.addToCartTimer = setTimeout(function () {
this.serverShoppingCartUpdate();
}.bind(this), 1000);
}
// send the request to the server to update the shopping cart quantity (add/subract) for the item.
// itemId : the product ID for the quantity being updated
// itemQuantity : the increase or decrease in the quantity ordered for the item.
// element : the shopping cart image.
this.serverShoppingCartUpdate = function () {
// create the post data;
var postData = [];
postData.push({'name': "item_id", 'value': this.itemId});
postData.push({'name': "item_qty", 'value': this.itemQuantity});
// call the server to perform the add cart action.
var shoppingCartAction = new ShoppingCartAction();
// create and event instace to be called when an item is added to the cart.
var eventInstance = new EventInstanceListenerThis("update_item_quantity", this, function (thisObject, eventInstanceData) {
// update the Payment summary section with the new shipping option price.
thisObject.verifyCartQuantity(eventInstanceData.eventData.item_id, eventInstanceData.eventData.quantity);
});
// setup the instance to call back when the shopping cart action completes.
shoppingCartAction.setActionSucessEvent(eventInstance);
shoppingCartAction.exectuteAction (this.shoppingCartActionActivity, postData);
}
// verifies that item elemet object quantity matches the server quantity provided and turn off the buffering flag.
// serverItemQuantity : the increase or decrease in the quantity ordered for the item.
// element : the shopping cart image.
this.verifyCartQuantity = function (serverItemId, severItemQuantity) {
checkParamSet (2, serverItemId, severItemQuantity);
if (serverItemId != this.itemId) {
throw new
Error("ItemManagerElement item ID ("+this.itemId+") dose not match that returned by the server ("+serverItemId+").");
}
if (severItemQuantity == this.itemQuantity) {
// the server quantity matches the element quantity. The item quantity has been set in the cart correctly.
// reset the buffering flag.
this.addToCartBuffering = false;
}
}
// sets up the event instance to be used when the controlled quantity changes
// eventInstance : an event instance to be fired when the controlled quantity changes.
this.setQuantityChangeEvent = function (eventInstance) {
checkParamSet (1, eventInstance);
this.eventInstance = eventInstance;
}
// returns the current item quantity.
this.getQuantity = function () {
return this.itemQuantity;
}
}
// used to manage an product detail item listing of products.
function SearchItemDetailManagerElement (productDetailElement) {
checkParamSet (1, productDetailElement);
this.productDetailElement = productDetailElement;
this.itemId = null; // the item Id search item being managed.
// Save the item quantity controllers.
this.itemGoodQuantityControl = null;
// this.eventManager = null; // an event manager used to trigger various item events.
this.qtyChangeEventInstance = null; // an event instance to fire controlled quantity changes.
// this.isAnimateAddToCart = false; // updated to control that only item is animated at a time.
// initialize the object.
this.initialize = function () {
// get the item ID for the item group
this.itemId = $(this.productDetailElement).attr("data-item-id");
// create an event instance to call when any of the quantities change.
var eventInstance = new EventInstanceListenerThis ("quantity_changed", this, function (thisObject, eventInstanceData) {
thisObject._updateItemStatus();
if (!empty(thisObject.qtyChangeEventInstance)) {
// trigger the quantity change event, forward even data which contains the item ID and quantity changed.
var eventData = eventInstanceData.eventData;
thisObject.qtyChangeEventInstance.triggerEvent(eventData);
}
});
// create the good quantity controllers
var itemQuantityControlElement = $(this.productDetailElement).find(".item-quantity-control");
this.itemGoodQuantityControl =
new SearchItemQuantityControl(this.itemId, itemQuantityControlElement, "update_item_quantity")
this.itemGoodQuantityControl.initializeWidget();
this.itemGoodQuantityControl.setQuantityChangeEvent(eventInstance);
// initalize the display.
this._initializeDisplay();
}
// initialize the page display look controlled by JS.
this._initializeDisplay = function () {
// round corner for qunity control set in the qunitty controler object.
// $(this.galleryGroupElement).find(".item-information").corner("30px");
}
// update the combined status for the item, to control the display of the good and bad quantity controllers.
this._updateItemStatus = function () {
// Get the current good and bad quantity value.
var goodItemQuantity = this.itemGoodQuantityControl.getQuantity();
// find the item control elment where the display class is located.
var itemControlElement = $(this.productDetailElement).find(".item-control-box");
// remove any current control class from the element.
$(itemControlElement).removeClass("item-in-cart").removeClass("item-not-in-cart");
if (goodItemQuantity>0) {
// The item has some quantity added to the shopping cart.
$(itemControlElement).addClass("item-in-cart");
} else {
// no quantity is set for the item.
$(itemControlElement).addClass("item-not-in-cart");
}
}
/* // sets the event manager to use when trigger the various item events.
// Events trigger:group_item_query - the item group query has loaded.
this.setEventManager = function (eventManager) {
this.eventManager = eventManager;
}*/
// sets up the event instance to be used when the controlled quantity changes
// eventInstance : an event instance to be fired when the controlled quantity changes.
this.setQuantityChangeEvent = function (eventInstance) {
checkParamSet (1, eventInstance);
this.qtyChangeEventInstance = eventInstance;
}
}
//the class manages the display and interaction of the specified element.
//it controls the displaying of an item in two states, summary and detail
//a fade out fade in transition is used to animate the change
//containerElement : jquery object for the element contining the elements to be apply the transition class
//actionElementObj : a plain object containing action elements and the classes to be applied to the container element
//- detailActionElement: Jquery object for the elements used to trigger the display of the item detail view
//- detailClass: the class name to be applied to the container element trigger the display of the item details
//- returnActionElement: Jquery object for the elements used to trigger the return to the initialial item view
//- returnClass: The calls name to be applied to the container element to trigger the diaply of the initialial item view
function ElementStateManager (containerElement, actionElementObj) {
checkParamSet (2, containerElement, actionElementObj);
this.containerElement = containerElement;
this.actionElementObj = actionElementObj;
this.isAnimateAddToCart = false; // controls the initiation of the state manager action animation.
// initialize the list by adding the click event to any next page buttons.
this.initializeWidget = function () {
// var thisObject = this;
var callbackData = {'thisObject': this}; // callback data
// add the click event to all the detail action element found.
var informationButton = $(this.containerElement).find(this.actionElementObj.detailActionElement);
$(informationButton).off("click").click( callbackData, function (event) {
// first animate the button action then call animation of the state switch.
event.data.thisObject.animateActionElement(this, function (element) {
// animate the switch to detail view.
this.showItemDetails(element);
}.bind(event.data.thisObject, this));
// event.data.thisObject.showItemDetails(this);
});
// add the click event to all the return to summary action element found.
var informationButton = $(this.containerElement).find(this.actionElementObj.returnActionElement);
$(informationButton).off("click").click( callbackData, function (event) {
// first animate the button action then call animation of the state switch.
event.data.thisObject.animateActionElement(this, function (element) {
// animate the switch to detail view.
this.showItemSummary(element);
}.bind(event.data.thisObject, this));
// event.data.thisObject.showItemSummary(this);
});
}
// show the detail information associated with the item.
// the element is the actual information icon image
this.showItemDetails = function (element) {
checkParamSet (1, element);
// get the inner elements of the containing element to be faded out.
var innerElement = $(element).parents(this.containerElement).children();
// create an animation of a card flip. The detail data is dispplayed at the point that the edge
// of the card is reached. card flip animation requires perspective change otherwise will look just
// like swip in an out, try fading.
var thisObject = this; // FIX THIS ONE.
$(innerElement).fadeOut("slow");
$(innerElement).promise().done( function () {
// apply the display detail class to the container when all the items have been faded out.
$(element).parents(thisObject.containerElement).addClass(thisObject.actionElementObj.detailClass)
.removeClass(thisObject.actionElementObj.returnClass);
$(innerElement).fadeIn("slow");
$(innerElement).show();
});
}
// show the summary information associated with the item.
// the element is the actual return icon image
this.showItemSummary = function (element) {
checkParamSet (1, element);
// get the inner elements of the containing element to be faded out.
var innerElement = $(element).parents(this.containerElement).children();
// create an animation of a card flip. The detail data is dispplayed at the point that the edge
// of the card is reached. card flip animation requires perspective change otherwise will look just
// like swip in an out, try fading.
var thisObject = this;
$(innerElement).fadeOut("slow");
$(innerElement).promise().done( function () {
// apply the display detail class to the container when all the items have been faded out.
$(element).parents(thisObject.containerElement).addClass(thisObject.actionElementObj.returnClass)
.removeClass(thisObject.actionElementObj.detailClass);
$(innerElement).fadeIn("slow");
$(innerElement).show();
});
}
// annimate the state action elements, then activates the callback function.
// element : the action element (image continer).
this.animateActionElement = function (element, callbackFunction) {
if (!this.isAnimateAddToCart) {
// cart animation is not running so we can start it.
// set flag to indicate the cart animation is running.
this.isAnimateAddToCart = true;
$(element).find("img").effect("scale", {percent: "125"}, 300, function () {
$(element).find("img").effect("scale", {percent: "80"}, 300, function () {
// set the flag to indicate the cart animation has stopped.
this.isAnimateAddToCart = false;
if (!empty(callbackFunction)) {
// activate the callback function.
callbackFunction();
}
}.bind(this));
}.bind(this));
}
}
}
// This object manages the display and functionality found on the item detail screen
// ** Prameters
// itemId: The ID of the item for which the item details will be displayed
// itemDetailElement: The JQuery item element within which the item detail will be displayed
function SearchItemDetailManager (itemId, itemDetailElement) {
checkParamSet (2, itemId, itemDetailElement);
this.itemId = itemId;
this.itemDetailElement = itemDetailElement;
// the event manger used when triggering events
this.eventManager = new EventManager();
// add ITEM_DETAIL_LOADED event to be triggered after the HTML fragment was loaded successfully inti the item detail element.
this.eventManager.addEvent("ITEM_DETAIL_LOADED");
// add ITEM_QTY_CHANGE event if item quantity changes on the product detail screen.
// return even data {itemId:, itemQuantity:}
this.eventManager.addEvent("ITEM_QTY_CHANGE");
// display the item detail in the specified elment and intialize screen functionality
this.display = function () {
// setup the event manager to active this object intialization after the HTML fragment is loaded.
this.eventManager.addListenerThis ("ITEM_DETAIL_LOADED", this, function (thisObject, eventInstanceData) {
thisObject.initialize();
// scroll the window to the top of the screen. Temporary fix for the scrolling of a window off the page.
// scrollWindowToTop();
// find how much the body of the page has scrolled.
var scrollTop = $(window).scrollTop(); // save the scroll top value.
// add 80 pixles to clear the menu.
scrollTop = scrollTop + 80;
// set the top of the item detail box to be displayed within the current postion of the scrolled screen.
$("#product-detail-frame-box").offset({'top':scrollTop});
});
// load the HTML fragment for the product details.
this.load();
}
// load the item detail HTML fragment for the item into the item detail element
// the ITEM_DETAIL_LOADED event will be fired after the HTML fragment has been loaded.
this.load = function () {
// setup the item id for which the details will be loaded.
var postData = [];
postData.push({name: "item_id", value: this.itemId});
// create a new page submitted request object.
var pageSubmitRequest = new PageSubmitRequest();
// extract the event instance with will be triggered when the HTML framgment is loaded successfully.
var eventInstance = this.eventManager.getEventInstance("ITEM_DETAIL_LOADED");
// the even instance will be tiggered when the HTML fragment loades successfully.
pageSubmitRequest.setSubmitSucessEvent (eventInstance);
// load the item display HTML fragment into the item detail element.
pageSubmitRequest.submit("display_item_detail", postData, this.itemDetailElement);
}
// intialize screen functionality for the loaded item detail HTML fragment
this.initialize = function () {
// initalize the item detail manager events
this._initializeEvents();
// initialize the page display look controlled by JS.
this._initializeDisplay();
}
// close the item detail display window
this.close = function () {
// remove all the child elments from elment within the product details where displayed.
$(this.itemDetailElement).empty();
// should set the item detail to not be active show can apply CSS.
// should clean up objects, try to free up memory.
}
// initialize the page display look controlled by JS.
this._initializeDisplay = function () {
// round the coners elements
$(this.itemDetailElement).find("#product-items .item-name").corner("5px");
}
// adds the events to various screen elements.
this._initializeEvents = function () {
// add the click event all gallery images.
var callbackData = {'thisObject': this}; // callback data
// adding event to control the selection of an image for te product image list.
$(this.itemDetailElement).find(".frame-control .close_frame").off("click").click( callbackData, function (event) {
event.data.thisObject.close();
});
// adding event close the product detail screen.
$(this.itemDetailElement).find("#product-images-list .product-image-link").off("click").click( callbackData, function (event) {
// we will not do animate, the {filter: "brighttness(0.5)"} did not work because it is not numeric value for "filter:"
// we will just set the select class for the selecte item in the list and the product detials
event.data.thisObject._setItemSelected(this);
});
// create the event the be called if the quantity of one of the elements found on the product detail screen changes.
// just pass up the even with the item data.
var eventInstance = new EventInstanceListenerThis ("quantity_changed", this, function (thisObject, eventInstanceData) {
var eventData = eventInstanceData.eventData;
thisObject.eventManager.triggerEvent("ITEM_QTY_CHANGE", eventData);
});
// create a item manager element for each item listed.
$("#product-items .product-detail-box").each( function (index, element) {
// Create a search item manager whith manges the
var itemManagerElement = new SearchItemDetailManagerElement(element);
itemManagerElement.initialize();
// setup a quantity change event handler.
itemManagerElement.setQuantityChangeEvent(eventInstance);
}.bind(this));
}
// for the given product list image elment, the item ID will be extracted and the product detetail image for that item ID
// will be set to the item-selected css class.
// * Prameters *
// productLinkElement: The JQuery element representing selected the in the product-image element
this._setItemSelected = function (productLinkElement) {
checkParamSet (1, productLinkElement);
// extract the galery ID for the items to be displayed.
var selectedItemId = $(productLinkElement).attr("data-item-id");
// set the item in the image list to be selected.
this._setItemSelectedList (selectedItemId);
// set the item in the product detail list to be selected.
this._setItemSelectedDetail (selectedItemId);
}
// sets the item in the items image list to be selected.
// * Prameters *
// selectedItemId: The item ID of the currently selecte product
this._setItemSelectedList = function (selectedItemId) {
checkParamSet (1, selectedItemId);
// loop through all the list items setting the one item to the selected class an others to the un selected class.
$(this.itemDetailElement).find("#product-images-list .product-image-link").each( function () {
// find the item Id for the list element.
var itemId = $(this).attr("data-item-id");
// remove the item-selected class and and set the item-not-selected class
if (itemId == selectedItemId ) {
// this is the new select items.
$(this).parent().removeClass("item-not-selected").addClass("item-selected");
} else {
// this is not the currently selecte item.
$(this).parent().removeClass("item-selected").addClass("item-not-selected");
}
});
}
// sets the item in the items detail list to be selected.
// * Prameters *
// selectedItemId: The item ID of the currently selecte product
this._setItemSelectedDetail = function (selectedItemId) {
checkParamSet (1, selectedItemId);
// loop through all the list items setting the one item to the selected class an others to the un selected class.
$(this.itemDetailElement).find("#product-items .product-detail-box").each( function () {
// find the item Id for the list element.
var itemId = $(this).attr("data-item-id");
// remove the item-selected class and and set the item-not-selected class
if (itemId == selectedItemId ) {
// this is the new select items.
$(this).removeClass("item-not-selected").addClass("item-selected");
} else {
// this is not the currently selecte item.
$(this).removeClass("item-selected").addClass("item-not-selected");
}
});
}
this.getEventManager = function () {
return this.eventManager;
}
}
//this PHP include messes up the outline of the JS code
//one item manager for each element.
function SearchItemManagerElement (galleryGroupElement) {
checkParamSet (1, galleryGroupElement);
this.galleryGroupElement = galleryGroupElement;
// initialize the item ID the element manager is managing
this.itemId = $(this.galleryGroupElement).attr("data-item-id");
// initialize the current item quantity, based on what is current displayed in the items gallery.
this.itemQuantity = Number($(this.galleryGroupElement).find(".item-count-cart p").text());
this.isAnimateAddToCart = false; // updated to control that only one cart is animated at a time.
this.addToCartTimer = null; // used to save the timer used to buffer/accumulate add/remove item clicks
this.addToCartBuffering = false; // an indication if the add to cart clicks are being buffered and the add to cart timer was started.
this.eventManager = null; // a common event manager to use to activate quantity change event for all item displayed in the gallery
// initialize the list by adding the click event to any next page buttons.
this.initializeWidget = function () {
// add the click event to the add to cart button to add the clicked item to the
// shopping cart.
var callbackData = {'thisObject': this}; // callback data
$(this.galleryGroupElement).find(".item-add-to-cart").off("click").click( callbackData, function (event) {
// animate the cart button when pressed.
event.data.thisObject.animateAddToCart(this);
// add one item to the cart.
event.data.thisObject.addToCart(this, 1);
});
// add the click event to the remove from cart button to add the remove item from the
// shopping cart.
$(this.galleryGroupElement).find(".item-remove-from-cart").off("click").click( callbackData, function (event) {
// animate the cart button when pressed.
event.data.thisObject.animateAddToCart(this);
// remove one item from the cart.
event.data.thisObject.addToCart(this, -1);
});
// clear the href setting from the item information icon, so it will not be activate.
// $(this.galleryGroupElement).find(".item-detail-information a").removeAttr("href");
// add the handling of the clicking of the information icon that will open the product detail screen.
$(this.galleryGroupElement).find(".item-detail-information").off("click").click( callbackData, function (event) {
// display the item detil for the current item.
event.data.thisObject.displayItemDetail();
});
// initialize the page display look controlled by JS.
this.initializeDisplay();
}
this.initializeDisplay = function () {
// round the coners elements
$(galleryGroupElement).find(".item-quantity-control").corner("30px");
$(galleryGroupElement).find(".item-information").corner("30px");
$(galleryGroupElement).find(".item-detail-information").corner("30px");
$(galleryGroupElement).find(".item-return").corner("30px");
}
// add the given item to the sytem shopping cart.
// element : the shopping cart image.
// quantity: The amount to change the cart by, usually +1, -1
this.addToCart = function (element, quantity) {
checkParamSet (2, element, quantity);
var itemId = $(element).parents(".gallery-group").attr("data-item-id");
if (this.itemId != itemId) {
// the item ID of the element does not matching the items ID of the object, there is some problem, should not happen.
throw new
Error("ItemManagerElement item ID ("+this.itemId+") dose not match that of the HTML element ("+itemId+").");
}
// increase/decrease the current item quantity.
this.itemQuantity = this.itemQuantity + quantity;
// the minumum item quantity can be is zero.
if (this.itemQuantity < 0) {
this.itemQuantity = 0;
}
// update the display of the item quantity.
this.updateCartQuantity ();
// update the server cart quantity.
this.updateShoppingCartUpdate();
}
// annimate the cart button when it is pressed.
// element : the shopping cart image.
this.animateAddToCart = function (element) {
// var thisObject = this;
// FIX THIS ANIMATION AS well, should pass element as part of bind.
if (!this.isAnimateAddToCart) {
// cart animation is not running so we can start it.
// set flag to indicate the cart animation is running.
this.isAnimateAddToCart = true;
$(element).find("img").effect("scale", {percent: "125"}, 300, function () {
$(element).find("img").effect("scale", {percent: "80"}, 300, function () {
// set the flag to indicate the cart animation has stopped.
this.isAnimateAddToCart = false;
}.bind(this));
}.bind(this));
}
}
// updated the item quantity, modified to use cart quantity paramter if specified, the cart quantity is comming from
// the update of the quantity that happended on another screen and update via and event.
// element : the shopping cart image.
// updateQuantity: a quantity which to update the object to, from a event
this.updateCartQuantity = function (updateQuantity) {
if (!empty(updateQuantity)) {
this.itemQuantity = updateQuantity;
}
// find the containing gallery-group class and extract the item ID value.
var itemId = $(this.galleryGroupElement).attr("data-item-id");
if (this.itemQuantity > 0) {
// display the all cart controls and the counter.
$(this.galleryGroupElement).find(".gallery-group-inner").addClass("item-in-cart")
.removeClass("item-not-in-cart");
} else {
// only display the add cart button since no items are in the cart for the item.
$(this.galleryGroupElement).find(".gallery-group-inner").addClass("item-not-in-cart")
.removeClass("item-in-cart");
}
$(this.galleryGroupElement).find(".item-count-cart p").text(this.itemQuantity);
}
// implements the buffering of the server call. The server data will be updated 1 second after the last time
// the quantity of the item changed..
this.updateShoppingCartUpdate = function () {
if (this.addToCartBuffering) {
// we currently buffering the server side call. Remove the old timer on delay call and start a new one.
if (this.addToCartTimer != "") {
// stop any previous calculation timer started
clearTimeout(this.addToCartTimer);
}
}
// wait second till after the last update item being added to the shopping cart.
// the bind is used set the htis scope of hte function call and pass parameters.
this.addToCartBuffering = true;
this.addToCartTimer = setTimeout(function () {
this.serverShoppingCartUpdate();
}.bind(this), 1000);
}
// send the request to the server to update the shopping cart quantity (add/subract) for the item.
// itemId : the product ID for the quantity being updated
// itemQuantity : the increase or decrease in the quantity ordered for the item.
// element : the shopping cart image.
this.serverShoppingCartUpdate = function () {
// create the post data;
var postData = [];
postData.push({'name': "item_id", 'value': this.itemId});
postData.push({'name': "item_qty", 'value': this.itemQuantity});
// call the server to perform the add cart action.
var shoppingCartAction = new ShoppingCartAction();
// create and event instace to be called when an item is added to the cart.
var eventInstance = new EventInstanceListenerThis("update_item_quantity", this, function (thisObject, eventInstanceData) {
// update the Payment summary section with the new shipping option price.
thisObject.verifyCartQuantity(eventInstanceData.eventData.item_id, eventInstanceData.eventData.quantity);
});
// setup the instance to call back when the shopping cart action completes.
shoppingCartAction.setActionSucessEvent(eventInstance);
shoppingCartAction.exectuteAction ("update_item_quantity", postData);
}
// verifies that item elemet object quantity matches the server quantity provided and turn off the buffering flag.
// serverItemQuantity : the increase or decrease in the quantity ordered for the item.
// element : the shopping cart image.
this.verifyCartQuantity = function (serverItemId, severItemQuantity) {
checkParamSet (2, serverItemId, severItemQuantity);
if (serverItemId != this.itemId) {
throw new
Error("ItemManagerElement item ID ("+this.itemId+") dose not match that returned by the server ("+serverItemId+").");
}
if (severItemQuantity == this.itemQuantity) {
// the server quantity matches the element quantity. The item quantity has been set in the cart correctly.
// reset the buffering flag.
this.addToCartBuffering = false;
}
}
// displays the product details screen for the current gallary group element.
this.displayItemDetail = displayItemDetail;
function displayItemDetail () {
// create a new item detail management object for the current item.
var searchItemDetailManager = new SearchItemDetailManager (this.itemId, "#item-details-window");
// load and initalize the item detail screen so it can be displayed and functional.
searchItemDetailManager.display();
// get the item detail event manager, add setup a listener for the quantity changed event.
var eventManager = searchItemDetailManager.getEventManager();
// add ITEM_QTY_CHANGE event if item quantity changes on the product detail screen.
// return even data {itemId:, itemQuantity:}
eventManager.addListenerThis ("ITEM_QTY_CHANGE", this, function (thisObject, eventInstanceData) {
if (!empty(thisObject.eventManager)) {
// trigger the item quantity change event for all the items in item search listing listening for the quantity change
// the event for this item will also get triggered any need quantity modification will happen at that time.
var eventData = eventInstanceData.eventData;
thisObject.eventManager.triggerEvent("ITEM_QTY_CHANGE", eventData);
}
});
}
// sets the event manager to use when trigger the various item events.
// The ITEM_QTY_CHANGE change event should be registered
// return even data {itemId:, itemQuantity:}
this.setEventManager = function (eventManager) {
this.eventManager = eventManager;
// add a listener to the event for the ITEM_QTY_CHANGE event.
this.eventManager.addListenerThis ("ITEM_QTY_CHANGE", this, function (thisObject, eventInstanceData) {
// trigger the item quantity change event for all the items in item search listing listening for the quantity change
// the event for this item will also get triggered any need quantity modification will happen at that time.
$itemId = eventInstanceData.eventData.itemId;
$itemQuantity = eventInstanceData.eventData.itemQuantity;
thisObject.checkRefreshRequired($itemId, $itemQuantity);
});
}
// checks if a refresh of the quantity displayed for the item is required, the item ID matches the current item.
// $itemId : the item ID for which the quantity is to be refreshed.
// $itemQuantity : the new quantity of the item in the shopping crt.
this.checkRefreshRequired = function ($itemId, $itemQuantity) {
checkParamSet (2, $itemId, $itemQuantity);
if ($itemId == this.itemId) {
// the quantity change is for this item, update the quantity and the cart status.
this.updateCartQuantity ($itemQuantity);
}
}
}
// used to manage an inventory count queries item.
function InventoryCountSearchItemManager (galleryGroupElement) {
checkParamSet (1, galleryGroupElement);
this.galleryGroupElement = galleryGroupElement;
this.itemId = null; // the item Id search item being managed.
// Save the two item quantity controllers.
this.itemGoodQuantityControl = null;
this.itemBadQuantityControl = null;
this.eventManager = null; // an event manager used to trigger various item events.
this.isAnimateAddToCart = false; // updated to control that only item is animated at a time.
// initialize the object.
this.initialize = function () {
// get the item ID for the item group
this.itemId = $(this.galleryGroupElement).attr("data-item-id");
// create an event instance to call when any of the quantities change.
var eventInstance = new EventInstanceListenerThis ("quantity_changed", this, function (thisObject) {
thisObject._updateItemStatus();
})
// create the good quantity controllers
var itemQuantityControlElement = $(this.galleryGroupElement).find(".item-quantity-control");
this.itemGoodQuantityControl =
new SearchItemQuantityControl(this.itemId, itemQuantityControlElement, "update_inventory_count_item_quantity")
this.itemGoodQuantityControl.initializeWidget();
this.itemGoodQuantityControl.setQuantityChangeEvent(eventInstance);
// create the bad quantity controllers
itemQuantityControlElement = $(this.galleryGroupElement).find(".bad-item-quantity-control");
this.itemBadQuantityControl =
new SearchItemQuantityControl(this.itemId, itemQuantityControlElement, "update_inventory_count_item_bad_quantity")
this.itemBadQuantityControl.initializeWidget();
this.itemBadQuantityControl.setQuantityChangeEvent(eventInstance);
// create the family query control.
var callbackData = {'thisObject': this}; // callback data
$(this.galleryGroupElement).find(".item-group-query").off("click").click( callbackData, function (event) {
// animate the cart button when pressed.
event.data.thisObject.animateAddToCart(this);
// query the items and display them on the screen.
event.data.thisObject._queryItemGroup();
});
// initalize the display.
this._initializeDisplay();
}
// initialize the page display look controlled by JS.
this._initializeDisplay = function () {
// rount the coners elements
$(this.galleryGroupElement).find(".item-information").corner("30px");
$(this.galleryGroupElement).find(".item-return").corner("30px");
$(this.galleryGroupElement).find(".item-group-query").corner("30px");
}
// update the combined status for the item, to control the display of the good and bad quantity controllers.
this._updateItemStatus = function () {
// Get the current good and bad quantity value.
var goodItemQuantity = this.itemGoodQuantityControl.getQuantity();
var badItemQuantity = this.itemBadQuantityControl.getQuantity();
// find the item control elment where the display class is located.
var itemControlElement = $(this.galleryGroupElement).find(".item-control");
// remove any current control class from the element.
$(itemControlElement).removeClass("item-status-00").removeClass("item-status-01")
.removeClass("item-status-02").removeClass("item-status-03");
if (goodItemQuantity>0 && badItemQuantity>0) {
// both good and bad quantity are set on the item.
$(itemControlElement).addClass("item-status-03");
} else if (goodItemQuantity>0) {
// the good quantity is set on the item
$(itemControlElement).addClass("item-status-01");
} else if (badItemQuantity>0) {
// the bad quantity is set on the item.
$(itemControlElement).addClass("item-status-02");
} else {
// no quantity is set for the item.
$(itemControlElement).addClass("item-status-00");
}
}
// returns a query of all the items in the associated group.
this._queryItemGroup = function () {
// trigger the start loading event.
this.eventManager.triggerEvent("group_item_query_started");
// add the use the item ID to query the group of items.
var postData = [];
postData.push({'name': "item_group#item_id", 'value': this.itemId});
// extract the query item group event instance to be called when the group query finished loading.
var eventInstance = this.eventManager.getEventInstance("group_item_query_loaded");
// create the submit form object to submit the request to the server.
var pageSubmitRequest = new PageSubmitRequest();
if (!isEmpty(eventInstance)) {
// setup and event manager to trigger and event when the submit is completed
pageSubmitRequest.setSubmitSucessEvent (eventInstance);
}
pageSubmitRequest.submit("inventory_count_display_group", postData, "#search-results");
}
// annimate the cart button when it is pressed.
// element : the shopping cart image.
this.animateAddToCart = function (element) {
if (!this.isAnimateAddToCart) {
// cart animation is not running so we can start it.
// set flag to indicate the cart animation is running.
this.isAnimateAddToCart = true;
$(element).find("img").effect("scale", {percent: "125"}, 300, function () {
$(element).find("img").effect("scale", {percent: "80"}, 300, function () {
// set the flag to indicate the cart animation has stopped.
this.isAnimateAddToCart = false;
}.bind(this));
}.bind(this));
}
}
// sets the event manager to use when trigger the various item events.
// Events trigger:group_item_query - the item group query has loaded.
this.setEventManager = function (eventManager) {
this.eventManager = eventManager;
}
}
//the item manager, manages the display and interaction of the item for the user.
//it controls the displaying of an item in two states, summary and detail
//a fade out fade in transition is used to animage the change
//containerElement : jquery object for the element contining the elements to be apply the transition class
//actionElementObj : a plain object containing action elements and the classes to be applied to the container element
//- detailActionElement: Jquery object for the elements used to trigger the display of the item detail view
//- detailClass: the class name to be applied to the container element trigger the display of the item details
//- returnActionElement: Jquery object for the elements used to trigger the return to the initialial item view
//- returnClass: The calls name to be applied to the container element to trigger the diaply of the initialial item view
//
// Parameters
//searchType = 1 (default) - shopping cart search, 2 - inventory count search
function SearchItemManager (searchType) {
checkParamSet (1, searchType);
/* this.isAnimateAddToCart = false; // updated to control that only one cart is animated at a time.
this.addToCartTimer = null; // used to save the timer used to buffer/accumulate add/remove item clicks
this.addToCartItemId = null; // the current items being added to the cart and bufferred.
this.addToCartCount = 0; // the count of the total items to add or remove from the cart.
this.addToCartBuffering = false; // an indication if the add to cart clicks are being buffered and the add to cart timer was started.
*/
// the search type.
this.searchType = searchType;
// this is set by the search result manager, for some query statuses.
this.eventManager = null; // an event manager used to trigger various item events.
// create an event manager to be used by all the created item monitor the quantity changed event.
this.itemEventManager = new EventManager();
// used by all items to report general changes that might effect all items.
// add ITEM_QTY_CHANGE event if item quantity changes on the product detail screen.
// return even data {itemId:, itemQuantity:}
this.itemEventManager.addEvent("ITEM_QTY_CHANGE");
// initialize the list by adding the click event to any next page buttons.
this.initializeWidget = function () {
/* We were using this for inventory count methods, seems we stoped using it.
*
* // create a new event manager to trigger when the various item events are activated.
// all items managed will trigger the same event manager.
this.eventManager = new EventManager();
// add the group item query event.
this.eventManager.addEvent("group_item_query_started");
this.eventManager.addEvent("group_item_query_loaded");*/
// create an state manager to control the functional elements of an summary
// and detail states of the item and set the appropriate classes..
var actionElementObj = {detailActionElement:".item-information",
detailClass: "display-item-detail",
returnActionElement: ".item-return",
returnClass: "display-item-summary"}
var itemStateManager = new ElementStateManager ("#search-results .gallery-group-inner", actionElementObj);
// initialize any current items found in a list.
itemStateManager.initializeWidget();
// create a item manager element for each item listed.
$(".item-list-page .gallery-group").each( function (index, element) {
if (this.searchType == 1) {
// using the original shopping cart search.
var itemManagerElement = new SearchItemManagerElement(element);
itemManagerElement.initializeWidget();
// use a common event manager for all items to the quantity change event can be processed by all of them.
// when the item detail screen quantity changes, it can be a change to any item list on the product detail screen (family)
itemManagerElement.setEventManager(this.itemEventManager);
} else if (this.searchType == 2) {
// using the new quantity controller object.
var inventoryCountSearchItemManager = new InventoryCountSearchItemManager(element);
inventoryCountSearchItemManager.initialize();
// set the event manger to be used to trigger various item events.
inventoryCountSearchItemManager.setEventManager(this.eventManager);
} else {
throw new Error("Search type value "+this.searchType+ "not defined.");
}
}.bind(this));
}
// return ad event manager which is triggered by the various item events.
// Events trigger:group_item_query_started - the item group query been activate, used to perform cleanup for new query results.
// group_item_query_loaded - the item group query has loaded.
// this.getEventManager = function () {
// return this.eventManager;
// }
// sets the event manager to use when trigger the various item events.
// Events trigger:group_item_query - the item group query has loaded.
this.setEventManager = function (eventManager) {
this.eventManager = eventManager;
}
}
// the oject finds lines up the items found in the container to be in the same row
// the page/html needs to be loaded before this function in called
// containerElement - JQuery object representing container elements in which the containing elements are to be balanced
// itemElement - JQuery selector used to select elments within the container to be balanced
// uses classes to determine height to assign the gallery group item, this allows for
// better CSS handling if screen size changes.
function BlanceRowManager (containerElement, itemElement){
checkParamSet (2, containerElement, itemElement);
// find all the matching containe elements
this.containerElement = containerElement;
this.itemElement = itemElement;
// this function balances all rows found withing container elements
// all items are in the same row if there top offset matches. Elements found to be within the same row
// are all set to the same hight to allow for the proper alignment of the float right CSS that is assumed to
// be set on the elments being blanaces.
this.balanceRow = function () {
// balance the items found in each continer element
var thisObject = this; // this object reference the blance row manager, to call functions
$(this.containerElement).each(function () {
thisObject.balanceItemsInContainer (this);
});
}
// this function balance the items found within the specific container
// containerElement - JQuery element
this.balanceItemsInContainer = function (containerElement) {
checkParamSet (1, containerElement);
var offsetRowTop = null; // offset to items in the row from the top of the screen.
var numItemsInRow = 0; // the number of items in a row
var countItemsInRow = 0; // a count of the number of current items in a row.
// var maxHeightInRow = 0; // the maximum height of item in the row.
var itemElementInRow = new Array();
var isImagePortait = false;
// find all the item elements within the container to be balanced
var thisObject = this; // this object reference the blance row manager, to call functions
$(containerElement).find(this.itemElement).each( function () {
// find the top offset of the first item, used to detemine what items are in the row
// as they should have the same offset value.
if (offsetRowTop == null) {
offsetRowTop = $(this).offset().top;
}
// use the top row as a count of the number of items to be displayed in a row.
if (offsetRowTop == $(this).offset().top) {
// this items is part of the first row
numItemsInRow++;
}
// remove any previous height class added to the item.
$(this).find(".gallery-group-inner").removeClass("max-gallery-group-height");
// if we have reached the end of the number of items in a row, we want to reset the maximum
// row height and row count for the new row.
if (countItemsInRow >= numItemsInRow) {
if (isImagePortait) {
// set all the item in the row to the same class to set the standart hieght if needed.
thisObject.blanceItemsInRow (countItemsInRow, "max-gallery-group-height", itemElementInRow);
}
countItemsInRow = 0;
isImagePortait = false;
// maxHeightInRow = 0;
}
// increment the count of the number of row items and store a list of of element to be processed.
itemElementInRow[countItemsInRow] = this;
countItemsInRow++;
// determ if the items is portrait, if yes set the flag to indicate one portrait items exists on the line.
if ($(this).hasClass("image-portrait")) {
isImagePortait = true;
}
})
}
// make item item in the row found in the array the same height.
this.blanceItemsInRow = function (countItemsInRow, heightClassName, itemElementInRow) {
checkParamSet (3, countItemsInRow, heightClassName, itemElementInRow);
for (let i = 0; i < countItemsInRow; i++) {
$(itemElementInRow[i]).find(".gallery-group-inner").addClass(heightClassName);
}
}
}
/*
//the oject finds lines up the items found in the container to be in the same row
//the page/html needs to be loaded before this function in called
//containerElement - JQuery object representing container elements in which the containing elements are to be balanced
//itemElement - JQuery selector used to select elments within the container to be balanced
function BlanceRowManager (containerElement, itemElement){
checkParamSet (2, containerElement, itemElement);
// find all the matching containe elements
this.containerElement = containerElement;
this.itemElement = itemElement;
// this function balances all rows found withing container elements
// all items are in the same row if there top offset matches. Elements found to be within the same row
// are all set to the same hight to allow for the proper alignment of the float right CSS that is assumed to
// be set on the elments being blanaces.
this.balanceRow = function () {
// balance the items found in each continer element
var thisObject = this; // this object reference the blance row manager, to call functions
$(this.containerElement).each(function () {
thisObject.balanceItemsInContainer (this);
});
}
// this function balance the items found within the specific container
// containerElement - JQuery element
this.balanceItemsInContainer = function (containerElement) {
checkParamSet (1, containerElement);
var offsetRowTop = null; // offset to items in the row from the top of the screen.
var numItemsInRow = 0; // the number of items in a row
var countItemsInRow = 0; // a count of the number of current items in a row.
var maxHeightInRow = 0; // the maximum height of item in the row.
var itemElementInRow = new Array();
// find all the item elements within the container to be balanced
var thisObject = this; // this object reference the blance row manager, to call functions
$(containerElement).find(this.itemElement).each( function () {
// find the top offset of the first item, used to detemine what items are in the row
// as they should have the same offset value.
if (offsetRowTop == null) {
offsetRowTop = $(this).offset().top;
}
// use the top row as a count of the number of items to be displayed in a row.
if (offsetRowTop == $(this).offset().top) {
// this items is part of the first row
numItemsInRow++;
}
// if we have reached the end of the number of items in a row, we want to reset the maximum
// row height and row count for the new row.
if (countItemsInRow >= numItemsInRow) {
// balance all the items in the completed row by making them the same height.
thisObject.blanceItemsInRow (countItemsInRow, maxHeightInRow, itemElementInRow);
countItemsInRow = 0;
maxHeightInRow = 0;
}
// increment the count of the number of row items and store a list of of element to be processed.
itemElementInRow[countItemsInRow] = this;
countItemsInRow++;
// compare the current height of the the previous maximum height and determine the new maximum row height.
if (maxHeightInRow < $(this).height()) {
maxHeightInRow = $(this).height();
}
})
}
// make item item in the row found in the array the same height.
this.blanceItemsInRow = function (countItemsInRow, maxHeightInRow, itemElementInRow) {
checkParamSet (3, countItemsInRow, maxHeightInRow, itemElementInRow);
for (let i = 0; i < countItemsInRow; i++) {
$(itemElementInRow[i]).height(maxHeightInRow);
}
}
} */
//Manages the list of results returned based on one of the page search methods.
// Controls the item list scrolling, item controls, balancing of displyed rows of items.
//searchType = 1 (default) - shopping cart search, 2 - inventory count search
function SearchResultManager(searchType) {
// this is the cleanup manager logs objects that require clean up after some event.
this.cleanUpManager = new CleanUpManager();
this.searchType = searchType;
if (empty(this.searchType)) {
// default the search type to 1 - for shopping cart search.
this.searchType = 1;
}
// this.eventManager = null; // an event manager used to trigger various retult events, current only supporting item events.
// create a new event manager to trigger when the various item events are activated.
// all items managed will trigger the same event manager.
this.eventManager = new EventManager();
// add the group item query event.
this.eventManager.addEvent("group_item_query_started");
this.eventManager.addEvent("group_item_query_loaded");
// create the blance row manger which will balance the list of item displayed into a row.
this.balanceRowManager = new BlanceRowManager("#search-results", ".gallery-group");
// when the intialize is called, the search results have already been loaded, by the gallery or attribute search
this.initialize = function () {
// first we will blance the currently select search results.
this.balanceRowManager.balanceRow();
// create the item list manager for the search results.
var itemListManager = new SearchItemListManager ("#search-results", this.searchType);
// initlaize the item list manager.
itemListManager.initializeWidget();
// add the item list manager to be clean up manager.
this.cleanUpManager.add (itemListManager);
// create and item manger to manage the functionality of a search item result.
// on the next page, the search item event manger is being changed.
var itemManager = new SearchItemManager (this.searchType);
// set the event manager to use to stop getting change when the next page of items loads.
// a little mess should try and clean up the logic.
itemManager.setEventManager(this.eventManager);
// initialize any current items found in a list.
itemManager.initializeWidget();
// // save the item event manager which triggered by item events.
// this.eventManager = itemManager.getEventManager();
/*
// create and event to be called after the data load successfully.
var eventManager = new EventManager ("item_page_loaded", function () {
// initalize the list item controls and look.
itemManager.initializeWidget();
})
// retrieve and event instance and set up to be called by the page loader.
var eventInstance = eventManager.getEventInstance("item_page_loaded");
*/
// create a new envent instance that also calls the balancer routine when the list scrolls.
var eventInstance = new EventInstanceListenerThis ("item_page_loaded", this, function (thisObject, eventInstanceData) {
// balance the new list items load, maybe should just do the new ones loaded only.
thisObject.balanceRowManager.balanceRow();
// initalize the list item controls and look.
itemManager.initializeWidget();
});
// setup the event instance to be called after the page of item data is loaded.
itemListManager.setPageLoadEvent(eventInstance);
// create a new envent instance that also calls the balancer routine screen resizes.
var resizeEventInstance = new EventInstanceListenerThis ("screen_resize", this, function (thisObject, eventInstanceData) {
// balance the new list items load, maybe should just do the new ones loaded only.
thisObject.balanceRowManager.balanceRow();
});
// setup the event instance to be called after the page of item data is loaded.
itemListManager.setResizeEvent(resizeEventInstance);
}
// clean up method.
this.cleanUp = function () {
// call the clean up found for the local objects
this.cleanUpManager.cleanUp();
}
// return an event manager which is triggered by the search result events.
// Events trigger:group_item_query_started - the item group query been activate, used to perform cleanup for new query results.
// group_item_query_loaded - the item group query has loaded.
this.getEventManager = function () {
return this.eventManager;
}
}
//setup the control of the screen attribute search selectors.
//searchType = 1 (default) - shopping cart search, 2 - inventory count search
function SearchAttributeManager(searchType) {
this.searchType = searchType;
if (empty(this.searchType)) {
// default the search type to 1 - for shopping cart search.
this.searchType = 1;
}
// this is the cleanup manager logs objects that require clean up after some event.
this.cleanUpManager = new CleanUpManager();
// the current attribute search results manager
this.searchResultManager = null;
// the current class attribute selector object.
this.classAttributeSelector = null;
this.eventManager = null; // an event manager used to track the attribute activit event.
if (this.searchType == 1) {
this.submitRequestActivity = "attribute_search"; // the attribute search result activity.
} else {
this.submitRequestActivity = "inventory_count_attribute_search"; // the inventory count attrubute search result activity.
}
this.initialize = function () {
// create the selector control for the attribute selection criteria.
this.classAttributeSelector = new SearchAttributeClassSelector ("#attribute-form-entry");
// initlaize the widget - adding triggers.
this.classAttributeSelector.initializeWidget();
// create a new event manager to handle trigger when the attribute search is activated.
this.eventManager = new EventManager();
// add the active attribute search event name which will be triggered when the activate search has
// been initialize and values returned.
var eventInstance = this.eventManager.addEvent("attribute_search_active");
// setup the search attribute activity.
var callbackData = {'thisObject': this, 'eventInstance': eventInstance}; // callback data
$("#attribute-search-button").off("click").click(callbackData, function(event) {
// validate all the input fields
var isValid = submitValidation("#attribute-form");
if (isValid) {
// submitted the attribute search data for processing..
// create the main pade utitlity object.
var mainPageUtility = new MainPageUtility();
// load the search results basd on the attribe criteria and create the result manager after the load
mainPageUtility.submitFormPage
("#attribute-form", event.data.thisObject.submitRequestActivity, "#search-results", event.data.eventInstance);
}
// return false so no other triggers are not activated.
return false;
});
// create a function to listen for the attribute search event activate.
this.eventManager.addListenerThis ("attribute_search_active", this, function (thisObject) {
thisObject._initializeSearchResultManager();
});
}
// clean up method.
this._initializeSearchResultManager = function () {
// before a new gallery is activated, cleanup any required object associated with an previously oppened gallery
// dose work right here for group item search, the results where already loaded. Usually return to the search gallery
// sub menu activate the cleanup.
// if (!empty(this.searchResultManager)) {
// this.searchResultManager.cleanUp();
// }
// setup all the items list managers for the gallery items loaded
this.searchResultManager = new SearchResultManager(this.searchType);
this.searchResultManager.initialize();
// get the generated results events manager.
var eventManager = this.searchResultManager.getEventManager();
// event listener to trigger when group item query has been activate, before loading.
eventManager.addListenerThis ("group_item_query_started", this, function (thisObject) {
// clean up any previous results.
if (!empty(thisObject.searchResultManager)) {
thisObject.searchResultManager.cleanUp();
}
});
// event listener to trigger when group item query has finished loading.
eventManager.addListenerThis ("group_item_query_loaded", this, function (thisObject) {
// regenerate the results manager to manage the group item query results.
thisObject._initializeSearchResultManager();
});
}
// return and event manager which is trigger when the gallery is activated.
// Eventrs trigger:gallery_active - the gallery has been activated and displayed.
this.getEventManager = function () {
return this.eventManager;
}
// clean up method.
this.cleanUp = function () {
// call the clean up found for the local objects
this.cleanUpManager.cleanUp();
// cleanup the search results object manger only if it exists.
if (!empty(this.searchResultManager)) {
this.searchResultManager.cleanUp();
}
// clear the any class attibutes selected.
this.classAttributeSelector.clearSelectedAttributes();
// reset the dsplay of the attibute class, shriking open sections. This stuff should really be somewhere else
this.classAttributeSelector.display();
}
}
//the class controls the functioning of the gallery browser menu.
//containerElement : jquery object for the containing the gallery menu htlm structure
//the "gallery_active" event is triggered when a gallery is viewed.
function SearchGalleryMenuManager (containerElement) {
checkParamSet (1, containerElement);
this.containerElement = containerElement;
this.eventInstance = null; // an event instance to fire when a gallery is activated.
this.submitRequestActivity = "display_gallery"; // Default to normal search page activity value.
// adds the click events to the maneu items.
this.initializeWidget = function () {
// add the click event all gallery images.
var callbackData = {'thisObject': this}; // callback data
$(this.containerElement).find(".gallery-icon").off("click").click( callbackData, function (event) {
// thisElment is OK here, the bind creates a new function for this. The this (container of the image) is
// set to the paramater, thisElement.
// highlight the image when it is pressed then show the gallery.
$(this).find("img").effect("highlight", {color: "rgba(218, 165, 32, 0.5)"}, 300, function (thisElement) {
// tigger the search menu event.
this.showGalleryItems(thisElement);
}.bind(event.data.thisObject, this));
});
// add the click event to all gallery titles
$(this.containerElement).find(".gallery-text").off("click").click( callbackData, function (event) {
//STILL NEED TO FIX THIS ONE.
// highlight the gallery name when it is pressed then show the gallery.
$(this).effect("highlight", {color: "rgba(218, 165, 32, 0.5)"}, 300, function () {
// tigger the search menu event.
event.data.thisObject.showGalleryItems(this);
});
// thisObject.showGalleryItems(this);
});
}
// makes and AJAX call to received the galery items
this.showGalleryItems = function (element) {
checkParamSet (1, element);
// extract the galery ID for the items to be displayed.
var galleryId = $(element).attr("data-gallery-id");
// add the gallery Id as submitted data.
var postData = [];
postData.push({name: "gallery_list#gallery_id", value: galleryId});
// create the submit form object to submit the request to the server.
var pageSubmitRequest = new PageSubmitRequest();
if (!isEmpty(this.eventInstance)) {
// setup and event manager to trigger and event whent he post is completed
pageSubmitRequest.setSubmitSucessEvent (this.eventInstance);
}
pageSubmitRequest.submit(this.submitRequestActivity, postData, "#search-results");
// pageSubmitRequest.submit("display_gallery", postData, "#search-results");
}
// sets up the event istance to be used when one of the galleries has been activiated
// eventInstance : an event instance to be fired when a gallery is activaited.
this.setGalleryActiveEvent = function (eventInstance) {
checkParamSet (1, eventInstance);
this.eventInstance = eventInstance;
}
// sets up the submit request activity to use whan calling back to the server, to support inventory count
// submitRequestActivity : the submit request acivity name, value found in the PHP form submit block (handler)
this.setSubmitRequestActivity = function (submitRequestActivity) {
checkParamSet (1, submitRequestActivity);
this.submitRequestActivity = submitRequestActivity;
}
}
//controls the working of the gallery search and the display of gallery items.
// searchType = 1 (default) - shopping cart search, 2 - inventory count search
function SearchGalleryManager (searchType) {
this.searchType = searchType;
if (empty(this.searchType)) {
// default the search type to 1 - for shopping cart search.
this.searchType = 1;
}
// this is the cleanup manager logs objects that require clean up after some event.
this.cleanUpManager = new CleanUpManager();
// the current gallery search results manager
this.searchResultManager = null;
this.eventManager = null; // an event manager used to track the gallery activit event.
if (this.searchType == 1) {
this.submitRequestActivity = "display_gallery"; // the shopping cart search result activity.
} else {
this.submitRequestActivity = "inventory_count_display_gallery"; // the inventory count search result activity.
}
this.initialize = function () {
// create the selector control for the attribute selection criteria.
var galleryMenu = new SearchGalleryMenuManager ("#browse-gallery-menu");
// initlaize the widget - adding triggers.
galleryMenu.initializeWidget();
galleryMenu.setSubmitRequestActivity(this.submitRequestActivity);
// create a new event manager, not using the global one because global event not needed.
// if we needed it we should have passed it in as a parameter or something.
this.eventManager = new EventManager();
// add the active gallery event name which will be called by the galery menu when the
// gallery load event is triggered
var eventInstance = this.eventManager.addEvent("gallery_active");
// specify the envent manager to use to trigger the gallery activity event.
galleryMenu.setGalleryActiveEvent (eventInstance);
// create a function to listen for the event and set the class of the "search-main" element to
// search-gallery-active.
this.eventManager.addListenerThis ("gallery_active", this, function (thisObject) {
thisObject._initializeSearchResultManager();
});
}
// clean up method.
this._initializeSearchResultManager = function () {
// before a new gallery is activated, cleanup any required object associated with an previously oppened gallery
// dose work right here for group item search, the results where already loaded. Usually return to the search gallery
// sub menu activate the cleanup.
// if (!empty(this.searchResultManager)) {
// this.searchResultManager.cleanUp();
// }
// setup all the items list managers for the gallery items loaded
this.searchResultManager = new SearchResultManager(this.searchType);
this.searchResultManager.initialize();
// get the generated results events manager.
var eventManager = this.searchResultManager.getEventManager();
// event listener to trigger when group item query has been activate, before loading.
eventManager.addListenerThis ("group_item_query_started", this, function (thisObject) {
// clean up any previous results.
if (!empty(thisObject.searchResultManager)) {
thisObject.searchResultManager.cleanUp();
}
});
// event listener to trigger when group item query has finished loading.
eventManager.addListenerThis ("group_item_query_loaded", this, function (thisObject) {
// regenerate the results manager to manage the group item query results.
thisObject._initializeSearchResultManager();
});
}
// clean up method.
this.cleanUp = function () {
// call the clean up found for the local objects
this.cleanUpManager.cleanUp();
// cleanup the search results object manger only if it exists.
if (!empty(this.searchResultManager)) {
this.searchResultManager.cleanUp();
this.searchResultManager = null;
}
}
// return and event manager which is trigger when the gallery is activated.
// Eventrs trigger:gallery_active - the gallery has been activated and displayed.
this.getEventManager = function () {
return this.eventManager;
}
}
// External class list.
// CleanUpManager;
// EventManager;
// MainPageUtility;
// HtmlWidgetPageManager;
// PageFormSubmitRequest;
//
// create a new search page manager to load and implement the search page functionality.
/**
* @class SearchPageManager
* @memberOf SearchPageManager
*/
function SearchPageManager () {
// this is the cleanup manager used to initialize things when a new page is loaded.
this.cleanUpManager = new CleanUpManager();
// the search menu manager object.
this.searchSubMenuManager = null;
// load and inialize the search page and load the html in the page-main DIV.
/**
* @method draw
*/
this.loadPage = function () {
// var thisObject = this;
eventInstanceListener = new EventInstanceListenerThis ("search_page_loaded", this, function () {
this.initialize();
});
/* // create an event instance to inialize the page functionality after the page is loaded
eventManager = new EventManager ("search_page_loaded", function () {
thisObject.initialize();
});*/
// create the page manager unitiliy
mainPageUtility = new MainPageUtility();
// load the search page.
mainPageUtility.loadMainPage ("search", eventInstanceListener);
// mainPageUtility.loadMainPage ("search", eventManager.getEventInstance("search_page_loaded"));
}
// initializes entire page javascript functionliaty, including main page .
this.initializePage = function () {
// initialize the default page javascript functionality
// create and initialize the main page manager
var mainPageManager = new MainPageManager();
mainPageManager.initialize();
// inistalize the search page specific javascript.
this.initialize();
}
// initializes the search page javascript functionality.
this.initialize = function () {
// initialize the form widget functionality.
// not used right now, would be used for the serach text field.
var htmlWidgetPageManager = new HtmlWidgetPageManager ();
htmlWidgetPageManager.initialize();
// initialize the page display look controlled by JS.
this.initializeDisplay();
// initialize the submenu activities
this.initializeSubMenu();
// setup the attribute selector.
this.initializeAttributeSearch();
// setup the gallery manager.
this.initializeGallerySearch();
// scroll to the top of the page
scrollWindowToTop();
}
// initialize the page display look controlled by JS.
this.initializeDisplay = function () {
// found the coners elements
$(".gallery-text").corner("5px");
$("#search-menu .menu-option").corner("5px");
$("#item-list-heading").corner("5px");
$("#attribute-search-button.menu-option").corner("5px");
$(".attribute-class a").corner("5px");
}
// setup the search sub menu and handlers.
this.initializeSubMenu = function () {
// create the new sub menu manager;
this.searchSubMenuManager = new SearchSubMenuManager ();
this.searchSubMenuManager.initialize();
// get the sub menu event manager.
var eventManager = this.searchSubMenuManager.getEventManager();
// if any search is inactivated, we want to clean up and pending search results.
eventManager.addListenerThis ("search_not_active", this, function (thisObject) {
// really just want to reset the search results list
thisObject.cleanUp(); // Maybe should be more specific about the clean up activity.
// reinitialize the search page manager object
// ***** NOTE *****
// reinitializing the object caused trouble becase multiple click handlers where being added to
// html elements twice, used off('click') to make things work properly now not but it items I
// am re-runing the trigger setup code when not needed.
thisObject.initialize();
});
eventManager.addListenerThis ("search_gallery_only", this, function (thisObject) {
// reset the list of serach results
thisObject.cleanUp(); // Maybe should be more specific about the clean up activity.
// reinitialize the search page manager object
// ***** NOTE *****
// reinitializing the object caused trouble becase multiple click handlers where being added to
// html elements twice, used off('click') to make things work properly now not but it items I
// am re-runing the trigger setup code when not needed.
thisObject.initialize();
});
eventManager.addListenerThis ("search_attribute_only", this, function (thisObject) {
// reset the list of serach results
thisObject.cleanUp(); // Maybe should be more specific about the clean up activity.
// reinitialize the search page manager object
// ***** NOTE *****
// reinitializing the object caused trouble becase multiple click handlers where being added to
// html elements twice, used off('click') to make things work properly now not but it items I
// am re-runing the trigger setup code when not needed.
thisObject.initialize();
});
}
// setup the gallery serach object and handlers.
this.initializeGallerySearch = function () {
// create the new gallery search manager;
var gallerySearchManager = new SearchGalleryManager();
gallerySearchManager.initialize();
// get the gallery event manager.
var eventManager = gallerySearchManager.getEventManager();
// if the gallery gets activated, want to trigger the display of the search sub menu.
eventManager.addListenerThis ("gallery_active", this, function (thisObject) {
// set the search submenu into the gallery active status.
thisObject.searchSubMenuManager.setGalleryAciveState();
// rescroll to the top of the page
scrollWindowToTop();
});
// add the gallery manager to the cleanup routine.
this.cleanUpManager.add (gallerySearchManager);
}
// setup the attribute serach object and handlers.
this.initializeAttributeSearch = function () {
// create the new attribute search manager;
var attributeSearchManager = new SearchAttributeManager ();
attributeSearchManager.initialize();
// get the attribute event manager.
var eventManager = attributeSearchManager.getEventManager();
// create an event instance to be used as a triggered when the attribute search is activated.
eventManager.addListenerThis ("attribute_search_active", this, function (thisObject) {
// set the search submenu into the gallery active status.
thisObject.searchSubMenuManager.setAttributeSearchAciveState();
// rescroll to the top of the page
scrollWindowToTop();
});
// add the gallery manager to the cleanup routine.
this.cleanUpManager.add(attributeSearchManager);
}
// clean up method.
this.cleanUp = function () {
// call the clean up found for the local objects
this.cleanUpManager.cleanUp();
}
}
//create a new contact US page manager to load and implement the contact us email page functionality.
function ContactUsPageManager () {
// load and inialize the contact us page.
this.loadPage = function () {
eventInstanceListener = new EventInstanceListenerThis ("contact_us_page_loaded", this, function () {
this.initialize();
});
/* // create an event instance to inialize the page functionality after the page is loaded
eventManager = new EventManager ("contact_us_page_loaded", function () {
thisObject.initialize();
});*/
// create the page manager unitiliy
mainPageUtility = new MainPageUtility();
// load the search page.
mainPageUtility.loadMainPage ("contact_us", eventInstanceListener);
// mainPageUtility.loadMainPage ("contact_us", eventManager.getEventInstance("contact_us_page_loaded"));
}
// initializes entire page javascript functionliaty, including main page .
this.initializePage = function () {
// initialize the default page javascript functionality
// create and initialize the main page manager
var mainPageManager = new MainPageManager();
mainPageManager.initialize();
// inistalize the search page specific javascript.
this.initialize();
}
// initializes the contact us page functionality.
this.initialize = function () {
// initialize the form widget functionality.
// not used right now, would be used for the serach text field.
var htmlWidgetPageManager = new HtmlWidgetPageManager ();
htmlWidgetPageManager.initialize();
// setup the email submit activity.
$("#send_email").off("click").click(function() {
// validate all the input fields
var isValid = submitValidation();
if (isValid) {
// submit the email form to the server only is the validation of all the fields passed.
// submit the email form data to the server and display the result in page-main
submitFormPage("#email-form", "send_email");
}
// scroll to the top of the page
scrollWindowToTop();
// return false so no other triggers are not activated.
return false;
});
}
}
//create a manager of check out sub menu elements and the controlling of the the display using class attributes
function CheckoutSubMenuManager () {
// the event manager which fires when the various sum menu items are activated.
this.eventManager = new EventManager;
// setup the sub menu envents.
this.eventManager.addEvent ("entry_not_active"); // the entry section on the checkout page has not been activiated.
this.eventManager.addEvent ("entry_active"); // the entry section on the check out page is activated.
this.eventManager.addEvent ("process_payment"); // the payment process of the check out paga have been activaite.
// ... and more menu events here.
// initializes the subment functionality functionality.
// add event manager to sub menu buttons, options
this.initialize = function () {
var callbackData = {'thisObject': this}; // callback data
// add click event to the starting of the billing and shipping details entry.
$("#cart-menu-option-start-entry").off("click").click(callbackData, function (event) {
$(this).effect("highlight", {color: "rgba(218, 165, 32, 0.5)"}, 300, function () {
// change the class of the bill entry section to be active.
$("#billing-shipping-entry").removeClass().addClass("entry-active");
// fire the event for the sub menu.
this.eventManager.triggerEvent ("entry_active");
}.bind(event.data.thisObject));
// return false so no other triggers are not activated.
return false;
});
// setup the check out payment activity, submits the billing and shipping details and then processes the payment.
$("#payment-option-paypal").off("click").click(callbackData, function(event) {
$(this).effect("highlight", {color: "rgba(218, 165, 32, 0.5)"}, 300, function () {
// fire the event for the sub menu.
this.eventManager.triggerEvent ("process_payment");
}.bind(event.data.thisObject));
// return false so no other triggers are not activated.
return false;
});
}
// return and event manager which is trigger when the various sub menu functionality is activated.
// The following event are fired: search-not-active ...
this.getEventManager = function () {
return this.eventManager;
}
}
//create a manager of check out sub menu elements and the controlling of the the display using class attributes
//initializeManager : set to TRUE to automatically initialize the manager, FALSE to not initialize the manager, defulat value is TRUE
function CheckoutShippingOptionsManager (initializeManager) {
// need to be clared before the initialization function that used it.
// var thisObject = this; // when defined function to call ahead, the this in the function did not refer to the object (referred to fuction).
this.selectedEventInstance = null; // the event instance to be called when a new shipping option is selected.
this.currentAddress = null; // the current address object.
if (empty(initializeManager)) {
// the initialize value was not set so default it it TRUE
initializeManager = true;
}
if (initializeManager) {
// automatically initialize the shipping option manager.
initialize.bind(this)();
}
// var thisObject = this; // when defined function to call ahead, the this in the function did not refer to the object (referred to fuction).
// initializes the shipping option functionality functionality.
this.initialize = initialize;
function initialize () {
// initialize the shipping options section class to indicate if the shipping options have been selected.
// can's call this before it is defined..
setShippingOptionsFoundClass.bind(this)();
// thisObject.setShippingOptionsFoundClass();
// initialize the current shipping options select.
setSelectedOptionClass.bind(this)();
var callbackData = {'thisObject': this}; // callback data
// add the click event to the shipping rate item, the radio button in not clicked because it is hidden.
$("#shipping-rate-list .shipping-rate-item").off("click").click(callbackData, function (event) {
// the the radio button property of the selected shipping rate option to selected.
$(this).find(".shipping-method-radio-button input").prop("checked", true);
$(this).effect("highlight", {color: "rgba(218, 165, 32, 0.5)"}, 300, function () {
// add the select options class to the selected shipping option.
event.data.thisObject.setSelectedOptionClass();
});
// fire the shipping option changed event.
if (!empty(event.data.thisObject.selectedEventInstance)) {
event.data.thisObject.selectedEventInstance.triggerEvent();
}
// return false so no other triggers are not activated.
return false;
});
}
// set the event instance to be called with a new shipping option is selected.
this.setSelectedEventInstance = function (eventInstance) {
// check that the parameter was set.
checkParamSet (1, eventInstance);
this.selectedEventInstance = eventInstance;
}
// returns the price of the currently selected shipping option.
this.getSelectedPrice = function () {
var currentPrice = null;
// select all the radio buttons for shipping options
$("#shipping-rate-list .shipping-method-radio-button input.widget-input-field").each( function(index) {
if ($(this).prop("checked")) {
// this is the shipping option that was select. get the price.
// find containing shipping rate option of the checked radio button.
var shippingRateOption = $(this).parents(".shipping-rate-item");
// find the price
currentPrice = $(shippingRateOption).find(".shipping-cost input").val();
}
});
return parseFloat(currentPrice);
}
// sets the class of the shipping option to the selected class status or no select status.
this.setSelectedOptionClass = setSelectedOptionClass;
function setSelectedOptionClass() {
// select all the radio buttons for shipping options
$("#shipping-rate-list .shipping-method-radio-button input.widget-input-field").each( function(index) {
if ($(this).prop("checked")) {
// this is the shipping option that was select. get the price.
$(this).parents(".shipping-rate-item").addClass("shipping-option-selected").removeClass("shipping-option-not-selected");
} else {
// this shipping option was not selected.
$(this).parents(".shipping-rate-item").addClass("shipping-option-not-selected").removeClass("shipping-option-selected");
}
});
}
// set the shipping address for with to display shipping option values for.
this.setShippingAddress = function (address) {
// check that the parameter was set.
checkParamSet (1, address);
// check if any of the shipping address information required for the
// pass the shipping address details back to the server and return an updated set of shipping options as and html snipet.
// The address along with the items in the cart will termine the shipping rates and options
// build up the address information.
var postData = [];
postData.push({name: "address#city", value: address.city});
postData.push({name: "address#state_prov", value: address.state_prov});
postData.push({name: "address#zip_postal", value: address.zip_postal});
postData.push({name: "address#country_code", value: address.country_code});
// create a new page submitted request object.
var pageSubmitRequest = new PageSubmitRequest();
// set the success event to the we can evaluate if the shipping option data was loaded successfully.
// want to change the shipping options section message and re-initialize events if the options where loaded successsfully.
var eventInstance = new EventInstanceListenerThis ("shipping_options_loaded", this, function (thisObject, eventInstanceData) {
// re-initalize the shipping option controls.
thisObject.initialize();
// fire the shipping option changed event.
if (!empty(thisObject.selectedEventInstance)) {
thisObject.selectedEventInstance.triggerEvent();
}
});
pageSubmitRequest.setSubmitSucessEvent (eventInstance);
// the shipping option html snipit will be displayed with the shipping rate list box element.
pageSubmitRequest.submit("get_shippping_options", postData, "#shipping-rate-list-box", 2, 2);
}
// clears all the shipping options being presented. And show the no shipping options available message.
this.clearShippingOptions = function () {
// need to create a class to toggle the display of the no shipping options message.
// remove the class indicating the shipping options are being displayed and change it to not being displayed.
$("#shipping-options").removeClass("shipping-options-found").addClass("shipping-options-not-found");
// clear out out the shipping options structure which will be loaded again.
$("#shipping-rate-list-box").empty();
// fire the shipping option changed event.
if (!empty(this.selectedEventInstance)) {
this.selectedEventInstance.triggerEvent();
}
}
// sets the class of the which indicates if any shipping options where selected.
// updated the section message.
this.setShippingOptionsFoundClass = setShippingOptionsFoundClass;
function setShippingOptionsFoundClass () {
if (isShippingOptionsFound()) {
// if (this.isShippingOptionsFound()) {
// shipping options where found, set the class of the shipping option section to shipping-options-found
$("#shipping-options").addClass("shipping-options-found").removeClass("shipping-options-not-found");
} else {
// no shipping option where found, set the class of the shipping options secion to shipping-options-not-found
$("#shipping-options").addClass("shipping-options-not-found").removeClass("shipping-options-found");
}
}
// returns and indication if shipping options have been loaded. Return TRUE if shipping option where loaded.
this.isShippingOptionsFound = isShippingOptionsFound;
function isShippingOptionsFound () {
var isShippingOptionsFound = false;
// checking if any data was set in the shipping rate list box. If not, no shipping options are being displayed.
// maybe should use some other data like a hiddend field to determine the shipping options found state when the reponse
// is returned from the server?
if ($("#shipping-rate-list-box").children().length > 0) {
isShippingOptionsFound = true;
}
return isShippingOptionsFound;
}
}
//create a manager to control the shipping location option ratio button functionliaty
//initializeManager : set to TRUE to automatically initialize the manager, FALSE to not initialize the manager, defulat value is TRUE
function CheckoutShippingLocationManager (initializeManager) {
this.changedLocationEventInstance = null; // the even instance called then the event location is changed.
if (empty(initializeManager)) {
// the initialize value was not set so default it it TRUE
initializeManager = true;
}
if (initializeManager) {
// automatically initialize the shipping option manager.
initialize.bind(this)();
}
// initializes the shipping option functionality functionality.
this.initialize = initialize;
function initialize () {
var callbackData = {'thisObject': this}; // callback data
// add click even to the radio button propery..
$("#shipping_location_options .widget-input-field").off("click").click(callbackData, function (event) {
// fire the shipping location changed event.
if (!empty(event.data.thisObject.changedLocationEventInstance)) {
event.data.thisObject.changedLocationEventInstance.triggerEvent();
}
// return false so no other triggers are not activated.
// return false; // This false for the radio button stopped the value from changing.
});
}
// set the event instance to be called with a new shipping option is selected.
this.setChangedLocationEventInstance = function (eventInstance) {
// check that the parameter was set.
checkParamSet (1, eventInstance);
this.changedLocationEventInstance = eventInstance;
}
// returns the currently selected shipping location value.
// 1 - shipping address same as billing address
// 2 - use alternate shipping address
this.getShippingLocation = function () {
var shippingLocationOption = null;
// select all the radio buttons for shipping options
$("#shipping_location_options .widget-input-field").each( function(index) {
if ($(this).prop("checked")) {
// this is the currently selected shipping location option value.
shippingLocationOption = $(this).val();
}
});
return shippingLocationOption;
}
}
// represents an address object.
function Address () {
this.address1 = null; // first line of address.
this.address2 = null; // second line of address.
this.city = null; // city name.
this.state_prov = null; // state of provice code.
this.zip_postal = null; // zip or postal code.
this.country_code = null; // country code.
// returns and inidcation if the address has been completely entered.
// completeness should also include valid but not doing that.
this.isAddressComplete = function () {
var isAddressComplete = true;
if (empty(this.address1)) {
// the first address line was not set.
isAddressComplete = false;
} else if (empty(this.city)) {
// the city name was not set.
isAddressComplete = false;
} else if (empty(this.state_prov)) {
// the state/provice code was not set.
isAddressComplete = false;
} else if (empty(this.zip_postal)) {
// the zip code was not set.
isAddressComplete = false;
} else if (empty(this.country_code)) {
// the country code was not set.
isAddressComplete = false;
}
return isAddressComplete;
}
}
// create a manager to contorl the entry of the billing details associated with current order
//initializeManager : set to TRUE to automatically initialize the manager, FALSE to not initialize the manager, defulat value is TRUE
function CheckoutBillingDetailsEntryManager (initializeManager) {
this.billingAddressChangedEventInstance = null; // the even instance called the billing address has.
if (empty(initializeManager)) {
// the initialize value was not set so default it it TRUE
initializeManager = true;
}
if (initializeManager) {
// automatically initialize the shipping option manager.
initialize.bind(this)();
}
// var thisObject = this; // when defined function to call ahead, the "this" in the function did not refer to the object.
// initializes the shipping option functionality functionality.
this.initialize = initialize;
function initialize () {
// fire event if any of the billing address fields changes
var callbackData = {'thisObject': this}; // callback data
$("#billing-address .widget-input-field").off("change").change(callbackData, function (event) {
// fire the billing address changed event.
if (!empty(event.data.thisObject.billingAddressChangedEventInstance)) {
event.data.thisObject.billingAddressChangedEventInstance.triggerEvent();
}
// return false so no other triggers are not activated.
return false; // This false fro the radio button stopped the value from changing.
});
}
// set the event instance to be called when the billing address had changed.
this.setBillingAddressChangedEventInstance = function (eventInstance) {
// check that the parameter was set.
checkParamSet (1, eventInstance);
this.billingAddressChangedEventInstance = eventInstance;
}
// returns true if the billing has been completely entered.
this.isBillingAddressComplete = function () {
// create an address object and initialize its data.
var address = this.getBillingAddress();
return address.isAddressComplete();
}
// returns an address object containing the billing address.
this.getBillingAddress = function () {
// create an address object and initialize its data.
var address = new Address();
address.address1 = $("#billing-address .address1 .widget-input-field").val();
address.address2 = $("#billing-address .address2 .widget-input-field").val();
address.city = $("#billing-address .city .widget-input-field").val();
address.state_prov = $("#billing-address .state-prov .widget-input-field").val();
address.zip_postal = $("#billing-address .zip-postal .widget-input-field").val();
address.country_code = $("#billing-address .country-code .widget-input-field").val();
return address;
}
}
// create a manager to contorl the entry of the shipping details associated with current order
//initializeManager : set to TRUE to automatically initialize the manager, FALSE to not initialize the manager, defulat value is TRUE
function CheckoutShippingDetailsEntryManager (initializeManager) {
this.shippingAddressChangedEventInstance = null; // the even instance called the billing address has.
if (empty(initializeManager)) {
// the initialize value was not set so default it it TRUE
initializeManager = true;
}
if (initializeManager) {
// automatically initialize the shipping option manager.
initialize.bind(this)();
}
// initializes the shipping option functionality functionality.
this.initialize = initialize;
function initialize () {
// fire event if any of the shipping address fields changes
var callbackData = {'thisObject': this}; // callback data
$("#shipping-address .widget-input-field").off("change").change(callbackData, function (event) {
// fire the shipping address changed event.
if (!empty(event.data.thisObject.shippingAddressChangedEventInstance)) {
event.data.thisObject.shippingAddressChangedEventInstance.triggerEvent();
}
// return false so no other triggers are not activated.
return false; // This false for the radio button stopped the value from changing.
});
}
// set the event instance to be called when the shipping address had changed.
this.setShippingAddressChangedEventInstance = function (eventInstance) {
// check that the parameter was set.
checkParamSet (1, eventInstance);
this.shippingAddressChangedEventInstance = eventInstance;
}
// returns true if the billing has been completely entered.
this.isShippingAddressComplete = function () {
// create an address object and initialize its data.
var address = this.getShippingAddress();
return address.isAddressComplete();
}
// returns an address object containing the shipping address.
this.getShippingAddress = function () {
// create an address object and initialize its data.
var address = new Address();
address.address1 = $("#shipping-address .address1 .widget-input-field").val();
address.address2 = $("#shipping-address .address2 .widget-input-field").val();
address.city = $("#shipping-address .city .widget-input-field").val();
address.state_prov = $("#shipping-address .state-prov .widget-input-field").val();
address.zip_postal = $("#shipping-address .zip-postal .widget-input-field").val();
address.country_code = $("#shipping-address .country-code .widget-input-field").val();
return address;
}
// set the shipping address with the given address details.
// address : an address object used to initialize the shipping address from.
this.setShippingAddress = function (address) {
// check that the parameter was set.
checkParamSet (1, address);
// extract the address data and display it.
$("#shipping-address .address1 .widget-input-field").val(address.address1);
$("#shipping-address .address2 .widget-input-field").val(address.address2);
$("#shipping-address .city .widget-input-field").val(address.city);
$("#shipping-address .state-prov .widget-input-field").val(address.state_prov);
$("#shipping-address .zip-postal .widget-input-field").val(address.zip_postal);
$("#shipping-address .country-code .widget-input-field").val(address.country_code);
// we do not need to trigger the event here, maybe can add a paramter in the future
// only used now to set the billing address as the ship to.
// trigger the shipping address changed event.
// this.shippingAddressChangedEventInstance.triggerEvent();
}
// disables the shipping address details entry fields.
this.disableShippingAddress = function () {
// disable all the shipping address input fields.
$("#shipping-address .widget-input-field").attr("disabled", "");
}
// enables the shipping address details entry fields.
this.enableShippingAddress = function () {
// enable all the shipping address input fields.
$("#shipping-address .widget-input-field").removeAttr("disabled");
}
// clear the shipping address details.
this.clearShippingAddress = function () {
// clear all the shipping address input fields.
$("#shipping-address .widget-input-field").val("");
// do not trigger the event, just used when clearing data to use detaul billing address as
// shipping address.
// trigger the shipping address changed event.
// this.shippingAddressChangedEventInstance.triggerEvent();
}
}
//create a manager of payment summary section of the checkout page
//ializeManager : set to TRUE to automatically initalize the manager, FALSE to not initalize the manager, defulat value is TRUE
function CheckoutPaymentSummryManager (initalizeManager) {
// this object is the current checkup payment summary manager object.
var thisObject = this;
if (empty(initalizeManager)) {
// the initalize value was not set so default it it TRUE
initalizeManager = true;
}
if (initalizeManager) {
// automatically initalize the shipping option manager.
initialize.bind(this)();
}
// initializes the shipping option functionality functionality.
thisObject.initialize = initialize;
function initialize () {
}
// set the payment summary cart total value.
thisObject.updateCartTotal = function (newCartTotal) {
// update the displayed cart total.
newCartTotal = parseFloat(newCartTotal);
newCartTotal = newCartTotal.toFixed(2);
$("#payment-details .cart-total .widget-field").text(newCartTotal);
// calculate the new total payment.
thisObject.calculateTotalPayment();
}
// set the payment summary shipping cost value.
thisObject.updateShippingCost = function (newShippingCost) {
// update the displayed shipping cost.
newShippingCost = parseFloat(newShippingCost);
newShippingCost = newShippingCost.toFixed(2);
$("#payment-details .shipping-cost .widget-field").text(newShippingCost);
// calculate the new total payment.
thisObject.calculateTotalPayment();
}
// calcualte the total payment and update the payment summary value.
thisObject.calculateTotalPayment = function () {
// Get the cart total and shipping cost amounts.
var cartTotal = $("#payment-details .cart-total .widget-field").text();
var shippingCost = $("#payment-details .shipping-cost .widget-field").text();
var totalPayment = parseFloat(cartTotal) + parseFloat(shippingCost);
totalPayment = totalPayment.toFixed(2);
$("#payment-details .payment-total .widget-field").text(totalPayment);
}
}
// The server request resouce object used to communicate data returning from a server page request.
// jsonObject - contains the html resouce information
function ServerRequestResource (jsonObject) {
// The status of the request.
this.status = jsonObject.status;
// the type of content retuned the resource data.
// see PHP HtmlResourceContentType object (HTML_PAGE = 1, HTML_FRAGMENT = 2, JSON_OBJECT = 3
this.contentType = jsonObject.content_type;
// data contained in the request of the content type.
this.data = jsonObject.data;
// returns true if there was some error processing the page request.
this.isError = function () {
var isError = false;
if (this.status == -1) {
// there was some error that occurrent during the page request.
isError = true;
}
return isError;
}
// returns true if the content of the message is an HTML fragment.
this.isHtmlFragment = function () {
var isHtmlFragment = false;
if (this.contentType == 2) {
// there was some error that occurrent during the page request.
isHtmlFragment = true;
}
return isHtmlFragment;
}
// returns true if the request was completed successfully with warning or errors.
this.isSuccessful = function () {
var isSuccessful = false
if (this.status == 0) {
// the request compleleted successfully.
isSuccessful = true;
}
return isSuccessful;
}
// returns true if the content of the message is an HTML fragment.
this.isJsonObject = function () {
var isJsonObject = false;
if (this.contentType == 3) {
// the data conject is a json object.
isJsonObject = true;
}
return isJsonObject;
}
// returns true if the content of the message is an HTML fragment.
this.isUrl = function () {
var isUrl = false;
if (this.contentType == 4) {
// the data conject is a json object.
isUrl = true;
}
return isUrl;
}
// return the status value.
this.getStatus = function () {
return this.status;
}
// return the data.
this.getData = function () {
return this.data;
}
}
// classes to handle differenent of server requests and loading animations.
// create a server http request object used to connect to the server
// resourceName - is http resource on the server to access
// the http request returns event for "REQUEST_WAITING", "REQUEST_SUCCESSFUL", "REQUEST_FAILED"
// the a server request resource object is returned when the "REQUEST_SUCCESSFUL" envent is triggered (as event data)
// If there are no listeners for the REQUEST_FAILED event, the default action will be to throw and exception.
function ServerHttpRequest (resouceName) {
checkParamSet (1, resouceName);
this.resouceName = resouceName;
// an event manager used to trigger event related to the request.
this.eventManager = new EventManager();
// add the various events.
this.eventManager.addEvent("REQUEST_WAITING");
this.eventManager.addEvent("REQUEST_SUCCESSFUL");
this.eventManager.addEvent("REQUEST_FAILED");
// sends a post request to the server for the resource attached to the object
// postData - data object to sumbmit
this.sendRequest = function (postData) {
thisObject = this;
$.post(this.resouceName, postData, 'json')
.done ( function (data, status) {
thisObject._postDone(data, status);
})
.fail (this._postFail);
// trigger the request waiting event
this.eventManager.triggerEvent("REQUEST_WAITING");
}
// handles the sucessful return of the post request.
this._postDone = function (data, status) {
var jsonObject = null;
try {
jsonObject = $.parseJSON(data);
} catch(e) {
// the data was not formated in JSON correctly. Create are own server request resource setting the data returned from
// the server as some html
// alert(e); // error in the above string (in this case, yes)!
// display the java script error.
var pageErrorManager = new PageErrorManager();
pageErrorManager.addJavascriptError(e.stack);
pageErrorManager.show();
// pass back the server response and an error
jsonObject = {'status':-1, 'content_type':2, 'data':data};
// // include the json part error apart of the error message.
// var htmlError = " Javascript Error: "+e.stack+
// " Server Error: