Version 3.0.4 has been posted and is available here.
Printable View
Version 3.0.4 has been posted and is available here.
I'd like to use this with a inline ajax popup.
However, I would need to pass the products_id in a link to the script instead of the script requesting it through the GET method.
Any quick ideas or solutions?
Was busy yesterday coding something ... which tends to result in me having reduced forum/response time.
No full blown solution, but in review of the involved code, the current use of $_GET['products_id'] is basically a verification against the page in which that JS code is loaded (product_info related) and is not specifically pertinent to operation. It's sort of an on/off switch because if the page is not one that should have that specific code or if someone is trying to spoof it then it provides at least one check for validity. Others might be able to be performed as well, but long and short of it is that the $_GET is not required for overall operation. Knowing what product is to be used about which to obtain information is necessary and basically the class does look for the $_POST of that information (expected to be a part of the data provided to the class likely by a hidden field within the data to submit as part of your routine).
So basically would want a "tailored" version of the javascript file that is included in includes/modules/pages/product_info for the "routine" that you are using with the suggestion of having some sort of "don't display/use me *if*" checks up front followed by the code to manage processing and display, whatever that may be.
Help any?
I really haven't looked into the code but I will disagree that $_GET['products_id'] is not pertinent to operation. Without the products ID the script doesn't function.
I could be wrong.
I don't think an "if" statement is necessary. Maybe another script to pass the id to dpu_ajax.
Maybe I should play with this more. :blush:
As written, I would agree with your disagreement about the $_GET being necessary, but the target of the modification/use is not the products_info page so therefore any need for the products_id (which the current code does have such a need up front that likely could be fulfilled by existing code.
Mostly will want to attach the existing javascript from this plugin in such a way to listen to the desired "indicators" or selections and to update the applicable price "field" based on the "final" price or other data being collected/displayed. All-in-all there is little that is done by the javascript part found in includes/modules/pages/product_info. It is pretty much a translator of action/data with some initial "do you think it's a good idea to even be presented to the customer checks" at the beginning.
Hi
I am trying to install Dynamic Price Updater onto a fresh 1.5.5 install using a template bought from ThemeForest.
The DPU works fine on the standard ZenCart template but doesn't work on the new ########## template.
I have taken a look at the page and the script is visible.
Please could anyone help? :shocking:Code:<script language="javascript" type="text/javascript">
// <![CDATA[
// Set some global vars
var theFormName = "cart_quantity";
var theForm = false;
var theURL = "/newinstall155/ajax.php";
// var theURL = "/newinstall155/dpu_ajax.php";
var _secondPrice = "cartAdd";
var objSP = false; // please don't adjust this
var DPURequest = [];
// Updater sidebox settings
var objSB = false; // this holds the sidebox object // IE. Left sidebox false should become document.getElementById('leftBoxContainer');
// For right sidebox, this should equal document.getElementById('rightBoxContainer');
// Perhaps this could be added as an additional admin configuration key. The result should end up being that a new SideBox is added
// before whatever is described in this "search". So this may actually need to be a div within the left or right boxes instead of the
// left or right side box.
// May also be that this it is entirely unnecessary to create a sidebox when one could already exist based on the file structure.
var imgLoc = "replace"; // Options are "replace" or , "" (empty)
var loadImg = document.createElement("img");
loadImg.src = "images/ajax-loader.gif";
loadImg.id = "DPULoaderImage";
var loadImgSB = document.createElement("img");
loadImgSB.src = "images/ajax-loader.gif";
loadImgSB.id = "DPULoaderImageSB";
loadImgSB.style.margin = "auto";
// loadImg.style.display = 'none';
function objXHR()
{ // scan the function clicked and act on it using the Ajax interthingy
var url; // URL to send HTTP DPURequests to
var timer; // timer for timing things
var XHR; // XMLHttpDPURequest object
var _responseXML; // holds XML formed responses from the server
var _responseText; // holds any textual response from the server
// var DPURequest = []; // associative array to hold DPURequests to be sent
// DPURequest = new Array();
this.createXHR();
}
objXHR.prototype.createXHR = function () { // this code has been modified from the Apple developers website
this.XHR = false;
// branch for native XMLHttpDPURequest object
if(window.XMLHttpRequest) { // decent, normal, law abiding browsers
try { // make sure the object can be created
this.XHR = new XMLHttpRequest();
} catch(e) { // it can't
this.XHR = false;
}
// branch for IE/Windows ActiveX version
} else if(window.ActiveXObject) { // this does stuff too
var tryNext = false;
try {
this.XHR = new ActiveXObject("Msxml2.XMLHTTP");
} catch(f) {
tryNext = true;
}
if (tryNext) {
try {
this.XHR = new ActiveXObject("Microsoft.XMLHTTP");
} catch(g) {
this.XHR = false;
}
}
}
};
objXHR.prototype.getData = function(strMode, resFunc, _data) { // send a DPURequest to the server in either GET or POST
strMode = (strMode.toLowerCase() == "post" ? "post" : "get");
var _this = this; // scope resolution
this.createXHR();
if (this.XHR) {
this.XHR.onreadystatechange = function () {
if (_this.XHR.readyState == 4) {
// only if "OK"
if (_this.XHR.status == 200) {
_this.responseXML = _this.XHR.responseXML;
_this.responseText = _this.XHR.responseText;
_this.responseHandler(resFunc);
} else {
alert("Status returned - " + _this.XHR.statusText);
}
}
};
this.XHR.open(strMode.toLowerCase(), this.url+"?act=DPU_Ajax&method=dpu_update"+(strMode.toLowerCase() == "get" ? "&" + this.compileRequest() : ""), true);
if (strMode.toLowerCase() == "post") {
this.XHR.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
this.XHR.setRequestHeader("X-Requested-With", "XMLHttpRequest");
}
this.XHR.send(_data);
} else {
var mess = "I couldn't contact the server!\n\nIf you use IE please allow ActiveX objects to run";
alert (mess);
}
};
objXHR.prototype.compileRequest = function () {
// parse the DPURequest array into a URL encoded string
var ret = ""; // return DPURequest string
for (var e in DPURequest) {
ret += e + "=" + DPURequest[e] + "&";
}
return (ret.substr(0, ret.length - 1));
};
objXHR.prototype.responseHandler = function (theFunction) { // redirect responses from the server to the right function
DPURequest = new Array();
this[theFunction](); // Eliminates concern of improper evaluation; however, does limit the response value(s)
};
objXHR.prototype.getPrice = function () {
var psp = false;
if (imgLoc == "replace") {
var thePrice = document.getElementById("productPrices");
var test = thePrice.getElementsByTagName("span");
for (var a=0,b=test.length; a<b; a++) {
if (test[a].className == "productSpecialPrice" || test[a].className == "productSalePrice" || test[a].className == "productSpecialPriceSale") {
psp = test[a];
}
}
}
if (psp && imgLoc == "replace") {
if (thePrice) {
loadImg.style.display = "inline"; //'block';
var pspClass = psp.className;
var pspStyle = psp.currentStyle || window.getComputedStyle(psp);
loadImg.style.height = pspStyle.lineHeight; // Maintains the height so that there is not a vertical shift of the content.
psp.innerHTML = loadImg.outerHTML;
}
} else {
document.getElementById("productPrices").appendChild(loadImg);
}
if (document.getElementById("dynamicpriceupdatersidebox")) {
var theSB = document.getElementById("dynamicpriceupdatersideboxContent");
theSB.innerHTML = "";
theSB.style.textAlign = "center";
theSB.appendChild(loadImgSB);
}
this.url = theURL;
var n=theForm.elements.length;
var temp = "";
for (var i=0; i<n; i++) {
var el = theForm.elements[i];
switch (el.type) { case "select":
case "select-one":
case "text":
case "number":
case "hidden":
temp += el.name+"="+encodeURIComponent(el.value)+"&";
break;
case "checkbox":
case "radio":
if (true == el.checked) {
temp += el.name+"="+encodeURIComponent(el.value)+"&";
}
break;
}
}
temp += "pspClass="+encodeURIComponent(pspClass);
//temp = temp.substr(0, temp.length - 1)
this.getData("post", "handlePrice", temp);
};
objXHR.prototype.handlePrice = function () {
var thePrice = document.getElementById("productPrices");
if (loadImg !== undefined && loadImg.parentNode != null && loadImg.parentNode.id == thePrice.id && imgLoc != "replace") {
thePrice.removeChild(loadImg);
}
// use the spans to see if there is a discount occuring up in this here house
var test = thePrice.getElementsByTagName("span");
var psp = false;
for (var a=0,b=test.length; a<b; a++) {
if (test[a].className == "productSpecialPrice" || test[a].className == "productSalePrice" || test[a].className == "productSpecialPriceSale") {
psp = test[a];
}
}
var type = this.responseXML.getElementsByTagName("responseType")[0].childNodes[0].nodeValue;
if (document.getElementById("dynamicpriceupdatersidebox")) {
var theSB = document.getElementById("dynamicpriceupdatersideboxContent");
theSB.style.textAlign = "left";
var sbContent = "";
updateSidebox = true;
} else {
updateSidebox = false;
}
if (type == "error") {
this.showErrors();
} else {
var temp = this.responseXML.getElementsByTagName("responseText");
for(var i=0, n=temp.length; i<n; i++) {
var type = temp[i].getAttribute("type");
switch (type) { case "priceTotal":
if (psp) {
psp.innerHTML = temp[i].childNodes[0].nodeValue;
} else {
thePrice.innerHTML = temp[i].childNodes[0].nodeValue;
}
if (_secondPrice !== false) {
this.updSP();
}
break;
case "quantity":
with (temp[i].childNodes[0]) {
if (nodeValue != "") {
if (psp) {
psp.innerHTML += nodeValue;
} else {
thePrice.innerHTML += nodeValue;
}
this.updSP();
}
}
break;
case "weight":
var theWeight = document.getElementById("productWeight");
if (theWeight) {
theWeight.innerHTML = temp[i].childNodes[0].nodeValue;
}
break;
case "sideboxContent":
if (updateSidebox) {
sbContent += temp[i].childNodes[0].nodeValue;
}
break;
}
}
}
if (updateSidebox) {
theSB.innerHTML = sbContent;
}
};
objXHR.prototype.updSP = function () {
// adjust the second price display; create the div if necessary
var flag = false; // error tracking flag
if (_secondPrice !== false) { // second price is active
var centre = document.getElementById("productGeneral");
var temp = document.getElementById("productPrices");
var itemp = document.getElementById(_secondPrice);
if (objSP === false) { // create the second price object
if (!temp || !itemp) {
flag = true;
}
if (!flag) {
objSP = temp.cloneNode(true);
objSP.id = temp.id + "Second";
itemp.parentNode.insertBefore(objSP, itemp.nextSibling);
}
}
objSP.innerHTML = temp.innerHTML;
}
};
objXHR.prototype.createSB = function ()
{ // create the sidebox for the attributes info display
if (!(document.getElementById("dynamicpriceupdatersidebox")) && objSB)
{
var tempC = document.createElement("div");
tempC.id = "dynamicpriceupdatersideboxContent";
tempC.className = "sideBoxContent";
tempC.innerHTML = "If you can read this Chrome has broken something";
objSB.appendChild(tempC);
temp.parentNode.insertBefore(objSB, temp);
}
};
objXHR.prototype.showErrors = function () {
var errorText = this.responseXML.getElementsByTagName("responseText");
var alertText = "";
var n=errorText.length;
for (var i=0; i<n; i++) {
alertText += "\n- "+errorText[i].childNodes[0].nodeValue;
}
alert ("Error! Message reads:\n\n"+alertText);
};
var xhr = new objXHR;
function init() {
var n=document.forms.length;
for (var i=0; i<n; i++) {
if (document.forms[i].name == theFormName) {
theForm = document.forms[i];
continue;
}
}
var n=theForm.elements.length;
for (var i=0; i<n; i++) {
switch (theForm.elements[i].type) {
case "select":
case "select-one":
theForm.elements[i].addEventListener("change", function () { xhr.getPrice(); });
break;
case "text":
theForm.elements[i].addEventListener("keyup", function () { xhr.getPrice(); });
break;
case "checkbox":
case "radio":
theForm.elements[i].addEventListener("click", function () { xhr.getPrice(); });
break;
case "number":
theForm.elements[i].addEventListener("change", function () { xhr.getPrice(); });
theForm.elements[i].addEventListener("keyup", function () { xhr.getPrice(); });
theForm.elements[i].addEventListener("input", function () { xhr.getPrice(); });
break;
}
}
this.createSB();
xhr.getPrice();
};
// ]]></script>
When dealing with javascript, it is important to first verify that the template passes an html validation. Errors in the that validation may prevent firing of the javascript, also, other javascript may interact/override the actions that are being waited on which can depend on load sequence of the javascript (for example the code here has been modified to also listen for the change of attribute selections instead of replacing any previous/other listening operations), then also it is good to watch execution of javascript through your browser to see what is going on, if there are any console errors, etc... This last thing can be done through pressing F12 while using your browser with the suggestion to reload the page after doing that.
Otherwise, for others to help the web page would need to be provided so that they can do the same or similar actions as described.
Hi i checked and there no errors but 26 warnings. Mainly sloppy coding and unclosed <p> tags etc
Curious... If in your current implementation, if you remove the check of the $_GET from the javascript code, does everything still work when using your inline type ajax? Meaning, does the code fire, or does it still not "work"? Wondering if there is a separate issue (and possible/likely solution) than just the initial call to display the page? Like maybe an update on the page needs to be performed? and/or maybe to display the value of the $_GET on the page load just to see if there is a difference between the two methods of accessing the page? (zen_get_all_get_parameters() should provide/retrieve all of the values set at that time/page and could be briefly added to say the tpl_product_info_display_default.php). Afterall, the $_GET parameter has to be set/available in order for the particular content to be gathered/displayed in the first place...
Hmm.. Sorry, feel like speaking in a circle... But the "output" would at least confirm/reaffirm the concerns/situation. I'm leaning more towards the need to fire a specific javascript event or to parse the javascript/ajax or something as part of displaying the object.
Well, first suggestion would be to try to close those things up properly to have none, the other would be to review how the code of the template differs from that of a standard ZC install and see if either there are files that are not loaded or some other sequencing issue that could maybe interfere with the standard ZC load/execution sequence. Then to also look at what/how other javascript is loaded. Not much made available with which I can help otherwise.