/** * Magento * * NOTICE OF LICENSE * * This source file is subject to the Academic Free License (AFL 3.0) * that is bundled with this package in the file LICENSE_AFL.txt. * It is also available through the world-wide-web at this URL: * http://opensource.org/licenses/afl-3.0.php * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@magentocommerce.com so we can send you a copy immediately. * * DISCLAIMER * * Do not edit or add to this file if you wish to upgrade Magento to newer * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * * @category Mage * @package Mage_Adminhtml * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ProductConfigure = Class.create(); ProductConfigure.prototype = { listTypes: $H({}), current: $H({}), itemsFilter: $H({}), blockWindow: null, blockForm: null, blockFormFields: null, blockFormAdd: null, blockFormConfirmed: null, blockConfirmed: null, blockIFrame: null, blockCancelBtn: null, blockMask: null, blockMsg: null, blockMsgError: null, windowHeight: null, confirmedCurrentId: null, confirmCallback: {}, cancelCallback: {}, onLoadIFrameCallback: {}, showWindowCallback: {}, beforeSubmitCallback: {}, iFrameJSVarname: null, _listTypeId: 1, /** * Initialize object */ initialize: function() { this._initWindowElements(); }, /** * Initialize window elements */ _initWindowElements: function() { this.blockWindow = $('product_composite_configure'); this.blockForm = $('product_composite_configure_form'); this.blockFormFields = $('product_composite_configure_form_fields'); this.blockFormAdd = $('product_composite_configure_form_additional'); this.blockFormConfirmed = $('product_composite_configure_form_confirmed'); this.blockConfirmed = $('product_composite_configure_confirmed'); this.blockIFrame = $('product_composite_configure_iframe'); this.blockCancelBtn = $('product_composite_configure_form_cancel'); this.blockMask = $('popup-window-mask'); this.blockMsg = $('product_composite_configure_messages'); this.blockMsgError = this.blockMsg.select('.error-msg')[0]; this.windowHeight = $('html-body').getHeight(); this.iFrameJSVarname = this.blockForm.select('input[name="as_js_varname"]')[0].value; }, /** * Returns next unique list type id */ _generateListTypeId: function () { return '_internal_lt_' + (this._listTypeId++); }, /** * Add product list types as scope and their urls * expamle: addListType('product_to_add', {urlFetch: 'http://magento...'}) * expamle: addListType('wishlist', {urlSubmit: 'http://magento...'}) * * @param type types as scope * @param urls obj can be * - {urlFetch: 'http://magento...'} for fetching configuration fields through ajax * - {urlConfirm: 'http://magento...'} for submit configured data through iFrame when clicked confirm button * - {urlSubmit: 'http://magento...'} for submit configured data through iFrame */ addListType: function(type, urls) { if ('undefined' == typeof this.listTypes[type]) { this.listTypes[type] = {}; } Object.extend(this.listTypes[type], urls); return this; }, /** * Adds complex list type - that is used to submit several list types at once * Only urlSubmit is possible for this list type * expamle: addComplexListType(['wishlist', 'product_list'], 'http://magento...') * * @param type types as scope * @param urls obj can be * - {urlSubmit: 'http://magento...'} for submit configured data through iFrame * @return type string */ addComplexListType: function(types, urlSubmit) { var type = this._generateListTypeId(); this.listTypes[type] = {}; this.listTypes[type].complexTypes = types; this.listTypes[type].urlSubmit = urlSubmit; return type; }, /** * Add filter of items * * @param listType scope name * @param itemsFilter */ addItemsFilter: function(listType, itemsFilter) { if (!listType || !itemsFilter) { return false; } if ('undefined' == typeof this.itemsFilter[listType]) { this.itemsFilter[listType] = []; } this.itemsFilter[listType] = this.itemsFilter[listType].concat(itemsFilter); return this; }, /** * Returns id of block where configuration for an item is stored * * @param listType scope name * @param itemId * @return string */ _getConfirmedBlockId: function (listType, itemId) { return this.blockConfirmed.id + '[' + listType + '][' + itemId + ']'; }, /** * Checks whether item has some configuration fields * * @param listType scope name * @param itemId * @return bool */ itemConfigured: function (listType, itemId) { var confirmedBlockId = this._getConfirmedBlockId(listType, itemId); var itemBlock = $(confirmedBlockId); return !!(itemBlock && itemBlock.innerHTML); }, /** * Show configuration fields of item, if it not found then get it through ajax * * @param listType scope name * @param itemId */ showItemConfiguration: function(listType, itemId) { if (!listType || !itemId) { return false; } this._initWindowElements(); this.current.listType = listType; this.current.itemId = itemId; this.confirmedCurrentId = this._getConfirmedBlockId(listType, itemId); if (!this.itemConfigured(listType, itemId)) { this._requestItemConfiguration(listType, itemId); } else { this._processFieldsData('item_restore'); this._showWindow(); } }, /** * Get configuration fields of product through ajax and show them * * @param listType scope name * @param itemId */ _requestItemConfiguration: function(listType, itemId) { if (!this.listTypes[listType].urlFetch) { return false; } var url = this.listTypes[listType].urlFetch; if (url) { new Ajax.Request(url, { parameters: {id: itemId}, onSuccess: function(transport) { var response = transport.responseText; if (response.isJSON()) { response = response.evalJSON(); if (response.error) { this.blockMsg.show(); this.blockMsgError.innerHTML = response.message; this.blockCancelBtn.hide(); this.setConfirmCallback(listType, null); this._showWindow(); } } else if (response) { response = response + ''; this.blockFormFields.update(response); // Add special div to hold mage data, e.g. scripts to execute on every popup show var mageData = {}; var scripts = response.extractScripts(); mageData.scripts = scripts; var scriptHolder = new Element('div', {'style': 'display:none'}); scriptHolder.mageData = mageData; this.blockFormFields.insert(scriptHolder); // Show window this._showWindow(); } }.bind(this) }); } }, /** * Triggered on confirm button click * Do submit configured data through iFrame if needed */ onConfirmBtn: function() { if (productCompositeConfigureForm.validate()) { if (this.listTypes[this.current.listType].urlConfirm) { this.submit(); } else { this._processFieldsData('item_confirm'); this._closeWindow(); if (Object.isFunction(this.confirmCallback[this.current.listType])) { this.confirmCallback[this.current.listType](); } } } return this; }, /** * Triggered on cancel button click */ onCancelBtn: function() { this._closeWindow(); if (Object.isFunction(this.cancelCallback[this.current.listType])) { this.cancelCallback[this.current.listType](); } return this; }, /** * Submit configured data through iFrame * * @param listType scope name */ submit: function (listType) { // prepare data if (listType) { this.current.listType = listType; this.current.itemId = null; } var urlConfirm = this.listTypes[this.current.listType].urlConfirm; var urlSubmit = this.listTypes[this.current.listType].urlSubmit; if (!urlConfirm && !urlSubmit) { return false; } if (urlConfirm) { this.blockForm.action = urlConfirm; this.addFields([new Element('input', {type: 'hidden', name: 'id', value: this.current.itemId})]); } else { this.blockForm.action = urlSubmit; var complexTypes = this.listTypes[this.current.listType].complexTypes; if (complexTypes) { this.addFields([new Element('input', {type: 'hidden', name: 'configure_complex_list_types', value: complexTypes.join(',')})]); } this._processFieldsData('current_confirmed_to_form'); // Disable item controls that duplicate added fields (e.g. sometimes qty controls can intersect) // so they won't be submitted var tagNames = ['input', 'select', 'textarea']; var names = {}; // Map of added field names for (var i = 0, len = tagNames.length; i < len; i++) { var tagName = tagNames[i]; var elements = this.blockFormAdd.getElementsByTagName(tagName); for (var index = 0, elLen = elements.length; index < elLen; index++) { names[elements[index].name] = true; } } for (var i = 0, len = tagNames.length; i < len; i++) { var tagName = tagNames[i]; var elements = this.blockFormConfirmed.getElementsByTagName(tagName); for (var index = 0, elLen = elements.length; index < elLen; index++) { var element = elements[index]; if (names[element.name]) { element.setAttribute('configure_disabled', 1); element.setAttribute('configure_prev_disabled', element.disabled ? 1 : 0); element.disabled = true; } else { element.setAttribute('configure_disabled', 0); } } } } // do submit if (Object.isFunction(this.beforeSubmitCallback[this.current.listType])) { this.beforeSubmitCallback[this.current.listType](); } this.blockForm.submit(); varienLoaderHandler.handler.onCreate({options: {loaderArea: true}}); return this; }, /** * Add dynamically additional fields for form * * @param fields */ addFields: function(fields) { fields.each(function(elm) { this.blockFormAdd.insert(elm); }.bind(this)); return this; }, /** * Triggered when form was submitted and iFrame was loaded. Get response from iFrame and handle it */ onLoadIFrame: function() { this.blockFormConfirmed.select('[configure_disabled=1]').each(function (element) { element.disabled = element.getAttribute('configure_prev_disabled') == '1'; }); this._processFieldsData('form_confirmed_to_confirmed'); var response = this.blockIFrame.contentWindow[this.iFrameJSVarname]; if (response && "object" == typeof response) { if (this.listTypes[this.current.listType].urlConfirm) { if (response.ok) { this._closeWindow(); this.clean('current'); } else if (response.error) { this.showItemConfiguration(this.current.listType, this.current.itemId); this.blockMsg.show(); this.blockMsgError.innerHTML = response.message; this._showWindow(); return false; } } if (Object.isFunction(this.onLoadIFrameCallback[this.current.listType])) { this.onLoadIFrameCallback[this.current.listType](response); } document.fire(this.current.listType + ':afterIFrameLoaded'); } varienLoaderHandler.handler.onComplete(); this.clean('current'); }, /** * Helper for fetching content from iFrame */ _getIFrameContent: function() { var content = (this.blockIFrame.contentWindow || this.blockIFrame.contentDocument); if (content.document) { content=content.document; } return content; }, /** * Helper to find qty of currently confirmed item */ getCurrentConfirmedQtyElement: function() { var elms = $(this.confirmedCurrentId).getElementsByTagName('input'); for (var i = 0; i < elms.length; i++) { if (elms[i].name == 'qty') { return elms[i]; } } }, /** * Helper to find qty of active form */ getCurrentFormQtyElement: function() { var elms = this.blockFormFields.getElementsByTagName('input'); for (var i = 0; i < elms.length; i++) { if (elms[i].name == 'qty') { return elms[i]; } } }, /** * Show configuration window */ _showWindow: function() { this._toggleSelectsExceptBlock(false); this.blockMask.setStyle({'height':this.windowHeight+'px'}).show(); this.blockWindow.setStyle({'marginTop':-this.blockWindow.getHeight()/2 + "px", 'display':'block'}); if (Object.isFunction(this.showWindowCallback[this.current.listType])) { this.showWindowCallback[this.current.listType](); } }, /** * toggles Selects states (for IE) except those to be shown in popup */ _toggleSelectsExceptBlock: function(flag) { if(Prototype.Browser.IE){ if (this.blockForm) { var states = new Array; var selects = this.blockForm.getElementsByTagName("select"); for(var i=0; i