Grails: casilla de verificación no se vuelve a establecer en falso


8

Estoy desarrollando un Grails (1.0.4) aplicación donde quiero editar una colección de colecciones en una sola página en una vista de cuadrícula. Lo hice funcionar bastante bien dependiendo solo del manejo de parámetros indexados de Spring MVC, excepto por una cosa:

Los valores booleanos (o, para el caso, booleanos) en la cuadrícula se pueden establecer mediante la casilla de verificación, pero no , es decir, cuando puedo comprobar la casilla de verificación y actualización, el valor se establece en true, pero después, cuando edito de nuevo, desactive la casilla de verificación y actualización, sigue siendo cierto.

Este es el código del SGP de la casilla de verificación:

<g:checkBox name="tage[${indexTag}].zuweisungen[${indexMitarb}].fixiert" value="${z.fixiert}" /> 

Y este es el HTML generado:

<input type="hidden" name="tage[0].zuweisungen[0]._fixiert" /> 
<input type="checkbox" name="tage[0].zuweisungen[0].fixiert" checked="checked" id="tage[0].zuweisungen[0].fixiert" /> 

He encontrado un Grails bug que describe exactamente este efecto, pero es marcado como fijo en 1.0.2, y el mecanismo problema descrito allí (subrayado en el nombre de campo oculto se pone en el lugar equivocado) no está presente en mi caso.

¿Alguna idea de lo que podría ser la razón?

1

me gustaría crear una pequeña aplicación de ejemplo que muestra el problema y adjuntarlo al error Grails (o crear uno nuevo). Alguien aquí puede depurar su aplicación de muestra o habrá demostrado que el error no está realmente solucionado.

  0

Creo que te refieres a 'mostrado' en lugar de 'brilló'. :-) 25 feb. 092009-02-25 20:35:04

  0

Demasiado perezoso para hacer eso en este momento :) Probablemente la mejor solución a largo plazo. 01 mar. 092009-03-01 13:00:26


1

creo que la solución más sencilla sería la de conectar un depurador y ver por qué está fallando Grails para poblar el valor. Teniendo en cuenta que Grails es de código abierto, podrás acceder al código fuente y, una vez que encuentres la solución, podrás parchar tu versión.

También he encontrado este otro error GRAILS-2861 que menciona el problema relacionado con el enlace a booleanos (ver el comentario de Marc en el hilo). Supongo que ese es exactamente el problema que estás describiendo.

  0

Desafortunadamente, toda la magia dinámica y metaprogramación que se desarrolla en Grails hace que sea casi imposible depurar a menos que sepa exactamente dónde mirar, probablemente en algún lugar dentro de Spring MVC. que realmente no sé 01 mar. 092009-03-01 13:02:16

  0

El error al que se vinculó es una cuestión diferente, creo, básicamente, un malentendido basado en el diferente significado del atributo "valor" en HTML y grails. 01 mar. 092009-03-01 13:02:59

  0

Debo confesar que todavía creo que estos dos están relacionados :-). Al observar la solución que ha publicado a continuación, parece que el problema es que el oculto o la casilla de verificación NO tienen un valor que transmitir cuando se envía el formulario (que se explica en el ticket). 01 mar. 092009-03-01 20:23:22

  0

La solución que está publicando me hace pensar que debe mirar el código de etiqueta personalizada y ver por qué no se genera el atributo de valor. Una vez que tenga ese atributo escrito en HTML, espero que este problema se solucione. 01 mar. 092009-03-01 20:24:47

  0

Estoy tratando de obtener la opinión del Sr.G y Graeme sobre el tema aquí. 01 mar. 092009-03-01 20:29:47

  0

No, el problema es que HTML no transmite nada para una casilla de verificación no marcada (para una marcada, usa "on" como valor predeterminado si no se especifica ninguno). El campo oculto es una solución para eso. 02 mar. 092009-03-02 10:45:23

  0

Y, por lo que yo entiendo, el atributo "valor" en griales tiene un significado completamente diferente que en HTML: en grises determina si la casilla de verificación en el formulario debe establecerse o no. En HTML, es la cadena que se envía al servidor si se estableció la casilla de verificación. 02 mar. 092009-03-02 10:49:01

  0

