Javascript не выполняется

Я не могу понять, почему мой javascript не выполняется (и на самом деле не выполняется).

/app/assets/javascripts/application.js:

//= require jquery
//= require bootstrap-sprockets
//= require turbolinks
//= require jquery_ujs
//= require_tree .

/app/controllers/project_controller.rb:

def upload
    @projects = Project.all.order(updated_at: :desc)
    @project = Project.find(params[:id])
    respond_to do |format|
        format.html
        format.js {render layout: false}
    end
end

/app/views/projects/show.html.erb:

<%= link_to project_upload_path, :project => @project.id, class: "btn btn-default" do %>
    Upload &nbsp;
    <%= glyph("plus") %>
<% end %>

/app/views/projects/upload.html.erb:

<div class="row">
    <div class="col-xs-12">
        <h2>Upload File to <%= @project.name %> project</h1>
    </div>
    <br>
    <div class="col-xs-12">
        <%= render :partial => "uploadform", :action => "savefile" %>
    </div>
</div>

/app/views/projects/_uploadform.html.erb:

<%= form_for :upload, url: {action: "savefile"}, :multipart => true  do |f| %>
    <%= f.hidden_field(:project_id, :value => params[:id]) %>
    <%= f.file_field :file, input_html: { hidden: true }, label: 'Upload Attachment'  %>
    <input id="file-display" class="input-large uneditable-input" type="text">
    <%= f.submit "Save File", :class => "btn btn-default btn-file", :id => "upload-btn" %>
<% end %>

/app/views/projects/upload.js.erb:

$(document).on('ajax:success', function() {
    alert("Test");
});

Все перепробовала. Я добавил и удалил "{render layout: false}" в своем контроллере. Я пробовал "page: change" и "turbolinks: load" в моем upload.js.erb (вместо "ajax: success"). Я пробовал все функции Java-Ready в "_uploadform.js.erb" (вместо "upload.js.erb"). Я пробовал «remote: true» в link_to (show.html.erb), но тогда он запускал только js.erb (только появилось предупреждение). Я также обновил Rails с 4.2.1 до 4.2.7.1 и попробовал "// = require jquery.turbolinks" в application.js (со всеми функциями, готовыми к работе с документами выше).

Как вы можете видеть в моем журнале, похоже, что он не отвечает с помощью Javascript:

Started GET "/projects/upload/20" for 127.0.0.1 at 2016-10-05 14:05:48 +0200
Processing by ProjectsController#upload as HTML
  Parameters: {"id"=>"20"}
  Project Load (0.0ms)  SELECT  "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT 1  [["id", 20]]
  Rendered projects/_uploadform.html.erb (0.0ms)
  Rendered projects/upload.html.erb within layouts/application (2.4ms)
Completed 200 OK in 327ms (Views: 324.8ms | ActiveRecord: 0.0ms)

Помогите, пожалуйста. Я не понимаю, почему это никак не работает.


person Jens Schmidt    schedule 05.10.2016    source источник
comment
Не думаю, что есть селектор ajax:success. Вы имели в виду $(document).ajaxSuccess   -  person VLAZ    schedule 05.10.2016
comment
Нет. Я не знаю, где я это взял, но он не работает ни с turbolinks: load, ни с page: change. Итак, да, возможно, ajax: success - это неправильно, но другие селекторы тоже не работают.   -  person Jens Schmidt    schedule 05.10.2016
comment
Не знаю, есть ли разница, но попробуйте загрузить jquery_ujs после jquery в свой application.js   -  person Alex Zakruzhetskyi    schedule 05.10.2016
comment
нет, к сожалению, это не помогло (даже если я просто загрузил jquery после jquery_ujs (потому что, на мой взгляд, я уже загрузил jquery_ujs после jquery)).   -  person Jens Schmidt    schedule 05.10.2016


Ответы (2)


Вам нужно указать rails для выполнения публикации формы через JavaScript. В журнале вы можете видеть, что PagesController отображает HTML, а не JS.

Processing by ProjectsController#upload as HTML

