Extraño comportamiento de reset

Tengo un problema al resetear un formulario, y ni siquiera entiendo el comportamiento que sucede. Te explico.
Tengo un form con unos campos donde uno de ellos está definido como
public class ModificacionDatosUsuarioForm extends ValidatorForm {
private boolean js;
....................
En la jsp tengo escrito esto:
<head>
<html:javascript formName="modificacionDatosUsuarioForm"/>
<script language="JavaScript">
// Inicialización
function restablecer() {
alert (document.modificacionDatosUsuarioForm.js.value);
document.modificacionDatosUsuarioForm.js.value = true;
document.modificacionDatosUsuarioForm.conf.value = "";
document.modificacionDatosUsuarioForm.conf.disabled = true;
alert (document.modificacionDatosUsuarioForm.js.value);
}
// Comprobación de valor de campo (función sólo de prueba)
function comprobar() {
alert (document.modificacionDatosUsuarioForm.js.value);
}
</script>
</head>
<body onload="restablecer();">
<%-- Si javascript está deshabilitado, muestro mensaje --%>
<logic:messagesPresent message="true" property="jsError">
<div class="centrar">
<html:messages id="msgJs" message="true" property="jsError" header="errors.header" footer="errors.footer">
<bean:write name="msgJs"/>
</html:messages>
</div>
</logic:messagesPresent>
<html:errors/>
<html:form action="/modificarDatosUsuario" method="POST" onsubmit="return validateModificacionDatosUsuarioForm(this);" onreset="restablecer();">
<div class="centrar">
<table class="formulario" height="360">
<tr>
<td>
<table width="100%">
<tr>
<td width="10%" height="50"> </td>
<td width="23%" height="50"> </td>
<td width="67%" height="50">
<html:hidden property="js" value="false"/>
................
<table width="100%">
<tr>
<td width="33%" height="100">
<div class="centrar">
<html:submit onclick="comprobar();">
<bean:message key="button.submit"/>
</html:submit>
</div>
</td>
<td width="33%" height="100">
<div class="centrar">
<html:reset>
<bean:message key="button.reset"/>
</html:reset>
</div>
</td>
<td width="33%" height="100">
<div class="centrar">
<html:cancel>
<bean:message key="button.cancel"/>
</html:cancel>
</div>
</td>
</tr>
</table>
...
Vamos a ver! La idea de todo esto es que el campo "js" sea oculto y de inicio con valor false, y que al cargar la página se ejecute el javascript "restablecer()", que es la función que pone los valores por defecto que yo deseo y donde "js" lo pongo ya a true. El comportamiento según las salidas de alert hasta ahí es correcto: primero muestra false y después true. Si se pulsa entonces aceptar no hay ningún problema, puesto que el alert de "comprobar()" sigue mostrando true para el valor de "js" y se va a la action correspondiente donde se ejecuta su lógica.
El problema ocurre cuando le doy al reset, donde se ejecuta de nuevo "restablecer()" con idéntica salida, pero al pulsar entonces aceptar, la salida de "comprobar()" no sé por qué ahora es false para "js" (cuando previamente acababa de ser true y no hago nada más). Se va a la action, y de ahí se retorna de nuevo a la jsp porque el valor de "js" es false y ese es el comportamiento adecuado en ese caso. Se mostraría un mensaje de error a través de html:errors (el mensaje de logic:messagesPresent)

2 Respuestas

Respuesta
1
He entendido bien lo que me has explicado, y la verdad me parece un poco extraño pero me he encontrado tantas cosas que ya no me sorprende.
No se por que te pasa esto, pero seria mejor que por defecto no le pusieras ningún valor a js y que lo vayas cambiando según te convenga. Es decir que por defecto el valor sea "".
La verdad es que no te puedo dar mucha más solución porque en realidad no puedo probarlo yo ni nada pero prueba eso que te he dicho y a ver que pasa.
Siento no poder ayudarte más pero me es imposible si no puedo probarlo yo personalmente.
¿Y si te digo que no puedo dejar el valor vacío? Habrás visto que es una variable boolean, y lo más que puedo hacer y hago es no darla valor en el action form (private boolean js;). Incluso es posible que por defecto ella misma sea false. El caso es que una vez en la jsp, el cometido de todo esto es darle valor false, y en la función javascript darle valor true. Y ya está!
La idea es comprobar si javascript está habilitado. Con
<html:hidden property="js" value="false"/>
Establezco por defecto que javascript está deshabilitado (en este punto es lo máximo que puedo esperar para darle un valor, y así lo tengo realmente), y si el usuario tiene habilitado javascript se ejecutará "restablecer()" donde el valor se pone a true, y si no lo tiene habilitado pues seguirá false. Esa es mi forma de averiguar si javascript está habilitado (quizá te lo pregunté hace tiempo)
Al pulsar aceptar en el formulario, vamos a una action donde se comprueba dicho valor. Si es false, redirijo de nuevo a la jsp y pido al usuario que habilite javascript si desea que la aplicación funcione correctamente, y si es true, pues se sigue con normalidad.
El problema, como te he explicado, es que el reset pone el valor a false sin saber por qué tras comprobar que de la función sale con el valor true, por lo que ya me tiene loco del todo. Si no hago reset funciona bien, pero si lo hago envía un valor false pese a que la función javascript, como has visto, se ejecuta y lo pone a true.
Como ves, espero al último momento posible para darle valor false por defecto, y sólo a través de "restablecer()" se produce un cambio en el mismo. ¿Alguna sugerencia más?
Gracias
Creo que ya he entendido el comportamiento del reset, al menos otra explicación no le veo, y es que parece ser que a pesar de llamar a "restablecer()" y ésta ejecutarse para dar valor true a la variable, como última tarea y de forma transparente se asigna a cada valor del formulario su valor inicial o por defecto (lo que viene siendo la tarea del reset, vamos), por lo que esa sería la razón por la que vuelve a false sin yo hacer nada más que pulsar Restablecer y luego Aceptar.
Yo pensé que ejecutando una función javascript al pulsar Restablecer, primero se reseteaba y luego se ejecutaba dicha función, pero por el comportamiento que veo es al revés.
He probado a poner en la jsp
<html:hidden property="js" value="">
, cosa que me sugeriste, y también
<html:hidden property="js">
, pero el resultado es el mismo. En este segundo caso se sigue mandando "false" porque es el valor por defecto del boolean, y en el primer caso se manda "", pero nunca "true" como yo busco.
El problema está entendido, que no es poco, pero no sé cómo solucionarlo :(
Creo que ya lo he solucionado, aunque lo he hecho tras darle muchas vueltas :)
De todo esto yo he sacado en claro, en vista de las pruebas que he estado haciendo, que el reseteado de los campos del formulario es posterior a cualquier ejecución javascript lanzada por el evento "onreset", por lo que en estas circunstancias la asignación de valores a campos del formulario en funciones de este tipo no sirve de nada. Supongo (si no da también problemas) que es útil para habilitar o deshabilitar campos y cosas así, pero no para asignar valores. Si no se establecen por defecto al principio, el reset asignará los valores por defecto propios de cada tipo de datos ("" para String en este caso, false para boolean...), y si esta opción no te sirve como me pasaba a mí, pues... a descabezarse. Al menos conseguí entender el problema que tenía, que no es poco.
Para solucionarlo, como la variable con la que determino si javascript está o no habilitado estaba con otras operaciones de gestión de campos, y esto necesitaba ejecutarlo con los eventos "onload" y "onreset", lo que he hecho ha sido sacar la variable de mi función "establecer()" y dejarla sola en otra función, la cual ahora ejecuto con el evento "onclick" del submit. De esta manera siempre se ejecutará la función después de cualquier reset posible y enviaré el valor adecuado
Gracias por tu interés
Un saludo
Respuesta
1
Disculpa si te envíe una respuesta en blanco, me equivoque.
Bueno, leyendo tu pregunta, entendí que tienes una propiedad en el Form que es booleana, entonces todo funciona bien, pero que pasa cuando aplicas reset, pues reestableces a sus valores por default de inicialización. en este caso tu no inicializaste js pero toma el valor por defecto, ejemplo: boolean=false,int=0,Object=null,etc. Y a si con todas las variables declaradas en tu form bean.
Si pones verdadero en tu variable, te darás cuenta que al resetear vuelve a poner ese valor.
Entonces la lógica de resetear un formulario es regresar a sus valores por los cuales fue cargado previamente.
La lógica del reset más o menos ya la entendía y ahora me ha quedado mucho más clara, pero el problema está en que como sé que dicha variable vuelve a false, con cada llamada a reset llamo a mi función javascript "restablecer()" para asignarla de nuevo el valor true. Eso se consigue, pero al pulsar Aceptar en el formulario la envía con el valor false.
La idea de esa variable es saber si javascript está o no habilitado. Por defecto es false, y si se puede entrar en "restablecer()" entonces se pone a true. Hasta ahí bien salvo cuando doy a reset, que se pone a false, entrando en "restablecer()" se pone a true, pero luego sin embargo se envía false, por lo que mi lógica de la action que va a continuación me devuelve a esa misma página para indicarme que "debería habilitar javascript".
¿Alguna sugerencia? Gracias
Has un override al método reset que se encuentra en ActionForm que extiende ValidateForm y en el método resetea tu variable.
En tu form ModificacionDatosUsuarioForm  escribe esto:
public void reset(ActionMapping mapping, HttpServletRequest request) {
       js=false;
}
Creo que ya lo he solucionado, aunque lo he hecho tras darle muchas vueltas y antes de leer tu consejo, por lo que tendré en cuenta lo que me has dicho si me diera algún otro problema inesperado, que espero que no! :)
De todo esto yo he sacado en claro, en vista de las pruebas que he estado haciendo, que el reseteado de los campos del formulario es posterior a cualquier ejecución javascript lanzada por el evento "onreset", por lo que en estas circunstancias la asignación de valores a campos del formulario en funciones de este tipo no sirve de nada. Supongo (si no da también problemas) que es útil para habilitar o deshabilitar campos y cosas así, pero no para asignar valores. Si no se establecen por defecto al principio, el reset asignará los valores por defecto propios de cada tipo de datos ("" para String en este caso, false para boolean...), y si esta opción no te sirve como me pasaba a mí, pues... a descabezarse. Al menos conseguí entender el problema que tenía, que no es poco.
Para solucionarlo, como la variable con la que determino si javascript está o no habilitado estaba con otras operaciones de gestión de campos, y esto necesitaba ejecutarlo con los eventos "onload" y "onreset", lo que he hecho ha sido sacar la variable de mi función "establecer()" y dejarla sola en otra función, la cual ahora ejecuto con el evento "onclick" del submit. De esta manera siempre se ejecutará la función después de cualquier reset posible y enviaré el valor adecuado
Gracias por tu consejo también
Un saludo

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas