2011-10-10 105 views
8

我有一個模式對話框,我從gsp加載表單,並且我正在努力尋找一個基於ajax的表單的正確解決方案,並通過JSON驗證包括。成功的消息像一個閃光範圍消息:Grails JQuery Ajax表單驗證

$('#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部分以呈現成功消息?
  • 如何在成功後更新頁面的其他部分?

謝謝!

回答

19

有很多不同的方法來完成這個,可能有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形式插件,但這將與通用$阿賈克斯/ $。員額/ $不用彷徨方法以及工作...

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

希望有幫助。

+0

格雷格,這是真棒,excactly什麼,我一直在尋找!非常感謝! – Gambo

+0

謝謝格雷格!標記另一個脖子保存;-) ...但是,你究竟在AjaxPostResponse中使用'html'成員? – vector

+1

@vector在這裏看到我的博客文章:http://blog.greggbolinger.com/delivering-html-with-json-using-grails – Gregg

2

接受的答案是好的,我都是以服務爲中心的方法。但是,使用Ajax控制器時,我發現有時需求非常簡單,錯誤處理和持久性可以在控制器中正確完成。一個不錯的oneliner您不錯的國際化錯誤添加到收藏是:

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有一個文檔的錯誤,所以用「數據」不'e'如果使用JQuery的話是默認的。

打電話給你的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>