Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

AJAX Attribute Manager support


Guest

Recommended Posts

Peter, I haven't tested it yet, because I took the time to go throgh the attributeManger.js and fixed a lot of bugs. som severe some not.

Here's my corrected code, hopefully you have time to test it to:

Kind regards

Sara

//Bug fixes by S.Juto 
var placeHolderDiv;
var url = 'attributeManager/attributeManager.php';
var debug = false;
var amRequester = new Requester();

function attributeManagerInit() {
if(amRequester.isAvailable()){ 
	amRefresh(true);
}
}
function getElement(id) {
return document.getElementById(id);
}
function getDropDownValue(id) {
var el = getElement(id);
return el !== null ? el.value : null;
}
function setDropDownValue(id,value,type) {
var el = getElement(id);
if(el === null){
	return;
}
switch(type){
	case 'i':
		el.value=value;
	break;
	case 's':
		for (var i=0; i < el.length; i++) {
			if (el[i].value === value) {
				el[i].selected = true;
			}
		}
		el.value=value;
	break;
}
}
//Warning: Missing default case in switch statement
//------------------------------------------------------------------<< Common Stuff
function amSendRequest(requestString,functionName, refresh, target) {
var arRequestString = new Array;
if('' !== requestString){
	arRequestString.push(requestString);}
if('' !== productsId){ 
	arRequestString.push('products_id='+productsId);}
if('' !== pageAction){
	arRequestString.push('pageAction='+pageAction);}
if('' !== sessionId){
	arRequestString.push(sessionId);}
if(refresh === false){ 
	amRequester.setAction(amEmpty);}	
else {
	amRequester.setAction((((null === functionName) || ('' === functionName)) ? amUpdateContent : functionName));}


if(null === target) {
	amRequester.setTarget('attributeManager');
}
else {
	amRequester.setTarget(target);
	arRequestString.push('target='+target);
}
requestString = arRequestString.join('&');
amRequester.loadURL(url, requestString);
return false;
}
function amEmpty(){}
function amReportError(request) {
alert('Sorry. There was an error.');
}
function amRefresh(bolFirstCall) {
var rString = (!bolFirstCall) ? 'amAction=refresh' : '';
amSendRequest(rString);
return false;
}
function amUpdateContent(id) {
getElement(amRequester.getTarget()).innerHTML = amRequester.getText();
amRestoreDisplayState();
}
//------------------------------------------------------------------<< page Actions
function amSetInterfaceLanguage(languageId) {
amSendRequest('amAction=setInterfaceLanguage&language_id='+languageId);
return false;
}
function amUpdate(optionId, optionValueId, optionSender) {
if (typeof optionSender=="undefined") {
	optionSender='na';
}
prefix=getDropDownValue('prefix_'+optionValueId);
price=getDropDownValue('price_'+optionValueId);
if((optionSender === 'prefix')&&((prefix === '')||(prefix === ' '))){
	price='0';
}
if(price.indexOf('-') === 0){
	prefix='-';
	setDropDownValue('prefix_'+optionValueId,'-','s');
	price=price.substr(1);
}
price=parseFloat(price);
if(isNaN(price)){
	price=0;
}else{
	price*=10000;
	price=Math.round(price);
	price=price/10000;
}
price=price+'';
if(price.indexOf(".")<0){
	price+='.';
}
while(price.length-price.indexOf(".")<5){
	price+='0';
}
setDropDownValue('price_'+optionValueId,price,'i');
if((price!=='0.0000')&&((prefix === '')||(prefix === ' '))){
	setDropDownValue('prefix_'+optionValueId,'%2B','s');//+
}
   weight_prefix=getDropDownValue('weight_prefix_'+optionValueId);
   weight=getDropDownValue('weight_'+optionValueId);
   if ((weight !== null) && (weight_prefix !== null)) {
     if((optionSender === 'weight_prefix')&&((weight_prefix === '')||(weight_prefix === ' '))){
       weight='0';
     }
     if(weight.indexOf('-') === 0){
       weight_prefix='-';
       setDropDownValue('weight_prefix_'+optionValueId,'-','s');
       weight=weight.substr(1);
     }
     weight=parseFloat(weight);
     if(isNaN(weight)){
       weight=0;
     }else{
       weight*=1000;
       weight=Math.round(weight);
       weight=weight/1000;
     }
     weight=weight+'';
     if(weight.indexOf(".")<0){
       weight+='.';
     }
     while(weight.length-weight.indexOf(".")<5){
       weight+='0';
     }
     setDropDownValue('weight_'+optionValueId,weight,'i');
     if((weight!=='0.000')&&((weight_prefix === '')||(weight_prefix === ' '))){
       setDropDownValue('weight_prefix_'+optionValueId,'%2B','s');//+
     }
   }
amSendRequest('amAction=update&option_id='+optionId+'&option_value_id='+optionValueId+'&price='+getDropDownValue('price_'+optionValueId)+'&prefix='+getDropDownValue('prefix_'+optionValueId)+'&sortOrder='+getDropDownValue('sortOrder_'+optionValueId)+'&weight='+getDropDownValue('weight_'+optionValueId)+'&weight_prefix='+getDropDownValue('weight_prefix_'+optionValueId),'',false);
getElement('price_'+optionValueId).blur();
   if ((weight !== null) && (weight_prefix !== null)){getElement('weight_'+optionValueId).blur();}
   var el = getElement('sortOrder_'+optionValueId);
if(el !== null) {el.blur();
return false;}
}
// QT Pro Plugin, modified by RusNN
function amUpdateProductStockQuantity(products_stock_id) {
amSendRequest('amAction=updateProductStockQuantity&products_stock_id='+products_stock_id+'&productStockQuantity='+getDropDownValue('productStockQuantity_'+products_stock_id));
return false;
}
var check = [];
function checkBox(id) {
   if(check[id] !== true) //if a value is not true, use this rather than === false, 'cos the first time no value will be set and it will be undefined, not true or false
       {
       document.getElementById('imgCheck_' + id).src = "attributeManager/images/icon_unchecked.gif"; // change the image
       document.getElementById('stockTracking_' + id).value = "1"; //change the field value. Was = "0"
       check[id] = true; //change the value for this checkbox in the array. Was = false
       }
   else
       {
       document.getElementById('imgCheck_' + id).src = "attributeManager/images/icon_checked.gif";
       document.getElementById('stockTracking_' + id).value = "0"; //value was ="1"
       check[id] = false; //Was true
       }
}

