Grails JQuery Ajax表单验证

时间:2011-10-10 20:29:53

标签: jquery json grails

我有一个模态对话框,我从gsp加载表单,我正在努力为基于ajax的表单找到合适的解决方案,其中包含JSON验证。成功消息,如闪存范围消息:

$('#calendar_form').live('click', function () {
        $.modal({
            ajax: './form'
            , title: '${message(code:'calendar.main.addAppointment')}'
            , overlayClose: true
        });
    });

在那个表格中我有以下JS:

$(document).ready(function() {
    $('#form1').submit(function() {

        $.ajax({
            type: 'POST',
            url: '${createLink(action:'post')}',
            data: $("#form1").serialize(),
            success: function(result) {
                alert(result);
            }
        });
    });
});

如果它成功并且发生错误我将返回JSON响应,并且我需要Ajax,否则我的模态对话框因新请求而消失。

所以这是我的问题:

  • 如何对我在控制器中验证期间发生的故障做出反应?
  • 我需要在控制器中使用哪些错误http代码进行验证错误?
  • 如何使用表单中的错误消息更新特定字段?
  • 如何更新页面的Flash部分以呈现成功消息?
  • 如何在成功后更新页面的其他部分?

谢谢!

2 个答案:

答案 0 :(得分:19)

有很多不同的方法可以实现这一点,可能还有一个或多个插件可以帮助您实现目标。但是,我会告诉你我一般如何处理这件事。我有一个看起来像这样的对象......

class AjaxPostResponse {
  boolean success
  String message
  String html
  def domainObject
  def errors = [:] 
}

这是我呈现为JSON的对象。因此,如果存在验证错误,则成功将变为false,并将所有错误添加到错误映射中。我在服务中执行此操作,该方法如下所示:

def preparePostResponse(domainInstance) {
    def g = grailsApplication.mainContext.getBean('org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib')
    def postResponse = new AjaxPostResponse(domainObject: domainInstance)
    if (domainInstance.hasErrors()) {
      g.eachError(bean: domainInstance) {
        postResponse.errors."${it.field}" = g.message(error: it)
      }
      postResponse.success = false
      postResponse.message = "There was an error"
    } else {
      postResponse.success = true
      postResponse.message = "Success"
    }
    return postResponse
}

所以我的控制器看起来像

def save = {
  def someObjInstance = new SomeObj(params)
  someObjInstance.save(flush:true)
  render myService.preparePostResponse(someObjInstance) as JSON
}

在我的客户端代码中我做了类似的事情(使用jQuery表单插件,但这也适用于通用的$ .ajax / $ .post / $ .get方法......

$(formElement).ajaxSubmit({
    dataType: 'json',
    success: function(jsonData) {
      if (jsonData.success) {
        // do good stuff
      } else {
        // bad stuff happened
        showErrors(jsonData.errors);
      }
    }
});

我的showErrors功能

function showErrors(errors, element) {
    var errorList = $("<ul>");
    for (field in errors) {
        errorList.append("<li>" + errors[field] + "</li>")
        $('input[name=' + field + ']').addClass('error');
    }
    if (!element) {
        $(".errors").html("").append(errorList).show(500);
    } else {
        $(element).html("").append(errorList).show(500);
    }
}

希望有所帮助。

答案 1 :(得分:2)

接受的答案是好的,我全都是以服务为中心的方法。但是,对于Ajax控制器,我发现有时需求非常简单,并且可以在控制器中完成错误处理和持久性。一个很好的oneliner将你的漂亮i18n错误添加到集合中:

if (!yourdomain.validate())
 {
     errors.addAll(yourdomain.errors.allErrors.collect {message(error: it)})
 } else {
     yourdomain.save(); //etc . . .
}

然后按如下方式返回JSON

render(contentType: "text/json") {
     if (errors)
     {
         success = 'false'
         errorList = errors
     } else {
         success = 'true'
         //otherstuff
     }
}

你的JavaScript(Grails 2有一个文档错误,所以如果使用JQuery,则使用'data'而不是'e'。

调用您的Ajax

<g:formRemote /*or remoteLink */ ...your URL, etc... onSuccess="doResponse(data)">
<div class="alert" style="display: none" id="error"></div>

处理回复

<g:javascript>
        function doResponse(data) {
            if (data.success == 'true') {
                //success stuff
            } else {
                var errorList = $('<ul class="errors">');
                for (var i = 0; i < data.errorList.length; i++) {
                    errorList.append('<li>' + data.errorList[i] + "</li>");
                }

                $('#error').html(errorList);
                $('#error').show();
            }

        }
   </g:javascript>