Search code examples
javascriptblazoronchange

How do you get "onchange" behavior in Blazor pages w/o JavaScript?


I'm currently building an business page for requesting funding for various departments. Depending on the amounts populated and their values I need to populate, in real time, the awarded amount. I know how to do this with JavaScript, but I want to do this the right way in Blazor with the @bind properties and my razor.cs file, but whenever I try to do @onchange with my methods I get a nasty error:

Severity Code Description Project File Line Suppression State Error (active) RZ10008 The attribute 'onchange' is used two or more times for this element. Attributes must be unique (case-insensitive). The attribute 'onchange' is used by the '@bind-value' directive attribute.

I have attempted other ways of doing this as well. For example the code sample below tries to use just value=@BoardApprovedAmt which is a property in the pages controller, and while the onchange event doesn't throw the error, it never fires the HandleInputChange() method.

        <hr />
            <div class="row">
                <div class="col-sm-4 col-md-4">
                    <label for="ceoApprAmount" class="form-label">CEO Approved Amount</label>
                <input @bind-value="@CeoApprovedAmt" type="text" pattern="-?\d+(\.\d{1,2})?" class="form-control form-control-sm" id="ceoApprAmount" />
                </div>
                <div class="col-sm-4 col-md-4">
                    <label for="boardApprAmount" class="form-label">Board Approved Amount</label>
                <input value="@BoardApprovedAmt" onchange="HandleInputChange()" type="text" pattern="-?\d+(\.\d{1,2})?" class="form-control form-control-sm" id="boardApprAmount" />
                </div>

                <div class="col-sm-4 col-md-4">
                    <label for="awardedAmount" class="form-label">Awarded Amount</label>
                    <input value="@SourceInput" type="text" pattern="-?\d+(\.\d{1,2})?" class="form-control form-control-sm" id="awardedAmount" />
                </div>
            </div>
            <div class="row">
                <div class="col-sm-4 col-md-4">
                    <label for="requestedAmount" class="form-label">Requested Amount</label>
                    <input @bind-value="@RequestedAmt"type="text" pattern="-?\d+(\.\d{1,2})?" class="form-control form-control-sm" id="requestedAmount" />
                </div>
                <div class="col-sm-4 col-md-4">
                    <label for="directorApprAmount" class="form-label">Director Approved Amount</label>
                    <input @bind-value="@DirectorApprAmt" type="text" pattern="-?\d+(\.\d{1,2})?" class="form-control form-control-sm" id="directorApprAmount" />
                </div>
            </div>````

Solution

  • I figured it out. You have to handle the bind:event.

    
    @page "/bind-event"
    
    <p>
        <label > Input 1</label>
        <input @bind="InputValue" @bind:event="oninput" @onchange="Calculate"/>
        <label> Input 2</label>
        <input @bind="InputValue2" @bind:event="oninput" @onchange="Calculate"/>
        <label> Input 3</label>
        <input @bind="InputValue3" @bind:event="oninput" @onchange="Calculate"/>
    </p>
    
    <p>
        <code>InputValue</code>: @InputValue
    </p>
    
    <p>
        <code>OutputValue</code>: @TotalValue
    </p>
    
    @code {
        private string? InputValue { get; set; }
        private string? InputValue2 { get;  set; }
        private string? InputValue3 { get;  set; }
        private decimal? TotalValue { get; set; }
    
        private void Calculate()
        {
            TotalValue = Convert.ToDecimal(InputValue) + Convert.ToDecimal(InputValue2) + Convert.ToDecimal(InputValue3); 
    
            
        }