2010-10-02 11 views
6

Tengo un Dojo SubmitButton con jsId = "saveParamButtonWidget". Me overrided su método onClick poniendo:Prevención del envío de formularios con Dojo

saveParamButtonWidget.onClick = editParam 

que define la función editParam() así:

function editParam(eventObj) { 
    dojo.stopEvent(eventObj); 
    // ... 
} 

dojo.stopEvent() se supone para detener la propagación de eventos y el procesamiento por defecto. Sin embargo, el navegador enviará el formulario de todos modos. También probé con lo siguiente:

function editParam(eventObj) { 
    eventObj.stopPropagation(); 
    eventObj.preventDefault(); 
    // ... 
} 

Lo mismo. La única forma que he conseguido evitar el envío de formularios es mediante la devolución de "falsa" del controlador de eventos:

function editParam(eventObj) { 
    // ... 
    return false; 
} 

Puede alguien decirme por qué las dos primeras formas no funcionaron? Gracias.

+0

Por favor, dar más información: qué tipo de widget usaste (nombre completo), dojo no conoce un "SubmitButton", supongo que es un dijit.form.Button, con el tipo "submit". Un fragmento de código ayudaría mucho –

+0

Lo siento, estaba usando el elemento de envío Dojo de Zend Framework, que se llama SubmitButton. Pero tienes razón, es un dijit.form.Button con el tipo "enviar". – Dario

Respuesta

23

De acuerdo, después de investigar un poco sobre la fuente, creo que puedo responder su pregunta definitivamente.

El motivo dojo.stopEvent() no funciona, pero return false sí, se debe enteramente a cómo está codificado dijit.form.Button. Si estás interesado, es hora de una pequeña excursión. Mantenga sus cascos puestos.

Cuando se hace clic en un dijit.form.Button ...

  1. método _onButtonClick del botón se invoca. (Esto se enganchó en la plantilla, a la ondijitclick evento especial que no sólo captura clic del ratón, sino también ciertas pulsaciones de teclas, para los propósitos a11y.)
  2. El método _onButtonClick primero invoca el método _onClick, que, suponiendo que el botón no está desactivado (que no es en este caso), invoca y devuelve el resultado de el método onClick. Esto es de particular interés ya que es el método que está anulando.
  3. Volviendo a _onButtonClick, si _onClick regresaron precisamentefalse (por ejemplo, si el controlador de onClick volvió false), _onButtonClickfianzas de inmediato. Es por esto que al devolver el código falso funciona como lo desee. ¿Pero qué pasa si no hace fianza por ahí? Vamos a seguir el rastro más ...
  4. A continuación, _onButtonClick comprueba si este botón no un descendiente de un formulario HTML real, pero es un descendiente de un widget con un método _onSubmit (pato mecanografía). Supongo que en su caso es dentro de un real cuenta (dijit.form.Form cuenta), así que omitiremos esto. (Tengo la impresión de que esta ruta de código en realidad no terminará de enviar, mientras que la suya aparentemente sí lo hace.)
  5. Se verifica una condición final: si el botón tiene un valueNode definido (sí), el método click de este nodo es invocado. Desafortunadamente, esto produce un objeto de evento completamente nuevo en un nodo input type="submit" invisible bajo su formulario, y por lo tanto todo lo que intentó decir el evento original se convierte en inmaterial, y el formulario continúa a enviar! Es por eso que dojo.stopEvent no funcionó - este código en dijit.form.Button no le presta atención.

Lo preparé como una prueba de concepto algo limitada (asegúrese de abrir firebug/etc.para obtener los registros): http://jsfiddle.net/Bf5H8/

Tal vez esto es algo que debe estar conectado como un error, pero supongo que la idea inicial puede haber sido que el apoyo a la conocida return false mecanismo sería suficiente.

Dicho esto, es muy posible que anular el envío del formulario esté más en línea con sus intereses que anular el botón onClick (como sugirió S.Jones), pero al menos esto debería resolver el misterio.

+0

Muchas gracias por su esfuerzo, Ken. – Dario

+0

Hablé con Doug sobre esto, es por diseño. Como mostró su análisis, sería problemático admitir stopEvent() ya que hay dos objetos de evento. Otro ejemplo de dónde debe devolver el valor falso es desde el método onSubmit en un formulario. En ese caso, ni siquiera hay un objeto de evento para invocar a stopEvent(). –

2

Interesante pregunta. +1

Creo que tiene que usar dojo.connect para conectar su función a un evento DOM para obtener acceso a esos métodos con un objeto de evento.

Ver: The Event Object (DojoTollkit.org Reference Guide)

El Evento Objeto

Cuando se conecta una función a una de DOM evento con dojo.connect, Dojo pasa su función de un objeto evento normalizado. Esto significa que, independientemente del navegador del cliente, , puede contar con un conjunto de atributos estándar sobre el evento y un conjunto de métodos para manipular el evento.

asumir que su función ha sido llamado por dojo.connect y toma una caso argumento con nombre, como:

dojo.connect(dojo.byId("node"), "onclick", function(event){ 
    // the var 'event' is available, and is the normalized object 
}); 

...

Dojo normaliza los métodos siguientes con un evento objeto:

  • event.preventDefault — prevenir la víspera el comportamiento predeterminado del NT (por ejemplo, un enlace de cargar una nueva página)
  • event.stopPropagation — prevenir un evento del evento desencadenante de un nodo padre

Además, dojo.stopEvent (evento) evitará tanto el comportamiento por defecto cualquier cualquier propagación (burbujeo) de un evento .


Dicho esto, la colocación de una función como la siguiente en su forma de realizar algo de lógica antes de enviarla, es un bastante limpio, fácil de entender & enfoque de mantener.

<script type="dojo/method" event="onSubmit"> 
    if (!this.validate()) { // or whatever else you'd like to evaluate 
     // insert calls here... 
     return false; 
    } 
    return true; 
<script> 

Cheers.

+0

Técnicamente, nada malo sucederá al configurar el método onClick directamente, ya que es solo un stub en 'dijit._Widget' destinado a ser enganchado de todos modos. De hecho, usar dojo.connect (o tal vez mejor, yourwidget.connect) en realidad hará * * peor porque entonces 'return false' tampoco funcionará. –

2

que tenían el mismo problema para el uso de dojo.stopEvent

Este problema se resuelve el problema formulario de presentación como esto - aquí es una forma simple que se usa para conectarse a través dojo:

this.formId = dojo.byId("formId"); 
dojo.connect(this.formId, 'onsubmit', function(evt) { 
    var val_main = validate_this_form(0); 
     if(val_main == false) 
      dojo.stopEvent(evt); 
}); 
+0

nota dojo.connect está en desuso por dojo.aspect y dojo.on –

Cuestiones relacionadas