// QT Pro Plugin
function amAddOption() {
amSendRequest('amAction=addOption&options='+getAllPromptTextValues()+'&optionSort='+getDropDownValue('optionSortDropDown')+'&optionTrack='+getPromptHiddenValue('stockTracking_1'),'',true,'newAttribute');
removeCustomPrompt();
return false;
}
function amAddOptionValue(){
var optionId = getDropDownValue('optionDropDown');
amSendRequest('amAction=addOptionValue&option_values='+getAllPromptTextValues()+'&option_id='+optionId,'',true,'newAttribute');
removeCustomPrompt();
return false;
}
function amAddAttributeToProduct() {
var option = getDropDownValue('optionDropDown');
var optionValue = getDropDownValue('optionValueDropDown');
var pricePrefix = getDropDownValue('prefix_0');
var price = getDropDownValue('newPrice');
 var weightPrefix = getDropDownValue('weight_prefix_0');
 var weight = getDropDownValue('newWeight');
//	var sortOrder = getDropDownValue('newSort');
var sortOrder = -1;
if(0 === option || 0 === optionValue){
	return false;}
amSendRequest('amAction=addAttributeToProduct&option_id='+option+'&option_value_id='+optionValue+'&prefix='+pricePrefix+'&price='+price+'&sortOrder='+sortOrder+'&weight_prefix='+weightPrefix+'&weight='+weight);
return false;
}
function amRemoveOptionFromProduct() {
amSendRequest('amAction=removeOptionFromProduct&option_id='+getPromptHiddenValue('option_id'));
return false;
}
function amRemoveOptionValueFromProduct() {
amSendRequest('amAction=removeOptionValueFromProduct&option_id='+getPromptHiddenValue('option_id')+'&option_value_id='+getPromptHiddenValue('option_value_id'));
return false;
}
// Begin QT Pro Plugin - added by Phocea, modified by RusNN
function amAddStockToProduct(dropDownOptionsList) {
// we rebuild the array
 	var dropDownOptions = dropDownOptionsList.split(/,/);
if(0 === dropDownOptions.length){
	return false;}
var optionValue = new Array(dropDownOptions.length);
	for(var i = 0; i < dropDownOptions.length; i++) {
		optionValue[i] = getDropDownValue(dropDownOptions[i]);
	}
var stockQuantity = getDropDownValue('stockQuantity');
var stockOptions = '';
for(var j = 0; i < dropDownOptions.length; j++)
{
		stockOptions = stockOptions + dropDownOptions[i]+'='+optionValue[i]+'&';
	}
amSendRequest('amAction=addStockToProduct&'+stockOptions+'stockQuantity='+stockQuantity);
return false;
}
function amRemoveStockOptionValueFromProduct() {
amSendRequest('amAction=removeStockOptionValueFromProduct&option_id='+getPromptHiddenValue('option_id'));
   removeCustomPrompt();
return false;
}
// End QT Pro Plugin - added by Phocea
function amAddOptionValueToProduct(optionId) {
var optionValueId = getDropDownValue('new_option_value_'+optionId);
if(0 === optionValueId){
	return false;}
amSendRequest('amAction=addOptionValueToProduct&option_id='+optionId+'&option_value_id='+optionValueId,'',true,'currentAttributes');
return false;
}
function amAddNewOptionValueToProduct() {
var optionId = getPromptHiddenValue('option_id');
var optionValues = getAllPromptTextValues();
amSendRequest('amAction=addNewOptionValueToProduct&option_values='+optionValues+'&option_id='+optionId,'',true,'currentAttributes');
removeCustomPrompt();
return false;
}
function amUpdateNewOptionValue(optionId) {
amSendRequest('amAction=updateNewOptionValue&option_id='+optionId,'',true,'newAttribute');
return false;
}
function loadTemplate() {
var templateId = getDropDownValue('template_drop');
amSendRequest('amAction=loadTemplate&template_id='+templateId);
removeCustomPrompt();
resetOpenClosedState();
}
function saveTemplate(){
var newName = getAllPromptTextValues();
var templateId = getElement("existing_template").value;
amSendRequest('amAction=saveTemplate&new_template_id='+templateId+'&template_name='+newName,'',true,'topBar');
removeCustomPrompt();
return false;	
}
function renameTemplate() {
var newName = getAllPromptTextValues();
var templateId = getPromptHiddenValue('template_id');
amSendRequest('amAction=renameTemplate&template_name='+newName+"&template_id="+templateId,'',true,'topBar');
removeCustomPrompt();
return false;	
}
function deleteTemplate() {
var templateId = getDropDownValue('template_drop');
amSendRequest('amAction=deleteTemplate&template_id='+templateId,'',true,'topBar');
removeCustomPrompt();
}
function amTemplateOrder(order) {
amSendRequest('amAction=setTemplateOrder&templateOrder='+order);
return false;
}
//------------------------------------------------------------------<< custom prompts
function getAllPromptTextValues() {
var allValues = getElement("popupContents").getElementsByTagName("input");
var returnArray = new Array;
for (var i = 0; i < allValues.length; i++){ 
	if('text' === allValues[i].type) {
		returnArray.push(allValues[i].id+':'+escape((getElement(allValues[i].id).value)));
return returnArray.join('|');}
}
}
//Warning: function getAllPromptTextValues does not always return a value
function getPromptHiddenValue(id) {
if(getElement(id)){
	return getElement(id).value;}
else {
	return false;}
}
function customPrompt(section,getVars) {
var requestString = 'amAction=prompt&section='+section;
if(null !== getVars){
	requestString += '&gets='+getVars;
amSendRequest(requestString, createCustomPrompt, true, 'prompt');
return false;}
}
function customTemplatePrompt(section) {
var templateDrop = getElement('template_drop');
var templateId = templateDrop.value;
var templateName = templateDrop.options[templateDrop.selectedIndex].text;
var requestString = 'amAction=prompt&section='+section+'&gets=template_name:'+templateName+'|'+'template_id:'+templateId;
if(0 !== templateId) {
	amSendRequest(requestString, createCustomPrompt, true, 'prompt');}
else {
	templateDrop.focus();}
return false;
}
function createCustomPrompt() {
	var attributeManager = getElement("attributeManager");
	var attributeManagerX = findPosX(attributeManager);
	var attributeManagerY = findPosY(attributeManager);
	var attributeManagerW = attributeManager.scrollWidth;
	var attributeManagerH = attributeManager.scrollHeight;
	// cover the attribute manager with a semi tranparent div
	newBit = attributeManager.appendChild(document.createElement("div"));
	newBit.id = "blackout";
	newBit.style.height = attributeManagerH;
	newBit.style.width = attributeManagerW;
	newBit.style.left = attributeManagerX;
	newBit.style.top = attributeManagerY;
	// hide select boxes (for IE)
showHideSelectBoxes('hidden'); 
// create a popup shaddow
popupShaddow = attributeManager.appendChild(document.createElement("div"));
popupShaddow.id = "popupShaddow";
// create the contents div
popupContents = attributeManager.appendChild(document.createElement("div"));
popupContents.id = "popupContents";
// put the ajax reqest text in the box
popupContents.innerHTML = amRequester.getText();
// work out the center postion for the box
leftPos = (((attributeManagerW - popupContents.scrollWidth) / 2) + attributeManagerX);
topPos = (((attributeManagerH - popupContents.scrollHeight) / 2) + attributeManagerY);
// position the box
popupContents.style.left = leftPos;
popupContents.style.top = topPos;
// size the shadow
popupShaddow.style.width = popupContents.scrollWidth;
popupShaddow.style.height =popupContents.scrollHeight;
// position the shadow
popupShaddow.style.left = leftPos+6;
popupShaddow.style.top = topPos+6;
// if the form has any inputs focus on the first one
if(inputs === popupContents.getElementsByTagName("input")){
	inputs[0].focus();}
return false;
}
function removeCustomPrompt() {
getElement("attributeManager").removeChild(getElement("popupContents"));
getElement("attributeManager").removeChild(getElement("popupShaddow"));
getElement("attributeManager").removeChild(getElement("blackout"));
showHideSelectBoxes('visible');	
}
function findPosX(obj) {
var curleft = 0;
if (obj.offsetParent){
	while (obj.offsetParent) {
		curleft += obj.offsetLeft;
		obj = obj.offsetParent;
	}
}
else if (obj.x){
	curleft += obj.x;}
return curleft;
}
function findPosY(obj) {
var curtop = 0;
if (obj.offsetParent) {
	while (obj.offsetParent) {
		curtop += obj.offsetTop;
		obj = obj.offsetParent;
	}
}
else if (obj.y){
	curtop += obj.y;}
return curtop;
}
function showHideSelectBoxes(vis) {
var selects = getElement('attributeManager').getElementsByTagName("select");
for(var i = 0; i < selects.length; i++){ 
	selects[i].style.visibility = vis;}
return false;
}
//------------------------------------------------------------------<< Display Controls
var openClosedState;
var attributeManagerClosedState = true;
var attributeTemplatesClosedState = true;
function resetOpenClosedState() {
 openClosedState = new Object();
}
resetOpenClosedState();
function amRestoreDisplayState() {
// Im sure this is a really bad way to do this but i couldn't figure out another 
var allTrs = getElement('attributeManager').getElementsByTagName("tr");
for (var i = 0; i < allTrs.length; i++) {
	for(var a in openClosedState) {
		var reg = new RegExp("trOptionsValues_"+a+"$");
		if (reg.test(allTrs[i].id)) {
			if(true === openClosedState[a]) {
				allTrs[i].style.display =  "";
				getElement("show_hide_"+a).src = "attributeManager/images/icon_minus.gif";
			}
			else {
				allTrs[i].style.display =  "none";
				getElement("show_hide_"+a).src = "attributeManager/images/icon_plus.gif";
			}
		}
	}
}
}
function amShowHideAttributeManager() {
getElement('attributeManagerAll').style.display = (true === attributeManagerClosedState) ? "none" : "";
attributeManagerClosedState = (true === attributeManagerClosedState) ? false : true;
getElement('showHideAll').src = "attributeManager/images/icon_"+ ((true === attributeManagerClosedState) ? "minus.gif" : "plus.gif");
return false;
}
function amShowHideAllOptionValues(options, show) {
for(var i =0; i < options.length; i++) {
	openClosedState[options[i]] = !show;
	amShowHideOptionsValues(options[i]);
}
return false;
}
function amShowHideOptionsValues(id) {
var allTrs = getElement('attributeManager').getElementsByTagName("tr");
for (var i = 0; i < allTrs.length; i++) {
	var reg = new RegExp("trOptionsValues_"+id+"$");
	if (reg.test(allTrs[i].id)){
		allTrs[i].style.display = (true === openClosedState[id]) ? "none" : "";}
}
if(true === openClosedState[id]){
	getElement("show_hide_"+id).src = "attributeManager/images/icon_plus.gif";
	openClosedState[id] = false;
}
else{
	getElement("show_hide_"+id).src = "attributeManager/images/icon_minus.gif";
	openClosedState[id] = true;
}
return false;
}
function amF(i){
if(i.value=='0.0000'){
	i.value='0.';
	i.select();
}
}
function amB(i){
if(i.value=='0.'){
	i.value='0.0000';
}
}
//----------------------------
// Change: Add download attributes function for AM
// @author Urs Nyffenegger ak mytool
// Function: Javascript Functions
//-----------------------------
function amEditDownloadForProduct(){
var products_attributes_filename = getDropDownValue('products_attributes_filename');
var products_attributes_maxdays = getDropDownValue('products_attributes_maxdays');
var products_attributes_maxcount = getDropDownValue('products_attributes_maxcount');
var products_attributes_id = getPromptHiddenValue('products_attributes_id');
amSendRequest('amAction=updateDownloadAttributeToProduct&option_id='+getPromptHiddenValue('option_id') + '&products_attributes_id='+products_attributes_id + '&products_attributes_filename=' + escape(products_attributes_filename) + '&products_attributes_maxdays=' + products_attributes_maxdays + '&products_attributes_maxcount=' + products_attributes_maxcount);
removeCustomPrompt();
return false;
}
function amAddNewDownloadForProduct(){
var products_attributes_filename = getDropDownValue('products_attributes_filename');
var products_attributes_maxdays = getDropDownValue('products_attributes_maxdays');
var products_attributes_maxcount = getDropDownValue('products_attributes_maxcount');
var products_attributes_id = getPromptHiddenValue('products_attributes_id');
amSendRequest('amAction=addDownloadAttributeToProduct&option_id='+getPromptHiddenValue('option_id') + '&products_attributes_id='+products_attributes_id + '&products_attributes_filename=' + escape(products_attributes_filename) + '&products_attributes_maxdays=' + products_attributes_maxdays + '&products_attributes_maxcount=' + products_attributes_maxcount);
removeCustomPrompt();
return false;
}
function amDeleteDownloadForProduct(){
var products_attributes_id = getPromptHiddenValue('products_attributes_id');
amSendRequest('amAction=removeDownloadAttributeToProduct&products_attributes_id='+products_attributes_id );
removeCustomPrompt();
return false;
}
function amMoveOptionValue(getVars, Direction){
var requestString = 'amAction=moveOptionValue';
if(null !== getVars){
	requestString += '&gets='+getVars + '&dir=' + Direction;
amSendRequest(requestString);}
return false;
}
function amMoveOption(getVars, Direction){
var requestString = 'amAction=moveOption';
if(null !== getVars){
	requestString += '&gets='+getVars + '&dir=' + Direction;
amSendRequest(requestString);}
return false;
}
//----------------------------
// EOF Change: download attributes for AM
//-----------------------------

