I am using partialview in modal form. In this form there is a select2 option list which working fine. But when press submit button, required fields as per model are not validating i.e. not showing error.
I have used lots option from internet, but failed to get the desired result.
When we remove the select2 field from partialview, it's working fine.
Cust_Mast.cs Model
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace IDESK.Models.Customer
{
public class Cust_Master
{
[Key]
[Display(Name = "CUST_CODE")]
[Required(ErrorMessage = "Please enter Customer Code")]
public int CUST_CODE { get; set; }
[Display(Name = "CUST_NAME")]
[Required(ErrorMessage = "Please enter Customer Name")]
[MaxLength(50)]
public string CUST_NAME { get; set; }
[Display(Name = "CUST_REGN")]
[Required(ErrorMessage = "Please enter Customer Regn")]
[MaxLength(20)]
public string CUST_REGN { get; set; }
[Display(Name = "SALES_ORG")]
[Required(ErrorMessage = "Please enter Customer Sales Orgn.")]
[MaxLength(20)]
public string SALES_ORG { get; set; }
[Display(Name = "CUST_GROUP")]
[Required(ErrorMessage = "Please enter Customer Customer Group")]
[MaxLength(20)]
public string CUST_GROUP { get; set; }
[Display(Name = "INCO_TERMs")]
[Required(ErrorMessage = "Please enter Inco Term")]
[MaxLength(5)]
public string INCO_TERMS { get; set; }
[Display(Name = "BILL_CURRENCY")]
[Required(ErrorMessage = "Please enter Bill Currency")]
[MaxLength(5)]
public string BILL_CURCY { get; set; }
[Display(Name = "Is Pallet?")]
public bool IsPallet { get; set; }
}
}
Index.cshtml
@model IEnumerable<IDESK.Models.Customer.Cust_Master>
<!DOCTYPE html>
@*<div id="notification"></div>*@
<div id="modal-placeholder"></div>
@Html.AntiForgeryToken()
<body >
<div >
<h4 style="color:indigo">Customer Master Index</h4>
<form method="post" enctype="multipart/form-data" asp-action="UploadFileData">
<button type="button" data-bs-toggle="ajax-modal" data-bs-target="#customer_model"
data-url="@Url.Action("Create",new {Model })">
<i ></i>
Create
</button>
<input type="submit" id="thisbutton" value="Upload data" />
@{
<!--accept="csv/CSV"-->
if (TempData["upload"] == "OK")
{
@Html.ActionLink("Save List", "SaveList", new { action = "SaveList" }, new { @class = "btn btn-secondary small" })
}
}
<div>
<input type="file" id="fileName" name="fileName" accept="Text/CSV" title="Select a file" style="margin-top:5px" />
</div>
</form>
@{
if (TempData["Message"] != null)
{
<div >
<div >
<div >
@Html.Raw(TempData["Alert"])
</div>
</div>
</div>
}
}
@await Html.PartialAsync("_tblCustomer", Model)
</div>
</body>
@section Scripts {
@*<script src="~/lib/jquery/jquery.min.js"></script>*@
<script src="~/lib/jquery-validation/dist/validate.min.js"></script>
<script src="/lib/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<partial name="_ValidationScriptsPartial" />
<script type="text/javascript">
$('body').on('shown.bs.modal', '.modal', function () {
$(this).find('select').each(function () {
var dropdownParent = $(document.body);
if ($(this).parents('.modal.in:first').length !== 0)
dropdownParent = $(this).parents('.modal.in:first');
$(this).select2({
dropdownParent: $('#customer_model'), //dropdownParent
});
//$("select").on("select2:close", function (e) { //---this for all
$("#ddlCustGroup").on("select2:close", function (e) { //---this for specific.
//$(this).valid();
$(this).trigger('blur');
});
$('#customer_model').validate({
ignore: null
});
$select.rules('add', 'required');
});
});
@* $(document).ready(function () {
$('button').click(function () {
// $(this).valid();
//if ($(this).valid())
$('.modal-header').load('@Url.Action("ShowMsg")');
// $('.modal-title').append("<div class='alert alert-success alert-dismissable'><button type='button' class='close' data-bs-dismiss='alert' aria-hidden='true'>×</button>Success</div>")
//else
// $('.modal-body').append("<div class='alert alert-danger alert-dismissable'><button type='button' class='close' data-bs-dismiss='alert' aria-hidden='true'>×</button>Failed</div>")
})
});*@
$.validator.unobtrusive.parse('#myForm');
</script>
}
_Customer.cshtml --partialview.
@model IDESK.Models.Customer.Cust_Master;
@{
Layout = null;
}
<link href="~/lib/select2/css/select2.css" rel="stylesheet" />
<script src="~/lib/select2/js/select2.js"></script>
<script src="~/lib/jquery-validation/dist/validate.min.js"></script>
<script src="/lib/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<script src="~/lib/twitter-bootstrap/js/bootstrap.js"></script> <!--For modal form-->
@*https://softdevpractice.com/blog/asp-net-core-mvc-ajax-modals/*@
@Html.AntiForgeryToken()
<div id="modal-placeholder"></div>
<div id="customer_model" tabindex="-1" role="dialog" aria-labelledby="customer_modelLabel"
data-bs-backdrop="static" data-bs-keyboard="false" aria-hidden="true">
<div id="movableDialog" role="document">
<div style="background-color: white; color: black; width: 600px; margin-left: auto; margin-right: auto">
<div style="background-color: #337ab7; color: white; cursor: move">
@{
if (ViewBag.action == "Edit")
{ <h6 id="customer_modelLabel">Update Raw Material</h6> }
else if (ViewBag.action == "Delete")
{ <h6 id="customer_modelLabel" style="color:darkorange">Shown Material will be deleted.<br />Please confirm?</h6> }
else
{ <h6 id="customer_modelLabel" style="text-align:center;">Create Raw Material</h6> }
}
@*<h4 id="rawmaterialLabel" style="text-align:center">Create Raw Material</h4>*@
<button type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true" style="color:darkred">×</span>
</button>
</div>
<div >
<form asp-action="Create" id="myForm">
<input name="IsValid" type="hidden" value="@ViewData.ModelState.IsValid.ToString()" />
<div >
<div >
<div >
<label asp-for="CUST_CODE" ></label>
<input asp-for="CUST_CODE" readonly style="color:darkgoldenrod;" />
<span asp-validation-for="CUST_CODE" ></span>
</div>
<div style="margin-top:5px">
<label asp-for="CUST_NAME" ></label>
<input asp-for="CUST_NAME" />
<span asp-validation-for="CUST_NAME" ></span>
</div>
<div style="margin-top:5px">
<label asp-for="CUST_GROUP" ></label>
<select asp-for="CUST_GROUP" 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" ></span>
</div>
<div style="margin-top:5px">
<label asp-for="CUST_REGN" ></label>
<input asp-for="CUST_REGN" />
<span asp-validation-for="CUST_REGN" ></span>
</div>
</div>
</div>
@{
if (ViewBag.action == "Edit")
{
<div >
<div >
@*<input type="submit" value="Save" />*@
<input type="hidden" name="action" value="Edit" />
<input type="hidden" name="id" value="@Model.CUST_CODE" />
@*<span><a asp-action="Index" >Back to List</a> </span>*@
</div>
</div>
}
else if (ViewBag.action == "Delete")
{
<div >
<div >
@*<input type="submit" value="Delete" />*@
<input type="hidden" name="action" value="Delete" />
<input type="hidden" name="id" value="@Model.CUST_CODE" />
@*<span><a asp-action="Index" >Back to List</a> </span>*@
</div>
</div>
}
else
{
<div >
<div >
@*<input type="submit" value="Create" />*@
<input type="hidden" name="action" value="Create" />
@*<span><a asp-action="Index" >Back to List</a> </span>*@
</div>
</div>
}
}
</form>
</div>
<div >
<button type="button" data-bs-dismiss="modal">Close</button>
@{
if (ViewBag.action == "Delete")
{
<button type="button" data-bs-save="modal">Delete</button>
}
else
{
<button type="button" data-bs-save="modal">Save</button>
}
}
</div>
</div>
</div>
</div>
<script type="text/javascript">
$('#customer_model').bind("viewtransfer", function () {
$('#myForm').removeData('validator');
$('#myForm').removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse('#myForm');
});
//$("#myForm").removeData("validator")
// .removeData("unobtrusiveValidation")
// .off("submit.validate click.validate focusin.validate focusout.validate keyup.validate invalid-form.validate");
//$.validator.unobtrusive.parse("#myForm");
</script>
---Site.js----
//const { Alert } = require("./lib/twitter-bootstrap/js/bootstrap.esm.js");
// Write your JavaScript code.
$(function () {
var placeholderElement = $('#modal-placeholder');
$.validator.setDefaults({
ignore: ""
});
//$('button[data-bs-toggle="ajax-modal"]').click(function (event) {
$(document).on('click', 'button[data-bs-toggle="ajax-modal"]', function (event) {
var url = $(this).data('url');
$.get(url).done(function (data) {
placeholderElement.html(data);
placeholderElement.find('.modal').modal('show');
});
});
placeholderElement.on('click', '[data-bs-save="modal"]', function (event) {
event.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var dataToSend = form.serialize();
$.post(actionUrl, dataToSend).done(function (data) {
var newBody = $('.modal-body', data);
placeholderElement.find('.modal-body').replaceWith(newBody);
var isValid = newBody.find('[name="IsValid"]').val() == 'True';
if (isValid) {
//$('#notification').text('Data saved successfully!');
//location.reload();
//placeholderElement.find('.modal').modal('hide');
var tableElement = $('#tblName');
var tableUrl = tableElement.data('url');
$.get(tableUrl).done(function (table) {
tableElement.replaceWith(table);
});
}
else {
// $('#notification').text('Data operation failed!');
placeholderElement.find('.modal').modal('show');
bootstrap.Alert();
}
bootstrap.Alert();
placeholderElement.find('.modal').modal('hide');
});
});
});
** CustomerMasterController.cs **
using IDESK.Models;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using IDESK.Models.Customer;
using Microsoft.EntityFrameworkCore;
using IDESK.Extensions.Alert;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Http;
using CsvHelper.Configuration;
using System.Globalization;
using System.IO;
using CsvHelper;
namespace IDESK.Controllers.Customer
{
public class CustomerMasterController : Controller
{
private readonly DbConn _dbConn;
public static List<Cust_Master> ItemList = new();
public SelectList Customers { get; set; }
public CustomerMasterController(DbConn _db)
{
_dbConn = _db;
}
public IActionResult Index()
{
try
{
var ListItem = _dbConn.CUST_MAST.ToList(); //--for single table
var isAjax = Request.Headers["X-Requested-With"] == "XMLHttpRequest";
if (isAjax)
{
return PartialView("_tblCustomer", ListItem);
}
// ModelState.Clear();
return View(ListItem);
}
catch (Exception ex)
{
return View();
}
}
[HttpGet]
public ActionResult Create(string action)
{
LoadDDL();
LoadIncoTerms();
LoadCurrency();
LoadCustGrop();
Cust_Master custmast = new Cust_Master();
return PartialView("_Customer", custmast);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Cust_Master collection, string action)
{
int result = 0;
try
{
if (ModelState.IsValid)
{
if (action == "Edit")
{
result = (int)(_dbConn.Entry(collection).State = EntityState.Modified);
await _dbConn.SaveChangesAsync();
ViewBag.action = "Edit";
TempData["Message"] = "Customer Master data Updated!";
TempData["Alert"] = CommonServices.CommonServices.ShowAlert(Alerts.Success, TempData["Message"].ToString());
return PartialView("_Customer", collection);
}
else if (action == "Create")
{
_dbConn.CUST_MAST.Add(collection);
result = (int)await _dbConn.SaveChangesAsync();
TempData["Message"] = "Customer Master data Created!";
ViewBag.action = "Create";
TempData["Alert"] = CommonServices.CommonServices.ShowAlert(Alerts.Success, TempData["Message"].ToString());
//ShowMsg();
LoadDDL();
LoadIncoTerms();
LoadCurrency();
LoadCustGrop();
return PartialView("_Customer", collection);
//return PartialView("Index", collection);
}
else if (action == "Delete")
{
result = (int)(_dbConn.Entry(collection).State = EntityState.Deleted);
await _dbConn.SaveChangesAsync();
ViewBag.action = "Delete";
TempData["Message"] = "Customer Master data Deleted!";
TempData["Alert"] = CommonServices.CommonServices.ShowAlert(Alerts.secondary, TempData["Message"].ToString());
}
if (result <= 0)
TempData["Alert"] = CommonServices.CommonServices.ShowAlert(Alerts.Danger, "Unknown error : Operation failed");
}
else
{
TempData["Message"] = "Operation failed! ...Invalid or Incomplete Data!";
TempData["Alert"] = CommonServices.CommonServices.ShowAlert(Alerts.Danger, TempData["Message"].ToString());
_dbConn.Entry(collection).State = EntityState.Detached;
// ShowMsg();
return PartialView("_Customer", collection);
// return RedirectToAction("Index");
//return PartialView("_AlertMsg");
}
_dbConn.Entry(collection).State = EntityState.Detached; //---Clears current state.
//return RedirectToAction("Index");
return PartialView("_Customer", collection);
//return PartialView("_tblPartial", collection);
}
catch (Exception ex)
{
TempData["Message"] = "Operation failed.\n" ex.ToString();
TempData["Alert"] = CommonServices.CommonServices.ShowAlert(Alerts.Danger, TempData["Message"].ToString());
//ModelState.Clear();
_dbConn.Entry(collection).State = EntityState.Detached; //---Clears current state.
return RedirectToAction("Index");
}
}
[HttpGet]
public ActionResult Edit(Cust_Master collection)
{
ViewBag.action = "Edit";
LoadDDL();
LoadIncoTerms();
LoadCurrency();
LoadCustGrop();
return PartialView("_Customer", collection);
}
public ActionResult ShowMsg()
{
return Content("Data added successfully");
}
public ActionResult Delete(Cust_Master collection)
{
ViewBag.action = "Delete";
LoadDDL();
LoadIncoTerms();
LoadCurrency();
LoadCustGrop();
return PartialView("_Customer", collection);
}
private void LoadDDL() //--Load Dept dropdown list.
{
try
{
var custRegnList = _dbConn.CUST_REGION.AsEnumerable().Select(x => new SelectListItem()
{
Text = String.Format("{0,-10} : {1} : {2} : {3} : {4} ", x.CUST_REGN, x.REGN_NAME,x.COUNTRY,x.STATE,x.CITY),
Value = x.CUST_REGN.ToString()
}).ToList();
ViewBag.CustRegnList = new SelectList(custRegnList, "Value", "Text");
}
catch (Exception ex)
{
throw ex;
}
}
private void LoadIncoTerms() //--Load Dept dropdown list.
{
try
{
var IncoList = _dbConn.INCO_TERMS.AsEnumerable().Select(x => new SelectListItem()
{
Text = String.Format("{0,-10} : {1}", x.INCO_TERMS, x.INCO_DESC),
Value = x.INCO_TERMS.ToString()
}).ToList();
ViewBag.IncoList = new SelectList(IncoList, "Value", "Text");
}
catch (Exception ex)
{
throw ex;
}
}
private void LoadCurrency() //--Load Dept dropdown list.
{
try
{
var Currency = _dbConn.CURRENCY.AsEnumerable().Select(x => new SelectListItem()
{
Text = String.Format("{0,-10} : {1}", x.BILL_CURCY, x.CURCY_NAME),
Value = x.BILL_CURCY.ToString()
}).ToList();
ViewBag.Currency = new SelectList(Currency, "Value", "Text");
}
catch (Exception ex)
{
throw ex;
}
}
private void LoadCustGrop()
{
try
{
var CustGroup = _dbConn.CUST_GROUP.AsEnumerable().Select(x => new SelectListItem()
{
Text = String.Format("{0,-10} : {1}", x.CUST_GROUP, x.CUST_GRP_DTL),
Value = x.CUST_GROUP.ToString()
}).ToList();
ViewBag.CustGroup = new SelectList(CustGroup, "Value", "Text");
}
catch (Exception ex)
{
throw ex;
}
}
public void OnGet()
{
this.Customers = new SelectList(this._dbConn.CUST_REGION, "CUST_REGN", "CUST_NAME");
}
}
}
CodePudding user response:
In Index view, call the partialview, and use modal form validation after using select2. You can refer to it.
HomeController:
public IActionResult Index()
{
var model = new Cust_Master();
var CustGroup = new List<SelectListItem>
{
new SelectListItem {Value="a", Text ="aaaaaaa"},
new SelectListItem {Value = "b", Text = "b"},
new SelectListItem {Value = "c", Text = "c"},
new SelectListItem {Value = "d", Text = "d"},
new SelectListItem {Value = "e", Text = "e"},
};
ViewBag.CustGroup = CustGroup;
return View(model);
}
[HttpPost]
public IActionResult Index(Cust_Master cust_Master)
{
return View();
}
Index view:
@model Cust_Master
@{
ViewData["Title"] = "Home Page";
}
@{
Html.RenderPartial("_IndexPartial");
}
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
<script>
$(document).ready(function () {
$("#btnShowModal").click(function () {
$("#Modal").modal('show');
$("#btnHideModal").click(function () {
$("#Modal").modal('hide');
});
});
$("#e1").select2({
dropdownParent: $('#Modal')
});
$("#checkbox").click(function(){
if($("#checkbox").is(':checked') ){
$("#e1 > option").prop("selected","selected");// Select All Options
$("#e1").trigger("change");// Trigger change to select 2
}else{
$("#e1 > option").removeAttr("selected");
$("#e1").trigger("change");// Trigger change to select 2
}
});
$("#button").click(function(){
alert($("#e1").val());
});
});
</script>}
Cust_Master:
public class Cust_Master
{
[Key]
[Display(Name = "CUST_CODE")]
[Required(ErrorMessage = "Please enter Customer Code")]
public int CUST_CODE { get; set; }
[Display(Name = "CUST_NAME")]
[Required(ErrorMessage = "Please enter Customer Name")]
[MaxLength(50)]
public string CUST_NAME { get; set; }
[Display(Name = "CUST_GROUP")]
[Required(ErrorMessage = "Please enter Customer Customer Group")]
[MaxLength(20)]
public List<string> CUST_GROUP { get; set; }
}
_IndexPartial:
@model Cust_Master
@{
ViewData["Title"] = "_IndexPartial";
}
<h1>_IndexPartial</h1>
<hr />
<button id="btnShowModal" type="button" > Modal </button>
<div id="Modal" >
<div >
<div >
<div >
<button id="btnHideModal" type="button" data-dismiss="modal"> ×</button>
</div>
<div >
<div >
<div >
<form asp-action="Index" >
<div asp-validation-summary="ModelOnly" ></div>
<div >
<label asp-for="CUST_CODE" ></label>
<input asp-for="CUST_CODE" />
<span asp-validation-for="CUST_CODE" ></span>
</div>
<div >
<label asp-for="CUST_NAME" ></label>
<input asp-for="CUST_NAME" />
<span asp-validation-for="CUST_NAME" ></span>
</div>
<div >
<label asp-for="CUST_GROUP" ></label>
<select multiple asp-for="CUST_GROUP" id="e1" style="width:300px" asp-items="@(new SelectList(ViewBag.CustGroup, "Value", "Text"))">
@* <option value="">---Select Customer Group---</option>*@
</select>
<input type="checkbox" id="checkbox" >Select All
<input type="button" id="button" value="check Selected">
<span asp-validation-for="CUST_GROUP" ></span>
</div>
<div >
<input type="submit" value="Create" />
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
Result:
CodePudding user response:
Behind all these scenaraios, I have changed my button type 'button' to input type 'submit' then validation worked fine.
But after that another proble produced. From controller,
return PartialView("_Customer", collection); caused existing layout null.