Click here to Skip to main content
16,020,741 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am using bootstrap modal form calling a partialview from Index.cshtml.
It's work fine until I use Select2. The same partialview working fine without Select2. The same Select2 also working fine with the same partialview.

But problem is that when using all things like bootstrap,partialview and Select2, model validation not working.

What I have tried:

HTML
<pre> src="/lib/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<!--For modal form-->
<div id="modal-placeholder"></div>
<div class="modal fade" id="customer_model" tabindex="-1" role="dialog" aria-labelledby="customer_modelLabel"
     data-bs-backdrop="static" data-bs-keyboard="true" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" id="movableDialog" role="document">
        <div class="modal-content" style="background-color: white; color: black; width:800px; margin-left: auto; margin-right: auto">
            <div class="modal-header" style="background-color: #337ab7; color: white; cursor: move">
                @{
                    if (ViewBag.action == "Edit")
                    { <h6 class="modal-title text-center" id="customer_modelLabel">Update Customer</h6> }
                    else if (ViewBag.action == "Delete")
                    { <h6 class="modal-title" id="customer_modelLabel" style="color:darkorange">Shown Customer will be deleted.<br />Please confirm?</h6> }
                    else
                    { <h6 class="modal-title" id="customer_modelLabel" style="text-align:center;">Create New Customer</h6> }
                }
                @*<h4 class="modal-title" id="rawmaterialLabel" style="text-align:center">Create Raw Material</h4>*@
                <button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true" style="color:darkred">×</span>
                </button>
            </div>
            <div class="modal-body">
                <form id="myForm" asp-action="Create" style="width:700px;">
                    <input name="IsValid" type="hidden" value="@ViewData.ModelState.IsValid.ToString()" />
                    <div class="form-group">
                        <div class="col-md-10">
                            <div class="form-inline" style="text-align:left;">
                                <label asp-for="CUST_CODE" class="control-label col-sm-4"></label>
                                <input asp-for="CUST_CODE" readonly class=" form-control col-md-4" style="color:darkgoldenrod; " />
                                <span asp-validation-for="CUST_CODE" class="text-danger"></span>
                            </div>
                            <div class="form-inline" style="margin-top:5px">
                                <label asp-for="CUST_NAME" class="control-label col-sm-4"></label>
                                <input asp-for="CUST_NAME" class=" form-control col-md-8" />
                                <span asp-validation-for="CUST_NAME" class="text-danger"></span>
                            </div>
                            <div class="form-inline" style="margin-top:5px">
                                <label asp-for="CUST_GROUP" class="control-label col-sm-4"></label>
                                <select asp-for="CUST_GROUP" style="width: 368px;" class="form-control col-md-8 select2-select" id="ddlCustGroup" name="CUST_GROUP" asp-items="@(new SelectList(ViewBag.CustGroup, "Value", "Text"))">
                                    <option value="">-Select Customer Group-</option>
                                </select>
                                <input type="hidden" name="CUST_GROUP" value="@Model.CUST_GROUP" />
                                <span asp-validation-for="CUST_GROUP" class="text-danger"></span>
                            </div>
          <div class="modal-footer">
                <button type="button" class="btn btn-danger" data-bs-dismiss="modal">Close</button>
                @{
                    if (ViewBag.action == "Delete")
                    {
                        <button type="button" class="btn btn-primary" data-bs-save="modal">Delete</button>
                    }
                    else
                    {
                        <button type="button" class="btn btn-primary" data-bs-save="modal">Save</button>
                    }
                }
            </div>
        </div>
    </div>
</div>
<link href="~/lib/select2/css/select2.css" rel="stylesheet" />
<script src="~/lib/select2/js/select2.js"></script>

