0

So i have 2 date boxes on a pop up and the second date box is linked to the first where when you select a date in the first the second will show a date 1 month in the future then you can up a duration from a drop down and the second date should continue to change. now i wanted to break that out into some custom components to keep diffrent pages feeling consistant so i tried breaking the whole control into a custom control as shown bellow

@using Microsoft.AspNetCore.Components.Forms

<div class="@MainClass">
    <div class="d-flex align-items-center">
        <label class="me-2" style="width: 150px;">@ChildContent</label>
        <div class="flex-grow-1 d-flex align-items-center">
            <div class="input-group">
                <InputDate @bind-Value="Value" class="form-control" placeholder="d/M/yy" disabled="@Disabled" />
            </div>
            @if (!string.IsNullOrWhiteSpace(ToolTipText))
            {
                <ToolTipInfo>@ToolTipText</ToolTipInfo>
            }
        </div>
    </div>
    @if (!string.IsNullOrWhiteSpace(HelpTextText))
    {
        <HelpText>If this is empty the repayment plan is still ongoing.</HelpText>
    }
</div>

@code {
    [Parameter] public string? Mb { get; set; } = "3";
    [Parameter] public RenderFragment ChildContent { get; set; } = default!;
    [Parameter] public DateTime Value { get; set; }
    [Parameter] public bool Disabled { get; set; } = false;
    [Parameter] public string? HelpTextText { get; set; }
    [Parameter] public string? ToolTipText { get; set; }
    [Parameter] public EventCallback<DateTime> ValueChanged { get; set; }

    private string MainClass => $"mb-{Mb}";

    async Task UpdateValue()
    {
        
        await ValueChanged.InvokeAsync(Value);
    }
}

But now when i implement it when i change the first date the second date dose not change

Iv tried loads of changes to the binding but nothing seams to make the second date change

1
  • UpdateValue is never called in the code you are showing. Commented Oct 16 at 15:13

2 Answers 2

0

The basic pattern for wrapping an <Input... /> control is

<div>
    <InputDate placeholder="dd-MM-yy"
        Value="Value" 
        ValueExpression="() => Value" 
        ValueChanged="ValueChanged"  />
</div>

@code {

    [Parameter] public DateTime Value { get; set; }
    [Parameter] public EventCallback<DateTime> ValueChanged { get; set; }
}

Note that Value will (should) only be set by the parent component. Never assign to your parameters.

Sign up to request clarification or add additional context in comments.

Comments

0

Henk Holterman's answer is one way of doing it.

You can also extend the standard InputBase controls. Here's an example of one of mine:

@inherits InputText
@if (_noColumn)
{
    @_mainContent
}
else
{
    <div class="@this.ColumnCss">
        @_mainContent
    </div>
}

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

    private bool _noColumn => this.ColumnCss is null;
    private string _label => this.Label ?? EditControlHelper.GetLabel(this.ValueExpression);

    // get property to get the render fragment built by the base class
    private RenderFragment _baseContent => builder => base.BuildRenderTree(builder);

    private RenderFragment _mainContent => __builder =>
    {
        <label class="form-label-sm small">@_label</label>

        @_baseContent

        <ValidationMessage [email protected] />
    };
}

And if you need to add functionality to the InputText you can do something like this:

@inherits InputText

@if (UpdateOnInput)
{
    <input class="@this.CssClass"
           type="text"
           value="@this.CurrentValueAsString"
           @oninput="this.OnChange"
           @attributes=this.AdditionalAttributes
           @ref=this.Element />
}
else
{
    <input class="@this.CssClass"
           type="text"
           value="@this.CurrentValueAsString"
           @onchange="this.OnChange"
           @attributes=this.AdditionalAttributes
           @ref=this.Element />
}

@code {
    [Parameter] public bool UpdateOnInput { get; set; }
    [Parameter] public bool SetFirstFocus { get; set; }

    protected Task OnChange(ChangeEventArgs e)
    {
        this.CurrentValueAsString = e.Value?.ToString() ?? null;
        return Task.CompletedTask;
    }

    protected async override Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender && this.SetFirstFocus && this.Element is not null)
            await this.Element.Value.FocusAsync();
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.