Asp.net-Mvc
Kendo Grid 編輯內聯自定義驗證消息,例如重複名稱等
我有一個實體位置,我正在使用帶有內聯編輯模式的 Kendu UI 網格。該實體擁有一個屬性DisplayName,該屬性是必需的,並且不能在數據庫中存在兩次。
目前,它可以顯示所需的驗證消息:
它還可以建構在LocationController Ajax InLine Create 方法中呼叫的方法CustomValidateModel ,該方法檢查 Name 是否已經存在於數據庫中,然後添加一個ModelError。*然後我通過 javascript 在.Events(events => events.Error(“onError”))*中擷取此錯誤,然後通過 javascript 彈出視窗顯示消息。
ModelState.AddModelError("DisplayName", "Name already exists.");
**這就是問題的癥結所在:**我不想看到這個 javascript 彈出消息。我還想在該欄位下方包含此資訊,例如“必填欄位!” 資訊。我已經搜尋了很多時間,但大多數人只建議通過 javascript 進行驗證和輸出,因為它目前有效。
此外,除了彈出視窗之外的實際問題是,使用者想要在 Grid 中創建的記錄在確認 javascript 彈出視窗後**消失。**但是為了可用性,我希望新行和輸入仍然存在。使用者應該能夠編輯給定的名稱,他想保存。並且 NOT 應該再次輸入完整的行。只有驗證消息“名稱已存在”。應提示資訊。
程式碼:
位置實體:
public class LocationDto { public Guid? ID { get; set; } [Required(AllowEmptyStrings = false, ErrorMessage = "Field required!")] public string DisplayName { get; set; } // other properties }LocationController 動作方法:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult CreateInline([DataSourceRequest] DataSourceRequest request, LocationDto model) { CustomValidateModel(model); // checks if the DisplayName is already existing in the DB if (model != null && ModelState.IsValid) { // Create and Save the Model into database } return Json(ModelState.ToDataSourceResult()); }javascript函式:
function onError(e, status) { if (e.errors) { var message = "Error:\n"; $.each(e.errors, function (key, value) { if (value.errors) { message += value.errors.join("\n"); } }); this.cancelChanges(); alert(message); } }我希望有可能以同樣的方式讓它工作。根據一致的視覺化和可用性的增強會很好。
通過修改另一個答案並嘗試,我建構了一個可行的解決方案:
位置 Edit.cshtml 網格剃刀:
.DataSource(ds => ds .Ajax() .Events(e => e.Error("onError")) .Model(m => { m.Id(e => e.ID); ... }) .Create(create => create.Action("CreateInLine", "Location")) .Read(...) .Update(update => update.Action("UpdateInLine", "Location")) .Destroy(...) )位置 Edit.cshtml js:
<script type="text/javascript"> function onError(e, status) { if (e.errors) { var message = "Error:\n"; var grid = $('#locationGrid').data('kendoGrid'); var gridElement = grid.editable.element; var validationMessageTemplate = kendo.template( "<div id='#=field#_validationMessage' " + "class='k-widget k-tooltip k-tooltip-validation " + "k-invalid-msg field-validation-error' " + "style='margin: 0.5em;' data-for='#=field#' " + "data-val-msg-for='#=field#' role='alert'>" + "<span class='k-icon k-warning'></span>" + "#=message#" + "<div class='k-callout k-callout-n'></div>" + "</div>"); $.each(e.errors, function (key, value) { if (value.errors) { gridElement.find("[data-valmsg-for=" + key + "],[data-val-msg-for=" + key + "]") .replaceWith(validationMessageTemplate({ field: key, message: value.errors[0] })); gridElement.find("input[name=" + key + "]").focus(); } }); grid.one("dataBinding", function (e) { e.preventDefault(); // cancel grid rebind }); } } </script>位置控制器.cs
[AcceptVerbs(HttpVerbs.Post)] public ActionResult CreateInLine([DataSourceRequest] DataSourceRequest request, LocationViewModel model) { CustomValidateModel(model); if (model != null && ModelState.IsValid) { var location = _repository.CreateNewInstance<Location>(); location.ID = Guid.NewGuid(); location.DisplayName = model.DisplayName; ... _repository.SaveChanges(); model = MapToViewModel(location); } return Json(new[] { model }.ToDataSourceResult(request, ModelState)); } private void CustomValidateModel(LocationViewModel model) { var existingEntity = _repository.GetAll<Location>() .Where(o => o.ID != model.ID) .Where(o => o.DisplayName.Equals(model.DisplayName)) .FirstOrDefault(); if (existingEntity != null) { if (existingEntity.Deleted == false) ModelState.AddModelError("DisplayName", "Name already exists."); else ModelState.AddModelError("DisplayName", "Name '" + existingEntity.DisplayName + "' already exists in DB, but deleted."); } }結果:


