0

I have a custom InputDate control in blazor that works fine but when I run my pp I get 01/01/0001 instead of dd/mm/yyyy.

I want to set dd/mm/yyyy if I don't set the time to NOW

if I use InputDate as normal it works fine and shows me dd/mm/yyyy but in the custom control I get some errors

here is my model:

  public class Quote
    {
        [Required(ErrorMessage = "Quote Date is a required field.")]              
        public DateTime? QuoteDate { get; set; }
    }

and the Customs Control:

@using System.Linq.Expressions

@inherits InputBase<DateTime>


     <div class=@ColumnLocation>
          @if (!string.IsNullOrWhiteSpace(Label))
            {              
                <label for="@Id">@Label</label>
            }                   
           <InputDate @bind-Value="@CurrentValue" class="form-control" placeholder="Enter date of preference"></InputDate>
           <ValidationMessage For="@ValidationFor" />
     </div>

@code {

    [Parameter] public string Id { get; set; }
    [Parameter] public string Label { get; set; }
    [Parameter] public Expression<Func<DateTime>> ValidationFor { get; set; }

    protected override bool TryParseValueFromString(string value, out DateTime result, out string validationErrorMessage)
    {
        result = DateTime.Parse(value);
        validationErrorMessage = null;
        return true;
    }
}

and the page:

@page "/counter"

   <EditForm Model="quote" OnValidSubmit="@SubmitButtonPressed" class="form-horizontal">
                    <DataAnnotationsValidator />

               
       @*for this custom control I've had some errors*@
           <UxInputDate Label="Quote Date3" @bind-Value="quote.QuoteDate" 
                                               ValidationFor="@(() => quote.QuoteDate)"/>                         
        @*for this normal control everything is fine*@
               <InputDate @bind-Value="quote.QuoteDate" class="form-control" ></InputDate>
                  

         <button type="submit" class="btn">Check 1</button>          
   </EditForm>
@code {
  
    Quote quote = new Quote();
    protected void SubmitButtonPressed()
    {
        ....
    }
}

errors:

cannot convert from 'Microsoft.AspNetCore.Components.EventCallback<System.DateTime?>' to 'Microsoft.AspNetCore.Components.EventCallback'

Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type

Cannot implicitly convert type 'System.DateTime?' to 'System.DateTime'. An explicit conversion exists (are you missing a cast?)

Ali
  • 300
  • 4
  • 11

1 Answers1

1

You're wrapping an InputBase within an InputBase which is a bit convoluted. Wrapping any InputBase control within another component with passthrough requires a little more code than you've implemented. There is a simpler way to create a generic wrapper control for an input with label and validation message.

@using System.Linq.Expressions
@typeparam TValue

<div class="m-2 p-2">
    @if (!string.IsNullOrWhiteSpace(Label))
    {
        <label for="@Id">@Label</label>
    }
    @ChildContent
    <ValidationMessage For="@ValidationFor" />
</div>

@code {
    [Parameter] public string Id { get; set; }
    [Parameter] public string Label { get; set; }
    [Parameter] public Expression<Func<TValue>> ValidationFor { get; set; }
    [Parameter] public RenderFragment ChildContent { get; set; }
}

Then implemented like this:

 <CompositeInputControl Label="String" ValidationFor="() => _model.SelectValue">
     <input @bind-value="_model.SelectValue" />
 </CompositeInputControl>
 
<CompositeInputControl Label="Date" ValidationFor="() => _model.Time">
       <InputDate @bind-Value="_model.Time"></InputDate>
 </CompositeInputControl>

If you want a more complex solution here's a screen shot of one of mine.

enter image description here I can point you to the repo code.

MrC aka Shaun Curtis
  • 19,075
  • 3
  • 13
  • 31
  • Thanks for your solution, but I have a css class that I'm using for my controls (class="form-control"), in your solution I have to add it to the child control each time I want to use this control like : , the purpose is reducing the code and I don't want to add this CSS class in all of my controls – Ali Nov 04 '21 at 00:36
  • Yes please, complex should be ok for me as well – Ali Nov 04 '21 at 09:01
  • is rendering here "[Parameter] public RenderFragment ChildContent { get; set; }" effect the performance? is I have a big app with 100 or more forms is it a good way to use this way of component creation? – Ali Nov 04 '21 at 09:31
  • See here for my composite control - https://github.com/ShaunCurtis/Blazor.Database/blob/master/Blazr.UIComponents/Components/FormBuilders/BaseFormEditControl.cs. The whole project/repo reflects my current development methodology. With 100 or more forms I would get all of my markup, functionality and css into components, and only use only components in the forms. You can see that principle applied in the repo to the WeatherForecast forms - https://github.com/ShaunCurtis/Blazor.Database/blob/master/Blazr.Database.UI/Forms/WeatherForecast/WeatherForecastEditorForm.razor – MrC aka Shaun Curtis Nov 05 '21 at 16:52