WIDGET_ERROR_CLASS = "validation-error"; IMAGE_REPOSITORY = "/VenetianMaskStore_Images/"; //IMAGE_REPOSITORY = "http://resources.venetianballmask.com/"; //IMAGE_REPOSITORY = "http://venetianballmask.com/mask_app_images/"; // create one event manager to be used by the entire page. //EVENT_MANAGER = new EventManager(); GALLERY_MENU = null; // runs the defaull page javescipt, sets the on doucment ready JQUERY function. $(document).ready(function(){ try { // // create and initialize the main page manager // var mainPageManager = new MainPageManager(); // mainPageManager.initialize(); // find out the name of the current page. var mainPageUtility = new MainPageUtility(); var pageName = mainPageUtility.getPageName(); var pageManager = null; // generate the specific page manager depending on the page name switch(pageName) { case "search.html": // starting the search page pageManager = new SearchPageManager(); break; case "contact_us.html": // starting the contact up page pageManager = new ContactUsPageManager(); break; case "checkout.html": // starting the checkout page pageManager = new CheckoutPageManager(); break; case "inventory_count_search.html": // starting the inventory search page pageManager = new InventoryCountSearchPageManager(); break; case "inventory_count_checkout.html": // starting the inventory search page pageManager = new InventoryCountCheckoutPageManager(); break; case "product_list.html": // starting the product list page pageManager = new ProductListPageManager(); break; default: // no specific default page generation is required. Start the default page manager. pageManager = new MainPageManager(); } // initialize the page manager to support the loading of the a new page. pageManager.initializePage(); } catch (e) { alert("stack details:\n" + e.stack); } }); // the class manages the HTML width functionliaty implementation for the page. // selectionId: an Jquery object used to limit the scope of the html widget manager, if null, the whole page is the scope function HtmlWidgetPageManager (selectorId) { this.selectorId = selectorId; if (empty(this.selectorId)) { this.selectorId = "body"; // default to the whole page. } // iniatlize the html widget page manager. this.initialize = function () { $(this.selectorId).find(".widget-input-field").change(function () { validateInput(this); }); }; } /*// update the display by adding some rounded coners. function updateDisplaySearchPage () { $(".gallery-text").corner("5px"); $("#search-menu .menu-option").corner("5px"); $("#item-list-heading").corner("5px"); }*/ //performs the input validation for the specified input node. //returns a value of TRUE if the input value is valid //inputNode: Jquery equivalant representing the input node of the widget to be validation. function validateInput (inputNode) { // made sure the node value is defined. checkParamSet(inputNode); // get the widget type. var widgetNode = $(inputNode).parent(); var widgetType = $(widgetNode).attr("data-widget-type"); // create an object for the input widget using the widget faction. // pass in the parent of the input node which is the widget container var htmlWidget = new HtmlWidget(); var htmlWidget = htmlWidget.htmlWidgetFactory(widgetType, widgetNode); // var htmlWidget = HtmlWidget.htmlWidgetFactory(widgetType, widgetNode); // validate the widget value. var isValid = htmlWidget.validateWidgetValue($(inputNode).val()); // update the display of the widget htmlWidget.display(); return isValid; } // perform all the required form validation before submitting data to the server. // returns a value of TRUE if all the validation passed. // sectionID: jquery object or equivalent, if set, will limit validation to the specified section. function submitValidation(sectionID) { var isValid = true; var selector = ".widget-input-field"; if (!empty(sectionID)) { // the selector ID was set, preprepend to the selector. selector = sectionID + " " + selector; } // the each function itterates over each item synchronously, like a loop. $(selector).each(function () { var isInputValid = validateInput(this); if (!isInputValid) { isValid = false; } }); if (!isValid) { // find the first error as use bring it into focus. selector = sectionID + " " + ".validation-error"; var errorElement = $(selector).first(); if (!empty(errorElement)) { scrollWindowToTopOfElement(errorElement, "#main-menu-box"); } } return isValid; } // submit the form on the page to be processed, the form takes up the page so the results // are displayed in the main display of the page // formId = jquery object, the form name is the same name as the server side activity. // activity = the activity to passed to server ajax routine as the operation to invoke on the server // targetElement : the elemnt use to display the html retult returned, a jquery object // targetInsertionType : 1 (default) - overwrite content of element; // 2 - append as a sibling of the target element // waitType : the way to display the wait icon when the request is loading // 1 (default) - inactivate the entire page until the request is complete // 2 - the wait icon is append to the end of the target element showing that // more data is being loaded. function submitFormPage(formId, activity, targetElement, targetInsertionType, waitType) { try { checkParamSet (2, formId, activity); if (empty(targetElement)) { // default the target element to the page-main id if not specefied. targetElement = "#page-main"; } // create the submit form object to submit the request to the server. pageFormSubmitRequest = new PageFormSubmitRequest(); // create an event instance to be called after the page loads. var eventManager = new EventManager("page-loaded", function () { // scroll to the top of the page scrollWindowToTop(); }); var eventInstance = new EventInstance (eventManager, "page-loaded"); pageFormSubmitRequest.setRequestSucessEvent (eventInstance); pageFormSubmitRequest.submit(formId, activity, targetElement, targetInsertionType, waitType); } catch (e) { alert("stack details:\n" + e.stack); } return false; // to stop multiple events being fired. } // add the wait item html snipit to the end of the target element and show it. // a unique ID is generated to track the wait icon inserted in the element // waitType : the way to display the wait icon when the request is loading // 1 (default) - inactivate the entire page until the request is complete // 2 - the wait icon is append to the end of the target element showing that // more data is being loaded. function showWaitIcon (targetElement, waitType) { checkParamSet (1, targetElement); if (empty(waitType)) { // default the wait type value. waitType = 1; } var className = ""; if (waitType == 1) { className = "wait-loading"; } else if (waitType == 2) { className = "wait-loading-element"; } else { throw new Error("Wait type "+waitType+" is not defined.") } var waitTemplate = "
" + "Wait Loading" + "
"; if (targetElement != "") { $(targetElement).append(waitTemplate); } // display the loading data image $("#8sudjshdkw").show(); } //removes the wait item html snipit to the end of the target element and show it. //a unique ID is generated to track the wait icon inserted in the element // waitIconId: Jquery object reprsenting the wait icon. function removeWaitIcon () { $("#8sudjshdkw").remove(); // hide the loading data image // maybe do not need to hide and display the wait icon // $(waitIconId).hide(); // if (waitIconId != "") { // $("#8sudjshdkw").remove(); // } } // this object contains funcionality to make a page request for content. // Looks like with one loads a whole page function PageHtmlContentRequest () { this.htmlResouceName = "ajax/menu.ajax.php"; this.htmlContendRequest = new HtmlContentRequest(this.htmlResouceName); this.loadHtmlContent = function (postData, targetElement) { this.htmlContendRequest.sendRequest (postData, targetElement); } // 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.htmlContendRequest.setRequestSucessEvent (eventInstance); } } //this object submits the data to the server and does validation as required function PageFormSubmitRequest () { this.htmlResouceName = "ajax/form_submit.ajax.php"; this.htmlContendRequest = new HtmlContentRequest(this.htmlResouceName); // submit the form data to the server performing data validations and displaying the results // 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 // targetElement : the html element to display the html data returned by the submit // targetInsertionType : 1 (default) - overwrite content of element; // 2 - append as a sibling of the target element // waitType : the way to display the wait icon when the request is loading // 1 (default) - inactivate the entire page until the request is complete // 2 - the wait icon is append to the end of the target element showing that // more data is being loaded. this.submit = function (sourceForm, activity, targetElement, targetInsertionType, waitType) { checkParamSet (3, targetElement, sourceForm, activity); // validated the submitted data on the browser // 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}); // sent the request to the server and display the result in target emlemnt this.htmlContendRequest.sendRequest (postData, targetElement, targetInsertionType, waitType); } // 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.htmlContendRequest.setRequestSucessEvent (eventInstance); } } //this object submits the data to the server and does validation as required //if an event instance is set, it will be triggered be when the post call is completed. function PageSubmitRequest () { this.htmlResouceName = "ajax/form_submit.ajax.php"; this.htmlContendRequest = new HtmlContentRequest(this.htmlResouceName); // request the HTML content to be inserted at teh target element, accepting extra parameters. // activity : the submit activity being performed, has to be a valid type defined on the server // postData: name, value data to be passed with the server post call // targetElement : the html element to display the html data returned by the submit // targetInsertionType : 1 (default) - overwrite content of element; // 2 - append as a sibling of the target element // waitType : the way to display the wait icon when the request is loading // 1 (default) - inactivate the entire page until the request is complete // 2 - the wait icon is append to the end of the target element showing that // more data is being loaded. this.submit = function (activity, postData, targetElement, targetInsertionType, waitType) { checkParamSet (2, activity, targetElement); // add the operation to the data submitted to the server. postData.push({name: "oper", value: activity}); this.htmlContendRequest.sendRequest (postData, targetElement, targetInsertionType, waitType); } // 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 : the event instance to be fired when the submet request is completed sucessfully this.setSubmitSucessEvent = function (eventInstance) { this.htmlContendRequest.setRequestSucessEvent (eventInstance); } } // this object loads HTML content into a specific element, a wait icon is displayed until the content is loaded // htmlResouceName - is the resource (page) on the server to send the post request to. // if an event instance is set, the given event instance will be triggered when the post call is completed. function HtmlContentRequest (htmlResouceName) { checkParamSet (1, htmlResouceName); this.htmlResouceName = htmlResouceName; this.eventInstance = null; // an event instance object to be triggered wehn the post request has returned sucessfully. // sends a post request to the server for the resource attached to the object // postData - data object to sumbmit // targetElement - the target element to insert the html retuned data into // targetInsertionType : 1 (default) - overwrite content of element; // 2 - append as a sibling of the target element // waitType : the way to display the wait icon when the request is loading // 1 (default) - inactivate the entire page until the request is complete // 2 - the wait icon is append to the end of the target element showing that // more data is being loaded. this.sendRequest = function (postData, targetElement, targetInsertionType, waitType) { checkParamSet (1, targetElement); if (isEmpty(targetInsertionType)) { // default the insertion type to 1 if not set. targetInsertionType = 1; } showWaitIcon(targetElement, waitType); thisObject = this; $.post(this.htmlResouceName, postData) .done ( function (data, status) { thisObject.postDone(targetElement, targetInsertionType, data, status); }) .fail (this.postFail); } // the result data will be an JSON object containing // error_number = internal status of the request - 0 - sucess, any other number, some error occurred. // error_message = a status message, a text of the sucess of failure of the request. // content_type = type of content contained in the data, 1 - HTML page; 2 - HTML fragment; 3 - JSON; 4 - Redirect URL // data = the data returned by the server. this.postDone = function (targetElement, targetInsertionType, data, status) { var htmlResult = data; // delete the wait icon since loading is completed. removeWaitIcon (); if (targetInsertionType == 1) { // overwrite the content of the target element. $(targetElement).html(htmlResult); } else if (targetInsertionType == 2) { // append the html at the end of the children of the target element. $(targetElement).append(htmlResult); } if (!isEmpty(this.eventInstance)) { // trigger the post sucessful event. this.eventInstance.triggerEvent (); } } // 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) { // need the try and catch the error her 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 content request failed status:"+status); } catch (e) { alert("stack details:\n" + e.stack); } } // sets up the event istance to be used, it will be fired when the post request returns a successful // result and data is insert into the page, the specified event manager will fire a trigger // eventInstance : the event instance to be fired this.setRequestSucessEvent = function (eventInstance) { checkParamSet (1, eventInstance); this.eventInstance = eventInstance; } } // this object calls the resource and passes an action request to the ajax server // an event can be setup to be triggered after the action is successful function ActionRequest (resouceName) { checkParamSet (1, resouceName); this.resouceName = resouceName; this.eventInstance = null; // an event instance object to be triggered wehn the post request has returned sucessfully. // send the action request to the server using passing the post date. this.exectuteAction = function (action, postData) { checkParamSet (1, action); if (!empty(postData)) { // add the operation to the data submitted to the server. postData.push({'name': "oper", 'value': action}); } else { // the post data was empty, just initialize it with the action. postdata = {'name': "oper", 'value': action}; } /* thisObject = this; $.post(this.resouceName, postData) .done ( function (data, status) { thisObject.postDone(data, status); }) .fail (this.postFail); */ // setup the ajax call settings and include a callbackBack field with data to pass to the done callback. var callbackData = {'thisObject': this}; /* var ajaxSettings = { 'type': "POST", 'dataType': "text", 'cache': false, 'url': this.resouceName, 'data': postData, 'callbackData': callbackData };*/ var ajaxSettings = { 'type': "POST", 'dataType': "json", 'url': this.resouceName, 'data': postData, 'callbackData': callbackData }; $.ajax(ajaxSettings).done ( function (data, status) { this.callbackData.thisObject.postDone(data, status); }) .fail (function (data, status) { this.callbackData.thisObject.postFail (data, status); }); } this.postDone = function (data, status) { this.eventInstance.triggerEvent (data); } // 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) { // need the try and catch the error her because it is an aysnchronise callback. // need to develop 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("Action request failed status:"+status); } catch (e) { alert("stack details:\n" + e.stack); } } // sets up the event istance to be used, it will be fired when the post request returns a successful // result this.setActionSucessEvent = function (eventInstance) { checkParamSet (1, eventInstance); this.eventInstance = eventInstance; } } // the class executes shopping cart actions by calling the server. function ShoppingCartAction () { this.resouceName = "ajax/shopping_cart.ajax.php"; this.actionRequest = new ActionRequest(this.resouceName); // send the action request to the server using passing the post date. this.exectuteAction = function (action, postData) { this.actionRequest.exectuteAction( action, postData); } // sets up the event istance to be used, it will be fired when the post request returns a successful // result this.setActionSucessEvent = function (eventInstance) { this.actionRequest.setActionSucessEvent (eventInstance); } } //the event manager allows for the registering of events and notifaction to listeners when the event fires //constructure of the of the event manager takes an event name and a call back back function and automatically //adds the event and setup a lister for the specified callback function, use to quickly create and event with //one event and one callback function // use parameters as a quick way to setup an event name and callback but kinds obsoleted in favour of EventInstanceListener //eventName: the name of the event to be added and that will triggered //eventCallback: the callback function with not parameters to be called when the event is triggered. function EventManager (eventName, eventCallback) { this.eventMap = new Map(); // a mapping of events by event name, the value of the map is an array // of objects containing call back function. // Code that uses eventName and eventCallback paramters at end of class. // eventName is a name of the event that can be listened for. // retuns an event instance which can be used to trigger the even. this.addEvent = function (eventName) { checkParamSet (1, eventName); // check if the eventname was already used. if (this.eventMap.has(eventName)) { throw new Error("Event name "+eventName+" is already registered."); } // setup and empty array associated with the event name. this.eventMap.set (eventName, []); return new EventInstance (this, eventName); } // add an event listener to list for an event to be fired // eventName: the event name registered by the addEvent function // eventCallback: the function to be used for the callback, one paramter // containing a generic event data object is returned this.addListener = function (eventName, parameter2, parameter3) { // determine the types of the variable parameters if (isFunction(parameter2)) { // the second parameter is the calback function. eventCallback = parameter2; callbackData = null; checkParamSet (2, eventName, eventCallback); } else if (isFunction(parameter3)) { // the third paramter is the call back function, the second parameter is the calback data. eventCallback = parameter3; callbackData = parameter2; checkParamSet (3, eventName, callbackData, eventCallback); } else { throw new Error("Callback function parameter not defined."); } // check if the event name exists. if (!this.eventMap.has(eventName)) { throw new Error("Event name "+eventName+" is not registered."); } // attach the call back function to the event. var callbackSet = this.eventMap.get(eventName); // add the new callback to the array. var callbackObject = null; if (empty(callbackData)) { // no call back data was provided. callbackObject = {'eventCallback': eventCallback} } else { // there is callback data. callbackObject = {'eventCallback': eventCallback, 'callbackData': callbackData} } callbackSet.push(callbackObject); } // add an event listener to list for an event to be fired // eventName: the event name registered by the addEvent function // thisObject: the object containing methods used within the call back function. // eventCallback: the function to be used for the callback, one paramter // containing a generic event data object is returned this.addListenerThis = function (eventName, thisObject, eventCallback) { checkParamSet (3, eventName, thisObject, eventCallback); // check if the event name exists. if (!this.eventMap.has(eventName)) { throw new Error("Event name "+eventName+" is not registered."); } // attach the call back function to the event. var callbackSet = this.eventMap.get(eventName); // add the new callback to the array. var callbackObject = null; // Add call back information to the stack callbackObject = {'callbackType': "callbackWithThisObject", 'eventCallback': eventCallback, 'thisObject': thisObject} callbackSet.push(callbackObject); } // trigger the event name to be fired for each of the listeners // eventName: the event name registered by the addEvent function // eventData: generic data object associated with the instance of the event fired this.triggerEvent = function (eventName, eventData) { // check if the event name exists. if (!this.eventMap.has(eventName)) { throw new Error("Event name "+eventName+" is not registered."); } // create ad event instance data object. // var eventInstanceData = new EventInstanceData (eventName, eventData); // get the array of function to call back. var callBackSet = this.eventMap.get(eventName); // loop all the function to be called. for (let callbackObject of callBackSet) { let callbackData = null; if ('callbackData' in callbackObject) { // setup the callback data specified when the callback was setup. callbackData = callbackObject.callbackData; } var eventInstanceData = new EventInstanceData (eventName, eventData, callbackData); var callbackType = "default"; if ('callbackType' in callbackObject) { // a specific callback callbackObjecttype was specified. callbackType = callbackObject.callbackType; } // determine the callback type. switch (callbackType) { case "callbackWithThisObject": // exectue the callback function this object data as a parameter. callbackObject.eventCallback(callbackObject.thisObject, eventInstanceData); break; case "default": // exectue the callback object just returning the envent instance data. callbackObject.eventCallback(eventInstanceData); break; default: // the type was not handled. throw new Error("Callback type '"+callbackType+"' not defined"); } } } // creates and event instance that can be triggered to fire the event associated with the event name // enventName: the name of the event the instance will be created for this.getEventInstance = function (eventName) { // check if the event name exists. if (!this.eventMap.has(eventName)) { throw new Error("Event name "+eventName+" is not registered."); } return new EventInstance (this, eventName); } // Determines if the envent has any listeners. // enventName: the name of the event // return true if listeners found this.hasListeners = function (eventName) { // check if the event name exists. if (!this.eventMap.has(eventName)) { throw new Error("Event name "+eventName+" is not registered."); } // get the array of function to call back. var callBackSet = this.eventMap.get(eventName); var hasListeners = false; if (!isEmpty(callBackSet)) { // there are listeners for the event. hasListeners = true; } return hasListeners; } // this code was added there because the function used not created at top, needed other method for setting up methods // for this code to be moved to the top. It confunssing to have the code here. if (!empty(eventName)) { if (!empty(eventCallback)){ // add the event this.addEvent(eventName); // add the event listener. this.addListener(eventName, eventCallback); } else { throw new Error("Event manager contructor error callback function for event name "+eventName+" is not defined."); } } } //the event instance represents a single event manager and event name, it is a compact way to trigger and event //eventManger : the event manager to associated with the instance. //eventName : the event name registered in the event manager to be triggered. function EventInstance (eventManager, eventName) { checkParamSet (2, eventManager, eventName); this.eventManager = eventManager; this.eventName = eventName; // trigger the event instance; this.triggerEvent = function (eventData) { this.eventManager.triggerEvent (this.eventName, eventData); } // add a new lister to be called if the even is triggered. // Parameter2: either callback data or the event callback function // Parameter3: either the event callback function or NULL this.addListener = function (parameter2, parameter3) { this.eventManager.addListener (this.eventName, parameter2, parameter3); } // thisObject: the object containing methods used within the call back function. // eventCallback: the function to be used for the callback, one paramter // containing a generic event data object is returned this.addListenerThis = function (thisObject, eventCallback) { this.eventManager.addListenerThis (this.eventName, thisObject, eventCallback); } } // the event data return information about the event returned to the listener // eventName : the name of the event that was fired // eventData: generic data object associated with the instance of the event fired function EventInstanceData (eventName, eventData, callbackData) { this.eventName = eventName; this.eventData = eventData; this.callbackData = callbackData; } //A quick way to make single managed event instance function EventInstanceListener (eventName, parameter2, parameter3) { // determine the types of the variable parameters if (isFunction(parameter2)) { // the second parameter is the calback function. eventCallback = parameter2; callbackData = null; checkParamSet (2, eventName, eventCallback); } else if (isFunction(parameter3)) { // the third paramter is the call back function, the second parameter is the calback data. eventCallback = parameter3; callbackData = parameter2; checkParamSet (3, eventName, callbackData, eventCallback); } // create a new event manager to handle trigger when the attribute search is activated. var eventManager = new EventManager(); // add the event name to the event manager and return the created even instance. this.eventInstance = eventManager.addEvent(eventName); // add a listner to the event using the given event callback. eventManager.addListener (eventName, callbackData, eventCallback); // trigger the event instance; this.triggerEvent = function (eventData) { this.eventInstance.triggerEvent (eventData); } } // A quick way to make single managed event instance // eventName: the event name registered by the addEvent function // thisObject: the object containing methods used within the call back function. // eventCallback: the function to be used for the callback, one paramter // containing a generic event data object is returned function EventInstanceListenerThis (eventName, thisObject, eventCallback) { checkParamSet (3, eventName, thisObject, eventCallback); // create a new event manager to handle trigger when the attribute search is activated. var eventManager = new EventManager(); // add the event name to the event manager and return the created even instance. this.eventInstance = eventManager.addEvent(eventName); // add a listner to the event using the given event callback. eventManager.addListenerThis (eventName, thisObject, eventCallback); // trigger the event instance; this.triggerEvent = function (eventData) { this.eventInstance.triggerEvent (eventData); } } // the cleanup manager tracks objects that need to be cleanup function CleanUpManager () { this.cleanUpSet = new Set(); // a set of objects that need to be cleanup. // add an object that has impement the cleanUp method this.add = function (cleanUpObject) { checkParamSet (1, cleanUpObject); if (Reflect.has(cleanUpObject, 'cleanUp')) { // add the clean up object to the set. this.cleanUpSet.add (cleanUpObject); } else { throw new Error("Object to add to the cleanup manager has no cleanUp method defined."); } } // activate the cleanup routine for any object in the set. this.cleanUp = function () { // issue the clean up over the set of objects. for (let cleanUpObject of this.cleanUpSet) { cleanUpObject.cleanUp(); } // clear all the items in the set. this.cleanUpSet.clear(); // this is acting like a reset. } } //create a manager to control the generic page error //initializeManager : set to TRUE to automatically initialize the manager, FALSE to not initialize the manager, defulat value is TRUE function PageErrorManager (initializeManager) { 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 error functionality functionality. this.initialize = initialize; // var thisObject = this; // when defined function to call ahead, the this in the function did not refer to the object. function initialize () { // add the click event two the close element. $("#error-section .error-close").off("click").click(function () { $("#error-section").hide(); // return false so no other triggers are not activated. return false; }); } this.addJavascriptError = function (errorMessage) { var newP = $("

