asp.net-mvc Kendo Grid 编辑内联自定义验证消息,例如重复名称等
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17552057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Kendo Grid Edit InLine Custom Validation message e.g. for duplicate Names etc
提问by florian.isopp
I have an entity Locationand I am using the Kendu UI Grid with InLine edit mode. The entity owns a property DisplayName, which is required and must not exist twicein the database.
我有一个实体Location并且我正在使用具有 InLine 编辑模式的 Kendu UI Grid。实体拥有一个属性DisplayName,这是必需的,并且不能在数据库中出现两次。
At the moment, it works to display the RequiredValidation message:

目前,它可以显示所需的验证消息:

And it also works to build up a method CustomValidateModelcalled in the LocationControllerAjax InLine Create method, that checks if the Name is already existing in the database and adds then a ModelError. I catch this error then in the .Events(events => events.Error("onError"))via javascript and show then the message via javascript popup.
它还可以构建一个在LocationControllerAjax InLine Create 方法中调用的CustomValidateModel方法,该方法检查 Name 是否已存在于数据库中,然后添加一个ModelError。我在.Events(events => events.Error("onError")) 中通过 javascript捕获此错误,然后通过 javascript 弹出窗口显示消息。
ModelState.AddModelError("DisplayName", "Name already exists.");


And this is the crux of the matter:I don't want to have this javascript popup message. I want to have also this information below the field, like this "Field required!" message. I have searched plenty of time, but the most people suggest only this Validation and output via javascript as it works in the moment.
这就是问题的关键:我不想有这个 javascript 弹出消息。我还想在字段下方显示此信息,例如“需要字段!” 信息。我已经搜索了很多时间,但大多数人只建议通过 javascript 进行验证和输出,因为它目前有效。
Additionally, the actual problem besides the popup, is, that the record, which the user wants to create in the Grid, is then disappearingafter confirming the javascript popup. But for usability, I want that the new line and the input persists. The users should be able to edit the given Name, he wanted to save. And NOT should enter the complete line again. Only the Validation message "Name already existing." should prompt for information.
此外,除了弹出窗口之外的实际问题是,用户想要在网格中创建的记录在确认 javascript 弹出窗口后消失了。但是为了可用性,我希望新行和输入保持不变。用户应该能够编辑给定的名称,他想保存。并且 NOT 应该再次输入完整的行。只有验证消息“名称已存在”。应该提示信息。
Code:
代码:
Location entity:
位置实体:
public class LocationDto
{
public Guid? ID { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Field required!")]
public string DisplayName { get; set; }
// other properties
}
LocationController Action method:
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:
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);
}
}
I hope there is a possibility to get this working in the same way. It would be fine according congruent visualization and an enhancement of usability.
我希望有可能以同样的方式使其工作。根据一致的可视化和可用性的增强,这会很好。
采纳答案by florian.isopp
With modifying of another answer and trying around, I constructed a working solution:
通过修改另一个答案并尝试,我构建了一个可行的解决方案:
Location Edit.cshtml Grid Razor:
位置 Edit.cshtml Grid Razor:
.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(...)
)
Location Edit.cshtml js:
位置 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
位置控制器.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.");
}
}
Result:
结果:


回答by larrydice
We accomplished this in a Grid just like you did on the controller side by adding our custom error to the model state and passing that back to the view. And then in the onError javascript event we built the validation message ourselves and placed it in the grid.
我们在 Grid 中完成了这一点,就像您在控制器端所做的一样,通过将我们的自定义错误添加到模型状态并将其传递回视图。然后在 onError javascript 事件中,我们自己构建了验证消息并将其放置在网格中。
Javascript onError:
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()
}
});
}
}
Then create a validationMessageTmpl(or whatever you want to call it):
然后创建一个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>
As far as why user input is disappearing, I assume that:
至于用户输入消失的原因,我假设:
this.cancelChanges();
may have something to do with it. I believe this does just what it says and cancels all changes. Which would reset your grid and remove all user input.
可能与它有关。我相信这就是它所说的并取消所有更改。这将重置您的网格并删除所有用户输入。
One thing to note:The code in the ModelState (also the key in your $.each) must be the same name as the view model property being used for the column you want to display the error on.
需要注意的一件事:ModelState 中的代码(也是 $.each 中的键)必须与要在其上显示错误的列所使用的视图模型属性同名。
回答by Mahib
You can try this;
你可以试试这个;
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;
}
}
And
和
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;
}
}
For further documentation check kendo demo site for custom validation.
有关更多文档,请查看kendo 演示站点以进行自定义验证。