Link to comment
Share on other sites

Thank you Sara! I made a copy of you fixes to compare and test. Hope, I will find a time to carefully work with AJAX AM. For now I have only added QT Pro feature to it and does not do any bugfixes.

Link to comment
Share on other sites

You are welcome! So, are you adding more QTpro to AM?

 

By the way I have a code correction for the above script, find the lines:

 

for(var j = 0; i < dropDownOptions.length; j++)

{

stockOptions = stockOptions + dropDownOptions+'='+optionValue+'&';

}

 

Change to:

 

for(var j = 0; i < dropDownOptions.length; j++)

{

stockOptions = stockOptions + dropDownOptions[j]+'='+optionValue[j]+'&';

}

 

I have tested the script and it works as expected plus the pages loads faster.

 

Sara

Link to comment
Share on other sites

UPDATE in the above code replace the entire function amSendRequest(requestString,functionName, refresh, target)

 

With:

 

function amSendRequest(requestString,functionName, refresh, target) {
var arRequestString = new Array;
if('' !== requestString){
	arRequestString.push(requestString);}
if('' !== productsId){ 
	arRequestString.push('products_id='+productsId);}
if('' !== pageAction){
	arRequestString.push('pageAction='+pageAction);}
if('' !== sessionId){
	arRequestString.push(sessionId);}
if(refresh == false){
	amRequester.setAction(amEmpty);}

else {
	amRequester.setAction((((null == functionName) || ('' == functionName)) ? amUpdateContent : functionName));}

if(null == target) {
	amRequester.setTarget('attributeManager');
}
else {
	amRequester.setTarget(target);
	arRequestString.push('target='+target);
}
requestString = arRequestString.join('&');
amRequester.loadURL(url, requestString);
return false;
}

 

