Author: jleroux
Date: Sun Jul 27 00:53:13 2008 New Revision: 680073 URL: http://svn.apache.org/viewvc?rev=680073&view=rev Log: An enhancing patch from Sumit Pandit "At main page of the ecommerce show popup on mouse over at product image and/or link." (https://issues.apache.org/jira/browse/OFBIZ-1891) - OFBIZ-1891 Added: ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.css (with props) ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.js (with props) Modified: ofbiz/trunk/applications/ecommerce/widget/CommonScreens.xml ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productsummary.ftl Modified: ofbiz/trunk/applications/ecommerce/widget/CommonScreens.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/ecommerce/widget/CommonScreens.xml?rev=680073&r1=680072&r2=680073&view=diff ============================================================================== --- ofbiz/trunk/applications/ecommerce/widget/CommonScreens.xml (original) +++ ofbiz/trunk/applications/ecommerce/widget/CommonScreens.xml Sun Jul 27 00:53:13 2008 @@ -44,13 +44,16 @@ <set field="layoutSettings.javaScripts[]" value="/images/calendar_date_select.js" global="true"/> <set field="layoutSettings.javaScripts[+0]" value="/images/prototypejs/validation.js" global="true"/> <set field="layoutSettings.javaScripts[+0]" value="/images/prototypejs/prototype.js" global="true"/> - + <set field="layoutSettings.javaScripts[]" value="/images/prototypejs/effects.js" global="true"/> + <set field="layoutSettings.javaScripts[]" value="/images/prototypejs/popup.js" global="true"/> + <set field="layoutSettings.extraHead" value="<link rel="stylesheet" href="/content/images/contentForum.css" type="text/css"/>" global="true"/> <script location="component://ecommerce/widget/EcommerceSetup.bsh"/> <!-- The default (main) stylesheets --> <set field="layoutSettings.styleSheets[+0]" value="/ecommerce/images/blog.css" global="true"/> - <set field="layoutSettings.styleSheets[+0]" value="${productStore.styleSheet}" default-value="/images/ecommain.css" global="true"/> + <set field="layoutSettings.styleSheets[+0]" value="${productStore.styleSheet}" default-value="/images/ecommain.css" global="true"/> + <set field="layoutSettings.styleSheets[+0]" value="/images/prototypejs/popup.css" global="true"/> </actions> <widgets> <!-- render header --> Modified: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productsummary.ftl URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productsummary.ftl?rev=680073&r1=680072&r2=680073&view=diff ============================================================================== --- ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productsummary.ftl (original) +++ ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/productsummary.ftl Sun Jul 27 00:53:13 2008 @@ -28,13 +28,31 @@ <#assign smallImageUrl = productContentWrapper.get("SMALL_IMAGE_URL")?if_exists> <#if !smallImageUrl?has_content><#assign smallImageUrl = "/images/defaultImage.jpg"></#if> <#-- end variable setup --> - + <#assign productInfoLinkId = "productInfoLink"> + <#assign productInfoLinkId = productInfoLinkId + product.productId/> + <#assign productDetailId = "productDetailId"/> + <#assign productDetailId = productDetailId + product.productId/> <div class="productsummary"> <div class="smallimage"> <a href="<@ofbizUrl>${targetRequestName}/<#if categoryId?exists>~category_id=${categoryId}/</#if>~product_id=${product.productId}</@ofbizUrl>"> - <img src="<@ofbizContentUrl>${contentPathPrefix?if_exists}${smallImageUrl}</@ofbizContentUrl>" alt="Small Image"/> + <span id="${productInfoLinkId}" class="popup_link"><img src="<@ofbizContentUrl>${contentPathPrefix?if_exists}${smallImageUrl}</@ofbizContentUrl>" alt="Small Image"/></span> </a> </div> + <div id="${productDetailId}" class="popup" > + <table> + <tr valign="top"> + <td> + <img src="<@ofbizContentUrl>${contentPathPrefix?if_exists}${smallImageUrl}</@ofbizContentUrl>" alt="Small Image"/><br/> + ${uiLabelMap.ProductProductId} : ${product.productId?if_exists}<br/> + ${uiLabelMap.ProductProductName} : ${product.productName?if_exists}<br/> + ${uiLabelMap.CommonDescription} : ${product.description?if_exists} + </td> + </tr> + </table> + </div> + <script type="text/javascript"> + new Popup('${productDetailId}','${productInfoLinkId}', {position: 'none'}) + </script> <div class="productbuy"> <#-- check to see if introductionDate hasn't passed yet --> <#if product.introductionDate?exists && nowTimestamp.before(product.introductionDate)> Added: ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.css URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.css?rev=680073&view=auto ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.css (added) +++ ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.css Sun Jul 27 00:53:13 2008 @@ -0,0 +1,35 @@ +/* + popup.js +*/ +div.popup { + max-width: 600px; + width: 250px; + border: 1px solid red; + padding: 5px; + background-color: white; + /* The following properties should not be changed */ + position: absolute; +} + +#popup_overlay { + background-color: whitesmoke; + /* The following properties should not be changed */ + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 500px; +} + +span.popup_link, a.popup_link { + cursor: pointer; + +} + +.popup td{ + background:#fff +} + +.popup_draghandle { + cursor: move; +} Propchange: ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.css ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.css ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.css ------------------------------------------------------------------------------ svn:mime-type = text/css Added: ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.js?rev=680073&view=auto ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.js (added) +++ ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.js Sun Jul 27 00:53:13 2008 @@ -0,0 +1,470 @@ +/* + popup.js + + A lightweight general purpose JavaScript DOM element popup class. + + Webpage: + http;//www.methods.co.nz/popup/popup.html + + Inspired by: + Lightbox2: http://www.huddletogether.com/projects/lightbox2/ + Lightbox Gone Wild: http://particletree.com/features/lightbox-gone-wild/ + Tooltip: http://blog.innerewut.de/pages/tooltip + Prototype library: http://www.prototypejs.org/ + Scriptaculous library: http://script.aculo.us/ + + Attributions: + - Uses the getPageSize() function from Lightbox v2.02 by Lokesh Dhakar + (http://www.huddletogether.com/projects/lightbox2/). + - Adapted the the modal overlay technique used in Lightbox v2.02 by Lokesh + Dhakar (http://www.huddletogether.com/projects/lightbox2/). + + Version: 1.0.1 + + Author: Stuart Rackham <[hidden email]> + License: This source code is released under the MIT license. + + Copyright (c) Stuart Rackham 2007 + +*/ + +var Popup = Class.create(); +Popup.zIndex = 1000; // z-index of first popup. + +Popup.prototype = { + + /* + Popup creation + */ + initialize: function(popup, link) { + var options = Object.extend({ + modal: false, + effect: 'fade', + hidden: true, + closebox: 'popup_closebox', // CSS class name of click-to-close elements. + draghandle: 'popup_draghandle' // CSS class name of drag handle elements. + }, arguments[2] || {}); + options.position = options.position || (options.modal ? 'center' : 'auto'); + options.trigger = options.trigger || (options.modal ? 'click' : 'mouseover'); + options.duration = this.first_value(options.duration, Popup.duration, 0.5); + options.show_duration = this.first_value(options.show_duration, options.duration); + options.hide_duration = this.first_value(options.hide_duration, options.duration); + options.opacity = this.first_value(options.opacity, Popup.opacity, 0.5); + options.show_delay = this.first_value(options.show_delay, Popup.show_delay, 500); + options.hide_delay = this.first_value(options.hide_delay, Popup.hide_delay, 200); + options.cursor_margin = this.first_value(options.cursor_margin, Popup.cursor_margin, 5); + this.options = options; + if (link) { + this.link = $(link); + } + this.popup = $(popup); + this.popup.popup = this; // Make the popup object a property of the DOM popup element. + if (options.hidden) { + this.popup.hide(); + } + if (options.closebox) { + this.closeboxes = document.getElementsByClassName(options.closebox, this.popup); + if (this.popup.hasClassName(options.closebox)) { + this.closeboxes[this.closeboxes.length] = this.popup; + } + } + else { + this.closeboxes = []; + } + if (options.draghandle) { + var draghandles = document.getElementsByClassName(options.draghandle, this.popup); + for (i = 0; i < draghandles.length; i++) { + new Draggable(this.popup, { handle: draghandles[i] }); + } + if (this.popup.hasClassName(options.draghandle)) { + new Draggable(this.popup, { handle: this.popup }); + } + } + this.register_events(); + }, + + + /* + Event functions + */ + + register_events: function() { + var trigger_function; + if (this.is_auto_open()) { + trigger_function = this.start_show_timer; + if (this.link) { + Event.observe(this.link, 'mouseout', this.stop_show_timer.bindAsEventListener(this)); + } + } + else { + trigger_function = this.show; + } + if (this.link) { + Event.observe(this.link, this.options.trigger, trigger_function.bindAsEventListener(this)); + } + if (!this.options.modal) { + Event.observe(this.popup, 'click', this.bring_to_front.bindAsEventListener(this)); + } + if (this.closeboxes.length > 0) { + for (var i = 0; i < this.closeboxes.length; i++) { + Event.observe(this.closeboxes[i], 'click', this.hide.bindAsEventListener(this)); + } + } + else { + if (this.link) { + Event.observe(this.link, 'mouseout', this.start_hide_timer.bindAsEventListener(this)); + } + Event.observe(this.popup, 'mouseover', this.stop_hide_timer.bindAsEventListener(this)); + Event.observe(this.popup, 'mouseout', this.start_hide_timer.bindAsEventListener(this)); + } + }, + + bring_to_front: function(event) { + // Bring to front if not already there. + if (Number(this.popup.style.zIndex) < Popup.zIndex - 1) { + this.popup.style.zIndex = Popup.zIndex++; + } + }, + + start_show_timer: function(event) { + // NOTE: event is bound to this.show but it's state changes between being + // bound here and arriving at this.show -- specifically, the mouse + // coordinates are reset to zero). I've no idea why. Anyway, this is the + // reason for passing the event mouse coordinates as properties of this. + this.stop_show_timer(event); + this.mouse_x = Event.pointerX(event); + this.mouse_y = Event.pointerY(event); + this.show_timer = setTimeout(this.show.bind(this, event), this.options.show_delay); + }, + + stop_show_timer: function(event) { + if (this.show_timer) { + clearTimeout(this.show_timer); + this.show_timer = null; + } + }, + + start_hide_timer: function(event) { + this.stop_hide_timer(event); + this.hide_timer = setTimeout(this.hide.bind(this, event), this.options.hide_delay); + }, + + stop_hide_timer: function(event) { + if (this.hide_timer) { + clearTimeout(this.hide_timer); + this.hide_timer = null; + } + }, + + show: function(event) { + this.stop_show_timer(event); + this.stop_hide_timer(event); + if (this.is_open) { + return; + } + if (this.options.modal) { + this.show_overlay(); + } + var pos; + if (!event) { + // We only arrive here if this.show has been called externally. + pos = this.get_popup_position(); + } + else if (this.is_auto_open()) { + // Because auto-open popups calls this.show indirectly via start_show_timer. + pos = this.get_popup_position(this.mouse_x, this.mouse_y); + } + else { + pos = this.get_popup_position(Event.pointerX(event), Event.pointerY(event)); + } + Element.setStyle(this.popup, { top: pos.y, left: pos.x, zIndex: Popup.zIndex++ }); + this.is_open = true; + switch (this.options.effect) { + case 'slide': + Effect.SlideDown(this.popup, {duration: this.options.show_duration}); + break; + case 'grow': + Effect.Grow(this.popup, {duration: this.options.show_duration}); + break; + case 'blind': + Effect.BlindDown(this.popup, {duration: this.options.show_duration}); + break; + case 'fade': + default: + Effect.Appear(this.popup, {duration: this.options.show_duration}); + break; + } + }, + + hide: function(event){ + this.is_open = false; + switch (this.options.effect) { + case 'slide': + Effect.SlideUp(this.popup, {duration: this.options.hide_duration}); + break; + case 'grow': + Effect.Shrink(this.popup, {duration: this.options.hide_duration}); + break; + case 'blind': + Effect.BlindUp(this.popup, {duration: this.options.hide_duration}); + break; + case 'fade': + default: + Effect.Fade(this.popup, {duration: this.options.hide_duration}); + break; + } + if (this.options.modal) { + this.hide_overlay(); + } + }, + + + /* + Helper functions + */ + + // Return the first function argument that is not undefined. + // Because when zero numerical value are possible you can't use || chains. + first_value: function() { + for (var i = 0; i < arguments.length; i++) { + if (arguments[i] !== undefined) { + return arguments[i]; + } + } + return undefined; + }, + + is_auto_open: function() { + return this.options.trigger == 'mouseover'; + }, + + show_overlay: function() { + if (!Popup.overlay) { + var overlay = document.createElement('div'); + overlay.setAttribute('id','popup_overlay'); + overlay.style.display = 'none'; + document.body.appendChild(overlay); + Popup.overlay = overlay; + Popup.overlay_levels = []; + } + Popup.overlay.style.height = this.get_page_dimensions().height + 'px'; + var z = Popup.zIndex++; + Popup.overlay.style.zIndex = z; + Popup.overlay_levels.push(z); + if ( Popup.overlay_levels.length == 1) { // Opening the first modal popup. + // Queue the global overlay effect to ensure correct execution order. + new Effect.Appear(Popup.overlay, + { duration: this.options.show_duration, + to: this.options.opacity, + queue: {position: 'end', scope: 'popup_overlay'} + }); + } + else { // There is another modal popup at a lower level so move the overlay forward. + Popup.overlay.style.zIndex = z; + } + }, + + hide_overlay: function() { + Popup.overlay_levels.pop(); + var z = Popup.overlay_levels.pop(); + if (z) { // There is another modal popup at a lower level so move the overlay back. + Popup.overlay_levels.push(z); + Popup.overlay.style.zIndex = z; + } + else { // The last modal popup is being closed so hide the overlay + // Queue the global overlay effect to ensure correct execution order. + new Effect.Fade(Popup.overlay, + { duration: this.options.hide_duration, + queue: {position: 'end', scope: 'popup_overlay'} + }); + } + }, + + + /* + Positioning functions + */ + + // Return the top and left CSS position strings as an {x,y} object that the + // popup should be shown at. mouse_x and mouse_y are the mouse x,y coordinates + // numbers when the popup was triggered. + get_popup_position: function(mouse_x, mouse_y) { + var pos; + switch (this.options.position) { + case 'auto': + pos = this.get_auto_position(mouse_x, mouse_y); + break; + case 'center': + pos = this.get_center_position(); + break; + case 'below': + pos = this.get_below_position(); + break; + default: + // Check for x,y postion format (x and y can be any valid CSS left or + // top property value). + if (mo = this.options.position.match(/^\s*([^\s,]+)\s*,\s*([^\s,]+)\s*$/)) { + pos = {x: mo[1], y: mo[2]}; + // If possible convert to numbers. + pos.x = Number(pos.x)+100 || pos.x+100; + pos.y = Number(pos.y) || pos.y; + } + else { + pos = {x: 50, y: 20}; + } + break; + } + if (typeof pos.x == 'number') { + pos.x += 'px'; + } + if (typeof pos.y == 'number') { + pos.y += 'px'; + } + return pos; + }, + + get_below_position: function() { + var pos = Position.cumulativeOffset(this.link); + return {x: pos[0], y: pos[1] + Element.getHeight(this.link)}; + }, + + get_center_position: function() { + dim = Element.getDimensions(this.popup); + var popup_width = dim.width; + var popup_height = dim.height; + dim = this.get_viewport_dimensions(); + var viewport_width = dim.width; + var viewport_height = dim.height; + + var x; + if (popup_width >= viewport_width) { + x = 0; + } + else { + x = (viewport_width - popup_width)/2; + } + + var y; + if (popup_height >= viewport_height) { + y = 0; + } + else { + y = (viewport_height - popup_height)/2; + } + + return {x: x, y: y}; + }, + + get_auto_position: function(mouse_x, mouse_y) { + dim = Element.getDimensions(this.popup); + var popup_width = dim.width; + var popup_height = dim.height; + dim = this.get_viewport_dimensions(); + var viewport_width = dim.width; + var viewport_height = dim.height; + + var available_right = viewport_width - (mouse_x + this.options.cursor_margin); + var available_left = mouse_x - this.options.cursor_margin; + var available_top = mouse_y - this.options.cursor_margin; + var available_bottom = viewport_height - (mouse_x + this.options.cursor_margin); + var offset = this.options.cursor_margin; + var x = mouse_x; + var y = mouse_y; + + if (popup_width >= viewport_width) { + x = 0; + } + else if (popup_width <= available_right) { + x += offset; + } + else if (popup_width <= available_left) { + x -= popup_width + offset; + } + else if (available_right >= available_left) { + x = viewport_width - popup_width; + } + else { + x = 0; + } + + if (popup_height >= viewport_height) { + y = 0; + } + else if (popup_height <= available_bottom) { + y += offset; + } + else if (popup_height <= available_top) { + y -= popup_height + offset; + } + else if (available_bottom >= available_top) { + y = viewport_height - popup_height; + } + else { + y = 0; + } + + return {x: x, y: y}; + }, + + get_viewport_dimensions: function() { + var dim = this.getPageSize(); + return {width: dim[2], height: dim[3]}; + }, + + get_page_dimensions: function() { + var dim = this.getPageSize(); + return {width: dim[0], height: dim[1]}; + }, + + // This function from Lightbox v2.02 by Lokesh Dhakar + // (http://www.huddletogether.com/projects/lightbox2/). + // + // Returns array with page width, height and window width, height + // Core code from - quirksmode.org + // Edit for Firefox by pHaez + // + getPageSize: function() { + var xScroll, yScroll; + + if (window.innerHeight && window.scrollMaxY) { + xScroll = document.body.scrollWidth; + yScroll = window.innerHeight + window.scrollMaxY; + } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac + xScroll = document.body.scrollWidth; + yScroll = document.body.scrollHeight; + } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari + xScroll = document.body.offsetWidth; + yScroll = document.body.offsetHeight; + } + + var windowWidth, windowHeight; + if (self.innerHeight) { // all except Explorer + windowWidth = self.innerWidth; + windowHeight = self.innerHeight; + } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode + windowWidth = document.documentElement.clientWidth; + windowHeight = document.documentElement.clientHeight; + } else if (document.body) { // other Explorers + windowWidth = document.body.clientWidth; + windowHeight = document.body.clientHeight; + } + + // for small pages with total height less then height of the viewport + if(yScroll < windowHeight){ + pageHeight = windowHeight; + } else { + pageHeight = yScroll; + } + + // for small pages with total width less then width of the viewport + if(xScroll < windowWidth){ + pageWidth = windowWidth; + } else { + pageWidth = xScroll; + } + + arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight); + return arrayPageSize; + } + +} Propchange: ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/prototypejs/popup.js ------------------------------------------------------------------------------ svn:mime-type = text/plain |
Free forum by Nabble | Edit this page |