Используйте JS для изменения <form> от удаленного до не удаленного в Rails 3, HAML

Проблема заключается в том, что у меня есть удаленная форма, которая на основе условия id как будто бы конвертируется в не-удаленную форму (с использованием UJS), а затем отправляет. обратите внимание, что форма имеет загрузку файла.

Здесь подробности: я изначально предоставил удаленную форму, используя

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

который создает HTML:

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

когда я нажимаю submit, как и ожидалось, форма отправляется "AS JS". в действии контроллера, я делаю некоторую проверку полей внутри представленной формы. Если все проверки проходят, я выполняю следующий шаблон .js.haml:

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

который успешно изменяет HTML на странице (засвидетельствован через Firebug), чтобы:

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

так как форма содержит f.file_field, я должен представить как multipart, чтобы изображение могло быть загружено, и я не могу отправить 'AS JS' теперь, когда я нажимаю кнопку "Отправить", действие контроллера "regularAction" действительно вызывается, но его все еще "AS JS"

вопрос в том, что еще мне нужно изменить в HTML, чтобы форма могла быть отправлена ​​не-xhr? это связано с заголовками?

Ответы

Ответ 1

jQuery немного сложнее с атрибутами данных, поскольку оба читает теги данных HTML5, а также собственное хранилище, связанное с DOM, который также называется данными. При написании атрибута это значение копируется в собственное хранилище данных jQuerys (предположительно когда data("remote") вызывается).

Однако это происходит только если данные jQuerys пусты для этого имени. Таким образом, параметр атрибут будет работать только один раз, после чего используется "кэшированное" значение даже если атрибут изменяется. Чтобы действительно избавиться от value, нам нужно удалить атрибут и собственное хранилище jQuery метод в этом порядке. Причина в том, что theres высокого уровня (element.removeData(…)) и низкоуровневой (jQuery. removeData(element, …)). Первый перечитывает данные HTML5 атрибут и сохраняет его в собственном хранилище jQuery. Использование довольно необычная функция низкого уровня, очевидно, также работает.

Кроме того, нам действительно нужно удалить атрибут - установив его на false недостаточно, поскольку Rails проверяет только, если form.data('remote') не undefined (найдите его в jquery_ujs.js).

TL; ДР:

  • attr("data-remote") != data("remote")
  • Эти две строки делают форму не удаленной (снова). Вопросы для заказа.
  $("form").removeAttr("data-remote");
  $("form").removeData("remote");

Его документально подтвердили, если вы действительно знаете, что ищете:

StackOverflow не позволяет отправлять более двух ссылок, но вы можете угадать файл removeData. Функции высокого уровня связаны с низкоуровневыми.

Предотвращение ошибки аутентификации маркера в Rails 4 +: Как сказал Стэн ниже, просто выполнение вышеизложенного приведет к ошибке с ошибкой InvalidAuthenticityToken. Обходной путь очень прост, см. Здесь для деталей: fooobar.com/questions/156168/...

Ответ 2

Проблема заключается в том, что ваш подход к отключению представления Ajax не совсем корректен. Вам нужно отменить события JavaScript, которые уже были добавлены rails.js(адаптером Rails UJS) в форму. Вы можете это сделать: $('form#new_myobj').unbind(), чтобы отменить все события, связанные с формой. Вам также необходимо $('form#new_myobj').removeAttr('data-remote') и $('form#new_myobj').removeAttr('data-type') удалить атрибуты data-remote и data-type (если они существуют).