2011-10-10 33 views
8

Tôi có một hộp thoại phương thức mà tôi tải một biểu mẫu từ một gsp và tôi đang đấu tranh để tìm ra giải pháp phù hợp cho biểu mẫu dựa trên ajax có xác thực JSON bao gồm. thông báo thành công như nhắn phạm vi đèn flash:Grails JQuery Ajax Form Validation

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

Trong hình thức mà tôi có JS sau:

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

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

Tôi trả lại một phản ứng JSON nếu thành công của nó và khi một lỗi xảy ra và tôi cần Ajax khác hộp thoại phương thức của tôi sẽ biến mất do yêu cầu mới.

Vì vậy, đây là những câu hỏi của tôi:

  • Làm thế nào để phản ứng về những thất bại đó xảy ra trong quá trình xác nhận của tôi trong bộ điều khiển của tôi?
  • Tôi cần sử dụng mã lỗi nào cho các lỗi xác thực trong bộ điều khiển của mình?
  • Làm cách nào để cập nhật các trường cụ thể có thông báo lỗi trong biểu mẫu của tôi?
  • Làm cách nào để cập nhật phần flash của trang của tôi để hiển thị thông báo thành công?
  • Làm cách nào để cập nhật các phần khác của trang sau thành công?

Cảm ơn bạn!

Trả lời

19

Có rất nhiều cách khác nhau để thực hiện việc này và có thể là 1 hoặc nhiều plugin để giúp bạn tiếp tục. Tuy nhiên, tôi sẽ chỉ cho bạn cách tôi thường giải quyết vấn đề này. Tôi có một đối tượng trông giống như thế này ...

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

Đây là đối tượng tôi hiển thị dưới dạng JSON. Vì vậy, nếu có lỗi xác thực, thành công trở thành sai và tôi thêm tất cả các lỗi vào bản đồ lỗi. Tôi làm điều này trong một dịch vụ và phương pháp mà trông như thế này:

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 
} 

Vì vậy, điều khiển của tôi trông giống như

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

Trong mã phía khách hàng của tôi, tôi làm điều gì đó như thế này (bằng cách sử dụng hình thức jQuery plugin, nhưng điều này sẽ làm việc với một $ .ajax generic/$ .post/$ .get phương pháp cũng ...

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

Và showErrors tôi hoạt

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

Hy vọng điều đó sẽ hữu ích.

+0

Gregg, đây là tuyệt vời và excactly những gì tôi đang tìm kiếm! Cảm ơn rất nhiều! – Gambo

+0

Cảm ơn Gregg! Đánh dấu một cổ khác được lưu ;-) ... nhưng, chính xác thì bạn đang sử dụng thành viên 'html' trong AjaxPostResponse? – vector

+1

@vector xem bài đăng trên blog của tôi tại đây: http://blog.greggbolinger.com/delivering-html-with-json-using-grails – Gregg

2

Câu trả lời được chấp nhận là tốt và tôi là tất cả để tiếp cận trung tâm dịch vụ. Tuy nhiên với bộ điều khiển Ajax tôi thấy đôi khi các yêu cầu rất đơn giản và xử lý lỗi và sự kiên trì có thể được thực hiện ngay trong bộ điều khiển. Một oneliner tốt đẹp để thêm lỗi i18n tốt đẹp của bạn đến một bộ sưu tập là:

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

Sau đó trở về JSON như sau

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

Và JavaScript của bạn (Grails 2 có một lỗi tài liệu, vì vậy sử dụng 'dữ liệu' không 'e' nếu sử dụng JQuery làm mặc định.

Gọi Ajax của bạn

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

Và quá trình phản ứng

<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>