flo*_*opp 12 asp.net-mvc razor kendo-ui kendo-grid kendo-asp.net-mvc
我有一个实体位置,我正在使用具有InLine编辑模式的Kendu UI网格.该实体拥有属性DisplayName,该属性是必需的,并且在数据库中不得存在两次.
目前,它可以显示" 必需的验证"消息:

它还可以构建一个在LocationController Ajax InLine Create方法中调用的方法CustomValidateModel,该方法检查Name是否已存在于数据库中,然后添加ModelError.我通过javascript 在.Events(events => events.Error("onError"))中捕获此错误,然后通过javascript弹出显示消息.
ModelState.AddModelError("DisplayName", "Name already exists.");
Run Code Online (Sandbox Code Playgroud)

这就是问题的症结所在:我不想拥有这个javascript弹出消息.我想在这个领域下面也有这个信息,比如"需要现场!" 信息.我已经搜索了很多时间,但大多数人建议只有这个验证和输出通过javascript,因为它在当下工作.
另外,除了弹出窗口之外的实际问题是,在确认javascript弹出窗口之后,用户想要在Grid中创建的记录正在消失.但是为了实用性,我希望新行和输入仍然存在.用户应该能够编辑给定的名称,他想保存.而不应该再次输入完整的行.只有验证消息"名称已存在".应该提示信息.
码:
位置实体:
public class LocationDto
{
public Guid? ID { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Field required!")]
public string DisplayName { get; set; }
// other properties
}
Run Code Online (Sandbox Code Playgroud)
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());
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我希望有可能以同样的方式实现这一点.根据一致的可视化和可用性的增强,这将是很好的.
lar*_*ice 10
我们在网格中实现了这一点,就像在控制器端一样,将自定义错误添加到模型状态并将其传递回视图.然后在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()
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
然后创建一个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>
Run Code Online (Sandbox Code Playgroud)
至于用户输入消失的原因,我认为:
this.cancelChanges();
Run Code Online (Sandbox Code Playgroud)
可能与它有关.我相信这就是它所说的并取消所有变化.这将重置您的网格并删除所有用户输入.
需要注意的一点是: ModelState中的代码(也是$ .each中的键)必须与要用于显示错误的列的视图模型属性相同.
通过修改另一个答案并尝试解决,我构建了一个可行的解决方案:
位置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(...)
)
Run Code Online (Sandbox Code Playgroud)
位置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>
Run Code Online (Sandbox Code Playgroud)
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.");
}
}
Run Code Online (Sandbox Code Playgroud)
结果:

| 归档时间: |
|
| 查看次数: |
22535 次 |
| 最近记录: |