Sara

Link to comment
Share on other sites

You are most welcome :)

 

Now, I have 2 questions:

 

My site is multilingaul, when I add an option I therefore have the opportunity to add the Option Name and the Option Values in these languages.

 

But, these data are not saved. The data saved is only for the selected administration language.

 

So, is it possible to insert the language specific data in the product attributes table for all languages?

 

Today I have to go into the product attribute and fix the language support manualy.

 

Next, for a given Option I try to add several Option Values, but that is not possible. The data is not saved for that product

 

I have to go to the product attribute once more to add these.

 

I beleive that the purpose is to add all of these through the Attribute Managers interface?

 

Any solutions?

 

Kindest

Sara

Link to comment
Share on other sites

My site is multilingaul, when I add an option I therefore have the opportunity to add the Option Name and the Option Values in these languages.

 

But, these data are not saved. The data saved is only for the selected administration language.

Due to the only language I have on my site I never test multilingual support. And for last year I don't remember any issue about. So, we may type options names and values in different languages, but this info does not save into DB? Or we have another pronlem like I had. My native cyrillic did not saved into DB properly, because attributeManager.js has have escape() function in getAllPromptTextValues(); but it must have encodeURIComponent() to support cyrillic and others. Try to change this first.

Link to comment
Share on other sites