@Michael: las casillas no marcadas NO se transmiten si no están marcadas (es el comportamiento normal de HTML), por lo que si Grails depende de algún valor para estar allí, todo lo que necesita hacer es agregar una función de JavaScript a la entrada de formulario que pasa por form.elements y establece el valor oculto para aquellos que lo faltan. 02 mar. 092009-03-02 23:33:24

  0

Se supone que Grails usa el campo oculto para inferir que la casilla de verificación con el mismo nombre (sans subrayado) no está marcada si no está presente en los parámetros de solicitud, que funciona para campos regulares, pero por alguna razón falla con campos indexados. 03 mar. 092009-03-03 00:28:31


0

probar esto, establezca los registros de depurar, Frist tratar el primer 3 si no se presenta el problema arriba, dar la vuelta a todos depurar:

codehaus.groovy.grails.web.servlet="error" // controllers 
codehaus.groovy.grails.web.pages="error" // GSP 
codehaus.groovy.grails.web.sitemesh="error" // layouts 
codehaus.groovy.grails."web.mapping.filter"="error" // URL mapping 
codehaus.groovy.grails."web.mapping"="error" // URL mapping 
codehaus.groovy.grails.commons="info" // core/classloading 
codehaus.groovy.grails.plugins="error" // plugins 
codehaus.groovy.grails.orm.hibernate="error" // hibernate integration 

Esto debería permitirle ver exactamente cuando y cómo la configuración de los parámetros está fallando y probablemente encuentre una solución alternativa.

  0

Desafortunadamente, no he encontrado sugerencias utilizables en el registro: no sabe cómo asignar el parámetro "._fixiert", pero, por supuesto, eso no está presente en el modelo de dominio de todos modos, ya que es solo una indicación de que una ausencia de ".fixiert = on" significa que debe establecerse en falso. 01 mar. 092009-03-01 13:05:53


2

Ésta es mi propia solución, básicamente, una solución que lo hace de forma manual lo que los griales enlace de datos deberían estar haciendo (pero no):

Map<String,String> checkboxes = params.findAll{def i = it.key.endsWith("._fixiert")} // all checkboxes 
checkboxes.each{ 
    String key = it.key.substring(0, it.key.indexOf("._fixiert")) 
    int tagIdx = Integer.parseInt(key.substring(key.indexOf('[')+1, key.indexOf(']'))) 
    int zuwIdx = Integer.parseInt(key.substring(key.lastIndexOf('[')+1, key.lastIndexOf(']'))) 
    if(params.get(key+".fixiert")) 
    { 
     dienstplanInstance.tage[tagIdx].zuweisungen[zuwIdx].fixiert = true 
    } 
    else 
    { 
     dienstplanInstance.tage[tagIdx].zuweisungen[zuwIdx].fixiert = false      
    } 
} 

Works, no requiere ningún cambio en sí mismo griales, pero ISN' t reutilizable (probablemente podría hacerse así con un poco de trabajo extra).


3

Esta es la solución que un tipo llamado Julius Huang propuso en la lista de correo de Grails-usuario. Es reutilizable, pero se basa en JavaScript para rellenar un campo oculto con la respuesta "falsa" para una casilla de verificación no revisada que HTML desafortunadamente no envía.

yo hackearé SGP para enviar "falso" cuando Desactive la casilla (true -> false) con encargo TagLib.

Por checkBox defecto envía nada cuando desmarque, así que utilice la casilla como controlador de eventos, pero enviar campo oculto en su lugar.

"params" en el controlador puede manejar "falso" -> "verdadero" sin ninguna modificación . p.ej. Todo sigue siendo mismo en el controlador.

El encargo etiqueta Uso de GSP (usedfunc_F muestra es "verdadero"),

<jh:checkBox name="surveyList[${i}].usedfunc_F" value="${survey.usedfunc_F}"></jh:checkBox> 

Esto es lo que genera la etiqueta,

<input type="hidden" name="surveyList[#{i}].usedfunc_F" id="surveyList[#{i}].usedfunc_F" value="false" /> 
<input type="checkbox" onclick="jhtoggle('surveyList[#{i}].usedfunc_F')" checked="checked" /> 

El Javascript

<script type="text/javascript"> 
function jhtoggle(obj) { 
    var jht = document.getElementById(obj); 
    jht.value = (jht.value !='true' ? 'true' : 'false'); 
} 
</script>