2011-10-10 15 views
8

Tengo un cuadro de diálogo modal donde cargo un formulario desde un gsp y estoy luchando para encontrar la solución adecuada para una forma basada en Ajax con la validación JSON incl. mensaje de éxito como un mensaje de alcance del flash:Grails JQuery Ajax Form Validation

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

En esa forma tengo el siguiente JS:

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

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

estoy volviendo una respuesta JSON si su éxito y cuando se produce un error y necesito Ajax de otro modo mi diálogo modal está desapareciendo debido a la nueva solicitud.

Así que aquí están mis preguntas:

  • ¿Cómo reacciono en los fallos que ocurren durante mi validación en el controlador?
  • ¿Qué códigos de error de http debo usar para los errores de validación en mi controlador?
  • ¿Cómo actualizo los campos específicos con mensajes de error en mi formulario?
  • ¿Cómo actualizo la parte flash de mi página para procesar el mensaje de éxito?
  • ¿Cómo es posible actualizar otras partes de la página después del éxito?

¡Gracias!

Respuesta

19

Hay muchas maneras diferentes de lograr esto y probablemente uno o más complementos para que funcione. Sin embargo, te mostraré cómo trato generalmente con esto. Tengo un objeto que se ve así ...

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

Este es el objeto que represento como JSON. Entonces, si hay errores de validación, el éxito se vuelve falso y agrego todos los errores al mapa de errores. Lo hago en un servicio y que el método se ve así:

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 
} 

Así que mi controlador se ve algo como

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

En mi código del lado del cliente que hago algo como esto (utilizando el formulario plugin de jQuery, pero esto funcionaría con un genérico $ .ajax/$ .post/$ .get método, así ...

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

Y mis showErrors funcionar

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

Espero que ayude.

+0

Gregg, esto es impresionante y la realidad sea exactamente lo que estaba buscando! ¡Muchas gracias! – Gambo

+0

Gracias Gregg! Marque otro cuello guardado ;-) ... pero, ¿qué está usando exactamente el miembro 'html' en AjaxPostResponse? – vector

+1

@vector vea la publicación de mi blog aquí: http://blog.greggbolinger.com/delivering-html-with-json-using-grails – Gregg

2

La respuesta aceptada es buena y estoy totalmente a favor de un enfoque centrado en el servicio. Sin embargo, con los controladores Ajax, a veces los requisitos son muy simples y el manejo y la persistencia de errores se pueden realizar directamente en el controlador. Un oneliner agradable para añadir sus agradables errores i18n a una colección es:

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

A continuación, volver JSON de la siguiente manera

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

Y tu JavaScript (Grails 2 tiene un error de documentación, a fin de utilizar 'datos' no 'e' si usa JQuery como es el predeterminado.

Llame a su Ajax

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

y procesar la respuesta

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