Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blazor InputText call async Method when TextChanged

Tags:

blazor

I try to capture text changes of InputText in Blazor (ServerSide) and then call a async method to check if input is correct coupon code or not.

HTML:

<EditForm Model="@Basket" OnValidSubmit="@CommitBasket">
    Gutscheincode
    <InputText class="coupon-input checkout-control pristine untouched" 
            @bind-Value="CouponCode"
            @onchange="CouponCodeChanged">
    </InputText>
    @CouponText
</EditForm>`

But The CouponCodeChanged isn't raised - OnKeyUp is not useful because the Text Value isn't changed at that state...

here is C# Method:

public async Task CouponCodeChanged(ChangeEventArgs args)
{
    using var client = ClientFactory.CreateClient();
    var result = await ApiCalls.GetCouponCodeData(client, AppState.BaseUrl, 2, CouponCode);
    CouponText = result== null ? "NOT FOUND" : $"exists:{result.Exists} amount:{result.Amount}";
}

Has anyone a hint or idea how to solve that in a convinient way?

Thx!

like image 266
baer999 Avatar asked Jan 26 '23 13:01

baer999


2 Answers

InputText component doesn't have a onchange event but ValueChanged.
However, if you want to subscribe to this event you need to pass a ValueExpression and it's not easy. The easiest I found to subscribe to this event is to override the InputText component.

CouponComponent.razor

@inherits InputText
<InputText class="coupon-input checkout-control pristine untouched" 
                   ValueExpression="ValueExpression" Value="@Value" ValueChanged="OnValueChanged" />
@code {
  [Parameter]
  public EventCallback<string> CouponValueChanged { get; set; }

  private async Task OnValueChanged(string value)
  {
     await ValueChanged.InvokeAsync(value);
     using var client = ClientFactory.CreateClient();
     var result = await ApiCalls.GetCouponCodeData(client, AppState.BaseUrl, 2, CouponCode);
     var coupon = result == null ? "NOT FOUND" : $"exists:{result.Exists} amount:{result.Amount}"
     await CouponValueChanged.InvokeAsync(coupon);
  }
}

Usage

<EditForm Model="@Basket" OnValidSubmit="@CommitBasket">
    Gutscheincode
    <CouponComponent @bind-Value="CouponCode"
        @CouponValueChanged="CouponCodeChanged">
    </InputText>
    @CouponText
</EditForm>

@code {
   private void CouponCodeChanged(string coupon)
   {
      CouponText = coupon;
      StateHasChanged();
   }
}
like image 175
agua from mars Avatar answered Feb 26 '23 22:02

agua from mars


This is working for me...

@using System.Linq.Expressions 

   <p>@Coupon Text: @CouponText</p>



    <EditForm Model="@basket" OnValidSubmit="@CommitBasket">
        Gutscheincode

            <InputText class="coupon-input checkout-control pristine untouched" Value="@basket.CouponCode" ValueChanged="@CouponCodeChanged" ValueExpression="@(() => basket.CouponCode)" />

    </EditForm>

    @code {
        private Basket basket = new Basket();
        private string CouponText;

        private string _value { get; set; }
        [Parameter]
        public string Value
        {
            get { return _value; }
            set
            {
                if (_value != value)
                {
                    _value = value;
                    if (ValueChanged.HasDelegate)
                    {
                        ValueChanged.InvokeAsync(value);
                    }
                }


            }
        }

        [Parameter] public EventCallback<string> ValueChanged { get; set; }
        [Parameter] public Expression<Func<string>> ValueExpression { get; set; }


        private void CouponCodeChanged(string CouponCode)
        {
            basket.CouponCode = CouponCode;
            CouponText =  basket.CouponCode;
        }

        private void CommitBasket()
        { }

        public class Basket
        {
            public Basket() { }
            public string CouponCode { get; set; } = "12345";
            public string CouponName { get; set; } = "Coupon Name";

        }
    }

You can also do it with the KeyUp event:

<InputText Id="CouponCode" Class="form-control" @bind-Value="@basket.CouponCode" @onkeyup='@(e => KeyUp(e, "CouponCode"))'></InputText>


@code {
    private EditContext EditContext;
    private Basket basket = new Basket();

     protected override void OnInitialized()
    {
        EditContext = new EditContext(basket);
        base.OnInitialized();
    }

    void KeyUp(KeyboardEventArgs e, string memberName)
    {
        var property = basket.GetType().GetProperty(memberName);
        var value = property.GetValue(basket);

        // Requires some tweaks to prevent unwanted stuff...
        property.SetValue(basket, value + e.Key);

        var id = EditContext.Field(memberName);


        EditContext.NotifyFieldChanged(id);
        property = basket.GetType().GetProperty(memberName);

        CouponText = property.GetValue(basket).ToString();

    }
}
like image 21
enet Avatar answered Feb 26 '23 23:02

enet