2012-03-28 13 views
14

El problema es que tengo una forma remota que, en función de la condición, le gusta convertir a una forma no remota (usando UJS), y luego enviar tenga en cuenta que el formulario tiene una carga de archivo.Use JS para cambiar <form> de remoto a no remoto en Rails 3, HAML

He aquí los detalles: He prestado inicialmente la forma remota utilizando

= form_for @myobj, :url => {:action=>"remoteAction", :controller=>"myobjects"}, :remote => true do |f| 
... (f.fields....) 

que produce el código HTML:

<form id="new_myobj" class="new_myobj" method="post" accept-charset="UTF-8" data-remote="true" action="/remoteAction"> 

cuando hago clic en Enviar, como era de esperar, se envía el formulario 'como JS '. en la acción del controlador, estoy haciendo una validación de los campos dentro del formulario enviado. Si se superan todas las validaciones, ejecuto la siguiente plantilla .js.haml:

$('form#new_myobj').removeAttr("data-remote"); 
$('form#new_myobj').attr('enctype', 'multipart/form-data'); 
$('form#new_myobj').attr('action', '/myobjects/regularAction'); 

que cambia con éxito el HTML de la página (testigo a través de Firebug) a:

<form id="new_myobj" class="new_myobj" method="post" accept-charset="UTF-8" enctype="multipart/form-data" action="/myobjects/regularAction"> 

ya que el formulario contiene un f.file_field, tengo que enviarlo como multiparte para que la imagen pueda cargarse, y no puedo enviar 'AS JS' ahora, cuando hago clic en enviar, la acción del controlador 'regularAction' se llama, pero sigue siendo 'AS JS '

la búsqueda es decir, ¿qué más necesito cambiar en el HTML para que el formulario se pueda enviar no xhr? ¿Está relacionado con los encabezados?

Respuesta

4

El problema es que su enfoque para desactivar el envío de Ajax no es del todo correcto. Debe desvincular los eventos de JavaScript que ya han sido agregados por rails.js (Rails UJS adapter) al formulario. Puede hacerlo por: $('form#new_myobj').unbind() para desvincular todos los eventos adjuntos al formulario. También necesita $('form#new_myobj').removeAttr('data-remote') y $('form#new_myobj').removeAttr('data-type') para eliminar los atributos data-remote y data-type (si existen).

+0

Gracias por su sugerencia, entonces agregué la llamada unbind() a mi plantilla js.haml, pero la segunda presentación todavía va a la 'acción' de acción regular 'AS JS ' –

+0

$ (' form # new_myobj '). Unbind() $ (' form # new_myobj '). RemoveAttr ("data-remote"); ... –

+0

¿Hay algún otro componente que deba desvincular, quizás? –

36

jQuery es un poco complicado con los atributos de datos ya que tanto lee las etiquetas de datos HTML5 como su propio almacenamiento vinculado al elemento DOM , que también se denomina datos. Al escribir en un atributo ese valor se copia en el propio almacenamiento de datos de jQuerys (supuestamente cuando se llama al data("remote")).

Sin embargo, esto solo ocurre si los datos de jQuery están vacíos para ese nombre. Por lo tanto, establecer el atributo solo funcionará una vez, después de eso, el valor "en caché" se usa incluso si el atributo cambia. Para realmente deshacerse del valor , necesitamos eliminar el atributo y el propio método de almacenamiento de jQuerys en ese orden. La razón es que hay una función de alto nivel (element.removeData(…)) y una de bajo nivel (jQuery. removeData(element, …)). El primero vuelve a leer el atributo de datos HTML5 y lo almacena en el propio almacenamiento de jQuery. El uso de la función inusual de bajo nivel obviamente también funciona.

También, necesitamos realmente para quitar el atributo - estableciéndolo en falsa no es suficiente ya que los carriles sólo comprueba si form.data('remote') no está definido (busque en jquery_ujs.js).

TL; DR:

  • attr("data-remote") != data("remote")
  • Estas dos líneas hacer una forma no a distancia (de nuevo). El orden importa
$("form").removeAttr("data-remote"); 
    $("form").removeData("remote"); 

Está documentado, si realmente sabe lo que está buscando:

stackoverflow no permite para publicar más de dos enlaces, pero puedes adivinar el de removeData. Las funciones de alto nivel están vinculadas a las de bajo nivel.

Evitar el error autenticidad token en rieles 4+: Como Stan comentado a continuación, sólo hacer lo anterior fallará con un error InvalidAuthenticityToken. La solución es fácil, vea aquí para más detalles: https://stackoverflow.com/a/19858504/1684530

+0

¡Excelente! ¡Te daría más de uno 'arriba', si fuera posible! –

+0

Claro y preciso, gracias :) – Benj

+2

Te quiero mucho en este momento –

Cuestiones relacionadas