Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass @binding-value to component on blazor

Tags:

c#

blazor

I created this component. file name: InputTextComponent.razor

<div class="form-group">
    <label for="Name">Name</label>
    <InputText @bind-Value="@Value"/>
</div>

@code {
    [Parameter]
    public string Value{ get; set; }
}

in the page index.razor

@page "/"

<EditForm model="@data" OnValidSubmit="()=>OnClickBtn()">
    <DataAnnotationsValidator></DataAnnotationsValidator>
    <ValidationSummary></ValidationSummary>
    <div class="modal-body">
      <InputTextComponent Value="data.Name"/>
    </div>
    <div class="modal-footer justify-content-between">
        <button type="button" >Cancel</button>
        <button type="submit" class="btn btn-primary">OK</button>
       
    </div>
</EditForm>
@code{
    public class Item
    {
        public string Name { get; set; } = string.Empty;
    }
    private Item data { get; set; } = new Item(){ Name="John"};
    private void OnClickBtn()
    {
        string k = "";
    }
}

When I run, it show :

then i edit the name field. and press "ok" button.

enter image description here

How to pass @bind-value into component. (the same InputText on blazor component).
Thanks all!!

like image 952
Nguyễn Văn Huy Avatar asked Jan 27 '26 16:01

Nguyễn Văn Huy


2 Answers

To achieve this you can manually implement the Change event in your child component InputTextComponent. The parameter is called Value, so you would need to implement an EventCallback with the name ValueChanged.

Your InputTextComponent would need to look like this:

<div class="form-group">
    <label for="Name">Name</label>
    <InputText @oninput="updateParent" @bind-Value="@Value"/>
</div>

@code {
    [Parameter]
    public string Value { get; set; }
    [Parameter]
    public EventCallback<string> ValueChanged { get; set; }

    async void updateParent(ChangeEventArgs e)
    {
        ValueChanged.InvokeAsync(e.Value.ToString());
    }
}

And then you can use @bind-Value in the parent component like <InputTextComponent @bind-Value="data.Name"/>

Here is a blazor repl showing the full thing.

like image 156
Axekan Avatar answered Jan 30 '26 06:01

Axekan


Here's another way to do it.

I've added a bit of functionality to show you how to build out a classic Bootstrap control.

@inherits InputText

<div class="form-group">
    <label class="form-label">@this.Label</label>
    @inputControl
    <div class="form-text">@this.Commentary</div>
</div>

@code {
    [Parameter] public string Label { get; set; }
    [Parameter] public string Commentary { get; set; }

    // Gets the underlying Renderfragment built by InputText
    private RenderFragment inputControl => (builder) => base.BuildRenderTree(builder);
}

And a demo page.

@page "/"

<PageTitle>Index</PageTitle>

<h1>Test Page</h1>

<EditForm Model=this.model>
    <MyInputText class="form-control" Label="Value" Commentary="Enter a value" @bind-Value=model.Value />
</EditForm>

<div class="alert alert-info mt-3">
    Value : @model.Value
</div>

@code {
    private ModelData model = new();

    public class ModelData {
        public string? Value { get; set; }
    }
}

As the other answer showed binding to oninput you can implement that like this. The above component would then inherit from BlazrInputText.

public class BlazrInputText : InputText
{
    [Parameter] public bool BindOnInput { get; set; } = true;

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        builder.OpenElement(0, "input");
        builder.AddMultipleAttributes(1, AdditionalAttributes);

        if (!string.IsNullOrWhiteSpace(this.CssClass))
            builder.AddAttribute(2, "class", CssClass);

        builder.AddAttribute(3, "value", BindConverter.FormatValue(CurrentValueAsString));

        if (BindOnInput)
            builder.AddAttribute(4, "oninput", EventCallback.Factory.CreateBinder<string?>(this, __value => CurrentValueAsString = __value, CurrentValueAsString));
        else
            builder.AddAttribute(5, "onchange", EventCallback.Factory.CreateBinder<string?>(this, __value => CurrentValueAsString = __value, CurrentValueAsString));

        builder.AddElementReferenceCapture(6, __inputReference => Element = __inputReference);
        builder.CloseElement();
    }
}
like image 39
MrC aka Shaun Curtis Avatar answered Jan 30 '26 04:01

MrC aka Shaun Curtis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!