Thank you Peter! I believe you a refering to post #1064?

 

I will try that tomorrow, right now I am so tired after a long days work.

 

Suggestion:

 

Someone should write a "how-to":

 

1) Using attribute manager for a new product

 

2) Editing an existing product

 

3) Editing Options and Options Values i.e changing these.

 

I Think most of the problems (including mine) are because the "work-flow" isn't described?

 

Kindest

 

Sara

Link to comment
Share on other sites

O' I see. You are doing a tremendous excellent work right, for which I am most greatful. :)

 

By the way I have found this why encodeURIComponent() for data in body of POST XHR request?

Hopefully it will be of help?

 

Sara

Link to comment
Share on other sites

O' I see. You are doing a tremendous excellent work right, for which I am most greatful. :)

 

By the way I have found this why encodeURIComponent() for data in body of POST XHR request?

Hopefully it will be of help?

 

Sara

:)

In my own version I changed this many times ago. But because I don't want to post only fixes this link may be helpful for somebody too. There are 2 places in attributeManager.js where encodeURIComponent() should be.

 

Since I post my fix to QT Pro Ajax AM become need some cleaning. Latest versions will cross together and now they need merging. Now it should include your updates too.

Link to comment
Share on other sites

Hello Peter, first I must say that you are doing a fantastic job. Excellent work! And, your English is quite good.

 

