Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<option> elements inserted dynamically during same diff as <select> don't get auto-selected #21453

Closed
pgillett opened this issue May 4, 2020 · 5 comments
Assignees
Labels
area-blazor Includes: Blazor, Razor Components bug This issue describes a behavior which is not expected - a bug. Done This issue has been fixed

Comments

@pgillett
Copy link

pgillett commented May 4, 2020

Issue

If I use a custom component for the option tag of a select, the initial bind doesn't seem to work. The selection is invalid and the component displays the top item.

From there on everything works as expected and binding is fine.

This is on server-side, have not tested WASM/client-side.

To reproduce

Code shows three components. An input field (purely to test binding), a select using the option tag, and a select using the custom option tag.

The 2nd select (custom option) incorrectly has item A highlighted.

<input @bind="TheValue" />

<select @bind="TheValue">
    <option value="A">Option A</option>
    <option value="B">Option B</option>
    <option value="C">Option C</option>
</select>

<select @bind="TheValue">
    <MyOption value="A">Option A</MyOption>
    <MyOption value="B">Option B</MyOption>
    <MyOption value="C">Option C</MyOption>
</select>

@code
{
    public string TheValue { get; set; } = "B";
}

And the custom MyOption component:

<option @attributes="InputAttributes">@ChildContent</option>

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public Dictionary<string, object> InputAttributes { get; set; }

    [Parameter] public RenderFragment ChildContent { get; set; }
}

(Doesn't make any difference with a value parameter instead of attribute splatting)

ASP.NET Core version 3.1.201

@pgillett pgillett changed the title Select using own option component does not bind to initial value Select using custom option tag/component does not bind to initial value May 4, 2020
@javiercn javiercn added the area-blazor Includes: Blazor, Razor Components label May 4, 2020
@javiercn
Copy link
Member

javiercn commented May 4, 2020

@pgillett thanks for contacting us.

Bind is a compiler feature and I believe for it to work with select it needs to be used in conjunction with options.

@SteveSandersonMS might know better, but that's my guess.

@SteveSandersonMS
Copy link
Member

SteveSandersonMS commented May 4, 2020

@pgillett Thanks for reporting this.

HTML <select> elements are a bit special because they can only hold certain values depending on their descendant elements. The framework has to do some nonobvious things to handle cases where the parent <select> has its value assigned before the descendants are inserted (e.g., when <option> elements are inserted dynamically at a later point in time).

We handle most of these cases perfectly well and until your report, I thought we handled all the possible cases. However upon investigation I see we are missing support for the case where <option> elements are inserted dynamically during the same render cycle as when the parent is instantiated.

In a sense this is quite an easy bug to fix: we could just remove this line of code and it would work fine.

However that opens up a design question: when there's no corresponding <option> for an assigned value, should we remember the assigned value indefinitely and match it up with an <option> inserted arbitrarily far into the future? I think in some cases that behavior would seem quite strange and unexpected.

Tentatively I think the preferred design would be that we match up assigned value values only with <option> elements that are available by the end of the current renderbatch. Implementing that is slightly more work than just removing the line I linked above, but it's not hugely difficult I expect. Note: I haven't 100% convinced myself about this design - maybe we should match them up indefinitely into the future.

Hopefully we can apply a fix for this as part of the 5.0 release. Until then, the best workaround would be to avoid having a separate component just to represent an individual <option> element, and instead inline its logic into the parent component.

@SteveSandersonMS SteveSandersonMS added the bug This issue describes a behavior which is not expected - a bug. label May 4, 2020
@SteveSandersonMS SteveSandersonMS changed the title Select using custom option tag/component does not bind to initial value <option> elements inserted dynamically during same batch as <select> don't get auto-selected May 4, 2020
@SteveSandersonMS SteveSandersonMS changed the title <option> elements inserted dynamically during same batch as <select> don't get auto-selected <option> elements inserted dynamically during same diff as <select> don't get auto-selected May 4, 2020
@javiercn
Copy link
Member

javiercn commented May 4, 2020

@SteveSandersonMS based on your comment, it seems this might be a dupe of #21432

@schotime
Copy link

schotime commented May 4, 2020

This does appear to be the same as what I found, but @SteveSandersonMS workaround would not apply as my options are already inlined.

Tentatively I think the preferred design would be that we match up assigned value values only with elements that are available by the end of the current renderbatch.

I would agree with this.

@mkArtakMSFT mkArtakMSFT added this to the Next sprint planning milestone May 4, 2020
@mrpmorris
Copy link

I think keeping the value and binding it when the option exists makes perfect sense.

The value is the value, the select is just a lookup presentation of that value. If the value isn't in the lookup, the lookup should display the wrong value because the coder has it wrong.

@captainsafia captainsafia moved this from 5.0-Preview7 to In progress in ASP.NET Core Blazor & MVC 5.0.x Jun 15, 2020
@captainsafia captainsafia added the Done This issue has been fixed label Jun 22, 2020
ASP.NET Core Blazor & MVC 5.0.x automation moved this from In progress to Done Jun 22, 2020
@dotnet dotnet locked as resolved and limited conversation to collaborators Jul 22, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components bug This issue describes a behavior which is not expected - a bug. Done This issue has been fixed
Projects
No open projects
Development

No branches or pull requests

7 participants