element (should change this)
var className = $(element).html();
return className;
}
}
//the object contols a scrolling events on the specified object.
//should only allow one scroll event trigger once when the item enters the viewing area.
//scrollElement : a jquey object specifything the scrollable element.
function ScrollManager (scrollElement){
// setting used to conctrol the scroll tracking respnsiveness
this.didScroll = false;
this.lastScrollTop = 0;
this.delta = 5;
this.scrollDelay = 500; // 1/2 second
this.scrollElement = scrollElement;
this.setIntervalId = null; // the ID of the set interval trigger set.
this.inViewAreaMap = new Map(); // A map of element for with the in view area event should be fired.
this.inViewAreaKey = 0; // A key used to index item of the map.
// use an event manager to trigger the needed callback functions
this.eventManager = null;
if (empty(this.scrollElement)) {
// if the scrollElement is not set, default to the browser window.
this.scrollElement = window;
}
// intalize the scroll manager to start its management.
this.initializeWidget = function () {
// attach the managage the scroll event fired against the scrollable element
// set the didScroll value to true, and will only process the scroll event after a delay.
// scrolling once even seems to call this twice, tries returning false after event.
var callbackData = {'thisObject': this}; // callback data
$(this.scrollElement).scroll(callbackData, function(event) {
event.data.thisObject.didScroll = true;
// return false; // did not help double scroll.
});
// setup the delay to for checking if the scroll even was fired.
this.setIntervalId = setInterval(function() {
if (this.didScroll) {
// The object has scroll so call the scrolling handler
this.didScroll = false;
this.hasScrolled();
}
}.bind(this), this.scrollDelay);
}
// stop the scroll manager from detection scrolling, otherwise, if may keep running even if the object is removed.
this.stop = function () {
if (!empty(this.setIntervalId)) {
clearInterval(this.setIntervalId);
}
}
// perform scroll handler checks.
this.hasScrolled = function () {
var scrollTop = $(this.scrollElement).scrollTop(); // save the scroll top value.
// Make sure they scroll more than delta
// some times the scroll trigger is being called twice, maybe flowing to parent?
// this delta check is stopping that.
if (Math.abs(this.lastScrollTop - scrollTop) > this.delta) {
this.lastScrollTop = scrollTop;
// process all the view are triggers
for (var viewAreaData of this.inViewAreaMap.values()) {
if (!viewAreaData.eventTriggered) {
// the event has not fired for this item yet. Only want to fire it once.
this.inViewAreaCheck (viewAreaData);
}
}
}
}
// trigger the specified event name using the event manager when the element scrolls into view.
// element: A jquery object representing the elment that gets scrolled into the view area
// eventInstance: The event instance object to be fired when the element has scrolled into view
// returns an ID used to remove the item from the in view area trigger as required.
this.addInViewArea = function (targetElement, eventInstance) {
checkParamSet (3, targetElement, eventInstance);
// add the target element and the callback function to the array.
var dataObject = {'targetElement': targetElement, 'eventInstance': eventInstance, 'eventTriggered': false};
this.inViewAreaKey++;
this.inViewAreaMap.set (this.inViewAreaKey, dataObject);
return this.inViewAreaKey;
}
// removes the specified key from being triggered by the in view area function during scrolling.
this.removeInViewArea = function (inViewAreaKey) {
checkParamSet (1, inViewAreaKey);
this.inViewAreaMap.delete(inViewAreaKey);
}
// determine if the targetElement has enter the view port and activate the callback function if it has.
// viewAreaData : a view aread data object represending the area to be checked.
// element: A jquery object representing the elment that gets scrolled into the view area
// eventInstance: The event instance object to be fired when the element has scrolled into view
// eventTriggered: A flag set to true after the view area event is triggered.
this.inViewAreaCheck = function (viewAreaData) {
checkParamSet (2, viewAreaData.targetElement, viewAreaData.eventInstance);
// determine the position of the element relative to the view port.
var elementOffset = $(viewAreaData.targetElement).offset();
var positionOffset = $(viewAreaData.targetElement).position();
var windowHeight = $(window).height();
var windowScroll = $(window).scrollTop();
var targetElementOffsetTop = elementOffset.top;
var windowInViewBottom = windowHeight + windowScroll
if (windowInViewBottom >= targetElementOffsetTop) {
// trigger the event.
viewAreaData.eventTriggered = true;
viewAreaData.eventInstance.triggerEvent();
}
}
// cleanup any associated data when the object is no longer needed.
this.cleanUp = function () {
// stop ship scroll manager for continuing to track scroll movement.
this.stop();
}
}
//this object controls the a list of items and paging
//selection ID
// class='item-list-page'
// class='item-list-next-page'
// input button with attribute data_item_list_next_page with the next page value
// input hidden with name = "next_page" and value of the next page
// ...
//...
//selectorId is a jquery object identifiying the item list structure container
function SearchItemListManager (selectorId, searchType) {
checkParamSet (1, selectorId);
this.selectorId = selectorId;
this.searchType = searchType;
if (empty(this.searchType)) {
// default the search type to 1 - for shopping cart search.
this.searchType = 1;
}
if (this.searchType == 1) {
this.submitRequestActivity = "next_page"; // the shopping cart search next page result activity.
} else {
this.submitRequestActivity = "inventory_count_next_page"; // the inventory count search next page result activity.
}
this.scrollManager = null;
this.inViewAreaId; // the ID of the current trigger/button registered witht scroll object for activating the list paging.
// used to store items to be triggered after the page is loaded.
this.pageLoadEventMap = new Map(); // A map of element for with the page load event should be activate.
this.pageLoadEventKey = 0; // A key used to index items of the map.
this.eventInstance = null; // the event instance to be activated after the page data loads.
// this is the cleanup manager logs objects that require clean up after some event.
this.cleanUpManager = new CleanUpManager();
// initialize the list by adding the click event to any next page buttons.
this.initializeWidget = function () {
// Find the next page input button at the end of list of items.
var nextPageButton = $(this.selectorId).find(".item-list-next-page input").first();
if ($(nextPageButton).is("input")) {
// we do not need to inialize the scroll manager if the next button was not found.
if (isEmpty(this.scrollManager)) {
// create the new window scroll manager (or use the existing one).
this.scrollManager = new ScrollManager();
// initialize the scroll maager
this.scrollManager.initializeWidget();
// add the scroll manager to the object cleanup list. We need to stop the scroll checking
this.cleanUpManager.add(this.scrollManager);
}
// create a new event manager
var eventManager = new EventManager();
// setup the event that will be called when the element scrolls into view.
var eventInstance = eventManager.addEvent("end_of_list");
// setup the event listener to call the spacific callback function when the end of the list is reached.
var callbackData = {'thisObject': this, 'nextPageButton': nextPageButton}
eventManager.addListener("end_of_list", callbackData, function (eventInstanceData) {
eventInstanceData.callbackData.thisObject.loadNextPage(eventInstanceData.callbackData.nextPageButton);
});
// add the next button into the inview area trigger, trigge the loading of items when the button
// scrolled into the viewing area.
this.inViewAreaId = this.scrollManager.addInViewArea(nextPageButton, eventInstance);
}
}
// load the next page of mapped search results.
// element in the input button with a form element as the parent.
this.loadNextPage = function (element) {
checkParamSet (1, element);
// get the value of the next page. the sibbling element
var nextPage = $(element).siblings("input").val();
// get the parent of the element which would be the containing form to submit.
var itemListForm = $(element).parent();
// remove the next page button, a new one will be loaded.
// remove the next page element from the scroll bar event listener list.
this.scrollManager.removeInViewArea (this.inViewAreaId);
// remove current new page button elment of the next call setting up the list manager will
// add first button again into the list view area trigger.
$(itemListForm).remove();
if (nextPage > 0) {
// create the submit form object to submit the request to the server.
var pageFormSubmitRequest = new PageFormSubmitRequest();
var eventInstance = new EventInstanceListenerThis ("new_page_loaded", this, function (thisObject) {
// initialize the control for the new page segment loaded.
thisObject.initializeWidget ();
if (!empty(thisObject.eventInstance)) {
// trigger the page loading event for any listerers to it.
thisObject.eventInstance.triggerEvent();
}
})
pageFormSubmitRequest.setRequestSucessEvent (eventInstance);
// submit the form to retrieve the next page of data. The next page is in a hidden field
// should setup the page number and data and pass it to the service
pageFormSubmitRequest.submit(itemListForm, this.submitRequestActivity, this.selectorId, 2, 2);
// pageFormSubmitRequest.submit(itemListForm, "next_page", this.selectorId, 2, 2);
}
}
// set the event to be activated when the new set of items load.
this.setPageLoadEvent = function (eventInstance) {
this.eventInstance = eventInstance;
}
// clean up method.
this.cleanUp = function () {
// call the clean up found for the local objects
this.cleanUpManager.cleanUp();
// clear any previous search results.
$(this.selectorId).empty();
}
}
//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.
// 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);
});
// 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-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
// element : the shopping cart image.
// cartQuantity: cart quantity to be displayed.
this.updateCartQuantity = function (cartQuantity) {
// 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;
}
}
}
//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));
}
}
}
// The object controls the quantity control widget with the specified parts
// Class item-add-to-cart - element clicked whent item added
// Class item-count-cart - 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)) {
this.eventInstance.triggerEvent();
}
}
// 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 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.eventManager = null; // an event manager used to trigger various item events.
// initialize the list by adding the click event to any next page buttons.
this.initializeWidget = function () {
/* // 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();
} 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;
}
}
//Manages the list of results returned based on one of the page search methods.
//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");
this.initialize = function () {
// 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 () {
itemManager.initializeWidget();
})
// retrieve and event instance and set up to be called by the page loader.
var eventInstance = eventManager.getEventInstance("item_page_loaded");
// setup the event instance to be called after the page of item data is loaded.
itemListManager.setPageLoadEvent(eventInstance);
}
// 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) {
// var thisElement = this; // saving the original element that was clicked.
// 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:
"+data;
//
// jsonObject = {'status':-1, 'content_type':2, 'data':htmlError};
}
// just trigger the request successful event, may we should handle the status.
// assume the listener knows how to handle the data.
this.eventManager.triggerEvent("REQUEST_SUCCESSFUL", jsonObject);
}
// how do we report the error issues my the call back function.
// throw error, where does it go. It displayed on the consol.
this._postFail = function (data, status) {
// determine if anyone is listening ont he request failed event.
if (this.eventManager.hasListeners("REQUEST_FAILED")) {
// we found listerners on the request failed event so trigger the event to handle the error.
this.eventManager.triggerEvent("REQUEST_FAILED");
} else {
// no listeners for the failure event so just throw an error.
// need the try and catch the error here because it is an aysnchronise call pack.
// need to develed a more general way to impleament the stack reporting of the
// error so it is obvious, not just in the consol.
try {
throw new Error("HTML service request failed for resource " + this.resouceName + " (status:" + status + ")");
} catch (e) {
alert("stack details:\n" + e.stack);
}
}
}
// reutrn the event manager managing the request event.
this.getEventManager = function () {
return this.eventManager;
}
}
//classes to handle differenent of server requests and loading animations.
// Manages the various of application requests to the sever and how the interation occur with the page.
function PageServerRequestManager () {
// targetElement : the html element to display the html data returned by the submit
this.targetElement = null;
// targetInsertionType : 1 (default) - overwrite content of element;
// 2 - append as a sibling of the target element
this.targetInsertionType = 1;
// actionElement : the JQuery element which initiated the request, if the action element
// is specified, it will be disabled until the request completes.
this.actionElement = null;
// 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.
this.waitType = 1;
// the event instance to be triggered when the load has completed successfully.
this.requestSuccessEventInstance = null;
// the request implements the form submitted request management. the result returned contains a status
// and HTML content containing the form data, with validation class information and or modified data.
// the status will be returned as part of the event instance, the html content will be used to override
// the target element. When the form in submitted, the entire screen will be disabled.
// resouceName - resource name on the server to access
// sorceFrom : the form to element to be submitted to the server, a Jquery element value
// activity : the submit activity being performed, has to be a valid type defined on the server
this.submitPageRequest = function (resouceName, sourceForm, activity, targetElement) {
checkParamSet (3, resouceName, sourceForm, activity);
// setup the manager control elements
this.targetElement = targetElement;
this.targetInsertionType = 1; // override the target element content
this.waitType = 1; // inactivate the whole page when loading.
// serialize the form data to send to the server
var postData = $(sourceForm).serializeArray();
// add the operation to the data submitted to the server.
postData.push({name: "oper", value: activity});
this._sendRequest(resouceName, postData);
}
// submit an action type request to the server.
// resouceName - resource name on the server to access
// activity : the submit activity being performed, has to be a valid type defined on the server
// actionElement: the element number to initiate the action request, will disabled until the request is completed
// postData : array data to be submitted to the server, as name value pairs, set to NULL if not used
// targetElement: the JQuery elment into which any result data will be displayed, set to NULL if not used
this.actionPageRequest = function (resouceName, activity, actionElement, postData, targetElement) {
checkParamSet (3, resouceName, activity, actionElement);
// setup the manager control elements
this.targetElement = targetElement;
this.targetInsertionType = 1; // override the target element content
this.waitType = 2; // inactivate the target element when loading loading.
// setup the action element to be disabled until the request is completed.
this.actionElement = actionElement;
// disable any action elemnt specfied, to avoid multiple clicks
this._disableActionElement ();
if (empty(postData)) {
// the post data was not set, need to initialize to push an object onto the post data
postData = [];
}
// add the operation to the data submitted to the server.
postData.push({name: "oper", value: activity});
this._sendRequest(resouceName, postData);
}
// sets up the event manger to be used. the when the post request returns a successful
// result and data is insert into the page, the specified event manager will fire a trigger
// with the specified event name.
// eventInstance : an event instance to be fired when the page request and been completed sucessfully
this.setRequestSucessEvent = function (eventInstance) {
this.requestSuccessEventInstance = eventInstance;
}
// sends the geneneric request using the server html request object.
// resouceName - resource name on the server to access
// postData - data object to sumbmit
this._sendRequest = function (resouceName, postData) {
// create the new HTTP server request object
var serverHttpRequest = new ServerHttpRequest (resouceName);
// get event manager and setup event callbacks required
var eventManager = serverHttpRequest.getEventManager();
// add the event listener for when the the call has been made and waiting for the request to finish.
eventManager.addListenerThis ("REQUEST_WAITING", this, function (thisObject) {
// perform waiting for request functionality.
thisObject._requestWaiting();
});
// add the event listener for when the call has sucessfully completed.
eventManager.addListenerThis ("REQUEST_SUCCESSFUL", this, function (thisObject, eventInstanceData) {
// activate the waiting animation.
thisObject._requestSuccessful(eventInstanceData);
});
// send the request to the server.
serverHttpRequest.sendRequest (postData);
}
// process a request successful event.
this._requestSuccessful = function (eventInstanceData) {
// activate the waiting animation.
this._removeWaitIcon();
// create an html resouce object from the data returned by the request.
var serverRequestResource = new ServerRequestResource(eventInstanceData.eventData);
// process and html fragment contained in the page server response if there was not error.
if (!serverRequestResource.isError()) {
if (!empty(this.targetElement) && serverRequestResource.isHtmlFragment()) {
// add the html fragment to the targetElement if it was set.
if (this.targetInsertionType == 1) {
// overwrite the content of the target element.
$(this.targetElement).html(serverRequestResource.data);
} else if (this.targetInsertionType == 2) {
// append the html at the end of the children of the target element.
$(this.targetElement).append(serverRequestResource.data);
}
}
} else {
// there is an error message in the request response
if (serverRequestResource.isHtmlFragment()) {
// the error is to displayed as HTML, displayed it in the error message section of the screen.
// display the java script error.
var pageErrorManager = new PageErrorManager();
pageErrorManager.addSeverError(serverRequestResource.data);
pageErrorManager.show();
}
}
// return the html resource object associated with the page request if the request success instance was set.
if (!empty(this.requestSuccessEventInstance)) {
// return the status and event data.
this.requestSuccessEventInstance.triggerEvent(serverRequestResource);
}
}
// process a request successful event.
this._requestWaiting = function () {
// activate the waiting animation.
this._showWaitIcon(this.targetElement, this.waitType);
}
// disable the action element and preform any disabling animations.
this._disableActionElement = function () {
if (!empty(this.actionElement)) {
$(this.actionElement).prop('disabled', true);
}
}
// add the wait item html snipit to the end of the target element and displays it.
// a unique ID is generated to track the wait icon inserted in the element
// should generate a random ID so mulitple parts or the page can be loaded at the same time
// targetElement : if target element is null and waitType is 2, no waiting icon will be displayed.
// 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.
this._showWaitIcon = function (targetElement, waitType) {
if (empty(waitType)) {
// default the wait type value.
waitType = 1;
}
var className = "";
if (waitType == 1) {
className = "wait-loading";
// if we are going to inactivate the page and one specific target element was specified
// attach the waiting element structure to the page body.
if (empty(targetElement)) {
targetElement = $("body");
}
} else if (waitType == 2) {
className = "wait-loading-element";
} else {
throw new Error("Wait type "+waitType+" is not defined.")
}
var waitTemplate = "" +
"
![Wait Loading Wait Loading]("+IMAGE_REPOSITORY+"images_pres/waiting.gif)
" +
"
";
if (!empty(targetElement)) {
$(targetElement).append(waitTemplate);
$("#8sudjshdkw").show();
}
}
// removes the wait item html snipit to the end of the target element.
// a unique ID is generated to track the wait icon inserted in the element
// waitIconId: Jquery object reprsenting the wait icon. - this want not implemented yet.
this._removeWaitIcon = function () {
$("#8sudjshdkw").remove();
}
// disable the current page, this might better defined in another class.
// the wait icon is displayed over the entire page.
this.disablePage = function () {
var className = "wait-loading";
var targetElement = $("body");
var waitTemplate = "" +
"
![Wait Loading Wait Loading]("+IMAGE_REPOSITORY+"images_pres/waiting.gif)
" +
"
";
if (!empty(targetElement)) {
$(targetElement).append(waitTemplate);
$("#7jh5gt69yy").show();
}
}
// enables a page that was disabled using the disablePage function.
this.enablePage = function () {
$("#7jh5gt69yy").remove();
}
}
//classes to handle differenent of server requests and loading animations.
// Implements a checkout page functionality server quests.
function CheckoutPageServerRequest () {
this.resouceName = "ajax/checkout_page.ajax.php";
// an event manager used to trigger event related to the request.
this.eventManager = new EventManager();
// add the various events.
this.eventManager.addEvent("BILLING_SHIPPING_DETAILS_UPDATED");
// implements the check out page process payment functionality. First the billing details are saved to the server
// and a successful save/validation, the the server payment process is initiated. An web address is returned to
// have the user approve the payment.
this.processPayment = function () {
// save and validate the current customer order details.
this._saveCustomerOrderDetails();
}
this._saveCustomerOrderDetails = function () {
// create the page sever request object.
var pageServerRequestManager = new PageServerRequestManager();
// create a new event instance to be activity when the request is completed successfully.
var eventInstance = new EventInstanceListenerThis ("REQUEST_SUCCESSFUL", this, function (thisObject, eventInstanceData) {
// when the save request is compleled pass the resource returned in the event data to the approve payment function.
checkParamSet (1, eventInstanceData);
thisObject._approvePayment(eventInstanceData.eventData);
})
pageServerRequestManager.setRequestSucessEvent(eventInstance);
// submitted the checkout page billing and validate/save the results.
pageServerRequestManager.submitPageRequest
(this.resouceName, "#billing-shipping-details", "save_customer_order", "#billing-shipping-details");
}
// initiate the payment approval process, if the customer order details have been validated and saved.
this._approvePayment = function (serverRequestResouce) {
checkParamSet (1, serverRequestResouce);
// the billing shipping details update. Trigger an event that is used update triggers and display of the data.
this.eventManager.triggerEvent("BILLING_SHIPPING_DETAILS_UPDATED");
if (serverRequestResouce.isSuccessful) {
// the customer order data was saved successfully with not validation errors. Setup the payment authoriazation
// and display the payment authorazation page using the http resource setup by the payment authorization.
// we want to display the wait icon while paypal order is setup and waiting to be redirected the PayPal URL.
// create the page sever request object.
var pageServerRequestManager = new PageServerRequestManager();
// create a new event instance to be activited when the request is completed successfully.
var eventInstance = new EventInstanceListenerThis ("REQUEST_SUCCESSFUL", this, function (thisObject, eventInstanceData) {
// when the save request is compleled pass the resource returned in the event data tot he approve payment function.
thisObject._athorizePayment(eventInstanceData.eventData);
})
pageServerRequestManager.setRequestSucessEvent(eventInstance);
// disable the page, when the PayPal URL returns, the wait will functionality will be reset (when the page reloads)
pageServerRequestManager.disablePage();
// setup the order payment details and retun the payment authorization link.
// the #payment-option-paypal element name should be here, should be setup somewhere else.
// No data is passed the since the payment_authorization uses the session order ID to contruct
// the paypal order from and request payment.
pageServerRequestManager.actionPageRequest
(this.resouceName, "payment_authorization", "#payment-option-paypal");
}
}
// use the HTTP auhtorization line found in the server resource to redirect the page the the authorizing service (PayPal).
this._athorizePayment = function (serverRequestResouce) {
if (serverRequestResouce.isSuccessful()) {
// no error occurred during the payment authorization request.
if (serverRequestResouce.isUrl()) {
// the authorization string was returned as the object.
paymentAuthorizationUrl = serverRequestResouce.getData();
// redirect to the payment authorization URL
httpRedirect(paymentAuthorizationUrl);
// static call not working but would like it to group utilities JsUtility.httpRedirect(paymentAuthorizationUrl);
} else {
throw new Error("Server data returned is not a URL as expected.");
}
} else {
throw new Error("Payment authorization requested failed with status ." + serverRequestResouce.getStatus());
}
}
// reutrn the event manager managing the request event.
this.getEventManager = function () {
return this.eventManager;
}
}
function ShoppingCartActionData () {
this.itemId = null; // the item ID assoicated with the actions.
this.itemQuantity = null; // the current item quantity
this.addToCartElement = null; // JQuery element representing the add to cart action, continer of the image.
.
this.removeFromCartElement = null; // JQuery element representing the remove from cart action, continer of the image.
this.deleteFromCartElement = null; // JQuery element representing the delete from cart action, continer of the image.
this.shoppingCartQuantityChangeAction = null; // the shopping cart action to call if the quantity changes +/- 1.
this.shoppingCartDeleteAction = null; // the shopping cart action to call delete the item from the cart.
}
// create a manager of shopping cart action like add to cart, remove from cart, and delete from cart. It manages the button animations
// and calling the server. Shared beteen the search page and checkout page functionality
// Three events are returned representing the possible shopping cart actions:
// add_to_cart - add one item to the cart
// remove_from_cart - remove one item from the cart
// delete_from_cart - delete the whole item from the cart
// cart_quantity_change - fired whenever the cart quantity changes
// the event data returned {'itemId': the item ID, 'quantityInCart': current cart quantity for the item, 'quantityChange': change in quantity}
//
// shoppingCartActionData - a shoppong cart action data object
// initializeManager : set to TRUE to automatically initialize the manager, FALSE to not initialize the manager, defulat value is TRUE
function ShoppingCartActionManager (shoppingCartActionData, initializeManager) {
checkParamSet (1, shoppingCartActionData);
this.shoppingCartActionData = shoppingCartActionData;
// validate the item ID and quantity are set.
checkParamSet (2, this.shoppingCartActionData.itemId, this.shoppingCartActionData.itemQuantity);
this.isAnimateAddToCart = false; // updated to control that only one item 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.shoppingCartActionEvent = null;
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 () {
// setup the shoppiong cart action event manager which will allow other function to receive events when
// the cart actions are activiated.
this.shoppingCartActionEvent = new EventManager();
this.shoppingCartActionEvent.addEvent("add_to_cart");
this.shoppingCartActionEvent.addEvent("remove_from_cart");
this.shoppingCartActionEvent.addEvent("delete_from_cart");
this.shoppingCartActionEvent.addEvent("cart_quantity_change");
var callbackData = {'thisObject': this}; // callback data
if (!empty(this.shoppingCartActionData.addToCartElement)) {
// add the click event to the add to cart button.
$(this.shoppingCartActionData.addToCartElement).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);
return false;
});
}
if (!empty(this.shoppingCartActionData.removeFromCartElement)) {
// add the click event to the remove from cart button
$(this.shoppingCartActionData.removeFromCartElement).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);
return false;
});
}
if (!empty(this.shoppingCartActionData.deleteFromCartElement)) {
// add the click event to the delete from cart button
$(this.shoppingCartActionData.deleteFromCartElement).off("click").click( callbackData, function (event) {
// animate the cart button when pressed. use same animation as add to cart
// the calling cart function should amimate the removing of the item from the shopping cart
// when it received the delete_from_cart event or change quantity event.
event.data.thisObject.animateAddToCart(this);
// remove one item from the cart.
event.data.thisObject.deleteFromCart(this);
return false;
});
}
}
// 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.shoppingCartActionData.itemQuantity = this.shoppingCartActionData.itemQuantity + quantity;
// the minumum item quantity can be is zero.
if (this.shoppingCartActionData.itemQuantity < 0) {
this.shoppingCartActionData.itemQuantity = 0;
}
// update the server cart quantity.
this.updateShoppingCartUpdate();
var eventName = null;
if (quantity > 1) {
// a new quantity of the item was added to the shopping cart.
eventName = "add_to_cart";
} else {
// some quantity was removed from the shopping cart.
eventName = "remove_from_cart";
}
// trigger the add to cart event.
var eventData = {'itemId': this.shoppingCartActionData.itemId,
'quantityInCart': this.shoppingCartActionData.itemQuantity,
'quantityChange': quantity};
this.shoppingCartActionEvent.triggerEvent (eventName, eventData);
// trigger the cart quantity change event.
this.shoppingCartActionEvent.triggerEvent ("cart_quantity_change", eventData);
}
// 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));
}
}
// 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.shoppingCartActionData.itemId});
postData.push({'name': "item_qty", 'value': this.shoppingCartActionData.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.shoppingCartActionData.shoppingCartQuantityChangeAction, 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.shoppingCartActionData.itemId) {
throw new
Error("ItemManagerElement item ID ("+this.shoppingCartActionData.itemId+") dose not match that returned by the server ("+serverItemId+").");
}
if (severItemQuantity == this.shoppingCartActionData.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;
}
}
// returns the shopping cart action event that is triggered.
this.getShoppingCartActionEvent = function () {
return this.shoppingCartActionEvent;
}
// remove all items from the system shopping cart.
// element : the shopping cart image.
this.deleteFromCart = function (element) {
checkParamSet (1, element);
// store the quantity delete.
var itemQuantityDeleted = this.shoppingCartActionData.itemQuantity
// set the item quantity to zero.
this.shoppingCartActionData.itemQuantity = 0;
// remove this item from the shopping cart.
this.deleteShoppingCartItem();
// trigger the delete from cart event.
var eventData = {'itemId': this.shoppingCartActionData.itemId,
'quantityInCart': this.shoppingCartActionData.itemQuantity,
'quantityChange': itemQuantityDeleted};
this.shoppingCartActionEvent.triggerEvent ("delete_from_cart", eventData);
// trigger the cart quantity change event.
this.shoppingCartActionEvent.triggerEvent ("cart_quantity_change", eventData);
}
// remove the item from the shopping cart. Stop any other quantity updates not sent to the server.
this.deleteShoppingCartItem = function () {
// stop any previous buffered update being sent to the server.
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);
}
}
// set flags to indicate no buffering of updates.
this.addToCartBuffering = false;
this.addToCartTimer = null;
this.serverShoppingCartDelete();
}
// send the request to the server to remove the shopping cart item.
this.serverShoppingCartDelete = function () {
// create the post data;
var postData = [];
postData.push({'name': "item_id", 'value': this.shoppingCartActionData.itemId});
// 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("delete_item", 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.shoppingCartActionData.shoppingCartDeleteAction, postData);
}
// returns the quantity in the cart for the item.
this.getQuantity = function () {
return this.shoppingCartActionData.itemQuantity;
}
}
//create a manager of a shopping cart item
//initializeManager : set to TRUE to automatically initialize the manager, FALSE to not initialize the manager, defulat value is TRUE
// Events: Quantity change event - returns event data {'item_id'}
function CheckoutShoppingCartItemManager (cartItemElement, initializeManager) {
checkParamSet (1, cartItemElement);
this.cartItemElement = cartItemElement;
this.quantityChangeEventInstance = null; // the event instance to be called when the quantity of the item changes.
// initialize the item ID the element manager is managing
this.itemId = $(this.cartItemElement).attr("data-item-id");
// initialize the item quantity.
this.itemQuantity = Number($(this.cartItemElement).find(".cart-item-qty p").text());
// store the item price used to update the item total when required.
this.itemPrice = Number($(this.cartItemElement).find(".cart-item-price p").text());
// the shopping cart action manager
this.shoppingCartActionManager = null;
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 () {
// setu the shopping cart manager initialization data.
var shoppingCartActionData = new ShoppingCartActionData();
shoppingCartActionData.itemId = this.itemId;
shoppingCartActionData.itemQuantity = this.itemQuantity;
shoppingCartActionData.addToCartElement = $(this.cartItemElement).find(".item-add-to-cart");
shoppingCartActionData.removeFromCartElement = $(this.cartItemElement).find(".item-remove-from-cart");
shoppingCartActionData.deleteFromCartElement = $(this.cartItemElement).find(".item-delete-from-cart");
shoppingCartActionData.shoppingCartQuantityChangeAction = "update_item_quantity";
shoppingCartActionData.shoppingCartDeleteAction = "delete_item";
// create a new shopping cart action manager for the item.
this.shoppingCartActionManager = new ShoppingCartActionManager(shoppingCartActionData);
// get the shopping cart action event.
var shoppingCartActionEvent = this.shoppingCartActionManager.getShoppingCartActionEvent();
// added the even listener for the cart quantity change event.
shoppingCartActionEvent.addListenerThis ("cart_quantity_change", this, function (thisObject, eventInstanceData) {
// update the displayed quantity of the cart item.
thisObject.updateCartQuantity(eventInstanceData.eventData.itemId, eventInstanceData.eventData.quantityInCart);
});
}
// updated the item quantity
// element : the shopping cart image.
// cartQuantity: cart quantity to be displayed.
this.updateCartQuantity = function (itemId, cartQuantity) {
if (itemId != this.itemId) {
throw new
Error("CheckoutShoppingCartItemManager item ID ("+this.itemId+") dose not match that returned by the shopping cart action ("+itemId+").");
}
// display the updated cart quantity.
$(this.cartItemElement).find(".cart-item-qty p").text(cartQuantity);
// update the item total.
var itemTotal = cartQuantity * this.itemPrice;
itemTotal = parseFloat(itemTotal).toFixed(2);
$(this.cartItemElement).find(".cart-item-total p").text(itemTotal);
// if the cart quantity is zero, perform the remove from cart animtion.
if (cartQuantity <= 0) {
this.animateDeleteFromCart();
}
// trigger the quanitty changed event instance.
if (!empty(this.quantityChangeEventInstance)) {
var data = {'item_id':this.itemId};
this.quantityChangeEventInstance.triggerEvent(data);
}
}
// annimate the cart button when it is pressed.
// element : the shopping cart image.
this.animateDeleteFromCart = function () {
$(this.cartItemElement).fadeOut("slow", function () {
});
}
// set the event instance to be called with a new shipping option is selected.
this.setQuantityChangeEventInstance = function (eventInstance) {
// check that the parameter was set.
checkParamSet (1, eventInstance);
this.quantityChangeEventInstance = eventInstance;
}
// returns the value of the cart item.
this.getAmount = function () {
// get the item quantity from the action manager.
var cartQuantity = this.shoppingCartActionManager.getQuantity();
var itemTotal = cartQuantity * this.itemPrice;
return itemTotal;
}
}
//create a manager of a shopping cart item
//initializeManager : set to TRUE to automatically initialize the manager, FALSE to not initialize the manager, defulat value is TRUE
// Events: Quantity change event - returns event data {'item_id'}
function InventoryCountCheckoutCartItemManager (cartItemElement, initializeManager) {
checkParamSet (1, cartItemElement);
this.cartItemElement = cartItemElement;
this.quantityChangeEventInstance = null; // the event instance to be called when the quantity of the item changes.
this.quantityBadChangeEventInstance = null; // the event instance to be called when the bd quantity of the item changes.
// initialize the item ID the element manager is managing
this.itemId = $(this.cartItemElement).attr("data-item-id");
// initialize the item quantity and bad quantity.
this.itemQuantity = Number($(this.cartItemElement).find(".cart-item-qty p").text());
this.itemBadQuantity = Number($(this.cartItemElement).find(".cart-item-bad-qty p").text());
// the shopping cart action manager
this.shoppingCartActionManager = null;
this.shoppingCartBadActionManager = null;
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 () {
// setup the shopping cart manager initialization data.
var shoppingCartActionData = new ShoppingCartActionData();
shoppingCartActionData.itemId = this.itemId;
shoppingCartActionData.itemQuantity = this.itemQuantity;
shoppingCartActionData.addToCartElement = $(this.cartItemElement).find(".item-add-to-cart");
shoppingCartActionData.removeFromCartElement = $(this.cartItemElement).find(".item-remove-from-cart");
shoppingCartActionData.deleteFromCartElement = $(this.cartItemElement).find(".item-delete-from-cart");
shoppingCartActionData.shoppingCartQuantityChangeAction = "update_inventory_count_item_quantity";
shoppingCartActionData.shoppingCartDeleteAction = "delete_inventory_count_item";
// create a new shopping cart action manager for the good quantity the item.
this.shoppingCartActionManager = new ShoppingCartActionManager(shoppingCartActionData);
// get the shopping cart action event.
var shoppingCartActionEvent = this.shoppingCartActionManager.getShoppingCartActionEvent();
// added the event listener for the cart quantity change event.
shoppingCartActionEvent.addListenerThis ("cart_quantity_change", this, function (thisObject, eventInstanceData) {
// update the displayed quantity of the cart item.
thisObject.updateCartQuantity(eventInstanceData.eventData.itemId, eventInstanceData.eventData.quantityInCart);
});
// added the event listener for the delete quantity change event.
// both the good and bad quantity will be set to zero.
shoppingCartActionEvent.addListenerThis ("delete_from_cart", this, function (thisObject, eventInstanceData) {
// delete quantity of the cart item.
thisObject._deleteCartQuantity(eventInstanceData.eventData.itemId, eventInstanceData.eventData.quantityInCart);
});
// setup the shopping cart initalize data for the bad quantity.
var shoppingCartBadActionData = new ShoppingCartActionData();
shoppingCartBadActionData.itemId = this.itemId;
shoppingCartBadActionData.itemQuantity = this.itemBadQuantity;
shoppingCartBadActionData.addToCartElement = $(this.cartItemElement).find(".bad-item-add-to-cart");
shoppingCartBadActionData.removeFromCartElement = $(this.cartItemElement).find(".bad-item-remove-from-cart");
shoppingCartBadActionData.deleteFromCartElement = null; // do delete cart quantity for the bad item.
shoppingCartBadActionData.shoppingCartQuantityChangeAction = "update_inventory_count_item_bad_quantity";
shoppingCartBadActionData.shoppingCartDeleteAction = null;
// create a new shopping cart action manager for the good quantity the item.
this.shoppingCartBadActionManager = new ShoppingCartActionManager(shoppingCartBadActionData);
// get the shopping cart action event.
var quantityBadChangeEventInstance = this.shoppingCartBadActionManager.getShoppingCartActionEvent();
// added the even listener for the cart quantity change event.
quantityBadChangeEventInstance.addListenerThis ("cart_quantity_change", this, function (thisObject, eventInstanceData) {
// update the displayed quantity of the cart item.
thisObject.updateCartBadQuantity(eventInstanceData.eventData.itemId, eventInstanceData.eventData.quantityInCart);
});
}
// updated the item quantity
// element : the shopping cart image.
// cartQuantity: cart quantity to be displayed.
this.updateCartQuantity = function (itemId, cartQuantity) {
if (itemId != this.itemId) {
throw new
Error("Item ID ("+this.itemId+") dose not match that returned by the shopping cart action ("+itemId+").");
}
// display the updated cart quantity.
$(this.cartItemElement).find(".cart-item-qty p").text(cartQuantity);
/* // update the item total.
var itemTotal = cartQuantity * this.itemPrice;
itemTotal = parseFloat(itemTotal).toFixed(2);
$(this.cartItemElement).find(".cart-item-total p").text(itemTotal);*/
// test it the item should be removed from the cart.
this._testDeleteFromCart();
// trigger the quanitty changed event instance.
if (!empty(this.quantityChangeEventInstance)) {
var data = {'item_id':this.itemId};
this.quantityChangeEventInstance.triggerEvent(data);
}
}
// updated the item bad quantity
// element : the shopping cart image.
// cartQuantity: cart quantity to be displayed.
this.updateCartBadQuantity = function (itemId, cartQuantity) {
if (itemId != this.itemId) {
throw new
Error("Item ID ("+this.itemId+") dose not match that returned by the shopping cart action ("+itemId+").");
}
// display the updated cart quantity.
$(this.cartItemElement).find(".cart-item-bad-qty p").text(cartQuantity);
// test it the item should be removed from the cart.
this._testDeleteFromCart();
// trigger the quanitty changed event instance.
if (!empty(this.quantityChangeEventInstance)) {
var data = {'item_id':this.itemId};
this.quantityChangeEventInstance.triggerEvent(data);
}
}
// tests if the item should be deleted from the cart by checking the good and bad quantities.
this._testDeleteFromCart = function () {
// get the booth the good and the bad quantity to determine if the item should be removed from the cart.
var goodQuantity = this.shoppingCartActionManager.getQuantity();
var badQuantity = this.shoppingCartBadActionManager.getQuantity();
// if the cart good and bad quantity is zero, perform the remove from cart animtion.
if (goodQuantity <= 0 && badQuantity <= 0) {
this.animateDeleteFromCart();
}
}
// annimate the cart button when it is pressed.
// element : the shopping cart image.
this.animateDeleteFromCart = function () {
$(this.cartItemElement).fadeOut("slow", function () {
});
}
// delete the cart quantities, assume the values in the database changed to zero, only return the good quantity.
this._deleteCartQuantity = function (itemId, cartQuantity) {
if (itemId != this.itemId) {
throw new
Error("Item ID ("+this.itemId+") dose not match that returned by the shopping cart action ("+itemId+").");
}
// display the updated cart quantity.
$(this.cartItemElement).find(".cart-item-qty p").text(0);
$(this.cartItemElement).find(".cart-item-bad-qty p").text(0);
// animate the remove from cart.
this.animateDeleteFromCart();
// trigger the quanitty changed event instance.
if (!empty(this.quantityChangeEventInstance)) {
var data = {'item_id':this.itemId};
this.quantityChangeEventInstance.triggerEvent(data);
}
}
// set the event instance to be called with a new shipping option is selected.
this.setQuantityChangeEventInstance = function (eventInstance) {
// check that the parameter was set.
checkParamSet (1, eventInstance);
this.quantityChangeEventInstance = eventInstance;
}
/* // returns the value of the cart item.
this.getAmount = function () {
// get the item quantity from the action manager.
var cartQuantity = this.shoppingCartActionManager.getQuantity();
var itemTotal = cartQuantity * this.itemPrice;
return itemTotal;
}*/
}
//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
//searchType = 1 (default) - shopping cart search, 2 - inventory count search
function CheckoutShoppingCartManager (initializeManager, searchType) {
if (empty(initializeManager)) {
// the initialize value was not set so default it it TRUE
initializeManager = true;
}
this.searchType = searchType;
if (empty(this.searchType)) {
// default the search type to 1 - for shopping cart search.
this.searchType = 1;
}
this.cartItemsSet = []; // an array of the cart items.
this.shoppingCartChangedEventInstance = null ; // the event instance to trigger if the shopping cart value changes.
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 () {
// loop through all the cart items and initialize the shopping cart item manager for each one.
// create a item manager element for each item listed.
$("#cart-item-list .cart-item").each( function (index, element) {
if (this.searchType == 1) {
// working with the basic shopping cart.
// create a new shopping cart item manager and add it to the array to be used to recalculate the cart.
var checkoutShoppingCartItemManager = new CheckoutShoppingCartItemManager(element);
this.cartItemsSet.push(checkoutShoppingCartItemManager);
// setup the quantity change event to be called.
var quantityChangeEventInstance = new EventInstanceListenerThis ("quantity_change", this, function (thisObject, eventData) {
// update the shopping cart totals and or indicate the cart is empty.
thisObject.updateCartTotals();
});
// set the new event instance to be called when the item quantity changes.
checkoutShoppingCartItemManager.setQuantityChangeEventInstance(quantityChangeEventInstance);
} else {
// working on the inventory count cart.
// create a new inventory count cart item manager.
var inventoryCountCheckoutCartItemManager = new InventoryCountCheckoutCartItemManager(element);
}
}.bind(this));
}
this.updateCartTotals = function () {
var cartTotalAmount = 0;
if (this.cartItemsSet.length > 0) {
// loop the items in the cart and cacluate the new total
for (let i = 0; i < this.cartItemsSet.length; i++) {
var cartItemAmount = this.cartItemsSet[i].getAmount();
cartTotalAmount = cartTotalAmount + cartItemAmount;
}
}
if (cartTotalAmount > 0) {
// display the cart amount total.
cartTotalAmount = parseFloat(cartTotalAmount).toFixed(2);
$("#cart-total-box .cart-total p").text(cartTotalAmount);
} else {
// there are not items in the shoppingcart, unless selling for free
// display the empty cart message and remove the cart item section from the page.
$("#cart_area").removeClass("cart-is-not-empty").addClass("cart-is-empty");
$("#shopping-cart").fadeOut("slow", function () {
$("#shopping-cart").remove();
});
$("#billing-shipping-entry").remove();
}
// trigger the shopping cart changed event.
this.shoppingCartChangedEventInstance.triggerEvent();
}
// set the event instance to be called if the shopping cart value changes.
this.setShoppingCartChangedEventInstance = function (eventInstance) {
// check that the parameter was set.
checkParamSet (1, eventInstance);
this.shoppingCartChangedEventInstance = eventInstance;
}
// returns the shopping cart total.
this.getCartTotal = function () {
var cartTotalAmount = $("#cart-total-box .cart-total p").text();
return parseFloat(cartTotalAmount);
}
}
//create a new page manager to load and implement the check out page functionality.
function CheckoutPageManager () {
// the check out page menu manager object.
this.checkoutSubMenuManager = null;
// the checkout page shipping option manager.
this.checkoutShippingOptionsManager = null;
// the checkout shipping location manager.
this.checkoutShippingLocationManager = null;
// manages the entry of the billing details.
this.checkoutBillingDetailsEntryManager = null;
// manager the entry of the shipping details.
this.checkoutShippingDetailsEntryManager = null;
// the checkout page summary manager.
this.checkoutPaymentSummryManager = null;
// the checkout shopping cart manager.
this.checkoutShoppingCartManager = null;
// load and inialize the checkout page.
this.loadPage = function () {
eventInstanceListener = new EventInstanceListenerThis ("check_out_page_loaded", this, function (thisObject) {
thisObject.initialize();
});
// create the page manager unitiliy
mainPageUtility = new MainPageUtility();
// load the checkout page and call and them activiate the check out page load event instance.
mainPageUtility.loadMainPage ("check_out", eventInstanceListener);
}
// 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 check out page javascript functionality.
this.initialize = function () {
// initialize the form widget functionality.
var htmlWidgetPageManager = new HtmlWidgetPageManager ();
htmlWidgetPageManager.initialize();
// initialize the submenu activities, like entering billing detail, process payment
this.initializeSubMenu();
// initialize the billing details entry manager.
this.initializeBillingDetailsEntryManager();
// initialize the shipping location manager, displays the shipping address information
// depending on the shippping locataion select.
this.initializeShippingLocation();
// initialize the shipping details entry manager.
this.initializeShippingDetailsEntryManager();
// initialize the shipping options menu functionality
this.initializeShippingOptions();
// initialize the payment summary section.
this.initializePaymentSummary();
// initialize the shopping cart manager, manages updating of the shopping cart items
this.initializeShoppingCart();
// initialize the page display look controlled by JS. After all other initalization is completed.
this.initializeDisplay();
}
// initialize the page display look controlled by JS.
this.initializeDisplay = function () {
// round the coners elements
$(".cart-item-name").corner("5px");
$("#cart-menu .menu-option").corner("5px");
$("#order-details .widget-label").corner("5px");
$("#order-details .widget-input-field").corner("5px");
$("#shipping-details .widget-label").corner("5px");
$("#shipping-details .widget-input-field").corner("5px");
$("#payment-menu .inline-menu-option").corner("5px");
$("#shipping_location_options").corner("5px");
$("#shipping-rate-list .shipping-rate-item .widget-field").corner("5px");
$(".cart-item-control li").corner("30px");
// initialize the display the the shipping details.
this.updateShippingDetails();
}
// setup the search sub menu and handlers on the checkout page.
this.initializeSubMenu = function () {
// create the new sub menu manager, control the applying of the check out page class control;
this.checkoutSubMenuManager = new CheckoutSubMenuManager ();
this.checkoutSubMenuManager.initialize();
// get the sub menu event manager.
var eventManager = this.checkoutSubMenuManager.getEventManager();
// check out event manager controls if the check out menu are activated.
// if any search is inactivated, we want to clean up and pending search results.
eventManager.addListenerThis ("process_payment", this, function (thisObject) {
// The payment process event was activated, billing and shipping details and activiate the payment processing.
thisObject._processPayment();
});
// when the billing and shipping details section is active. Scroll the window to the top of the billing and shipping element.
eventManager.addListener ("entry_active", function () {
scrollWindowToTopOfElement ("#billing-shipping-entry", "#main-menu-box");
});
}
// setup the shipping options manager associated with the checkout page.
this.initializeShippingOptions = function () {
// create the new shipping option section controller. By default it is initialized.
this.checkoutShippingOptionsManager = new CheckoutShippingOptionsManager();
// create and event instace to be called when a shipping option is selected.
var eventInstance = new EventInstanceListenerThis("shipping_option_selected", this, function (thisObject, eventInstanceData) {
// update the Payment summary section with the new shipping option price.
thisObject.updatePaymentSummary();
});
this.checkoutShippingOptionsManager.setSelectedEventInstance (eventInstance);
}
// initialize the shipping location manager, displays the shipping address information
// depending on the shippping locataion select.
this.initializeShippingLocation = function () {
// create the shipping location manager. By default it is initialized.
this.checkoutShippingLocationManager = new CheckoutShippingLocationManager();
// create and event instace to be called when a shipping location is changed.
var eventInstance = new EventInstanceListenerThis("shipping_location_changed", this, function (thisObject, eventInstanceData) {
// update the shipping details as required.
thisObject.updateShippingDetails();
// update the shipping options as required.
thisObject.updateShippingOptions();
});
this.checkoutShippingLocationManager.setChangedLocationEventInstance (eventInstance);
}
// initialize the entry manager used to control the entry of the billing information associated with the sales order.
this.initializeBillingDetailsEntryManager = function () {
// create the shipping location manager. By default it is initialized.
this.checkoutBillingDetailsEntryManager = new CheckoutBillingDetailsEntryManager();
// create and event instace to be called billing details have been changed.
var eventInstance = new EventInstanceListenerThis("billing_details_changed", this, function (thisObject, eventInstanceData) {
// update the shipping details as required.
thisObject.updateShippingDetails();
// update the shipping options as required.
thisObject.updateShippingOptions();
});
this.checkoutBillingDetailsEntryManager.setBillingAddressChangedEventInstance (eventInstance);
}
// initialize the entry manager used to control the entry of the shipping information associated with the sales order.
this.initializeShippingDetailsEntryManager = function () {
// create the shipping location manager. By default it is initialized.
this.checkoutShippingDetailsEntryManager = new CheckoutShippingDetailsEntryManager();
// create and event instace to be called billing details have been changed.
var eventInstance = new EventInstanceListenerThis("shipping_details_changed", this, function (thisObject, eventInstanceData) {
// update the shipping options if the shipping details change.
thisObject.updateShippingOptions();
});
this.checkoutShippingDetailsEntryManager.setShippingAddressChangedEventInstance (eventInstance);
}
// check the start of the shipping location option and the bill address to determine the display of the shipping details
// update the shipping options if the billing address zip code changes.
this.updateShippingDetails = function () {
// if the billing address is complete and the shipping location is set to same as bill to, display the
// bill to address as the shipping address.
var shippingLocationType = this.checkoutShippingLocationManager.getShippingLocation();
if (shippingLocationType == 1) {
// the shipping location is the same as the bill to address.
// determine if the bill to address is complete.
if (this.checkoutBillingDetailsEntryManager.isBillingAddressComplete()) {
// get the billing address.
var address = this.checkoutBillingDetailsEntryManager.getBillingAddress();
// display the billing address as the ship to address.
this.checkoutShippingDetailsEntryManager.setShippingAddress(address);
} else {
// if the billing address is not complete, clear the shipping address details displayed.
this.checkoutShippingDetailsEntryManager.clearShippingAddress();
}
// disable the entry of the shipping address details.
this.checkoutShippingDetailsEntryManager.disableShippingAddress();
} else {
// the shipping location address is different than the billing address.
// clear any billing deatails showing as shipping details (default)
this.checkoutShippingDetailsEntryManager.clearShippingAddress();
// enable the entry of the shipping address details.
this.checkoutShippingDetailsEntryManager.enableShippingAddress();
}
}
// update the shipping options display and values if the shipping details associated with the order change.
// query the server for new shipping option and display them.
this.updateShippingOptions = function () {
// get the current shipping location type set.
var shippingLocationType = this.checkoutShippingLocationManager.getShippingLocation();
if (shippingLocationType == 1) {
// the shipping location is the same as the bill to address.
// determine if the bill to address is complete.
if (this.checkoutBillingDetailsEntryManager.isBillingAddressComplete()) {
// get the billing address.
var address = this.checkoutBillingDetailsEntryManager.getBillingAddress();
// use the billing address data to display new shipping options, if they changed?
this.checkoutShippingOptionsManager.setShippingAddress(address);
} else {
// if the billing address is not complete, clear the shipping options.
this.checkoutShippingOptionsManager.clearShippingOptions();
}
} else {
// the shipping location address is different than the billing address.
// determine if the alternate shipping address is complete.
if (this.checkoutShippingDetailsEntryManager.isShippingAddressComplete()) {
// get the shipping address.
var address = this.checkoutShippingDetailsEntryManager.getShippingAddress();
// use the shipping address data to display new shipping options, if they changed?
this.checkoutShippingOptionsManager.setShippingAddress(address);
} else {
// if the shiping address is not complete, clear the shipping options.
this.checkoutShippingOptionsManager.clearShippingOptions();
}
}
}
// setup the payment summary manager associated with the checkout page.
this.initializePaymentSummary = function () {
this.checkoutPaymentSummryManager = new CheckoutPaymentSummryManager();
}
// setup the order summary manager associated with the checkout page.
this.initializeOrderSummary = function () {
}
// update the display of the payment summary section of the checkout page.
this.updatePaymentSummary = function () {
// get the current shopping cart value.
var cartTotal = this.checkoutShoppingCartManager.getCartTotal();
// update the payment summary cart total amount.
this.checkoutPaymentSummryManager.updateCartTotal(cartTotal);
// get the price of the select shipping option.
var shippingOptionPrice = this.checkoutShippingOptionsManager.getSelectedPrice();
// update the payment summary shipping cost.
this.checkoutPaymentSummryManager.updateShippingCost(shippingOptionPrice);
}
// perform the payment process functions when the payment button is activiated..
this._processPayment = function () {
// validate all the input fields
var isValid = submitValidation("#billing-shipping-entry");
if (isValid) {
// submit the email form to the server only is the validation of all the fields passed.
// save the customer order and/or display return validated order data.
// submitFormPage("#billing-shipping-details", "process_payment");
// create the new checkout page sever request
var checkoutPageServerRequest = new CheckoutPageServerRequest();
// get event manager and setup event callbacks required
var eventManager = checkoutPageServerRequest.getEventManager();
// setup the callback to be activated if the billing and shipping details have been updated.
eventManager.addListenerThis ("BILLING_SHIPPING_DETAILS_UPDATED", this, function (thisObject) {
// re-intialze all the event associated in the billing and shipping details section of the screen.
thisObject._reInitializeBillingShippingDetails();
});
// activate the process payment method.
checkoutPageServerRequest.processPayment();
}
// // scroll to the top of the page
// scrollWindowToTop();
}
// re-initialize the billing and shipping details, need to call the intialize of each of the seciont managers.
this._reInitializeBillingShippingDetails = function () {
// the checkout page shipping option manager.
this.checkoutShippingOptionsManager.initialize();
// the checkout shipping location manager.
this.checkoutShippingLocationManager.initialize();
// manages the entry of the billing details.
this.checkoutBillingDetailsEntryManager.initialize();
// manager the entry of the shipping details.
this.checkoutShippingDetailsEntryManager.initialize();
// ?? might call the update payment summary here to update the shipping cost based on the selected shipping option.
// initialize the page display look controlled by JS. After all other initialization is completed.
this.initializeDisplay();
}
// Setup the shopping cart functionality on the checkout page.
this.initializeShoppingCart = function () {
// create the new shipping option section controller. By default it is initialized.
this.checkoutShoppingCartManager = new CheckoutShoppingCartManager();
// setup and event instance to be called if the shopping cart value changes.
var eventInstance = new EventInstanceListenerThis("shopping_cart_changed", this, function (thisObject, eventInstanceData) {
// update the Payment summary section with the new shopping cart amount.
thisObject.updatePaymentSummary();
});
this.checkoutShoppingCartManager.setShoppingCartChangedEventInstance (eventInstance);
}
}
// create a new search page manager to load and implement the search page functionality.
/**
* @class SearchPageManager
* @memberOf SearchPageManager
*/
function InventoryCountSearchPageManager () {
// 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.
// this one loads the page using an ajax call. No being used.
this.loadPage = function () {
eventInstanceListener = new EventInstanceListenerThis ("search_page_loaded", this, function () {
this.initialize();
});
// create the page manager unitiliy
mainPageUtility = new MainPageUtility();
// load the search page.
mainPageUtility.loadMainPage ("search", eventInstanceListener);
}
// initializes entire page javascript functionliaty, including main page.
// called when page loaded using HTML file "inventory_count_search.html"
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(2);
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 (2);
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();
}
}
//classes to handle differenent of server requests and loading animations.
// Implements a checkout page functionality server quests.
function InventoryCountPageServerRequest () {
this.resouceName = "ajax/inventory_count_page.ajax.php";
// an event manager used to trigger event related to the request.
this.eventManager = new EventManager();
// add the various events.
this.eventManager.addEvent("inventory_count_saved");
// submits the inventory count ticket to the server.
this.submitInventoryCount = function () {
// save the inventory count ticket.
this._saveInventoryCount();
}
this._saveInventoryCount = function () {
// create the page sever request object.
var pageServerRequestManager = new PageServerRequestManager();
// create a new event instance to be activity when the request is completed successfully.
var eventInstance = new EventInstanceListenerThis ("REQUEST_SUCCESSFUL", this, function (thisObject, eventInstanceData) {
// when the save request is compleled pass the resource returned in the event data to the approve payment function.
checkParamSet (1, eventInstanceData);
// the inventory ticket was saved successfully, display a message.
thisObject._verifyInventoryTicket(eventInstanceData.eventData);
})
pageServerRequestManager.setRequestSucessEvent(eventInstance);
// submitted the inventory count ticket information to save.
pageServerRequestManager.submitPageRequest
(this.resouceName, "#inventory-count-details-box", "save_inventory_count_ticket");
}
// show the results of the saved ticket..
this._verifyInventoryTicket = function (serverRequestResource) {
checkParamSet (1, serverRequestResource);
if (serverRequestResource.isSuccessful()) {
// no error occurred during the payment authorization request.
// trigger the save invnetory ticket event.
this.eventManager.triggerEvent("inventory_count_saved", serverRequestResource);
} else {
throw new Error("Inventory count ticket save was not successful ." + serverRequestResource.getStatus());
}
}
// reutrn the event manager managing the request event.
this.getEventManager = function () {
return this.eventManager;
}
}
//create a new page manager to load and implement the check out page functionality.
function InventoryCountCheckoutPageManager () {
// the checkout shopping cart manager.
this.checkoutShoppingCartManager = null;
/* // load and inialize the checkout page. When using AJAX call the load the page. Now using HTML.
this.loadPage = function () {
eventInstanceListener = new EventInstanceListenerThis ("check_out_page_loaded", this, function (thisObject) {
thisObject.initialize();
});
// create the page manager unitiliy
mainPageUtility = new MainPageUtility();
// load the checkout page and call and them activiate the check out page load event instance.
mainPageUtility.loadMainPage ("check_out", eventInstanceListener);
}*/
// 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 check out page javascript functionality.
this.initialize = function () {
// initialize the form widget functionality.
var htmlWidgetPageManager = new HtmlWidgetPageManager ();
htmlWidgetPageManager.initialize();
// initialize the submenu activities, like entering billing detail, process payment
this.initializeSubMenu();
// initialize the shopping cart manager, manages updating of the shopping cart items
this.initializeShoppingCart();
// initialize the page display look controlled by JS. After all other initalization is completed.
this.initializeDisplay();
}
// initialize the page display look controlled by JS.
this.initializeDisplay = function () {
// round the coners elements
$(".cart-item-name").corner("5px");
$("#cart-menu .menu-option").corner("5px");
$("#inventory-count-details .widget-label").corner("5px");
$("#inventory-count-details .widget-input-field").corner("5px");
$("#submit-count-menu .inline-menu-option").corner("5px");
$(".cart-item-control li").corner("30px");
}
// setup the search sub menu and handlers on the checkout page.
this.initializeSubMenu = function () {
// for the simple one button sumit inventory count. Did not create a new object.
// add click event to view only available galleries.
clickHighlight ("#submit-count-menu-option", function () {
// submit the inventory count ticket.
this._submitInventoryCount();
// return false so no other triggers are not activated.
return false;
}.bind(this));
}
// perform the submitting of the inventory count when the submitt button is activated.
this._submitInventoryCount = function () {
// validate all the input fields
var isValid = submitValidation("#inventory-count-details");
if (isValid) {
// All input fields have been validated.
// create the new checkout page sever request
var inventoryCountPageServerRequest = new InventoryCountPageServerRequest();
// get event manager and setup event callbacks required
var eventManager = inventoryCountPageServerRequest.getEventManager();
// setup the callback to be activated if the billing and shipping details have been updated.
eventManager.addListenerThis ("inventory_count_saved", this, function (thisObject) {
// if the inventory count ticket save was success so display the ticked page.
// the current ticket number was stored as a session variable on the server.
httpRedirect("inventory_count_confirmation.html");
});
// activate the process payment method.
inventoryCountPageServerRequest.submitInventoryCount();
}
}
// Setup the shopping cart functionality on the checkout page.
this.initializeShoppingCart = function () {
// create the new shopping cart manager for the inventory count scren. By default it is initialized.
this.checkoutShoppingCartManager = new CheckoutShoppingCartManager(true, 2);
}
}
//create a prouct list page manager to load and implement the product list page functionality.
function ProductListPageManager () {
// used to load the page using an AJAX call, not used now.
/* this.loadPage = function () {
eventInstanceListener = new EventInstanceListenerThis ("product_list_page_loaded", this, function () {
this.initialize();
});
// create the page manager unitiliy
mainPageUtility = new MainPageUtility();
// load the search page.
mainPageUtility.loadMainPage ("product_list_page_loaded", eventInstanceListener);
}*/
// 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();
// initialize the page display look controlled by JS.
this.initializeDisplay();
}
// initialize the page display look controlled by JS.
this.initializeDisplay = function () {
// round the coners elements
$("#product-list-page .product-detail .item-name").corner("5px");
}
}
/**
* Java script utility functions
*/
// this function throws and error if one of the paramters is not set.
// numParams - the number of paramters passed to the function to be checked
// param? - a parameter to be checked.
function checkParamSet (numParams, param1, param2, param3, param4) {
var checkParamSet_v = true;
if (isEmpty(numParams)) {
checkParamSet_v = false;
}
if (numParams > 0) {
if (isEmpty(param1)) {
checkParamSet_v = false;
}
}
if (numParams > 1) {
if (isEmpty(param2)) {
checkParamSet_v = false;
}
}
if (numParams > 3) {
if (isEmpty(param3)) {
checkParamSet_v = false;
}
}
if (numParams > 4) {
if (isEmpty(param4)) {
checkParamSet_v = false;
}
}
if (!checkParamSet_v) {
// one of the paramter values was not set.
// alert ("Paramters not defined.");
throw new Error("Paramters not defined.");
}
}
//implements some PHP like function names to make it easier to convert the PHP to Java script code
//returns the lower case value of the paramter
function strtolower (stringText) {
return stringText.toLocaleLowerCase();
}
// thise function determines if the parameter is empty
// empty is null, ""
function isEmpty (value) {
var isEmpty_v = false;
// determine the type of the opbject value.
switch ($.type(value)) {
case "undefined":
case "null":
// the value is null.
isEmpty_v = true;
break;
case "object":
// check if the object is empy.
if ($.isEmptyObject(value)) {
isEmpty_v = true;
}
break;
case "boolean":
case "number":
case "string":
case "function":
case "array":
case "date":
case "error":
case "symbol":
case "regexp":
// the trim() removes blank spaces from the string, consider blank spaces as empty
var stringValue = value.toString();
stringValue = stringValue.trim();
if (stringValue == "") {
isEmpty_v = true;
}
break;
default:
// the type was not handled.
throw new Error("Type of value '"+$.type(value)+"'not defined");
}
return isEmpty_v;
}
function empty (value) {
return isEmpty(value);
}
// scrolls the page to the top of the browser window.
function scrollWindowToTop () {
$("html, body").animate({ scrollTop: "0px" }, 0);
}
//scrolls the top of a specific element in page.
// scrollTopElement: jquery or equivalent element, the elment which should be scrolled to the top of the window
// scrollOffsetElement: jquery or equivalent element, the size of the scroll element heigh will be left and an offset
// betweent the top of the window and the element.
function scrollWindowToTopOfElement (scrollTopElement, scrollOffsetElement) {
if (empty(scrollTopElement)) {
throw new Error("Scroll top element value not set.");
}
// determine the position of the element relative to the view port.
var elementOffset = $(scrollTopElement).offset();
var positionOffset = $(scrollTopElement).position();
var windowHeight = $(window).height();
var windowScroll = $(window).scrollTop();
var targetElementOffsetTop = elementOffset.top;
var windowInViewBottom = windowHeight + windowScroll;
var scrollOffset = 0
if (!empty(scrollOffsetElement)) {
// determine the height of the scroll offset element, including margins padding, etc.
scrollOffset = $(scrollOffsetElement).outerHeight();
}
var scrollTopPostion = targetElementOffsetTop - scrollOffset + "px";
$("html, body").animate({ scrollTop: scrollTopPostion }, 0);
}
/**
* add the click and highlight event to the element
* assume the click and hightlighted element are the same now.
* @param clickElement : a jquery element, the element that will be clicked and hightlighted
* @param callback : the call back function to be called.
* @returns
*/
function clickHighlight (clickElement, callback) {
checkParamSet (2, clickElement, callback);
$(clickElement).off("click").click(function () {
$(this).effect("highlight", {color: "rgba(218, 165, 32, 0.5)"}, 300, callback);
});
}
/**
* retriect the page to the specified URL.
* @param clickElement : a jquery element, the element that will be clicked and hightlighted
* @param callback : the call back function to be called.
* @returns
*/
function httpRedirect (url) {
window.location.href = url;
}
// create a utility function to encapsulate the java script utilities, the make them easier to find.
function JsUtility () {
this.httpRedirect = function (url) {
window.location.href = url;
}
}
// tests if the value is a function, return true for function.
function isFunction (value) {
var isFunction_v = false;
// determine the type of the opbject value.
switch ($.type(value)) {
case "function":
// the value is a function.
isFunction_v = true;
break;
default:
// the value is not a function.
isFunction_v = false;
}
return isFunction_v;
}
// reprensts a screen widget on the JS side
// uses Jquery libriary.
function HtmlWidget (node) {
this.widgetValidationType; // the widget validation type
this.isWidgetValid = true; // The current validation status of the widget.
this.widgetErrorText; // the text to represent the field in a generic message.
this.widgetNode; // the Jquery node associated with the widget (the outside container, not clear).
this.widgetErrorClass;
this.widgetValidationText = []; // an array of validation text message.
// defining the function first here allowed the call below to execute
this.initalizeWidget = initalizeWidget;
if (!empty(node)) {
// initalize the widget given the node
this.initalizeWidget(node); // can't call this before the function is initalized?
}
// parses widget values from a given DOM object.
// node - a Jquery object or convertable
function initalizeWidget (node) {
// made sure the node value is defined.
checkParamSet(node);
// the parent of the input
this.widgetNode = node;
this.widgetValidationType = $(node).attr("data-widget-validation-type");
this.widgetErrorText = $(node).attr("data-widget-error-text");
if (empty(this.widgetErrorText)) {
// default the error text to any label set on the widget.
this.widgetErrorText = $(node).attr("data-widget-label");
}
if (empty(this.widgetErrorText)) {
// default the error text to any field name set on the widget.
this.widgetErrorText = $(node).attr("data-widget-field-name");
}
this.widgetErrorClass = $(node).attr("data-widget-class");
if (empty(this.widgetErrorClass)) {
// use the default widget error class value.
this.widgetErrorClass = WIDGET_ERROR_CLASS;
}
}
// generates a html widget of the specified type and returns the object
this.htmlWidgetFactory = htmlWidgetFactory;
function htmlWidgetFactory (widgetType, widgetNode) {
var htmlWidget = null;
switch (strtolower(widgetType)) {
case "input_text": // create the basic input widget
htmlWidget = new InputText(widgetNode);
break;
case "input_text_area": // create the basic text aread input using based htm widget functionality
htmlWidget = new HtmlWidget(widgetNode);
break;
case "input_email": // create the basic input text email widget
htmlWidget = new InputEmail(widgetNode);
break;
case "option_list": // create the a basic widget to control the option list validation
htmlWidget = new HtmlWidget(widgetNode);
break;
case "radio_button": // create the a basic widget to control the option list validation
htmlWidget = new HtmlWidget(widgetNode);
break;
default :
throw new Error("Widget type "+ widgetType + " not defined.");
}
return htmlWidget;
}
// validates the widget value is valid based on the validation type setting.
// the validation error text and class are applied to the widget if the validation fails.
// $widgetValue - if the value of the widget to be validated and populated back into the form.
this.validateWidgetValue = function (widgetValue) {
// do the basic validation on the field. The widget validation flag and messages will be set
// to be set when the widget template is generated.
return this.basicValueValidation(widgetValue);
}
// preforms basic validation of the widget value based on the validation type
this.basicValueValidation = function (widgetValue) {
var isValid = true;
// populate the widget value based on the value being validated.
this.widgetValue = widgetValue;
if (!empty(this.widgetValidationType)) {
if ( strtolower(this.widgetValidationType) == "not empty") {
// make sure the widget value is not empty
if (empty(widgetValue)) {
// the widget value is empty and has failed the validation
isValid = false;
this.isWidgetValid = false; // maybe should set the sub class.
this.widgetValidationText.push("The "+this.widgetErrorText+" field value is required.");
}
} else {
throw new Error("HTML widget validation type of this.widgetValidationType not defined.");
}
}
return isValid;
}
// render the widget to update display based on the state of the widget.
this.display = function () {
if (!empty(this.widgetNode)) {
// clear anny validation attibutes set on the widget.
this.clearValidation();
if (!this.isWidgetValid) {
// the widget is not in a valid state. Set validation messages and attributes.
this.setValidation();
}
} else {
// the widget node was not specified
throw new Error("Widget object DOM node not set.")
}
}
// clear any validation message or attributes currenly set on the widget node.
this.clearValidation = function () {
if (!empty(this.widgetNode)) {
// clear the validation attibute set on the widget container
var errorMessageNodes = $(this.widgetNode).find(".widget-validation-message");
// clear any error message text contained in the first validation message.
var widgetValidationMessageNode = $(errorMessageNodes).slice(0,1).html("");
// remove all error messages after the first one
$(errorMessageNodes).slice(1).remove();
// remove error class from the parent containing the html widget.
$(widgetValidationMessageNode).parent().removeClass(this.widgetErrorClass);
} else {
// the widget node was not specified
throw new Error("Widget object DOM node not set.")
}
}
// setup the validation message assoiciate with the html object to be displayed.
this.setValidation = function () {
if (!empty(this.widgetNode)) {
// the node representing the widget error messages
// this will only return one node since we cleared all the other messages
var errorMessageNode = $(this.widgetNode).find(".widget-validation-message");
// add the validation error class to the parent container widget.
$(this.widgetNode).addClass(this.widgetErrorClass);
// var parentNode = $(errorMessageNode).parent();
// $(parentNode).addClass(this.widgetErrorClass);
// setup the validation error message node creating numtiple message nodes if required.
var isFirst = true;
for (let validationMessage of this.widgetValidationText) {
if (!isFirst) {
// we need to create a new node to display the validation message
// the first one is placed in the existing node.
var newErrorMessageNode = $(errorMessageNode).clone();
$(newErrorMessageNode).insertAfter(errorMessageNode);
errorMessageNode = newErrorMessageNode;
}
isFirst = false;
// update the text value of the validation node.
$(errorMessageNode).text(validationMessage);
}
} else {
// the widget node was not specified
throw new Error("Widget object DOM node not set.")
}
}
}
// handles creation and setup of an input text type widget.
// used the HtmlWidget Functionality as a base
// noode: specifies a jquery node to be used to initalize the object
function InputText (node) {
// create the html widget object
this.htmlWidget = new HtmlWidget(node);
// validates the widget value is valid based on the validation type setting.
// the validation error text and class are applied to the widget if the validation fails.
// $widgetValue - if the value of the widget to be validated and populated back into the form.
this.validateWidgetValue = function (widgetValue) {
// do the basic validation on the field. The widget validation flag and messages will be set
// to be set when the widget template is generated.
return this.htmlWidget.basicValueValidation(widgetValue);
}
// render the widget to update display based on the state of the widget.
this.display = function () {
this.htmlWidget.display();
}
}
// handles creation and setup of an input email type widget.
// used the HtmlWidget Functionality as a base
// noode: specifies a jquery node to be used to initalize the object
function InputEmail (node) {
// create the html widget object
this.htmlWidget = new HtmlWidget(node);
// validates the widget value is valid based on the validation type setting.
// the validation error text and class are applied to the widget if the validation fails.
// $widgetValue - if the value of the widget to be validated and populated back into the form.
this.validateWidgetValue = function (widgetValue) {
// do the basic validation on the field. The widget validation flag and messages will be set
// to be set when the widget template is generated.
var isValid = this.htmlWidget.basicValueValidation(widgetValue);
if (isValid) {
// validate the format of the email address entered.
isValid = this._validateEmailAddressFormat (widgetValue);
if (!isValid) {
this.htmlWidget.isWidgetValid = false; // maybe should set the sub class.
this.htmlWidget.widgetValidationText.
push("The "+this.htmlWidget.widgetErrorText+" field format is not valid.");
// this.htmlWidget.widgetValidationText.
// push("(2) The "+this.htmlWidget.widgetErrorText+" field format is not valid.");
}
}
return isValid;
}
// render the widget to update display based on the state of the widget.
this.display = function () {
this.htmlWidget.display();
}
// preforms basic validation of the widget value based on the validation type
this._validateEmailAddressFormat = function (emailAddress) {
isValid = true;
if (!empty(emailAddress)) {
var mailFormat = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
if (!emailAddress.match(mailFormat)) {
// An invalid email address syntax was found.
isValid = false;
}
}
return isValid;
}
}