So, back to issues:

1) Can I use your advice in post#1064 about encodeURIComponent ? Or should I wait until you have the final advice?

 

2) How can I set Track Stock to be true as default, when editing a new product?

 

3) Adjacent to adding options values to a product, is it possible to have an input field for stock quantity for this option value?

 

 

I have also fixed the requester.js to the below, I have it running ok since some days ago.

 

I have also redesigned QTpro, to use lanaguage files for the texts. It works nicely.

Today I have English and Swedish. For Spanish and German I use copies of the English files.

 

If you would like to have these I could e-mail those to you.

 

 

The requester looks like this:

 

//Bug fixed by S.Juto
function Requester()
{
this.action = null;
this.XML = null;
this.commInterface = null;
this.targetId = null;
// Initialise XMLHttpRequest object
this.resetXMLHR();
return true;
}
/**
* Check if the XMLHttpRequest object is available 
*/
Requester.prototype.isAvailable = function(){
return (this.commInterface === null) ? false : true;
};
/* Execute the action which has been associated with the completion of this object */
Requester.prototype.executeAction = function() {
// If XMLHR object has finished retrieving the data
if (this.commInterface.readyState === 4)	{
	// If the data was retrieved successfully
	try	{
		if (this.commInterface.status === 200)	{
			this.responseText = this.commInterface.requestXML;
			this.action();
		}
		// IE returns status = 0 on some occasions, so ignore
		else if (this.commInterface.status !== 0){
			alert("There was an error while retrieving the URL: " + this.commInterface.statusText);
		}
	}
	catch (error){}
}
return true;
};
/* Return responseText */
Requester.prototype.getText = function() {
return this.commInterface.responseText;
};
/* Return responseXML */
Requester.prototype.getXML = function() {
return this.commInterface.responseXML;
};
/* Initialise XMLHR object and load URL */
Requester.prototype.loadURL = function(URL, CGI) {
this.resetXMLHR();
this.commInterface.open("GET", URL + "?" + CGI);
var e=(document.charset||document.characterSet||'ISO-8859-8-i');
this.commInterface.setRequestHeader("Content-Type", "text/html; charset="+e);
this.commInterface.setRequestHeader('Accept-Charset',e);
this.commInterface.send(null);
return true;
};
/* Turn off existing connections and create a new XMLHR object */
Requester.prototype.resetXMLHR = function() {
var self = this;
if (this.commInterface !== null && this.commInterface.readyState !== 0 && this.commInterface.readyState !== 4)	{
	this.commInterface.abort();
}
try	{
	this.commInterface = new XMLHttpRequest();
}
catch (error) {
	try {
		this.commInterface = new ActiveXObject("Microsoft.XMLHTTP");
	}
	catch (error) {
		return false;
	}
}
this.commInterface.onreadystatechange = function()	{
	self.executeAction();
	return true;
};
return true;
};
/* Assign the function which will be executed once the XMLHR object finishes retrieving data */
Requester.prototype.setAction = function(actionFunction,part) {
this.action = actionFunction;
return true;
};
Requester.prototype.setTarget = function(targetId) {
this.targetId = targetId;
return true;
};
Requester.prototype.getTarget = function() {
return this.targetId;
};

 

