【问题标题】:Grails JQuery Ajax Form ValidationGrails JQuery Ajax 表单验证
【发布时间】:2011-12-04 19:43:04
【问题描述】:

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

$('#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);
            }
        });
    });
});

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

所以这是我的问题:

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

谢谢!

【问题讨论】:

    标签: jquery json grails


    【解决方案1】:

    有很多不同的方法可以实现这一点,并且可能有 1 个或多个插件可以让您继续前进。但是,我将向您展示我通常如何处理此问题。我有一个看起来像这样的对象...

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

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

    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);
        }
    }
    

    希望对您有所帮助。

    【讨论】:

    【解决方案2】:

    公认的答案很好,我完全赞成以服务为中心的方法。然而,对于 Ajax 控制器,我发现有时要求非常简单,错误处理和持久性可以直接在控制器中完成。一个不错的单行器可以将你的 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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-25
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      相关资源
      最近更新 更多