Aspnetcore: How to create a component of InputText to use in EditForm

Created on 10 Mar 2019  路  6Comments  路  Source: dotnet/aspnetcore

Cenario

I'm trying to make a component that uses InputText, but when I edit the textbox, it doesn't update the EditForm Model. This is how i'm trying to do this:

RazorInputTest.razor

<div class="form-group">
    <label class="col-form-label">@Label</label>
    <InputText Class="form-control" bind-Value="@Value"></InputText>
</div>

@functions{
    [Parameter] string Label { get; set; }
    [Parameter] string Value { get; set; }
    [Parameter] EventCallback<string> ValueChanged { get; set; }
}

Index.razor

<span>Name of the category: @category.Name</span>
<EditForm Model="@category">
    <RazorInputTest bind-Value="@category.Name"/>
</EditForm>

When I edit the input, the span with the "Name of the category" doesn't update, but I don't know what I am doing wrong.

Objective

I'm doing a set of bootstrap formated components and this is an important part of this project: preformated input-boxes. I want to create components that binds viewmodels, like InputText does inside the EditForm, but InputText inside a component, inside a EditForm inside another component.

area-blazor question

Most helpful comment

@pjmagee Consider inheriting from InputBase directly, e.g.:

 @inherits InputBase<string>
 <input type="password" bind="@CurrentValue" id="@Id" class="@CssClass" />

All 6 comments

It won鈥檛 update because this code doesn鈥檛 trigger ValueChanged anywhere.

Hi @medeirosraul - what Steve said is right, this won't send change notifications because in Index.razor you're attaching a binding to RazorInputTest.Value, but nothing is going to invoke RazorInputTest.ValueChanged.

It's really our intended pattern for you to subclass InputText if you want to replace its UI but unfortunately that doesn't work well in preview3 (#8192).

If you want a solution to wrap an InputText, you'll have to write a little more code.

RazorInputTest.razor

<div class="form-group">
    <label class="col-form-label">@Label</label>
    <InputText Class="form-control" Value="@Value" ValueChanged="@ValueChanged" ValueExpression="@ValueExpression"></InputText>
</div>

@functions{
    [Parameter] string Label { get; set; }
    [Parameter] string Value { get; set; }
    [Parameter] EventCallback<string> ValueChanged { get; set; }
    [Parameter] Expression<Func<string>> ValueExpression { get; set; }
}

Index.razor won't have to change.

This works, thank you.
So I think the "bind" attribute also sets "ValueExpression" when code generated.

@rynowak What about the input type of password, do we fall back to the standard html input?

@pjmagee Consider inheriting from InputBase directly, e.g.:

 @inherits InputBase<string>
 <input type="password" bind="@CurrentValue" id="@Id" class="@CssClass" />

Hello, the following worked for me:
File : CustomTextBox.razor

@code {
public string _Value;
[Parameter]
public string Value
{
get
{
return _Value;
}
set
{
if (_Value != value)
{
ValueChanged.InvokeAsync(value);
}
_Value = value;
}
}
[Parameter]
public EventCallback ValueChanged { get; set; }
}

use:

Was this page helpful?
0 / 5 - 0 ratings