Skip to content

[Razor Components] Check-boxes behaving strangely in lists. #8202

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

Closed
davidbmasterson opened this issue Mar 5, 2019 · 8 comments
Closed

[Razor Components] Check-boxes behaving strangely in lists. #8202

davidbmasterson opened this issue Mar 5, 2019 · 8 comments
Assignees
Labels
area-blazor Includes: Blazor, Razor Components bug This issue describes a behavior which is not expected - a bug. ✔️ Resolution: Duplicate Resolved as a duplicate of another issue

Comments

@davidbmasterson
Copy link

With 2 for loops one for checked items and one for unchecked items.
When you check the first item on the unchecked list, the first item moves to the checked list and disappears from the unchecked list as you would expect.

However what was the second item in the unchecked list is now showing as checked in the page and false in the underlying List this continues to happen if you check other items

it works as expected if you start from the bottom of the list

Using
Using Visual studio 2019 version 16.0.0 Preview 4
Dot Net Core 3.0 preview 2

Create a razor components site

Replace the code in index.cshtml with

`@page "/"

checked items
    @foreach (var story in Stories.Where(c => c.Checked == true).ToArray()) {
  • @story.Description
  • }
unchecked items
    @foreach (var story in Stories.Where(c => c.Checked == false).ToArray()) {
  • @story.Description
  • }
state of values in list
@foreach (var story in Stories) { }
@story.Description @story.Checked.ToString()

@functions {

public List<Tag> Stories { get; set; } = new List<Tag>();

protected override async Task OnInitAsync()
{
    Stories.Add(new Tag() { Id = 1, Description = "Angels", Checked = false });
    Stories.Add(new Tag() { Id = 2, Description = "Knights", Checked = false });
    Stories.Add(new Tag() { Id = 3, Description = "Dinosaurs", Checked = false });
    Stories.Add(new Tag() { Id = 4, Description = "Dragons", Checked = false });
}
public class Tag
{
    public int Id { get; set; }
    public string Description { get; set; }
    public bool Checked { get; set; }
}

}`

State after clicking first item on unchecked list only
image

I would expect items checked or unchecked in either list to move from one list to the other and for this to have no effect on the other check-boxes

@davidbmasterson davidbmasterson changed the title [Blazor] Check-boxes behaving strangely in lists. [Razor Components] Check-boxes behaving strangely in lists. Mar 5, 2019
@JesperOlsen
Copy link

JesperOlsen commented Mar 5, 2019

Was searching for a solution to a problem exactly like what you describe and found your very new ticket.
Though my checkboxes are in a table, but they exhibit the same behaviour.
When I click one checkbox my business logic dictates that that row is removed from the table. When the UI rerenders the row is removed but the row beneath the removed row now has it's checkbox checked?!

@mkArtakMSFT mkArtakMSFT added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates area-blazor Includes: Blazor, Razor Components labels Mar 5, 2019
@mkArtakMSFT
Copy link
Contributor

Thanks for contacting us, @davidbmasterson.

@mkArtakMSFT
Copy link
Contributor

Thank you for filing this issue. In order for us to investigate this issue, please provide a minimalistic repro project that illustrates the problem.

@mkArtakMSFT
Copy link
Contributor

@javiercn, could you please investigate this, when we'll get a repro? Thanks!

@davidbmasterson
Copy link
Author

here is the repro

https://github.com/davidbmasterson/exampleproject_checkboxes

have fun

@javiercn
Copy link
Member

I repro this with our latest bits.

Looking into it.

@javiercn
Copy link
Member

The issue here is that the act of clicking the checkbox modifies the state of the component. Our diffing algorithms produces a set of instructions that tell the browser to do the following (roughly)

  • Insert an checkbox with angels on the first list.
  • Update the text on the first input of the second list to knights.
  • Update the text on the second input of the second list to dinosaurs.
  • Update the text on the third input of the second list to dragons.
  • Remove the fourth input on the second list.

The problem is that in this case checking the first checkbox in the second list marks the checkbox as checked, which the server model does not have any idea about.

There are several ways we can avoid this.

  • Use prevent default on the checkbox and let the server set the values as appropriate. This works in this case but doesn't work in others, like when the checkbox won't disappear, as that would introduce visible lag.
  • Use the new support for key that @SteveSandersonMS That will avoid this problem, but not other similar problems related to asynchronicity in inputs, like Components bind-value-oninput can lose cursor position with fast typing #8204
  • Provide some cleanup callback that runs before applying the next batch(), that can cause flickering if the batch is unrelated (we could potentially correlate the batch to the event id)
  • Providing some sort of specialization for inputs? (still thinking how this would work).

In any case, this can't be a small fix but something with a bigger scope.

@javiercn javiercn added bug This issue describes a behavior which is not expected - a bug. cost: M and removed investigate labels Apr 26, 2019
@mkArtakMSFT mkArtakMSFT removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels May 9, 2019
@javiercn javiercn removed the Working label May 31, 2019
@javiercn
Copy link
Member

Closing as the recommended action in this situation is to use @key on the items list

@mkArtakMSFT mkArtakMSFT added the ✔️ Resolution: Duplicate Resolved as a duplicate of another issue label May 31, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Dec 3, 2019
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. ✔️ Resolution: Duplicate Resolved as a duplicate of another issue
Projects
None yet
Development

No branches or pull requests

5 participants