Kind regards

 

Sara

Link to comment
Share on other sites

Hello Sara!

 

I do too small for that contrib. Everything was done before me, I only improve anothers job. So, you can post your version yourself.

 

1) You may use encodeURIComponent, but I'm not sure it solve your issue.

 

2) Track Stock is set for option, not for each product. You may enable and disable stock tracking in standart osC products_attributes.php page if QT Pro installed correctly.

 

3) If I correctly understand, you are not enable Track Stock for the option. Enable Track Stock. Now you may enter quantity for option values. But for the first, you should add options what ever you need to your product.

Below options you should see a QT Pro block. If Track Stock is enabled you see a number of dropdown lists, the quantity of dropdowns is equal to quantity of options you assign to a product. Using dropdowns you may set all possible combinations of option values to yuor product and in the right of the last dropdown there will be the input field for quantity of a this option combination. Fill all fields an press green button in the right. This combination will stored in the database (press + button to see). Add another combination. The summary stock will calculate automatically.

Adding same combination will redraw the stock for the combination and for a product. You may also enter a quantity to combination using field Quantity right of the combination.

 

 

You are right! The checkbox Track Stock at product page is not working when you add new option. So, you need to set it manually at products_attributes.php after creating an option and then reload your product page to allow modification of Track Stock become to work.

Link to comment
Share on other sites

Hello again Peter!

 

I made a search for the escape function and found three instances of it in my attributeManager.js:

Line 290:

 

returnArray.push(allValues.id+':'+escape((getElement(allValues.id).value)));

and REPLACE it with

returnArray.push(allValues.id+':'+encodeURIComponent((getElement(allValues.id).value)));

 

NB: There are two more instances of escape:

 

Line 473:

amSendRequest('amAction=updateDownloadAttributeToProduct&option_id='+getPromptHiddenValue('option_id') + '&products_attributes_id='+products_attributes_id + '&products_attributes_filename=' + escape(products_attributes_filename) + '&products_attributes_maxdays=' + products_attributes_maxdays + '&products_attributes_maxcount=' + products_attributes_maxcount);

Line 482:

amSendRequest('amAction=addDownloadAttributeToProduct&option_id='+getPromptHiddenValue('option_id') + '&products_attributes_id='+products_attributes_id + '&products_attributes_filename=' + escape(products_attributes_filename) + '&products_attributes_maxdays=' + products_attributes_maxdays + '&products_attributes_maxcount=' + products_attributes_maxcount);

 

I assume that I need to replace all three with the encodeURIComponent. Correct?

Link to comment
Share on other sites

I replaced only first: returnArray.push(allValues.id+':'+encodeURIComponent((getElement(allValues.id).value)));

 

All others are for file names of downloadable attributes. If you have this and use file names on native language it will be better to replace them too.

Link to comment
Share on other sites

Hello Peter, I have done this as you suggested:

 

1. FIND in catalog\admin\attributeManager\javascript\attributeManager.js around line 290

 

returnArray.push(allValues.id+':'+escape((getElement(allValues.id).value)));

and REPLACE it with

returnArray.push(allValues.id+':'+encodeURIComponent((getElement(allValues.id).value)));

 

