2012-03-28 23 views
14

Problem polega na tym, że mam formularz zdalny, który na podstawie warunku, jest taki, aby konwertować na formularz niezajęty (za pomocą UJS), i następnie prześlij. uwaga w formularzu przesłano plik.Użyj JS, aby zmienić <form> ze zdalnego na niepodzielny w Railsach 3, HAML

Oto szczegóły: Mam wstępnie renderowane zdalny formularz używając

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

która produkuje HTML:

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

Kiedy klikam submit, zgodnie z oczekiwaniami, formularz jest składany „AS JS ". w akcji kontrolera, robię pewne sprawdzanie pól wewnątrz przesyłanego formularza. Jeśli przechodzą wszystkie walidacje, i wykonać następujące .js.haml szablonu:

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

który skutecznie zmienia HTML na stronie (świadkiem przez Firebug) na adres:

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

ponieważ forma zawiera f.file_field, muszę przesłać jako wieloczęściowy, więc obraz może być przesłany, i nie mogę przesłać "AS JS" teraz, gdy klikam submit, akcja kontrolera "regularAction" jest rzeczywiście wywoływana, ale wciąż jest "AS JS" "

the quest jon jest, co jeszcze muszę zmienić w kodzie HTML, aby formularz mógł zostać przesłany w innym formacie niż xhr? czy jest powiązany z nagłówkami?

Odpowiedz

4

Problem polega na tym, że twoje podejście do wyłączenia przesyłania Ajaxa nie jest całkiem poprawne. Musisz odłączyć zdarzenia JavaScript, które zostały już dodane do formularza przez rails.js (adapter Rails UJS). Możesz to zrobić przez: $('form#new_myobj').unbind(), aby odłączyć wszystkie zdarzenia dołączone do formularza. Musisz również $('form#new_myobj').removeAttr('data-remote') i $('form#new_myobj').removeAttr('data-type') usunąć atrybuty data-remote i data-type (jeśli istniały).

+0

Dzięki za sugestię, więc dodałem wywołanie unbind() do mojego szablonu js.haml, ale drugie zgłoszenie nadal przechodzi do akcji "regularAction" AS AS ' –

+0

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

+0

czy jest jakiś inny komponent, który muszę rozwiązać? –

36

jQuery jest nieco skomplikowany z atrybutami danych, ponieważ zarówno odczytuje znaczniki danych HTML5, jak i własną pamięć związaną z elementem DOM , który jest również nazywany danymi. Podczas zapisywania do atrybutu ta wartość zostaje skopiowana do własnego magazynu danych jQuerys (prawdopodobnie , gdy jest wywoływana data("remote")).

Jednak dzieje się tak tylko , jeśli dane jQuery są puste dla tej nazwy. Tak więc ustawienie atrybutu zadziała tylko raz, po czym zostanie użyta wartość "buforowana" , nawet jeśli atrybut się zmieni. Aby naprawdę pozbyć się wartości , musimy usunąć atrybut i własną pamięć masową jQuerys metoda w tej kolejności. Powodem jest wysoki poziom funkcji (element.removeData(…)) i niski poziom (jQuery. removeData(element, …)). Ten pierwszy ponownie odczytuje atrybut HTML5 o wartości i zapisuje go w pamięci własnej jQuery. Używanie raczej niezwykłej funkcji niskiego poziomu oczywiście również działa.

Ponadto, mamy naprawdę trzeba usunąć atrybut - ustawienie go na fałszywej jest nie tyle od Rails tylko sprawdza, czy form.data('remote') nie jest niezdefiniowany (poszukaj go w jquery_ujs.js).

TL, DR:

  • attr("data-remote") != data("remote")
  • tych dwóch linii, aby forma nie zdalnego (ponownie). Zamów sprawy.
$("form").removeAttr("data-remote"); 
    $("form").removeData("remote"); 

Jest udokumentowane, jeśli rzeczywiście wiedzą, czego szukasz:

StackOverflow nie pozwala mi, aby opublikować więcej niż dwa linki, ale można odgadnąć, usunąć jeden. Funkcje wysokiego poziomu są powiązane z funkcjami niskiego poziomu.

Unikanie tokena błąd autentyczności Rails 4+: jako Stan skomentował poniżej, po prostu robi powyższe nie powiedzie się z powodu błędu InvalidAuthenticityToken. Sposób obejścia jest łatwy, zobacz tutaj, aby uzyskać szczegółowe informacje: https://stackoverflow.com/a/19858504/1684530

+0

Świetny! Dałbym ci więcej niż jeden "do góry", gdyby to było możliwe !!! –

+0

Wyczyść i dokładnie, dzięki :) – Benj

+2

Kocham cię tak bardzo teraz –