Daddoon / Blazor.Polyfill

Blazor server-side Polyfills and fixes for Internet Explorer 11 & Edge Legacy

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error with TelerikDatePicker Blazor component

daver77 opened this issue · comments

Hi, we use the Telerik Calendar control which works fine with the polyfill but the DatePicker throws an error. Any idea what the error could be? Here's a link to the telerik-blazor.js.

[2019-11-25T10:16:17.594Z] Error: Microsoft.JSInterop.JSException: Object doesn't support this action
TypeError: Object doesn't support this action
at value (https://localhost:44377/_content/telerik.ui.for.blazor/js/telerik-blazor.js:37:8083)
at value (https://localhost:44377/_content/telerik.ui.for.blazor/js/telerik-blazor.js:37:7870)
at e (https://localhost:44377/_content/telerik.ui.for.blazor/js/telerik-blazor.js:37:4215)
at r (https://localhost:44377/_content/telerik.ui.for.blazor/js/telerik-blazor.js:1:5739)
at o (https://localhost:44377/_content/telerik.ui.for.blazor/js/telerik-blazor.js:37:2442)
at Anonymous function (https://localhost:44377/_framework/blazor.server.js:8:28731)
at Promise (https://localhost:44377/js/blazor.polyfill.js:8904:7)
at e.jsCallDispatcher.beginInvokeJSFromDotNet (https://localhost:44377/_framework/blazor.server.js:8:28701)
at Anonymous function (https://localhost:44377/_framework/blazor.server.js:1:19139)
at e.prototype.invokeClientMethod (https:/

With just this stacktrace i cannot tell if the Polyfill is the error.
Does your component work on other browser ?

But what come to my mind is two possible cases:

  • Your component use some ECMAScript syntax that may not be supported by IE11, wich has an old JS engine. Remember that even on blazor.server.js version, Javascript is still executed through the browser, but correct me if i'm wrong.
  • It may also show that there is a missing functionnality / polyfill for a specific feature, on IE11.

Wich version of the Polyfill do you use ? The last one ?

Seeing your stacktrace, it would be better to set IE11 debugger to Stop at each exception mode, and then put a breakpoint just before the code that goes in exception.

Then i imagine you should be able to see which closure/function/feature is missing on an object compared to other browsers.

In my opinion, it must not be something unfixable.

I'm using 3.0.1, yeah it works in proper browsers.

Here's what it breaks on

return new window.IntersectionObserver(function(e){e.forEach(function(e){e.intersectionRatio>=0&&e.intersectionRatio<1&&t.onAnchorHide()})},e)

image

In my opinion this is not a lack of polyfill for Blazor, but only the fact that telerik use IntersectionObserver and IE11 may not support it.

Can you try to add the following polyfill to your project and confirm it is working on IE11 then:

https://github.com/w3c/IntersectionObserver/blob/master/polyfill/README.md

Yeah I don't think it's a Blazor issue, it seems there may be a few extra polyfills I need to add.

Can you tell me if my suggestion resolve this issue ? If yes, maybe i will add some additional notes in the README of the project, for any person using Telerik component with Blazor.

It got past that error but there's more I need, still working on it

Tell me where this is going if you go through your errors ;) !

I got to this, the page now loads without Blazor disconnecting. The TelerikDatePicker dropdown does not work though and does not error but you can type in the box and the change events fire so that will do me for now.

if (/MSIE \d|Trident.*rv:/.test(navigator.userAgent)) { document.write('<script src="https://polyfill.io/v3/polyfill.min.js?features=Element.prototype.closest%2CIntersectionObserver%2Cdocument.querySelector"><\/script>'); document.write('<script src="/js/blazor.polyfill.min.js"><\/script>'); }

Thanks for your report! The last missing thing may be CSS related ?
Otherwise i will update the README with your info for Telerik component, as i don't want to add too much thing in the Blazor.Polyfill package itself, but using Telerik component on IE11 for Blazor is a good thing!

Closing !

Updated the README

More of a question for @daver77, but have you made any progress on the CSS incompatibility with Telerik Components in IE. Seems like all the Dropdown, Combobox, DatePicker popups have the same issue.

I actually just did the IE break on all exceptions and got this error: Will try some other polyfills.

image

EDIT:
I'm dumb. Now I see that that exception is normal for checking browser capabilities.

@mcbride-clint no sorry, my app was internal for the company so I just forced them to use Chrome!

Wish I could get my company to switch our primary browser to Chrome

I was able to work out the issue with the JS/CSS. When they are invoking their show command they are setting the display style to null which IE is ignoring. I copied out their JS file and formatted it find the lines and changed the display change to empty string("") and now dropdowns and datepickers show as expected.

Working on the keyboard navigation now. It looks like it's a Blazor command that is not working correctly.

commented

I was able to work out the issue with the JS/CSS. When they are invoking their show command they are setting the display style to null which IE is ignoring. I copied out their JS file and formatted it find the lines and changed the display change to empty string("") and now dropdowns and datepickers show as expected.

I was also experiencing this issue with Telerik UI for Blazor's data grid column filter menu popup.

I'm using Telerik UI for Blazor v2.25.0 and was able to use this inline MSBuild task to resolve the issue:

<UsingTask
    TaskName="FixTelerikBlazorJs" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
    <ParameterGroup>
      <FilePath ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Using Namespace="System"/>
      <Using Namespace="System.IO"/>
      <Using Namespace="System.Text"/>
      <Code Type="Fragment" Language="cs">
        <![CDATA[
            // read file contents
            string inputContents = File.ReadAllText(FilePath, Encoding.UTF8);

            // replace file contents
            string outputContents = inputContents.Replace("style.display=null", "style.display=''");

            // write file contents
            File.WriteAllText(
                FilePath,
                outputContents,
                Encoding.UTF8);
        ]]>
      </Code>
    </Task>
  </UsingTask>
<Target Name="FixTelerikBlazorJs" AfterTargets="CopyLinkedContentFiles">
    <FixTelerikBlazorJs
        FilePath=".\wwwroot\js\telerik.ui.for.blazor\2.25.0\telerik-blazor.js" />
</Target>

Thank you!

That MSBuild Task it a really cool way to do that. We were having some issue with some components on 2.19 so we are still on 2.18. I cannot get a copy of our edited file but I copied out our instructions that I have been leaving at the top of the file as we were upgrading.

2.18
List of Custom Fixes to implement again in later versions
Animation Show and ShowAsync replaced display = null with display = "" for IE compatibility
Replace display = null with display = ""
TranslateKeyName translate IE KeyboardNames to new standard
Replace this.name += t.name with this.Name += TranslateKeyName(t.key)

function TranslateKeyName(name){
  switch (name) {
    case "Down":
      return "ArrowDown";
    case "Up":
      return "ArrowUp";
    case "Left":
      return "ArrowLeft";
    case "Right":
      return "ArrowRight";
  }
}

Thanks all for your contribution !

If you sort this in order to give a workaround / "How To" guide to make TelerikDatePicker implementation easy, feel free to do a PR on this project README, as it may be usefull for other people too.

commented

I know I'm commenting on a closed thread, but this repository doesn't have a Discussion feature, and creating a new issue doesn't seem appropriate.

I noticed telerik-blazor.js in Telerik UI for Blazor 3.4.0 now uses arrow functions which can't be polly-filled.

I'm wondering if anyone has figured out how to use webpack and babeljs for example to transpile telerik-blazor.js to work on IE11?

Here is my webpack.config.js:

const path = require('path');

module.exports = {
    mode: "production",
    entry: {
        'telerik.ui.for.blazor/3.4.0/telerik-blazor': './wwwroot/js/telerik.ui.for.blazor/3.4.0/telerik-blazor.js'
    },
    output: {
        path: path.resolve(__dirname, 'wwwroot/js'),
        filename: "[name].es5.js"
    },
    target: ['web', 'es5'],
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            ['@babel/preset-env', {
                                targets: {
                                    "ie": "11"
                                }
                            }]
                        ]
                    }
                }
            }
        ]
    },
}

In <head> in _Layout.cshtml, I include the transpiled JavaScript file, generated from webpack:
<script src="~/js/telerik.ui.for.blazor/3.4.0/telerik-blazor.es5.js"></script>

However, when trying to load a page with Telerik UI controls, even using a non-IE browser, I get the following JavaScript error:

Error: Microsoft.JSInterop.JSException: Could not find 'TelerikBlazor' in 'window'.
p/<@https://localhost/MyWebApplication/_framework/blazor.server.js:8:35233
p@https://localhost/MyWebApplication/_framework/blazor.server.js:8:35193
beginInvokeJSFromDotNet/r<@https://localhost/MyWebApplication/_framework/blazor.server.js:8:35903

Thank you.

commented

Just to follow up, I was able to resolve my issue by adding

        library: "TelerikBlazor",
        libraryTarget: "window"

Here's the result:

const path = require('path');

module.exports = {
    mode: "production",
    entry: {
        'telerik.ui.for.blazor/3.4.0/telerik-blazor': './wwwroot/js/telerik.ui.for.blazor/3.4.0/telerik-blazor.js'
    },
    output: {
        path: path.resolve(__dirname, 'wwwroot/js'),
        filename: "[name].es5.js",
        library: "TelerikBlazor",
        libraryTarget: "window"
    },
    target: ['web', 'es5'],
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            ['@babel/preset-env', {
                                targets: {
                                    "ie": "11"
                                }
                            }]
                        ]
                    }
                }
            }
        ]
    },
}