").addClass("error-heading").text("Javascript Error:"); $("#error-section .error-message").append(newP) newP = $("

").html(errorMessage); $("#error-section .error-message").append(newP); // $("#error-section .error-message").append("

").html(errorMessage); } this.addSeverError = function (errorMessage) { var newP = $("

").addClass("error-heading").text("Sever Error:"); $("#error-section .error-message").append(newP); newP = $("

").html(errorMessage); $("#error-section .error-message").append(newP); } this.show = function () { $("#error-section").show(); } } // implements generic page functionality and the main menu functionality // the class manages all the AJAX funcationality for the page loaded. function MainPageManager () { // event manager used track menu events. this.eventManager = null; // the page error manager used to display generic page errors. this.pageErrorManager = null; // this is the cleanup manager used to initialize things when a new page is loaded. this.cleanUpManager = new CleanUpManager(); // initializes entire page javascript functionliaty. this.initializePage = function () { // inistalize the default page specific javascript. this.initialize(); } // initialize all the page functionality. this.initialize = function () { // create the menu manager and initialize it. var mainMenuManager = new MainMenuManager(); mainMenuManager.initialize(); // get the event manager used by the menu. this.eventManager = mainMenuManager.getEventManager(); // setup the various menu page load event activity to perform when the event is triggered this.menuEventHandler (); // create a shopping cart to store items for purchase this.pageErrorManager = new PageErrorManager(); } // add a listener for each menu event to load the appropreate page. this.menuEventHandler = function () { // var thisObject = this; /* // add an event listner to be called search page is activated. this.eventManager.addListener ("search", function () { // load the search page structure and initialize it. var searchPageManager = new SearchPageManager(); searchPageManager.loadPage(); // add the search page object to the cleanup manager. thisObject.cleanUpManager.add(searchPageManager); });*/ /* // add an event listner to be called contact us page is activated. this.eventManager.addListener ("contact_us", function () { // load and initialize the contact us page. var contactUsPageManager = new ContactUsPageManager(); contactUsPageManager.loadPage(); });*/ // add an event listner to be called check out page is activiated. this.eventManager.addListener ("check_out", function () { // load and initialize the checkout us page. var checkoutPageManager = new CheckoutPageManager(); checkoutPageManager.loadPage(); }); } } // a setup of utilities used to perform generic page loading activities function MainPageUtility () { // load and display the specified main page structure // pageName - server side main page to be loaded. // eventInstance - the event instance to be trigger after the page loads. this.loadMainPage = function (pageName, eventInstance) { checkParamSet (1, pageName); // set the menu name as the ajax operation data. var dataSet = {oper: pageName} // create the page content request object and then request the // specific menu html block to be displayed var pageHtmlContentRequest = new PageHtmlContentRequest(); // setup and event manager to trigger an event when the post is completed pageHtmlContentRequest.setRequestSucessEvent (eventInstance); pageHtmlContentRequest.loadHtmlContent(dataSet, "#page-main"); } // submits a form page data to a server activity and retuns and event when the data is loaded. // formId: Form Id of data to sumbit (Jquery object) // activity: Name of activity as defined on the server // targetElement: The element into which the returned data is to be displayed (Jquery object) // targetInsertionType: If the date returned will be appended to the element or override it // waitType: Scope at which the screen is inactivated by the loading icon before the data is loaded. this.submitFormPage = function (formId, activity, targetElement, eventInstance, targetInsertionType, waitType) { checkParamSet (3, formId, activity, targetElement); // create the submit form object to submit the request to the server. pageFormSubmitRequest = new PageFormSubmitRequest(); pageFormSubmitRequest.setRequestSucessEvent (eventInstance); pageFormSubmitRequest.submit(formId, activity, targetElement, targetInsertionType, waitType); } // extract the name of the loaded html document. // this.getPageName = function () { // checkParamSet (3, formId, activity, targetElement); var htmlPath = window.location.pathname; var pageName = htmlPath.split("/").pop(); return pageName; } } // the class manages the page menu. function MainMenuManager () { // create an event manager to handle all the menu trigger. this.eventManager = new EventManager(); // this is the cleanup manager used to initialize things when a new page is loaded. this.cleanUpManager = new CleanUpManager(); // initializes the main menu sets up tiggers to load other pages. this.initialize = function () { // setup the buttons to be activate when clicked. this.setMenuClickEvents(); // setup and event manager that will be used to initialize menu functionaly // after the menu page has been loaded. this.setMenuEventManager(); } // setup the buttons to be activate when clicked. this.setMenuClickEvents = function () { // perform required cleanup before a new page is loaded. this.cleanUpManager.cleanUp(); var thisObject = this; // setup the ajax call to populate home menu page. /* $("#menu-option-home").off("click").click(function() { // highlight and trigger the home menu event. thisObject.activateMenuEvent (this, "home"); // return false so no other triggers are activated. return false; });*/ /* // setup the ajax call to populate about us menu page. $("#menu-option-about-us").off("click").click(function() { // highlight and trigger the about us event thisObject.activateMenuEvent (this, "about_us"); // return false so no other triggers are activated. return false; }); */ /* // setup the ajax call to populate contact us menu page. $("#menu-option-contact-us").off("click").click(function() { // highlight and trigger the contact us event thisObject.activateMenuEvent (this, "contact_us"); // return false so no other triggers are activated. return false; });*/ /* // setup the ajax call to populate find menu page. $("#menu-option-find").off("click").click(function() { // highlight and tigger the search menu event. thisObject.activateMenuEvent (this, "search"); // return false so no other triggers are activated. return false; });*/ /* // setup the ajax call to populate check out page. $("#menu-option-check-out").off("click").click(function() { // highlight and tigger the search menu event. thisObject.activateMenuEvent (this, "check_out"); // return false so no other triggers are activated. return false; });*/ } // setup and event manager that will be used to initialize menu functionaly // after the menu page has been loaded. this.setMenuEventManager = function () { // register an event to be fired for each of possible menu options // this.eventManager.addEvent("home"); this.eventManager.addEvent("about_us"); // this.eventManager.addEvent("contact_us"); this.eventManager.addEvent("search"); this.eventManager.addEvent("check_out"); } // highlight the menu option and trigger the menu event. this.activateMenuEvent = function (menuElement, eventName) { checkParamSet(2, menuElement, eventName); var thisObject = this; // highlight the menu option and trigger the even. $(menuElement).effect("highlight", {color: "rgba(218, 165, 32, 0.5)"}, 300, function () { // tigger the search menu event. thisObject.eventManager.triggerEvent (eventName); }); } // return and event manager which is trigger when the various menu functionality is activated. // The following event are fired: search, contact_us ... this.getEventManager = function () { return this.eventManager; } } //create a new search page manager to implement the search page functionality after it is loaded function SearchSubMenuManager () { // 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 ("search_not_active"); this.eventManager.addEvent ("search_gallery_only"); this.eventManager.addEvent ("search_attribute_only"); // ... and more menu events here. // initializes the search page functionality. this.initialize = function () { // add click event to return the main search page view. clickHighlight ("#search-menu-option-home", function () { // reset the search mail class to not active $("#search-main").removeClass().addClass("search-not-active"); // fire the event for the sub menu. this.eventManager.triggerEvent ("search_not_active"); // return false so no other triggers are not activated. return false; }.bind(this)); // add click event to view only available galleries. clickHighlight ("#search-menu-option-gallery", function () { // reset the search mail class to not active $("#search-main").removeClass().addClass("search-gallery-only"); // fire the event for the sub menu. this.eventManager.triggerEvent ("search_gallery_only"); // return false so no other triggers are not activated. return false; }.bind(this)); // add click event to view only available attribute. clickHighlight ("#search-menu-option-attribute", function () { // reset the search mail class to not active $("#search-main").removeClass().addClass("search-attribute-only"); // fire the event for the sub menu. this.eventManager.triggerEvent ("search_attribute_only"); // return false so no other triggers are not activated. return false; }.bind(this)); } // 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; } // set the search sub menu into the gallery activate state. this.setGalleryAciveState = function () { $("#search-main").removeClass().addClass("search-gallery-active"); } // set the search sub menu into the gallery activate state. this.setAttributeSearchAciveState = function () { $("#search-main").removeClass().addClass("search-attribute-active"); } } //this object controls the class attribute selector widget //selectorID is the ID associated with the element containing the selector, this is a jquery object value or string //the attribute values within the attribute class are expended when the attribute class element is pressed //attribute values are hidden when another attribute class is selected except for checked attributes //HTML structure //selection ID // class='attribute-class' // class='attribute-value'; value = attribute ID; usually a check box // ... //... function SearchAttributeClassSelector (selectorId) { checkParamSet (1, selectorId); this.selectorId = selectorId; this.expandDelay = 50; this.expandAccelerator = 20; // stores the current active class name, used to control if the same class name is activated, it should close // the next activation. this.activeClassName = null ; // initialize the selector by adding triggers to the required elements. this.initializeWidget = function () { // add the expandAttributeClass function on the click trigger of all the attribute class elements . var thisObject = this; // STILL NEED TO FIX THIS ONE $(this.selectorId).find(".attribute-class").each( function () { // this is the attribute class element. $(this).find("a:first").off("click").click( function () { thisObject.toggleAttributeClass(this); // thisObject.expandAttributeClass(this); return false; }); }); // add the functionality to select the attribute values within the class. $(this.selectorId).find(".attribute-value").off("click").click( function () { thisObject.toggleAttributeValue(this); return false; // there was problem where if the false was not returned here, the click was passed down to actual element // after the
  • click was processed, because of and animation delay, the was set before the
  • // logic was activated, even though the
  • click was processed first. }); } // render the widget to update display based on the state of the widget. // notClassName : string of the text of the class name to be skipped. this.display = function (notClassName) { // select all the attribute classes var thisObject = this; $(this.selectorId).find(".attribute-class").each( function () { var className = $(this).find("a:first").html(); // do not want to update the class attribue display for the current class activated because // all the elements will just be expanded. if (className != notClassName || isEmpty(notClassName)) { thisObject.displayClassAttributes(this); } }); } // toggles the select attribute class to be open or closes, closes all other attribute class. // element : Jquery object or equivalent representing the attribute class - the element set as the "attribute-class" // element. this.toggleAttributeClass = function (element) { // get the class name represented by the element var className = this.getClassName (element); if (className == this.activeClassName) { // the same class has been activate twice, just closs all the attribute section showing selected items only. this.display(); // clear the active class value. this.activeClassName = null; } else { // activating the class for the first time, so close all the other ones and open this one up. this.expandAttributeClass(element); // set the active class value. this.activeClassName = className; } } // expand the attribute class. // element : Jquery object or equivalent representing the attribute class - the element set as the "attribute-class" // is either the element it self or its parent. this.expandAttributeClass = function (element) { // get attribute class name of the attribute class to be expanded. // the class name is the content of the element (should change this) var className = $(element).html(); // update the display of the other attribute classes, except for the current attribute class this.display(className); // we clicked the element within the class // the parent element is the attribute class, the attribute values to display them. // want to create the expanding event here. var thisObject = this; $(element).parent().find(".attribute-value").each( function (index) { // the show() without 1 will not work with the delay so added it (not use animation queue) $(this).delay(thisObject.calculateDelay(index)).show(1); }); } // show items in the attribute class that have a value, hide the reset. // element : Jquery object or equivalent representing the attribute class - the element set as the "attribute-class" // not the parent. this.displayClassAttributes = function (element) { // hide all the attribute values taht had not been set. var thisObject = this; $(element).find(".attribute-value").each( function (index) { if (!$(this).find("input").prop("checked")) { // The attribute value was not set to hide it. $(this).delay(thisObject.calculateDelay(index)).hide(1); } }); } // calculate the animation delay based on the index of the value attribute being anamated. this.calculateDelay = function (index) { return this.expandDelay*index - this.expandAccelerator*(index-1); } // toggle the value of the attribute value to be set as checked or not checked. // the elment should be the outer container of the checkbox and its label this.toggleAttributeValue = function (element) { var thisObject = this; $(element).effect("highlight", {color: "rgba(218, 165, 32, 0.5)"}, 300, function () { if ($(element).find("input").prop("checked")) { // checkbox was already set so unset it. $(element).find("input").prop("checked", false); // $(element).find("input").removeAttr("checked"); } else { // the checked element was not set to select the item. $(element).find("input").prop("checked",true); // $(element).find("input").attr("checked",""); } }); } // clear all the items set in the class attribute selector. this.clearSelectedAttributes = function () { // select all the attribute classes var thisObject = this; $(this.selectorId).find(".attribute-value").each( function () { if ($(this).find("input").prop("checked")) { // The attribute value was not set to hide it. $(this).find("input").prop("checked", false); } }); } // extract the class name from from the element set with the attribute-class class. // element : Jquery object or equivalent representing the attribute class - the element set as the "attribute-class" // element. this.getClassName = function (element) { // get attribute class name of the attribute class to be expanded. // the class name is the content of the 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" + "
    "; if (!empty(targetElement)) { $(targetElement).append(waitTemplate); $("#8sudjshdkw").show(); } // if (targetElement != "") { // $(targetElement).append(waitTemplate); // } // display the loading data image // $("#8sudjshdkw").show(); } /* // 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 // 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) { checkParamSet (1, targetElement); if (empty(waitType)) { // default the wait type value. waitType = 1; } var className = ""; if (waitType == 1) { className = "wait-loading"; } else if (waitType == 2) { className = "wait-loading-element"; } else { throw new Error("Wait type "+waitType+" is not defined.") } var waitTemplate = "
    " + "Wait Loading" + "
    "; if (targetElement != "") { $(targetElement).append(waitTemplate); } // display the loading data image $("#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(); } } //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. // 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); // 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. 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(); // 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; } }