SamProf / MatBlazor

Material Design components for Blazor and Razor Components
http://www.matblazor.com
MIT License
2.84k stars 386 forks source link

MatAutocomplete - looks for ValueExprression when inside EditForm with Validation #213

Closed etcircle closed 4 years ago

etcircle commented 5 years ago

The Autocomplete doesn't seem to work within a form with EditForm validation.

InvalidOperationException: MatBlazor.MatTextField requires a value for the 'ValueExpression' parameter. Normally this is provided automatically when using 'bind-Value'.
MatBlazor.BaseMatInputComponent<T>.SetParametersAsync(ParameterView parameters) in BaseMatInputComponent.cs
+
                        FieldIdentifier = FieldIdentifier.Create(ValueExpression);
Microsoft.AspNetCore.Components.Rendering.ComponentState.SetDirectParameters(ParameterView parameters)
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(ref DiffContext diffContext, int frameIndex)
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(ref DiffContext diffContext, int frameIndex)
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(ref DiffContext diffContext, int newFrameIndex)
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(ref DiffContext diffContext, int oldStartIndex, int oldEndIndexExcl, int newStartIndex, int newEndIndexExcl)
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer renderer, RenderBatchBuilder batchBuilder, int componentId, ArrayRange<RenderTreeFrame> oldTree, ArrayRange<RenderTreeFrame> newTree)
xbpass commented 5 years ago

I'm having the same issue, tried coping out side of the EditForm, then it just runs

lheinold commented 5 years ago

I was having the same problem so I looked into this. Autocomplete creates a text field:

<MatTextField Icon="@Icon" OnFocus="@OpenPopup" HideClearButton="true" FullWidth="@FullWidth" OnFocusOut="@ClosePopup" Label="@Label" Value=@StringValue OnInput=@OnValueChanged Outlined="@Outlined" Attributes="@Attributes" Id="@Id"></MatTextField>

MatTextField needs a ValueExpression when EditContext is set (which is a cascading value from EditForm), but there is no value binding for the mat text field within MatAutoComplete. Currently BaseMatAutocomplete inherits from BaseMatDomComponent, which is not an input component so therefore doesn't support EditContext/ValueExpression.

I made the following changes locally but I'm not sure if this is the right way to fix it:

Just these changes get rid of the error but validation in the text field doesn't work. I added @bind-Value="Value" but "Value" doesn't have the same validation rules as whatever the value passed into the autocomplete component was. I'm not sure of the best way to fix this, ideas? My current solution is turning off validation in the text field and adding custom css, but that's a bad way to do it.

abibtj commented 5 years ago

I'm having the same issue. Unfortunately, I cannot move MatAutocomplete outside EditForm. I'm yet to come up with a solution to this challenge.

bnemetchek commented 5 years ago

Make a new component, named something like "MatAutocompleteForm.razor"

@namespace MatBlazor
@typeparam ItemType
@inherits BaseMatAutocomplete<ItemType>
@using System.Collections;

<div class="@WrapperClassMapper.Class">
    <MatTextField Icon="@Icon" OnFocus="@OpenPopup" HideClearButton="true" FullWidth="@FullWidth" OnFocusOut="@ClosePopup" Label="@Label" Value=@StringValue OnInput=@OnValueChanged OnKeyDown="@OnKeyDown" Outlined="@Outlined" Attributes="@Attributes" Id="@Id" ValueExpression="@(() => _dummyVal)"></MatTextField>
    @if (IsShowingClearButton)
    {
        <div class="mat-autocomplete-clearbutton">
            <MatIconButton Icon="clear" OnMouseDown="@ClearText"></MatIconButton>
        </div>
    }
    @if (Collection != null && IsOpened)
    {
        <div class="mat-autocomplete-popup">
            <MatList @ref="ListRef" SingleSelection="true">
                @foreach (var elementWrapper in GetFilteredCollection(StringValue))
                {
                    <MatListItem OnMouseDown="@((e) => ItemClicked(elementWrapper.Element))">
                        @if (ItemTemplate != null)
                        {
                            @ItemTemplate(elementWrapper.Element)
                        }
                        else
                        {
                            <MatListItemText>@(elementWrapper.StringValue)</MatListItemText>
                        }
                    </MatListItem>
                }
            </MatList>
        </div>
    }
</div>

@code {
    private string _dummyVal { get; set; }
}
katiep23 commented 4 years ago

Here is what I used: https://docs.telerik.com/blazor-ui/knowledge-base/value-changed-validation-model

eldaran83 commented 4 years ago

I'm having the same issue, Autocomplete doesn't seem to work within a form with EditForm validation.. Unfortunately, I cannot move MatAutocomplete outside EditForm. Somebody fix it ? you ave a solution ? thx

enkodellc commented 4 years ago

Merged fix into develop branch.