2. ADD to catalog\admin\attributeManager\includes\attributeManagerGeneralFunctions.inc.php BEFORE last ?>

 

// convert charset from UTF-8 to e-shop defaults

function amIconv($string) {

return iconv('UTF-8', CHARSET . '//TRANSLIT', $string);

}

 

3. FIND in catalog\admin\attributeManager\classes\attributeManager.class.php around line 274

 

'products_options_name' => amDB::input($name)

 

and REPLACE it with

'products_options_name' => amIconv(amDB::input($name))

 

4. FIND in catalog\admin\attributeManager\classes\attributeManager.class.php around line 319

 

'products_options_values_name' => amDB::input($name)

 

and REPLACE it with

'products_options_values_name' => amIconv(amDB::input($name))

 

And, I tested by defining a new Option and Option values in my shops 4 languages

But, they do not show up in product attributes for other languages than the selected administrative language.

 

So, It seems to me that the tables for these are not updated for all langugaes. I think that a loop over all languages is missing, or?

 

Like so:

 

for ($i = 0, $n = sizeof($languages); $i < $n; $i ++) {

//Insert Option names

//Insert Option Values

}

 

I think the loop have to be in attributeManager.php

 

Also, I do not understand the "Track Stock" possibility. I have marked it, but it does not seem to do anything?

 

I thought that it would be setting the "Track Stock" to "Yes" in the product attribute.

 

Can you help me with this issues, please?

 

Kindest

Sara

Link to comment
Share on other sites

Hi Peter, in the javascript you need to replace the function amAddStockToProduct

 

with:

 

function amAddStockToProduct(dropDownOptionsList) {

// we rebuild the array

var dropDownOptions = dropDownOptionsList.split(/,/);

if(0 === dropDownOptions.length){

return false;}

var optionValue = new Array(dropDownOptions.length);

for(var i = 0; i < dropDownOptions.length; i++) {

optionValue = getDropDownValue(dropDownOptions);

}

var stockQuantity = getDropDownValue('stockQuantity');

var stockOptions = '';

-bug fix-> for(var j = 0; j < dropDownOptions.length; j++) {

stockOptions = stockOptions + dropDownOptions[j]+'='+optionValue[j]+'&';

}

amSendRequest('amAction=addStockToProduct&'+stockOptions+'stockQuantity='+stockQuantity);

return false;

 

I missed to insert j as the lower limit.

 

Kindest Sara

Link to comment
Share on other sites

Hi,

I've recently started helping with an OSCommerce site with AJAX installed, so I'm afraid I know very little about it, and already I have a problem.

 

We've recently been forced to move to a new webhost. Unfortunately, Attribute Manager doesn't work at the new webhost, even though nothing should have changed.

 

When we go into any product page, the Attribute Manager box isn't there below the price (though there is a message saying 'Save Product before adding options').

 

Also, we see an error message on every product edit screen: 'There was an error while retrieving the URL: not acceptable' I think this error might have something to do with Attribute Manager.

 

Can you give me any help solving this? We are on php 4.4.9, OSCommerce 2.2-MS2, AJAX Attribute Manager 2.8.9 (though 2.8.8 acts the same)

 

Thanks

Catherine

Link to comment
Share on other sites

Hello Peter. I have tried to replace the escape. That did not solve the problem with adding options and values and product attribute for other languages.

 

If I change the admin language to another, AAM will still only insert Option names and values for the default language.

Also I have tried version 2.8.6 ... same problem again. The Option name and values are not inserted into the DB.

 

If, I use the osc standard product attribute and insert option names and values, they show up in the AAM.

 

But that's what AAM is supposed to do directly.

 

So, any news about the language problem?

 

Kindest

 

Sara

Link to comment
Share on other sites

  • 2 weeks later...

I just finished installing, and I'm having an issue with the placeholders rendering instead of the English words. For instance, here is what comes up when the save template button is clicked:

 

sdfbrn.gif

 

I am using V2-8.9 with osCommerce 2.2 RC2a.

 

I disabled QT Pro in the config file, as I dont have that contribution installed.

Link to comment
Share on other sites

Found the solution to my problem here: http://www.oscmax.com/forums/oscmax-v2-installation-issues/17844-warning-not-valid-mysql-installe-rc4-2.html#post42440

 

The problem is with the first line of this file: /catalog/admin/attributeManager/languages/english/attributeManager.php

 

<?

 

Should be changed to:

 

<?php

 

Works fine now.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...