Search code examples
javascriptasp.netvalidationdatepicker

Validate input data from a DropDown depending of a DatePicker on another PartialView


I have some trouble with my ASP.NET MVC project.

I'm trying to check if the choice selected by a user in a DropDown is valid. This depends entirely of a date (chosen by the user) on another tab.

I have my OfferController which renders FormView (with Offer as a model). FormView contains 2 or 3 tabs, each one being a PartialView with it's own model.

I want to check a DateTime value entered on the first tab (VehicleView with VehicleDetails as model) to send an error message if needed on the second tab (WarrantyView with Warranty as model). This message has to be shown immediately when the user selects an incorrect item in the DropDown.

The model Offer contains both VehicleDetails and Warranty.

Others validations (using annotations) are working fine.

I've tried creating a CustomValidator as explained here but I couldn't get the updated value for the date from VehicleDetails.

I also tried to write some JavaScript, but as I've never done that before, I couldn't get far.

The date from the first tab:

@*[...]*@    
<div class='form-group'>
<div class="col-md-6">
    @Html.LabelFor(model => model.FirstImmatriculationDate)
</div>
<div class="col-md-6">
    <div>
        <div class="input-group" style="width: 148px;">
            <input class="form-control date-picker" type="text" data-date-format="dd/mm/yyyy" name="FirstImmatriculationDate" id="FirstImmatriculationDate" value="@Model.FormattedFirstImmat">
            <span class="input-group-addon">
                <i class="fa fa-calendar"></i>
            </span>
            @Html.ValidationMessageFor(model => model.FirstImmatriculationDate, "", new { @class = "text-danger" })
        </div>
    </div>
    <span id="error_msgFirstImmat" class="text-danger"> @Resources.VehicleDetails_FirstImmatError</span>
    <span id="error_msgFirstImmatTooOld" class="text-danger"> @Resources.VehicleDetails_FirstImmatTooOld</span>
    <span id="error_msgFirstImmatFormatDate" class="text-danger"> @Resources.General_FormatDate</span>
</div>
</div>
@*[...]*@

The DropDown on the second tab (on which the data validation must be done):

@*[...]*@
<div class='form-group'>
<div class="col-md-6">
    @Html.LabelFor(model => model.Omnium_InnerNrDeductibleFormula)
</div>
<div class="col-md-6">
    @Html.DropDownListFor(model => model.Omnium_InnerNrDeductibleFormula, (SelectListItem[])ViewBag.lstFormulaDeduc, new { @id = "Omnium_InnerNrDeductibleFormulaId" })
    @Html.ValidationMessageFor(model => model.Omnium_InnerNrDeductibleFormula, "", new { @class = "text-danger" })
    <span id="error_MisingFormula" class="text-danger">@Resources.Warranty_FormulaMissing</span>
</div>
</div>
@*[...]*@

The code from the Forms view calling the two partial views

@*[...]*@
<div id="vehicleQuote" class="tab-pane in active">
<p>@Html.EditorFor(model => model.VehicleDetails)</p>
<a href="#" id="btnWarrantiesPage" class="btn  btn-group-lg" title="@Resources.Warranty_NextPage" style="margin-left:61%">
    <i class="btn-label glyphicon glyphicon-arrow-right"></i>
    @Resources.Warranty_NextPage
</a>
</div>
<div id="warrantyQuote" class="tab-pane">
    <p>@Html.EditorFor(model => model.Warranty)</p>
</div>
@{
    if (Model.ResultsModel != null)
    {
        if (Model.ResultsModel.RC != null || Model.ResultsModel.errorMsg != null)
        {
            <div id="resultQuote" class="tab-pane in active">
                <p>@Html.EditorFor(model => model.ResultsModel)</p>
            </div>
        }
    }
}

<div id="submitQuote">
    <div style="margin-left:61%">

        <button type="submit" id="btnSave" name="BtnSave" class="btn btn-palegreen" value="@Resources.General_Save">
            <i class="btn-label glyphicon glyphicon-saved"></i>
            @Resources.General_Save
        </button>
        <button type="submit" id="btnTaskTarification" name="btnTaskTarification" class="btn btn" value="@Resources.General_Save">
            <i class="btn-label glyphicon glyphicon-print"></i>
            @Resources.General_Print
        </button>
    </div>
    <a href="@Url.Action("Index", "Customers")" class="btn  btn-group-lg" title="@Resources.General_Cancel" style="margin-left:10px;">
        <i class="btn-label glyphicon glyphicon-arrow-left"></i>
        @Resources.General_Cancel
    </a>
</div>
@*[...]*@

The part of the model used for the DatePicker

public class VehicleDetails
{        
    [Display(Name = "VehicleDetails_FirstImmatriculationDate", ResourceType = typeof(Resources.Resources))]
    public DateTime? FirstImmatriculationDate { get; set; }
    //[...]
}

The part of the model used for the item selected in the DropDown

public class Warranty
{
    [Display(Name = "Warranty_Omnium_InnerNrDeductibleFormula", ResourceType = typeof(Resources.Resources))]
    public string Omnium_InnerNrDeductibleFormula { get; set; }
    //[...]
}

Solution

  • Is it okay for you to use jQuery?

    If it is, you can simply listen to the change event of your dropdown, and check the date of your other input.

    $('#Omnium_InnerNrDeductibleFormulaId').change(function(){
    
        var date = $('#FirstImmatriculationDate').val();
    
        // do whatever you want with the date value, and display an error message if necessary.
    
        // for example, you could put an hidden message in your DOM
        // and show/hide it depending on the result of your test :
        if(isValid(date)){
            $('#warning-message').hide();
        }
        else{
            $('#warning-message').show();
        }
    }