Попробуйте добавить: remote => true в свой помощник form_for

<%= form_for :upload, url: {action: "savefile"}, :multipart => true, :remote => true do |f| %> <%= f.hidden_field(:project_id, :value => params[:id]) %> <%= f.file_field :file, input_html: { hidden: true }, label: 'Upload Attachment' %> <input id="file-display" class="input-large uneditable-input" type="text"> <%= f.submit "Save File", :class => "btn btn-default btn-file", :id => "upload-btn" %> <% end %>

См. Руководства по рельсам http://guides.rubyonrails.org/working_with_javascript_in_rails.html#form-for для получения дополнительной информации.

person Jason Yost    schedule 05.10.2016
comment
К сожалению, это тоже не работает. Я также пытался переместить вещи из upload.js.erb в _uploadform.js.erb, но в журналах я вижу, что он все еще отображается в HTML вместо JS, хотя у меня есть data-remote = true в HTML моего форма. Любые другие идеи? - person Jens Schmidt; 05.10.2016
comment
Я обнаружил, что если я установил значения по умолчанию: {: format = ›'js'} в моем routes.rb, мне нужно было создать исключение из Forgery (protect_from_forgery кроме:: upload, из-за ошибки: Предупреждение безопасности: встроенный тег ‹script› на другом сайте запросил защищенный JavaScript. Если вы знаете, что делаете, отключите защиту от подделки для этого действия, чтобы разрешить встраивание JavaScript из разных источников.), а затем JS просто отображается в браузере как текстовый файл. - person Jens Schmidt; 06.10.2016

Похоже, вы пытаетесь загрузить файлы с помощью запроса AJAX, требующего: multipart => true и: remote => true для определения вашей формы.

Загрузка файлов не может выполняться удаленно, однако эта проблема легко решается с помощью драгоценного камня Remotipart - он позволяет загружать файлы AJAX без каких-либо дополнительных изменений в вашем коде.

  1. Добавьте gem 'remotipart' в свой Gemfile.
  2. Добавьте // = require jquery.remotipart в application.js (после jquery_ujs)
  3. Используйте remote: true и multipart: true в объявлении формы.

Теперь у вас должна быть возможность асинхронно загружать файлы.

Для получения дополнительной информации посетите https://github.com/JangoSteve/remotipart.

person David    schedule 05.10.2016
comment
На самом деле я пытаюсь использовать Boostrap Design для кнопки Filebrowser. Разве в этой ситуации невозможно иметь Javascript (чтобы делать что угодно после загрузки страницы)? - person Jens Schmidt; 06.10.2016
comment
Что ж, это именно то, что дает вам удаленный доступ. Я обновил свой ответ более четкими инструкциями - person David; 06.10.2016
comment
Спасибо, но он работает не так, как я ожидал. Может быть, мне было непонятно, чего я пытаюсь достичь. Я хотел бы выполнить javascript, когда мое представление с моей кнопкой просмотра файла (представление с form_for на нем) завершит загрузку, а не после того, как я что-то загрузил. Даже с удаленной частью мой javascript в этот момент не выполняется. - person Jens Schmidt; 06.10.2016
comment
Если я правильно понимаю, вы пытаетесь отобразить форму загрузки и запустить код в upload.js.erb. Rails так не работает. upload.js.erb отображается в результате AJAX-вызова действия загрузки контроллера, а upload.html.erb отображается в результате HTML-вызова действия загрузки контроллера (но не обоих одновременно). Ваша ссылка в show.html.erb представляет собой прямой вызов html, поэтому загрузка отвечает путем рендеринга upload.html.erb. Если вы хотите вызвать (jquery) при загрузке страницы, просто вставьте $ (document) .ready (function () {...}); в теге ‹script› в файле html.erb - person David; 06.10.2016
comment
В этом случае, я думаю, в прошлом меня вводили в заблуждение некоторые учебники - я думал, встроенные скрипты - это плохая идея, а не путь рельсов. И, конечно же, с этим все работает. Большое спасибо! - person Jens Schmidt; 06.10.2016