jdtcn / BlazorDateRangePicker

A Blazor component for choosing date ranges and dates
MIT License
182 stars 35 forks source link

Uncaught TypeError TypeError: clickAndPositionHandler.getPickerPosition is not a function #96

Closed ericbrunner closed 7 months ago

ericbrunner commented 7 months ago

Hi,

I updated to v. 5.0.0. but see the error in the VS console.

Uncaught TypeError TypeError: clickAndPositionHandler.getPickerPosition is not a function at resizeFunction (C:\Users\ErichBrunner.nuget\packages\blazordaterangepicker\5.0.0\staticwebassets\clickAndPositionHandler.js:26:33)

Stacktrace:

Error: Could not find 'addClickOutsideEvent' ('addClickOutsideEvent' was undefined).
    at http://localhost:5000/_framework/blazor.web.js:1:734
    at Array.forEach (<anonymous>)
    at l.findFunction (http://localhost:5000/_framework/blazor.web.js:1:702)
    at b (http://localhost:5000/_framework/blazor.web.js:1:5445)
    at http://localhost:5000/_framework/blazor.web.js:1:3238
    at new Promise (<anonymous>)
    at y.beginInvokeJSFromDotNet (http://localhost:5000/_framework/blazor.web.js:1:3201)
    at fn._invokeClientMethod (http://localhost:5000/_framework/blazor.web.js:1:62869)
    at fn._processIncomingData (http://localhost:5000/_framework/blazor.web.js:1:60344)
    at connection.onreceive (http://localhost:5000/_framework/blazor.web.js:1:53985)
Microsoft.JSInterop.JSException: Could not find 'addClickOutsideEvent' ('addClickOutsideEvent' was undefined).
Error: Could not find 'addClickOutsideEvent' ('addClickOutsideEvent' was undefined).
    at http://localhost:5000/_framework/blazor.web.js:1:734
    at Array.forEach (<anonymous>)
    at l.findFunction (http://localhost:5000/_framework/blazor.web.js:1:702)
    at b (http://localhost:5000/_framework/blazor.web.js:1:5445)
    at http://localhost:5000/_framework/blazor.web.js:1:3238
    at new Promise (<anonymous>)
    at y.beginInvokeJSFromDotNet (http://localhost:5000/_framework/blazor.web.js:1:3201)
    at fn._invokeClientMethod (http://localhost:5000/_framework/blazor.web.js:1:62869)
    at fn._processIncomingData (http://localhost:5000/_framework/blazor.web.js:1:60344)
    at connection.onreceive (http://localhost:5000/_framework/blazor.web.js:1:53985)
   at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args)
   at Microsoft.JSInterop.JSObjectReferenceExtensions.InvokeVoidAsync(IJSObjectReference jsObjectReference, String identifier, Object[] args)
   at BlazorDateRangePicker.DateRangePicker.Open()
   at BlazorDateRangePicker.DateRangePicker.Toggle()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

Here my setup in App.razor

@using System.Reflection
<!DOCTYPE html>
<html lang="en">

<head>
    <meta http-equiv="X-Content-Type-Options" content="nosniff">
    <meta http-equiv="X-XSS-Protection" content="1; mode=block">
    <meta name="version" content="@Version"/>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <base href="/"/>
    <link rel="stylesheet" href="bootstrap/bootstrap.min.css"/>
    @*  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.2/font/bootstrap-icons.min.css"> *@
    <link rel="stylesheet" href="bootstrap-icons-1.11.2/font/bootstrap-icons.min.css">
    <link rel="stylesheet" href="app.css"/>
    <link rel="stylesheet" href="Stadtverwaltung.BlazorApp.styles.css"/>
    <link rel="icon" type="image/png" href="favicon.png"/>
    <HeadOutlet @rendermode="App.InteractiveServerWithoutPrerendering"/>
</head>

<body>
<Routes @rendermode="App.InteractiveServerWithoutPrerendering"/>
<script src="_framework/blazor.web.js"></script>
<script src="js/app.js"></script>

<div id="components-reconnect-modal">
    Seite wird neu geladen ...
</div>
</body>

</html>

@code
{
    public static string Version => Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "unset";
    public static IComponentRenderMode InteractiveServerWithoutPrerendering { get; } = new InteractiveServerRenderMode(prerender: false);
}

Here my wrapper Component Code:


@page "/date-range-picker-ex"

@using System.Globalization
@using BlazorDateRangePicker
@using Stadtverwaltung.BlazorApp.State

@inject ILogger<DateRangePickerEx> Logger;
@inject StateContainer StateContainer

<div class="row">
    <div class="col-12 g-0">

        <DateRangePicker @ref="_picker"
                         @bind-StartDate="StartDate"
                         @bind-EndDate="EndDate"
                         OnRangeSelect="OnRangeSelect"
                         Culture="@(CultureInfo.GetCultureInfo("de-AT"))">
            <PickerTemplate>
                <div id="@context.Id" @onclick="context.Toggle" class="daterange-picker-ex">
                    <i class="bi bi-calendar"></i>&nbsp;
                    <span>
                        @if (context.TStartDate == null && context.TEndDate == null)
                        {
                            <span>Auswahl Zeitraum ...</span>
                        }
                        else if (context is { TStartDate: not null, TEndDate: null })
                        {
                            if (context.HoverDate > context.TStartDate)
                            {
                                @($"{context.TStartDate.Value.ToString(context.DateFormat)} - {context.HoverDate.Value.ToString(context.DateFormat)}")
                            }
                            else
                            {
                                <span>@context.TStartDate.Value.ToString("dd.MM.yyyy")</span>
                            }
                        }
                        else
                        {
                            <span>
                                @context.FormattedRange
                            </span>
                        }
                    </span>
                    <i class="bi bi-chevron-down bi-align-end"></i>
                </div>
            </PickerTemplate>
            <ButtonsTemplate>
                <button class="cancelBtn btn btn-sm btn-default"
                        @onclick="@context.ClickCancel" type="button">
                    Abbrechen
                </button>

                <button class="cancelBtn btn btn-sm btn-success"
                        @onclick="@(e => TodayClick(e, context))" type="button">
                    Heute
                </button>

                <button class="applyBtn btn btn-sm btn-primary" @onclick="@context.ClickApply"
                        disabled="@(context.TStartDate == null || context.TEndDate == null)"
                        type="button">
                    Anwenden
                </button>
            </ButtonsTemplate>
        </DateRangePicker>

    </div>
</div>

@code {
    DateTimeOffset? StartDate { get; set; }
    DateTimeOffset? EndDate { get; set; }

    [Parameter] public EventCallback<DateRange> OnDateRangeSelect { get; set; }

    protected override void OnInitialized()
    {
        StartDate = StateContainer.StartDate ?? DateTime.Today;
        EndDate = StateContainer.EndDate ?? new DateTimeOffset(
            DateOnly.FromDateTime(DateTime.Today.AddDays(1)),
            new TimeOnly(23, 59, 59), DateTimeOffset.Now.Offset);
    }

    private void OnRangeSelect(DateRange dateRange)
    {
        StateContainer.StartDate = dateRange.Start;
        StateContainer.EndDate = dateRange.End;

        OnDateRangeSelect.InvokeAsync(dateRange);
    }

    DateRangePicker? _picker;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            if (_picker == null)
            {
                Logger.LogError($"{nameof(_picker)} is null");
                return;
            }

            await _picker.OnRangeSelect.InvokeAsync(_picker is { TStartDate: not null, TEndDate: not null }
                ? new DateRange()
                {
                    Start = _picker.TStartDate.Value,
                    End = _picker.TEndDate.Value
                }
                : new DateRange());
        }
    }

    void TodayClick(MouseEventArgs e, DateRangePicker picker)
    {
        var today = DateTime.Today;
        var start = new DateTimeOffset(DateOnly.FromDateTime(today), new TimeOnly(0, 0, 0), DateTimeOffset.Now.Offset);
        var end  = new DateTimeOffset(DateOnly.FromDateTime(today), new TimeOnly(23, 59, 59), DateTimeOffset.Now.Offset);

        StartDate = start;
        EndDate = end;

        picker.Close();
        picker.OnRangeSelect.InvokeAsync(new DateRange() {Start = StartDate.Value, End = EndDate.Value});
    }

}
OndrejUzovic commented 7 months ago

After upgrading to 5.0.0 I get the same exception but with slightly different call-stack:

The exception occurs when I click into the input element. (blazor server site, .NET 8)

Error: Microsoft.JSInterop.JSException: Could not find 'addClickOutsideEvent' ('addClickOutsideEvent' was undefined).
Error: Could not find 'addClickOutsideEvent' ('addClickOutsideEvent' was undefined).
    at https://localhost:44395/_framework/blazor.server.js:1:734
    at Array.forEach (<anonymous>)
    at l.findFunction (https://localhost:44395/_framework/blazor.server.js:1:702)
    at _ (https://localhost:44395/_framework/blazor.server.js:1:5445)
    at https://localhost:44395/_framework/blazor.server.js:1:3238
    at new Promise (<anonymous>)
    at y.beginInvokeJSFromDotNet (https://localhost:44395/_framework/blazor.server.js:1:3201)
    at Yt._invokeClientMethod (https://localhost:44395/_framework/blazor.server.js:1:60713)
    at Yt._processIncomingData (https://localhost:44395/_framework/blazor.server.js:1:58188)
    at Yt.connection.onreceive (https://localhost:44395/_framework/blazor.server.js:1:51829)
   at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args)
   at Microsoft.JSInterop.JSObjectReferenceExtensions.InvokeVoidAsync(IJSObjectReference jsObjectReference, String identifier, Object[] args)
   at BlazorDateRangePicker.DateRangePicker.Open()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
log @ blazor.server.js:1
unhandledError @ blazor.server.js:1
(anonymous) @ blazor.server.js:1
_invokeClientMethod @ blazor.server.js:1
_processIncomingData @ blazor.server.js:1
Yt.connection.onreceive @ blazor.server.js:1
s.onmessage @ blazor.server.js:1
jdtcn commented 7 months ago

I have tried server and client, net6 and net8 and I do not get this error. Please check your browser console for js script loading errors, it should load /_content/BlazorDateRangePicker/clickAndPositionHandler.js And please tell me what browser you are using

ericbrunner commented 7 months ago

Edge Browser. At first it occured while debugging on localhost when I click the DateRangePicker but the error disappeared after several clicks. Then I noticed that it occurs when I do a dotnet publish of the app. So as Release build in DOTNET_ENVIRONMENT=Production. Here the error remains. No script load error in js console.

Kind regards, Erich


From: Sergey @.> Sent: Monday, January 22, 2024 5:55:44 PM To: jdtcn/BlazorDateRangePicker @.> Cc: Eric Brunner @.>; Author @.> Subject: Re: [jdtcn/BlazorDateRangePicker] Uncaught TypeError TypeError: clickAndPositionHandler.getPickerPosition is not a function (Issue #96)

I have tried server and client, net6 and net8 and I do not get this error. Please check your browser console for js script loading errors, it should load /_content/BlazorDateRangePicker/clickAndPositionHandler.js And please tell me what browser you are using

— Reply to this email directly, view it on GitHubhttps://github.com/jdtcn/BlazorDateRangePicker/issues/96#issuecomment-1904416402, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABROBL4TEP4D7QKQNWB7PA3YP2KZBAVCNFSM6AAAAABCFANUSGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMBUGQYTMNBQGI. You are receiving this because you authored the thread.Message ID: @.***>

jdtcn commented 7 months ago

Thanks for your help, I found the problem, made a mistake while refactoring, I published version 5.1.0 with the fix, please check it out

ericbrunner commented 7 months ago

@jdtcn

When the DateRangePicker is clicked on mobile device my ErrorBoundary catches an exception and reloads the page. Any idea what causes the exception? It occurs sind v. 5.x

In Chrome it works. In Edge it doesn't. I guess its a caching issue.

After clearing Edge cache it worked.

Screenshot_20240124_195443_Settings

jdtcn commented 7 months ago

Hi, I think this time the problem is not with the picker, I see that sometimes there is an error happens on the server but the browser console is clear. I took your code and it works in edge/chrome/firefox, maybe the exception happens after selecting the date. If you have a stack trace please share it.

ericbrunner commented 7 months ago

@jdtcn had to clear Edge cache. You can try it: take version 4.5 and open in Edge. Upgrade to 5.x and open again in Edge. The issue I described should appear.

jdtcn commented 7 months ago

Indeed, there is a problem with the cache, it doesn't try to load the new js file version even though according to the headers it should, anyway I fixed it with the grandfather method, added ?v={Version} to the file name, published version 5.2.0 with the fix. Thank you for your help! I should get rid of that js altogether, I'll do it sometime.