DESCRIPTION On our Magento Shopping Cart when a user clicks the Add to Basket button on the Product Details page on any of the Internet Explorer browsers they get a popup in the browser with the following error message:
Exception : TypeError: Unable to get property 'tagName of undefined or null reference
At first I though this error was due to an AJAX call but after further investigation in the browser debugger I can see that it is being caused when the JavaScript is trying to modify the DOM nodes/ HTML tags and their attributes.
I set the breakpoints on all sub-tree & attribute modifications on the #mdl_ajax_confirm
div
, the call stack is:
ajax_cart.js:87
ajax_cart.js:89
ajax_cart.js:91
ajax_cart.js:97
ajax_cart.js:99
ajax_cart.js:104
ajax_cart.js:110
ajax_cart.js:112
ajax_cart.js:113
In IE it breaks on ajax_cart.js:104
and goes to prototype:1617
to handle the exception.
So the offending piece of code seems to be ajax_cart.js:104 which is:
$$('.block-cart').each(function (el){
el.replace(mini_cart_txt);
//new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
});
In Chrome this returns it returns HTML but in IE it returns the same error in the console as the pop up: Unable to get property 'tagName' of undefined or null reference
QUESTION
I checked the IE console and the mini_cart_txt
var
is there before ajax_cart.js:104 is executed, the issue is I believe coming from el
? I'm not sure how to fix it or what exactly is happening with that block of code?
Below is the rest of the code, thanks in advance :)
CODE
ajax_cart.js
var inCart = false;
if (window.location.toString().search('/product_compare/') != -1){
var win = window.opener;
}
else{
var win = window;
}
if (window.location.toString().search('/checkout/cart/') != -1){
inCart = true;
}
function setLocation(url){
if(!inCart && (/*(url.search('/add') != -1 ) || (url.search('/remove') != -1 ) ||*/ url.search('checkout/cart/add') != -1) ){
sendcart(url, 'url');
}else if((url.search('catalog/product_compare') != -1) ){
sendcompare(url, 'url');
}
else{
window.location.href = url;
}
}
function sendcompare(url, type){
//alert('test');
showLoading();
url = url.replace("catalog/product_compare/add","bestseller/index/compare");
url += 'isAjax/1/';
//jQuery('#ajax_loading'+id).show();
jQuery.ajax( {
url : url,
dataType : 'json',
success : function(data) {
// jQuery('#ajax_loading'+id).hide();
if(data.status == 'ERROR'){
alert(data.message);
}
else if(data.already!='')
{
$('mdl-temp-div').innerHTML = data.already;
var return_message = data.already;
$('mdl_ajax_confirm').innerHTML = '<div id="mdl_ajax_confirm_wrapper"><div class="f-block"><ul class="messages"><li class="notice-msg">'+return_message + '</li></ul></div></div>';
showConfirm();
}
else{
$('mdl-temp-div').innerHTML = data.message;
var return_message = data.message;
$('mdl_ajax_confirm').innerHTML = '<div id="mdl_ajax_confirm_wrapper"><div class="f-block"><ul class="messages"><li class="success-msg">'+return_message + '</li></ul></div></div>';
showConfirm();
if(jQuery('.header-compare').length){
jQuery('.header-compare').replaceWith(data.sidebar);
// Clear All
}else{
if(jQuery('.col-right').length){
jQuery('.col-right').prepend(data.sidebar);
}
}
}
}
});
}
function sendcart(url, type){
showLoading();
if (type == 'form'){
url = ($('product_addtocart_form').action).replace('checkout', 'mdlajaxcheckout/index/cart');
//url = ($('product_addtocart_form').action);
var myAjax = new Ajax.Request(
url,
{
method: 'post',
postBody: $('product_addtocart_form').serialize(),
parameters : Form.serialize("product_addtocart_form"),
onException: function (xhr, e)
{
alert('Exception : ' + e);
},
onComplete: function (xhr)
{
$('mdl-temp-div').innerHTML = xhr.responseText;
var return_message = $('mdl-temp-div').down('.mdl_ajax_message').innerHTML;
var middle_text = '<div class="mdl-cart-bts">'+$('mdl-temp-div').down('.back-ajax-add').innerHTML+'</div>';
$('mdl_ajax_confirm').innerHTML = '<div id="mdl_ajax_confirm_wrapper">'+return_message + middle_text + '</div>';
var link_cart_txt = $('mdl-temp-div').down('.cart_content').innerHTML;
$$('.top-link-cart').each(function (el){
el.innerHTML = link_cart_txt;
});
var mini_cart_txt = $('mdl-temp-div').down('.cart_side_ajax').innerHTML;
$$('.mini-cart').each(function (el){
el.replace(mini_cart_txt);
//new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
});
$$('.block-cart').each(function (el){
el.replace(mini_cart_txt);
//new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
});
replaceDelUrls();
if (ajax_cart_show_popup){
showConfirm();
} else {
hideMdlOverlay();
}
}
});
} else if (type == 'url'){
url = url.replace('checkout', 'mdlajaxcheckout/index/cart');
//alert(url);
var myAjax = new Ajax.Request(
url,
{
method: 'post',
postBody: '',
onException: function (xhr, e)
{
alert('Exception : ' + e);
},
onComplete: function (xhr)
{
$('mdl-temp-div').innerHTML = xhr.responseText;
var return_message = $('mdl-temp-div').down('.mdl_ajax_message').innerHTML;
var middle_text = '<div class="mdl-cart-bts">'+$('mdl-temp-div').down('.back-ajax-add').innerHTML+'</div>';
var content_ajax = return_message + middle_text;
$('mdl_ajax_confirm').innerHTML = '<div id="mdl_ajax_confirm_wrapper">'+content_ajax + '</div>';
var link_cart_txt = $('mdl-temp-div').down('.cart_content').innerHTML;
$$('.top-link-cart').each(function (el){
el.innerHTML = link_cart_txt;
});
var mini_cart_txt = $('mdl-temp-div').down('.cart_side_ajax').innerHTML;
//alert(mini_cart_txt);
$$('.mini-cart').each(function (el){
el.replace(mini_cart_txt);
//new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
});
$$('.block-cart').each(function (el){
el.replace(mini_cart_txt);
//new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
});
replaceDelUrls();
if (ajax_cart_show_popup){
showConfirm();
} else {
hideMdlOverlay();
}
}
});
}
}
function replaceDelUrls(){
//if (!inCart){
$$('a').each(function(el){
if(el.href.search('checkout/cart/delete') != -1 && el.href.search('javascript:cartdelete') == -1){
el.href = 'javascript:cartdelete(\'' + el.href +'\')';
}
});
//}
}
function replaceAddUrls(){
$$('a').each(function(link){
if(link.href.search('checkout/cart/add') != -1){
link.href = 'javascript:setLocation(\''+link.href+'\'); void(0);';
}
});
}
function cartdelete(url){
showLoading();
url = url.replace('checkout', 'mdlajaxcheckout/index/cartdelete');
var myAjax = new Ajax.Request(
url,
{
method: 'post',
postBody: '',
onException: function (xhr, e)
{
alert('Exception : ' + e);
},
onComplete: function (xhr)
{
$('mdl-temp-div').innerHTML = xhr.responseText;
//$('mdl-temp-div').insert(xhr.responseText);
var cart_content = $('mdl-temp-div').down('.cart_content').innerHTML;
//alert(cart_content);
$$('.top-link-cart').each(function (el){
el.innerHTML = cart_content;
});
var process_reload_cart = false;
var full_cart_content = $('mdl-temp-div').down('.mdl_full_cart_content').innerHTML;
$$('.cart').each(function (el){
el.replace(full_cart_content);
process_reload_cart = true;
});
if (!process_reload_cart){
$$('.checkout-cart-index .col-main').each(function (el){
el.replace(full_cart_content);
//new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
});
}
var cart_side = '';
if ($('mdl-temp-div').down('.cart_side_ajax')){
cart_side = $('mdl-temp-div').down('.cart_side_ajax').innerHTML;
}
$$('.mini-cart').each(function (el){
el.replace(cart_side);
//new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
});
$$('.block-cart').each(function (el){
el.replace(cart_side);
//new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
});
replaceDelUrls();
//$('mdl_ajax_progress').hide();
hideMdlOverlay();
}
});
}
function showMdlOverlay(){
new Effect.Appear($('mdl-overlay'), { duration: 0.5, to: 0.8 });
}
function hideMdlOverlay(){
$('mdl-overlay').hide();
$('mdl_ajax_progress').hide();
$('mdl_ajax_confirm').hide();
}
function mdlCenterWindow(element) {
if($(element) != null) {
// retrieve required dimensions
var el = $(element);
var elDims = el.getDimensions();
var browserName=navigator.appName;
if(browserName==="Microsoft Internet Explorer") {
if(document.documentElement.clientWidth==0) {
//IE8 Quirks
//alert('In Quirks Mode!');
var y=(document.viewport.getScrollOffsets().top + (document.body.clientHeight - elDims.height) / 2);
var x=(document.viewport.getScrollOffsets().left + (document.body.clientWidth - elDims.width) / 2);
}
else {
var y=(document.viewport.getScrollOffsets().top + (document.documentElement.clientHeight - elDims.height) / 2);
var x=(document.viewport.getScrollOffsets().left + (document.documentElement.clientWidth - elDims.width) / 2);
}
}
else {
// calculate the center of the page using the browser andelement dimensions
var y = Math.round(document.viewport.getScrollOffsets().top + ((window.innerHeight - $(element).getHeight()))/2);
var x = Math.round(document.viewport.getScrollOffsets().left + ((window.innerWidth - $(element).getWidth()))/2);
}
// set the style of the element so it is centered
var styles = {
position: 'absolute',
top: y + 'px',
left : x + 'px'
};
el.setStyle(styles);
}
}
function showLoading(){
showMdlOverlay();
var progress_box = $('mdl_ajax_progress');
progress_box.show();
progress_box.style.width = loadingW + 'px';
progress_box.style.height = loadingH + 'px';
$('mdl_ajax_progress').innerHTML = $('mdl-loading-data').innerHTML;
progress_box.style.position = 'absolute';
mdlCenterWindow(progress_box);
}
function showConfirm(){
showMdlOverlay();
$('mdl_ajax_progress').hide();
var confirm_box = $('mdl_ajax_confirm');
confirm_box.show();
confirm_box.style.width = confirmW + 'px';
confirm_box.style.height = confirmH + 'px';
//mdl_ajax_confirm_wrapper
if ($('mdl_ajax_confirm_wrapper') && $('mdl-upsell-product-table')){
//alert($('mdl_ajax_confirm_wrapper').getHeight());
confirm_box.style.height = $('mdl_ajax_confirm_wrapper').getHeight() + 'px';
decorateTable('mdl-upsell-product-table');
}
$('mdl_ajax_confirm_wrapper').replace('<div id="mdl_ajax_confirm_wrapper">'+$('mdl_ajax_confirm_wrapper').innerHTML);
confirm_box.style.position = 'absolute';
mdlCenterWindow(confirm_box);
}
document.observe("dom:loaded", function() {
replaceDelUrls();
replaceAddUrls();
Event.observe($('mdl-overlay'), 'click', hideMdlOverlay);
var cartInt = setInterval(function(){
if (typeof productAddToCartForm != 'undefined'){
if ($('mdl-overlay')){
Event.observe($('mdl-overlay'), 'click', hideMdlOverlay);
}
productAddToCartForm.submit = function(url){
if(this.validator && this.validator.validate()){
sendcart('', 'form');
clearInterval(cartInt);
}
return false;
}
} else {
clearInterval(cartInt);
}
},500);
});
When I go through each line of code in the call stack before ajax_cart.js:104 both browsers react the same.
87: $('mdl_ajax_confirm').innerHTML = '<div id="mdl_ajax_confirm_wrapper">'+return_message + middle_text + '</div>';
RETURNS HTML ON ALL BROWSERS
89: var link_cart_txt = $('mdl-temp-div').down('.cart_content').innerHTML;
UNDEFINED ON ALL
91:$$('.top-link-cart').each(function (el){el.innerHTML = link_cart_txt; });
RETURNS [object Array][] ON ALL
97: var mini_cart_txt = $('mdl-temp-div').down('.cart_side_ajax').innerHTML;
UNDEFINED ON ALL
99: $$('.mini-cart').each(function (el){ el.replace(mini_cart_txt); //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });});
RETURNS [object Array][] ON ALL
104: $$('.block-cart').each(function (el){ el.replace(mini_cart_txt); //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 }); });
Unable to get property 'tagName' of undefined or null reference on IE RETURNS HTML ON ALL CHROME
Ok, so after quite a bit of trial and error I found out what the issue was and was able to solve it.
The code was breaking an line 104 of ajax_cart.js which had this block of code:
This piece of prototype.js was searching the DOM for the
.block-cart
div to replace it with the HTML set in it'smini_cart_txt
variable. It uses the Prototype $$() Method method to search the DOM and return all elements with the.block-car
t class, it then iterates over each of them and replaces their content with themini_cart_txt
variable.The issue was that our theme's HTML was modified and now included two div's with the
.block-cart
div.Also the HTML in
mini_cart_txt
variable naturally also had two.block_cart
classes, whereas in the original theme there was only one div with a class of.block-cart
.This was what was causing the exception in IE but not in Chrome. I'm not certain why Chrome skipped past this exception. Perhaps Chrome replaced the first
.block-cart
div and then did not continue to replace the second.block-cart
div which was a child of the first one, whereas IE was running into a kind of loop which caused an exception.Anyway I was able to fix the issue by removing the
block-cart
class name from the the child div of the first block-cart div.