Skip to content

Conversation

@vnbaaij
Copy link
Collaborator

@vnbaaij vnbaaij commented Sep 3, 2024

Storing the situation as described in last issue comment: #2609 (comment)

Explanation:

Given the question "How can I reset the slider value?" we've found there is an issue with doing that. We are using the following sample code (slightly adapted version from the code used in the issue):

<div style="display: flex; flex-direction: column; align-items: flex-start; height: min-content;">
    <label for="rtl-slider" style="margin-left: 8px;">rtl support</label>
    <div dir="rtl" style="width: 100%;">
        <FluentSlider id="rtl-slider" Min="0" Max="100" Step="10" @bind-Value=value2>
            <FluentSliderLabel Position="10">10</FluentSliderLabel>
            <FluentSliderLabel Position="20">20</FluentSliderLabel>
            <FluentSliderLabel Position="40">40</FluentSliderLabel>
            <FluentSliderLabel Position="60">60</FluentSliderLabel>
            <FluentSliderLabel Position="80">80</FluentSliderLabel>
        </FluentSlider>
        Value 2: @value2
        <FluentButton OnClick="() => value2 = 0 ">Reset</FluentButton>  @* THIS LINE IMPORTANT *@
    </div>
</div>

<div style="display: flex; flex-direction: column; align-items: flex-start; height: min-content;">
    <label for="rtl-slider" style="margin-left: 8px;">rtl support</label>
    <div dir="rtl" style="width: 100%;">
        <FluentSlider id="rtl-slider" Min="0" Max="100" Step="10" @bind-Value=value1>
            <FluentSliderLabel Position="10">10</FluentSliderLabel>
            <FluentSliderLabel Position="20">20</FluentSliderLabel>
            <FluentSliderLabel Position="40">40</FluentSliderLabel>
            <FluentSliderLabel Position="60">60</FluentSliderLabel>
            <FluentSliderLabel Position="80">80</FluentSliderLabel>
        </FluentSlider>
        Value 1: @value1
        <FluentButton OnClick="() => value1 = 0 ">Reset</FluentButton>  @* THIS LINE IMPORTANT *@
    </div>
</div>

@code {
    int value1=30, value2 = 50;
}

What I've found so far:

  • Addding below to FluentSlider.razor
current-value="@FormatValueAsString(Value)"  @* ADD THIS LINE *@
aria-valuenow="@FormatValueAsString(Value)" @* ADD THIS LINE *@

Works when using the Blazor code from above. What does not work is using the Slider inside another component that can influence the slider's value. I'm using the DataGrid Typical Usage filter example for this. moving the thumb a couple of times in quick succession throws it into a loop:
grid-slider

Not adding the current-value to the slider tag and using the script for earlier PR that Gary (@oneolddev) mentioned has the same result (reset works, grid goes into loop) if we invoke the js function on every render (ie in OnAfterRenderAsync but outside of `firstRender' block):

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        _jsModule ??= await JSRuntime.InvokeAsync<IJSObjectReference>("import", JAVASCRIPT_FILE);
    }
    if (_jsModule is not null)
    {
        await _jsModule!.InvokeVoidAsync("updateSlider", Element);
    }
}

If we move the script call to inside the firstRender block, the data grid filter example works flawlessly. @LuohuaRain's code works for some part not not completely. If you move a slider and then press reset, the value gets set to 0 but the thumb is not updated. If you press reset without moving a slider, it will set the value and the thumb correctly:

issue-slider

Now we just need a working combination of these two. I've tried everything I could think of but was not able to find a definitive solution. So Gary, if your offer still stands, please take a look.

@vnbaaij vnbaaij linked an issue Sep 3, 2024 that may be closed by this pull request
@github-actions
Copy link

github-actions bot commented Sep 3, 2024

Unit Tests

  • ❌[FAILED] Microsoft.FluentUI.AspNetCore.Components.Tests.Slider.FluentSliderTests.FluentSlider_WithLabel
  • ❌[FAILED] Microsoft.FluentUI.AspNetCore.Components.Tests.Slider.FluentSliderTests.FluentSlider_WithLabelTemplate
  • ❌[FAILED] Microsoft.FluentUI.AspNetCore.Components.Tests.Slider.FluentSliderTests.FluentSlider_Vertical
  • ❌[FAILED] Microsoft.FluentUI.AspNetCore.Components.Tests.Slider.FluentSliderTests.FluentSlider_Double
  • ❌[FAILED] Microsoft.FluentUI.AspNetCore.Components.Tests.Slider.FluentSliderTests.FluentSlider_Horizontal
  • ❌[FAILED] Microsoft.FluentUI.AspNetCore.Components.Tests.Slider.FluentSliderTests.FluentSlider_Default

Details on your Workflow / Core Tests page.

@vnbaaij vnbaaij modified the milestones: v4.10.0, v4.10.1 Sep 3, 2024
@vnbaaij
Copy link
Collaborator Author

vnbaaij commented Sep 12, 2024

@oneolddev Hi Gary, were you able to make any progress on this?

@oneolddev
Copy link
Contributor

@oneolddev Hi Gary, were you able to make any progress on this?

@vnbaaij, Hi Vincent

Sorry, I got busy with another more pressing issue.

I believe I have a fix for this problem. I'm not quite sure how to add my changes to your PR so I added some comments as part of the code review. Below is a summary.

Changes to OnAfterRenderAsync in FluentSlider.razor.cs

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            _jsModule ??= await JSRuntime.InvokeAsync<IJSObjectReference>("import", JAVASCRIPT_FILE);
        }
        else
        {
            if (_jsModule is not null)
            {
                await _jsModule!.InvokeVoidAsync("updateSlider", Element);
            }
        }
    }

Remove from FluentSlider.razor

 aria-valuenow="@FormatValueAsString(Value)"

The root cause of the slider issue is the expected two-way binding behaviour. What actually is happening is that thumbnail is only rendered on the first render of the slider web component. Subsequent changes in the value do not result in the thumbnail being redrawn which is the expected behaviour. The call to updateSlider resolves that problem by forcing a redraw. Note: It calls a implementation specific slider function.

@oneolddev
Copy link
Contributor

I spoke too soon. I'm now seeing the jittering in the the datagrid. 😢

@oneolddev
Copy link
Contributor

The jittering occurs when dragging the thumbnail. As the thumbnail is dragged, the value is being updated causing a rerender. updateSlider is called but may not complete before the next rerender call.

@oneolddev
Copy link
Contributor

@vnbaaij

I have a fix for this issue. It required me to specifically target those states where the slider thumbnail needed to be redrawn.

@vnbaaij
Copy link
Collaborator Author

vnbaaij commented Sep 17, 2024

Resolved with #2665

@vnbaaij vnbaaij closed this Sep 17, 2024
@vnbaaij vnbaaij deleted the users/vnbaaij/fix-issue-#2609 branch September 25, 2024 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] FluentSlider two-way binding issue

3 participants