Kendo Grid 编辑内联自定义验证消息,例如对于重复的名称等
Posted
技术标签:
【中文标题】Kendo Grid 编辑内联自定义验证消息,例如对于重复的名称等【英文标题】:Kendo Grid Edit InLine Custom Validation message e.g. for duplicate Names etc 【发布时间】:2013-07-07 06:51:39 【问题描述】:我有一个实体 Location 并且我正在使用具有内联编辑模式的 Kendu UI Grid。 该实体拥有一个属性DisplayName,这是必需的,并且不能在数据库中存在两次。
目前,它可以显示 Required 验证消息:
它还可以构建在 LocationController Ajax InLine Create 方法中调用的方法 CustomValidateModel,该方法检查 Name 是否已存在于数据库中,然后添加模型错误。然后我在 .Events(events => events.Error("onError")) 中通过 javascript 捕获此错误,然后通过 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);
我希望有可能以相同的方式使其工作。根据一致的可视化和可用性的增强会很好。
【问题讨论】:
【参考方案1】:我们在 Grid 中完成了这项工作,就像您在控制器端所做的那样,将我们的自定义错误添加到模型状态并将其传递回视图。然后在 onError javascript 事件中,我们自己构建了验证消息并将其放置在网格中。
Javascript onError:
function onError(e, status)
if (e.errors)
var message = "Error:\n";
var grid = $('#gridID').data('kendoGrid');
var gridElement = grid.editable.element;
$.each(e.errors, function (key, value)
if (value.errors)
gridElement.find("[data-valmsg-for=" + key + "],[data-val-msg-for=" + key + "]")
.replaceWith(validationMessageTmpl( field: key, message: value.errors[0] ));
gridElement.find("input[name=" + key + "]").focus()
);
然后创建一个 validationMessageTmpl(或任何你想调用的名称):
var validationMessageTmpl = kendo.template($("#message").html());
<script type="text/kendo-template" id="message">
<div class="k-widget k-tooltip k-tooltip-validation k-invalid-msg field-validation-error" style="margin: 0.5em; display: block; " data-for="#=field#" data-valmsg-for="#=field#" id="#=field#_validationMessage">
<span class="k-icon k-warning">
</span>
#=message#
<div class="k-callout k-callout-n">
</div>
</div>
</script>
至于用户输入消失的原因,我假设:
this.cancelChanges();
可能与此有关。我相信这正是它所说的并取消了所有更改。这将重置您的网格并删除所有用户输入。
需要注意的一点: ModelState 中的代码(也是 $.each 中的键)必须与用于要显示的列的视图模型属性同名出错了。
【讨论】:
一个很好的起点,但是 kendo 模板比 prev post 中字符串变量中的 html 标记更好 还有一个很好的技巧如何使处理程序更通用:.Events(e => e.Error("onGridServerError.bind(gridId: 'grid_custom_field_options')")) JS: var grid = $('#' + this.gridId).getKendoGrid(); 我相信你还需要添加 grid.one("dataBinding", function (e) e.preventDefault(); );如果缺少这部分,消息将消失,例如在弹出窗口中。【参考方案2】:通过修改另一个答案并尝试,我构建了一个可行的解决方案:
位置 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>
LocationController.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.");
结果:
【讨论】:
我建议你在下一个答案中使用剑道模板。 还有一个很好的技巧如何使处理程序更通用:.Events(e => e.Error("onGridServerError.bind(gridId: 'grid_custom_field_options')")) JS: var grid = $('#' + this.gridId).getKendoGrid(); 从 validationMessageTemplate 中删除类 'k-invalid-msg' ==> 这添加 css 'display:none'【参考方案3】:你可以试试这个;
DisplayName:
validation:
required: true,
DisplayNameValidation: function (input)
var exists = CheckName(input.val());
if (exists && input.is("[name='DisplayName']") && input.val() != "")
input.attr("data-DisplayNameValidation-msg", "Name already exists.");
return false;
return true;
还有
function CheckName(Name)
var exists = false;
$.ajax
(
type: "POST",
url: "CheckName",
data: "Name:'" + Name + "'",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
error: function (msg)
,
success: function (response)
exists = response;
);
return exists;
更多文档请查看kendo demo site for custom validation。
【讨论】:
以上是关于Kendo Grid 编辑内联自定义验证消息,例如对于重复的名称等的主要内容,如果未能解决你的问题,请参考以下文章
如何在 kendo.ui.grid 中创建自定义 kendo.ui.Window 以进行编辑