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

Nesting BitDropdown in BitAccordion results in: "does not support changing the EditContext dynamically" #7497

Closed
1 task done
ShahryarSaljoughi opened this issue May 11, 2024 · 6 comments

Comments

@ShahryarSaljoughi
Copy link
Contributor

ShahryarSaljoughi commented May 11, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

As I nest a BitDropdown inside a BitAccordion component, and navigate to the page where my form resides, I get an error complaining that changing EditContext is not allowed!
The bug is not seen If I directly place the BitDropdown inside the EditForm.

I see that there are two other issues (#4531 and #3837 ) slightly similar to mine. They are different than mine in that, my reported bug is neither casecading the edit context or messing with it nor is having any typos.

I've put as much context as I find useful in the "Steps to reproduce" section. Ask me If any further information is needed.
Thank you.

Expected Behavior

It's expected to see a drop down being rendered within an accordion element.

Steps To Reproduce

I have created the most minimalistec project possible to demonstrate how the bug is seen.
Here is the repo.

Steps to face the bug:

Step 1: Create a new project using bit-bp (boilerplate template) template

I'm using the 8.8.1 version of Bit.Boilerplate template.

Step 2: Trip projects

remove the Iac and Maui projects.

Step 3: Create a new page (AddCustomer) within Client.Core project:

I added the following files and folders:

-Client.Core
---Components
------Pages
-------AddCustomerPage.razor
-------AddCustomerPage.razor.cs
-------AddCustomerPage.razor.scss

Then I modified the compilerconfig.json file as told in bit videos.

Step 4: Create DTO within shared project

Created the CustomerDto class inside shared project.

Step 5: Create the form within the new page (AddCustomer page):

  • Add EditForm
  • add BitAccordion within EditForm
  • Add BitDropdown within BitAccordion

Exceptions (if any)

$exceptionl.Message is :

Bit.BlazorUI.BitDropdown`2[Bit.BlazorUI.BitDropdownItem`1[EditContextIssue.Shared.Enums.Gender],EditContextIssue.Shared.Enums.Gender] does not support changing the EditContext dynamically.

$exception.StackTrace is:

   at Bit.BlazorUI.BitInputBase`1.SetParametersAsync(ParameterView parameters)
   at Bit.BlazorUI.BitDropdown`2.SetParametersAsync(ParameterView parameters)
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.SupplyCombinedParameters(ParameterView directAndCascadingParameters)

.NET Version

8.0.204

Anything else?

No response

@ShahryarSaljoughi
Copy link
Contributor Author

ShahryarSaljoughi commented May 11, 2024

I figured out that for BitDropdwon binding is a must, in order to work (at least when it is nested within a BitAccordion), in contrast to other native Input components such as InputText.
I bound the BitDropdown component to some object and now it works.
However I assume it would be more suitable for BitDropdown to render correctly even if it is not bound to anything.

This solved the issue:

<div class="col-md-6">
    <BitDropdown Label="جنسیت"
                 Dir="@BitDir.Rtl"
                 Items="@genders"
                 TItem="BitDropdownItem<Gender?>"
                 TValue="Gender?"
                 @bind-Value="customerInput.Gender"
                 Placeholder="انتخاب کنید" />

Where genders is:

List<BitDropdownItem<Gender?>> genders = new()
{
    new () {Text = "مرد", Value = Gender.Male},
    new () {Text = "زن", Value = Gender.Female},
    new () {Text = "سایر", Value = Gender.Other},
};

And the model is given a property to store the gender of a customer.

@msynk
Copy link
Member

msynk commented May 13, 2024

Thanks for contacting us. We're investigating this issue.
We'll let you know if it's possible to work on this issue.

@msynk
Copy link
Member

msynk commented May 13, 2024

@ShahryarSaljoughi
Using an input component inside a form element without specifying the ValueExpression (automatically assigned when using the @bind- directive for the Value parameter) is not supported in our input components. generally, it seems useless to put an input component without having its value bound to a model inside an EditForm.

you mentioned that you can use an InputText component without binding its value which is not true, this component needs the ValueExpression parameter and won't even render without it.

On the other hand, when you put an element in the BitAccordion, it won't be rendered until the accordion gets opened. at this point, the cascading EditContext (coming from the EditForm component) won't be matched with the internals of the rendered BitDropdown component without a strict ValueExpression.

So you need to bind the Value parameter of input components to something to have a working form.

@ShahryarSaljoughi
Copy link
Contributor Author

regarding the :

it seems useless to put an input component without having its value bound to a model inside an EditForm.

Though I accept that at the end of developing a component you'll have all inputs bound to some object, having UI rendered without bindings helps with the development experience. Meaning that you can first focus on the appearance and then bring in the functionality of that look.

Honestly, I'm not yet convinced that we are stuck to not having rendred UI without binding Inputs.
I need to investigate the issue further. I'll reach out to you in case I find any possible enhancement.

@msynk
Copy link
Member

msynk commented May 13, 2024

It seems you've mistaken the problem. the thing is the bit BlazorUI components are trying to be fail-safe, unlike the components of other sources, like the Input component developed by the Blazor team such as the InputText you've mentioned in the issue. that component won't even render without a ValueExpression as I've already explained. so in this regard, our components are one level ahead of the other ones.

the problem you're experiencing here is the behavior of the BitAccordion component which forces a re-render of its child components after expanding making the BitDropdown's lifecycle run again, in this state the issue of mismatching EditContexts happens (you can check out the source of the BitInputBase class to understand the exact flow).

anyway, you can NOT have an input component inside an EditForm without providing a ValueEpression for it to create an appropriate instance of EditContext for it. it's NOT a limitation of the bit BlazorUI but the Blazor/ASP.NET validation itself.

@msynk
Copy link
Member

msynk commented May 28, 2024

I'm closing this issue since there has been no activity in a long time.

@msynk msynk closed this as completed May 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

No branches or pull requests

2 participants