File: /home/accemeff/public_html/acc/js/mage/adminhtml/product/composite/configure.js
/**
* 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@magento.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.magento.com for more information.
*
* @category Mage
* @package Mage_Adminhtml
* @copyright Copyright (c) 2006-2017 X.commerce, Inc. and affiliates (http://www.magento.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<selects.length; i++){
states[i] = selects[i].style.visibility;
}
}
toggleSelectsUnderBlock(this.blockMask, flag);
if (this.blockForm) {
for(i=0; i<selects.length; i++){
selects[i].style.visibility = states[i];
}
}
}
},
/**
* Close configuration window
*/
_closeWindow: function() {
toggleSelectsUnderBlock(this.blockMask, true);
this.blockMask.style.display = 'none';
this.blockWindow.style.display = 'none';
this.clean('window');
},
/**
* Attach callback function triggered when confirm button was clicked
*
* @param confirmCallback
*/
setConfirmCallback: function(listType, confirmCallback) {
this.confirmCallback[listType] = confirmCallback;
return this;
},
/**
* Attach callback function triggered when cancel button was clicked
*
* @param cancelCallback
*/
setCancelCallback: function(listType, cancelCallback) {
this.cancelCallback[listType] = cancelCallback;
return this;
},
/**
* Attach callback function triggered when iFrame was loaded
*
* @param onLoadIFrameCallback
*/
setOnLoadIFrameCallback: function(listType, onLoadIFrameCallback) {
this.onLoadIFrameCallback[listType] = onLoadIFrameCallback;
return this;
},
/**
* Attach callback function triggered when iFrame was loaded
*
* @param showWindowCallback
*/
setShowWindowCallback: function(listType, showWindowCallback) {
this.showWindowCallback[listType] = showWindowCallback;
return this;
},
/**
* Attach callback function triggered before submitting form
*
* @param beforeSubmitCallback
*/
setBeforeSubmitCallback: function(listType, beforeSubmitCallback) {
this.beforeSubmitCallback[listType] = beforeSubmitCallback;
return this;
},
/**
* Clean object data
*
* @param method can be 'all' or 'current'
*/
clean: function(method) {
var listInfo = null;
var listTypes = null;
var removeConfirmed = function (listTypes) {
this.blockConfirmed.childElements().each(function(elm) {
for (var i = 0, len = listTypes.length; i < len; i++) {
var pattern = this.blockConfirmed.id + '[' + listTypes[i] + ']';
if (elm.id.indexOf(pattern) == 0) {
elm.remove();
break;
}
}
}.bind(this));
}.bind(this);
switch (method) {
case 'current':
listInfo = this.listTypes[this.current.listType];
listTypes = [this.current.listType];
if (listInfo.complexTypes) {
listTypes = listTypes.concat(listInfo.complexTypes);
}
removeConfirmed(listTypes);
break;
case 'window':
this.blockFormFields.update();
this.blockMsg.hide();
this.blockMsgError.update();
this.blockCancelBtn.show();
break;
default:
// search in list types for its cleaning
if (this.listTypes[method]) {
listInfo = this.listTypes[method];
listTypes = [method];
if (listInfo.complexTypes) {
listTypes = listTypes.concat(listInfo.complexTypes);
}
removeConfirmed(listTypes);
// clean all
} else if (!method) {
this.current = $H({});
this.blockConfirmed.update();
this.blockFormFields.update();
this.blockMsg.hide();
this.blockMsgError.update();
this.blockCancelBtn.show();
}
break;
}
this._getIFrameContent().body.innerHTML = '';
this.blockIFrame.contentWindow[this.iFrameJSVarname] = {};
this.blockFormAdd.update();
this.blockFormConfirmed.update();
this.blockForm.action = '';
return this;
},
/**
* Process fields data: save, restore, move saved to form and back
*
* @param method can be 'item_confirm', 'item_restore', 'current_confirmed_to_form', 'form_confirmed_to_confirmed'
*/
_processFieldsData: function(method) {
/**
* Internal function for rename fields names of some list type
* if listType is not specified, then it won't be added as prefix to all names
*
* @param method can be 'current_confirmed_to_form', 'form_confirmed_to_confirmed'
* @param blockItem
*/
var _renameFields = function(method, blockItem, listType) {
var pattern = null;
var patternFlat = null;
var replacement = null;
var replacementFlat = null;
var scopeArr = blockItem.id.match(/.*\[\w+\]\[([^\]]+)\]$/);
var itemId = scopeArr[1];
if (method == 'current_confirmed_to_form') {
pattern = RegExp('(\\w+)(\\[?)');
patternFlat = RegExp('(\\w+)');
replacement = 'item[' + itemId + '][$1]$2';
replacementFlat = 'item_' + itemId + '_$1';
if (listType) {
replacement = 'list[' + listType + '][item][' + itemId + '][$1]$2';
replacementFlat = 'list_' + listType + '_' + replacementFlat;
}
} else if (method == 'form_confirmed_to_confirmed') {
var stPattern = 'item\\[' + itemId + '\\]\\[(\\w+)\\](.*)';
var stPatternFlat = 'item_' + itemId + '_(\\w+)';
if (listType) {
stPattern = 'list\\[' + listType + '\\]\\[item\\]\\[' + itemId + '\\]\\[(\\w+)\\](.*)';
stPatternFlat = 'list_' + listType + '_' + stPatternFlat;
}
pattern = new RegExp(stPattern);
patternFlat = new RegExp(stPatternFlat);
replacement = '$1$2';
replacementFlat = '$1';
} else {
return false;
}
var rename = function (elms) {
for (var i = 0; i < elms.length; i++) {
if (elms[i].name && elms[i].type == 'file') {
elms[i].name = elms[i].name.replace(patternFlat, replacementFlat);
} else if (elms[i].name) {
elms[i].name = elms[i].name.replace(pattern, replacement);
}
}
};
rename(blockItem.getElementsByTagName('input'));
rename(blockItem.getElementsByTagName('select'));
rename(blockItem.getElementsByTagName('textarea'));
}.bind(this);
switch (method) {
case 'item_confirm':
if (!$(this.confirmedCurrentId)) {
this.blockConfirmed.insert(new Element('div', {id: this.confirmedCurrentId}));
} else {
$(this.confirmedCurrentId).update();
}
this.blockFormFields.childElements().each(function(elm) {
$(this.confirmedCurrentId).insert(elm);
}.bind(this));
break;
case 'item_restore':
this.blockFormFields.update();
// clone confirmed to form
var mageData = null;
$(this.confirmedCurrentId).childElements().each(function(elm) {
var cloned = elm.cloneNode(true);
if (elm.mageData) {
cloned.mageData = elm.mageData;
mageData = elm.mageData;
}
this.blockFormFields.insert(cloned);
}.bind(this));
// get confirmed values
var fieldsValue = {};
var getConfirmedValues = function (elms) {
for (var i = 0; i < elms.length; i++) {
if (elms[i].name) {
if ('undefined' == typeof fieldsValue[elms[i].name] ) {
fieldsValue[elms[i].name] = {};
}
if (elms[i].type == 'checkbox') {
fieldsValue[elms[i].name][elms[i].value] = elms[i].checked;
} else if (elms[i].type == 'radio') {
if (elms[i].checked) {
fieldsValue[elms[i].name] = elms[i].value;
}
} else {
fieldsValue[elms[i].name] = Form.Element.getValue(elms[i]);
}
}
}
}.bind(this);
getConfirmedValues($(this.confirmedCurrentId).getElementsByTagName('input'));
getConfirmedValues($(this.confirmedCurrentId).getElementsByTagName('select'));
getConfirmedValues($(this.confirmedCurrentId).getElementsByTagName('textarea'));
// restore confirmed values
var restoreConfirmedValues = function (elms) {
for (var i = 0; i < elms.length; i++) {
if ('undefined' != typeof fieldsValue[elms[i].name]) {
if (elms[i].type != 'file') {
if (elms[i].type == 'checkbox') {
elms[i].checked = fieldsValue[elms[i].name][elms[i].value];
} else if (elms[i].type == 'radio') {
if (elms[i].value == fieldsValue[elms[i].name]) {
elms[i].checked = true;
}
} else {
elms[i].setValue(fieldsValue[elms[i].name]);
}
}
}
}
}.bind(this);
restoreConfirmedValues(this.blockFormFields.getElementsByTagName('input'));
restoreConfirmedValues(this.blockFormFields.getElementsByTagName('select'));
restoreConfirmedValues(this.blockFormFields.getElementsByTagName('textarea'));
// Execute scripts
if (mageData && mageData.scripts) {
this.restorePhase = true;
try {
mageData.scripts.map(function(script) {
return eval(script);
});
} catch (e) {}
this.restorePhase = false;
}
break;
case 'current_confirmed_to_form':
var allowedListTypes = {};
allowedListTypes[this.current.listType] = true;
var listInfo = this.listTypes[this.current.listType];
if (listInfo.complexTypes) {
for (var i = 0, len = listInfo.complexTypes.length; i < len; i++) {
allowedListTypes[listInfo.complexTypes[i]] = true;
}
}
this.blockFormConfirmed.update();
this.blockConfirmed.childElements().each(function(blockItem) {
var scopeArr = blockItem.id.match(/.*\[(\w+)\]\[([^\]]+)\]$/);
var listType = scopeArr[1];
var itemId = scopeArr[2];
if (allowedListTypes[listType] && (!this.itemsFilter[listType]
|| this.itemsFilter[listType].indexOf(itemId) != -1)) {
_renameFields(method, blockItem, listInfo.complexTypes ? listType : null);
this.blockFormConfirmed.insert(blockItem);
}
}.bind(this));
break;
case 'form_confirmed_to_confirmed':
var listInfo = this.listTypes[this.current.listType];
this.blockFormConfirmed.childElements().each(function(blockItem) {
var scopeArr = blockItem.id.match(/.*\[(\w+)\]\[([^\]]+)\]$/);
var listType = scopeArr[1];
_renameFields(method, blockItem, listInfo.complexTypes ? listType : null);
this.blockConfirmed.insert(blockItem);
}.bind(this));
break;
}
},
/**
* Check if qty selected correctly
*
* @param object element
* @param object event
*/
changeOptionQty: function(element, event)
{
var checkQty = true;
if ('undefined' != typeof event) {
if (event.keyCode == 8 || event.keyCode == 46) {
checkQty = false;
}
}
if (checkQty && (Number(element.value) <= 0 || isNaN(Number(element.value)))) {
element.value = 1;
}
}
};
Event.observe(window, 'load', function() {
productConfigure = new ProductConfigure();
});