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-cartdiv to replace it with the HTML set in it'smini_cart_txtvariable. It uses the Prototype $$() Method method to search the DOM and return all elements with the.block-cart class, it then iterates over each of them and replaces their content with themini_cart_txtvariable.The issue was that our theme's HTML was modified and now included two div's with the
.block-cartdiv.Also the HTML in
mini_cart_txtvariable naturally also had two.block_cartclasses, 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-cartdiv and then did not continue to replace the second.block-cartdiv 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-cartclass name from the the child div of the first block-cart div.