<script type="text/javascript">

    //$('#myForm').removeData("validator");
    //$('#myForm').removeData("unobtrusiveValidation");
    //$.validator.unobtrusive.parse('#myForm');

    //$("#myForm").validate({
    //    rules: {
    //        ddlCustGroup: "required"
    //    },
    //    messages: {
    //        ddlCustGroup: "Please select your region"
    //    }

    //});

            $(document).ready(function () {
            $('#ddlCustGroup').select2({
                dropdownParent: $('.modal-body')
            });
            $('#ddlCustGroup').attr("required", "required");
            $("body").on("change", "#ddlCustGroup", function () {
                $("#ddlCustGroup > option").removeAttr("selected");
                // $("#ddlCustGroup").trigger("change");// Trigger change to select 2
                $("input[name=CUST_GROUP]").val($(this).find("option:selected").text());
                $(this).valid();
                $('#ddlCustGroup').attr("required", "required");
            });

            //----Customer Region

            $('#ddlCustomers').select2({
                dropdownParent: $('.modal-body')
            });
            $("body").on("change", "#ddlCustomers", function () {
                $("input[name=CUST_REGN]").val($(this).find("option:selected").text());
                $(this).valid();
            });

            //----Customer Sales Organization

            $('#ddlSalesOrg').select2({
                dropdownParent: $('.modal-body')
            });

            $("body").on("change", "#ddlSalesOrg", function () {
                $("input[name=SALES_ORG]").val($(this).find("option:selected").text());
                $(this).valid();
            });

            //----Customer Inco-Terms
            $('#ddlInco').select2({
                dropdownParent: $('.modal-body')
            });
            $("body").on("change", "#ddlInco", function () {
                $("input[name=INCO_TERMS]").val($(this).find("option:selected").text());
                $(this).valid();
            });

            //----Customer Bill Currency
            $('#ddlCurrency').select2({
                dropdownParent: $('.modal-body')
            });
            $("body").on("change", "#ddlCurrency", function () {
                $("input[name=BILL_CURCY]").val($(this).find("option:selected").text());
                $(this).valid();
            });
        });
</script>
Posted
Updated 13-May-23 0:27am
Comments
Richard Deeming 20-Jun-22 4:44am    
The first thing that jumps out at me is that you're adding the required attribute to the list in code, after applying Select2 to the list.

You need to mark the model property as [Required] instead. That way, the validation attributes will already be emitted in the rendered HTML, and you won't need to add them via Javascript.

Also, you're removing the selected attribute from all of the list options every time the list changes. The user will never be able to select anything from the list!
anil_kumar_bhakta 20-Jun-22 13:56pm    
The 'required' attrubute was added for testing. Without required it also behave the same.
In Model, it is already marked as required like below: -
...
[Display(Name = "CUST_GROUP")]
[Required(ErrorMessage = "Please enter Customer Group")]
[MaxLength(20)]
public string CUST_GROUP { get; set; }
...
"Also, you're removing the selected attribute from all of the list options every time the list changes. The user will never be able to select anything from the list!"
I think it is required when user select the option. If user select any of the listed item and again select the placeholder it is going to validadte. But my concern is that when user press 'save' button it must be validate. I also set the control break in my controller it goes and modelstate invalidated then it come back to partialview and validation message not displaying. However it works perfect without Select2.
anil_kumar_bhakta 20-Jun-22 14:05pm    
Console responses are as below: -
....
System.ArgumentNullException: Value cannot be null. (Parameter 'items')
at Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList..ctor(IEnumerable items, String dataValueField, String dataTextField, IEnumerable selectedValues, String dataGroupField)
at Microsoft.AspNetCore.Mvc.Rendering.SelectList..ctor(IEnumerable items, String dataValueField, String dataTextField, Object selectedValue)
at Microsoft.AspNetCore.Mvc.Rendering.SelectList..ctor(IEnumerable items, String dataValueField, String dataTextField)
at CallSite.Target(Closure , CallSite , Type , Object , String , String )
at IDESK.Models.CustomerMaster.Views_CustomerMaster__Customer.<executeasync>b__38_6() in D:\OCCL\IDESK\IDESK\Views\CustomerMaster\_Customer.cshtml:line 58
at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.GetChildContentAsync(Boolean useCachedResult, HtmlEncoder encoder)
at Microsoft.AspNetCore.Mvc.TagHelpers.RenderAtEndOfFormTagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.<runasync>g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, Int32 i, Int32 count)
at IDESK.Models.CustomerMaster.Views_CustomerMaster__Customer.ExecuteAsync() in D:\OCCL\IDESK\IDESK\Views\CustomerMaster\_Customer.cshtml:line 32
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode)
at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode)
at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ActionContext actionContext, IView view, ViewDataDictionary viewData, ITempDataDictionary tempData, String contentType, Nullable`1 statusCode)
at Microsoft.AspNetCore.Mvc.ViewFeatures.PartialViewResultExecutor.ExecuteAsync(ActionContext context, PartialViewResult result)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<invokenextresultfilterasync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<invokenextresourcefilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<invokeasync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext

1 solution

This code you can used in MultiModal form in one page .




//On load content
if ($('.select').length > 0) {
$(".select").select2({
minimumResultsForSearch: -1,
width: '100%'
});
}
//Fix select2 if click on modal edit
$('.edit-icon').on('click', function () {
var modal = $(this).attr('data-bs-target');
$(".select").select2({
minimumResultsForSearch: -1,
width: '100%',
dropdownParent: $(modal)
});
});
//when close Modal return to default
$('.close').on('click', function () {
$(".select").select2({
minimumResultsForSearch: -1,
width: '100%'
});
});
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900