In <head> in _Layout.cshtml:

<script src="https://polyfill.io/v3/polyfill.min.js?version=3.111.0&features=Object.getOwnPropertyNames%2CObject.assign%2CElement.prototype.closest%2Cdocument.querySelector"></script>
<script src="~/js/telerik.ui.for.blazor/3.4.0/telerik-blazor.es5.js"></script>

Good if you have found a solution about this.
I tried to implement something to do this semi-automatically through the ES5ConversionScope option, listed here

Maybe i should add more description about this option.
When this value is enabled, Blazor.Polyfill will try to convert to an ES5 compliant version of a JS file and will write it in a es5module folder (if i remember this right) at the root of your project. Also the SHA of the source file will be written on the converted destination file, and so the conversion to ES5 will be done again only if the source file changed.

When this is enabled, no need to manually target to the es5module folder that was created, as a HTTP handler on the server will automatically serve the ES5 version of your file transparently. Of course all of this work only when the file is hosted in your app, not on a CDN.

First boot of your app should be longer, or if a dependency change, as it will try to make a ES5 version at least once that will be cached in your project.

This should prevent to manually doing thing, and also this is working when you don't have the control to the access to a JS file, like a JS file that is loaded dynamically through a RCL (Razor Class Library).

I canno't guarantee that this will work with all scenario. I didn't have issue at the moment on my projects btw.