1

I just upgraded to ASP.NET DevExpress 16.2 and suddenly the ASPxPopupControl does not work. The webpage throws an exception.

Here is the code where it bombs:

ASPx.GetCanBeActiveElementsInContainer = function(container) {
 var canBeActiveTags = ["INPUT", "A", "UL", "BUTTON", "TEXTAREA", "SELECT", "IFRAME"],
  canBeActiveElements = [];
 Data.ForEach(canBeActiveTags, function(tag) {
  var elements = container.getElementsByTagName(tag);
  canBeActiveElements = canBeActiveElements.concat([].slice.call(elements));
 });

It bombs on the canBeActiveElements = canBeActiveElements.concat([].slice.call(elements)); line.

The error message is:

Array.prototype.slice: 'this' is not a JavaScript object

Not quite sure why this is happening since it is a 3rd party UI add on component.

What does this exception means or how to fix this?

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
John
  • 211
  • 2
  • 12

1 Answers1

0

AFAIK getElementsByTagName(tag) returns NodeList which can be treated as array of elements - they're simply host objects. Note that Array.prototype.slice is dependent on implementation, some older browser versions (IE 8 or earlier) have lack support of applying slice for host objects.

The workaround for this problem is create a try-catch block to determine if slice for host objects applicable, and utilize Array.prototype.push method as replacement of slice.call method when running in old browsers:

ASPx.GetCanBeActiveElementsInContainer = function(container) {
    var canBeActiveTags = ["INPUT", "A", "UL", "BUTTON", "TEXTAREA", "SELECT", "IFRAME"],
    canBeActiveElements = [];
    Data.ForEach(canBeActiveTags, function(tag) {
        var elements = container.getElementsByTagName(tag);
        try {
            // this works if running in IE 9+ or newer browsers
            canBeActiveElements = canBeActiveElements.concat([].slice.call(elements));
        } catch (e) {
            // for IE 8 or older browsers
            // adapted from /a/13317785
            var temp = [];
            for (var i = 0; i < elements.length; i++) {
                temp.push(elements[i]);
            }
            canBeActiveElements = canBeActiveElements.concat(temp);
        }
    });
}

NB: The changes above may work if JS code given above used inside ASPX page (not as part of any built-in JS libraries provided by DevExpress).

Reference:

"Array.prototype.slice: 'this' is not a JavaScript object" error in IE8

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61