Я новичок в Rails, пытаюсь сделать многоразовое модальное окно. Суть заключается в том, что бы сделать контейнер и импортировать туда нужный мне контент через
yield
.
ПС: HTML код будет написан с помощью HAML. Так же я использую
bootstrap-modal-rails gem для отображения окон.
Так выглядит мой контейнер для окна:
%div(class="modal" id="mainModal ajax-modal" tabindex="-1" role="dialog"){:'aria-labelledby'=>"mainModalLabel", :'aria-hidden'=>"true"}
%div(class="c-modal__container")
%div(class="c-modal__layout modal__content")
= yield
В моем
application.html.haml
у меня
div
элемент, который в дальнейшем отображает мое диалоговое окно:
-# ...code...
%div(id="modal-holder")
- unless params[:nojs]
= javascript_include_tag 'desktop'
-# ...code...
Отсюда выходит моя проблема. У меня есть
book controller
. Каждый пользователь может добавлять книгу, редактировать ее информацию и так далее. Я использую многоступенчатую регистрацию, другими словами, когда пользователь нажимает
добавить книгу, у меня должно появиться диалоговое окно, с формой регистрации, которые (при успешном заполнении формы) переносит на страницу
дополнительная информация.
Ссылка в моем меню:
= link_to "New book", new_book_path, class: "c-link--navbar", data: { modal: true }
Код модального окна:
$(function() {
var modal_holder_selector, modal_selector;
modal_holder_selector = '#modal-holder';
modal_selector = '.modal';
$(document).on('click', 'a[data-modal]', function() {
var location;
location = $(this).attr('href');
$.get(location, function(data) {
return $(modal_holder_selector).html(data).find(modal_selector).modal();
});
return false;
});
return $(document).on('ajax:success', 'form[data-modal]',
function(event, data, status, xhr) {
var url;
url = xhr.getResponseHeader('Location');
if (url) {
window.location = url;
} else {
$('.modal-backdrop').remove();
$(modal_holder_selector).html(data).find(modal_selector).modal();
}
return false;
});
});
При переходе по ссылке или кнопке, вылетает окно с формой:
-# ...code...
= form_for(@book, remote: remote, html: {role: :form}, class: "c-form") do |f|
-# Forms here...
= f.submit "Add a new book", class: "c-btn"
-# ...code...
В целом все работает правильно, однако при допущении ошибки при вводе, меня перекидывает на
отдельную страницу, где находится аналогичная форма. Иными словами, мое окно становиться отдельной страницей.
Мой
book controller
:
class BooksController < ApplicationController
respond_to :html, :json, :js
...
def index
@books = current_user.books
end
def new
@book = current_user.books.build
respond_modal_with @book
end
def create
@book = current_user.books.build(book_params)
if @book.save
redirect_to general_book_path(@book), notice: "Saved."
else
flash.now[:notice] = "Something went wrong."
render :new
end
end
...
end
respond_modal_width
метод:
class ModalResponder < ActionController::Responder
cattr_accessor :modal_layout
self.modal_layout = 'modal'
def render(*args)
options = args.extract_options!
if request.xhr?
options.merge! layout: modal_layout
end
controller.render *args, options
end
def default_render(*args)
render(*args)
end
def redirect_to(options)
if request.xhr?
head :ok, location: controller.url_for(options)
else
controller.redirect_to(options)
end
end
end
Собственно моя задача заключается в том, что бы при ошибке, пользователя не перекидывало на новую страницу, а оставляло на одной и той же, с открытым диалоговым окном. Я прекрасно понимаю, что подобную проверку можно сделать с обычным
jQuery
, но мне нужно понять как добиться подобного результата с
Ruby on Rails
. Хочу заметить, что в
yeild
загружается непосредственно сам
action
, а не
partial
. По этому поводу, у меня выходит вторая проблема, связанная с тем, что
jQuery code
не работает внутри моего окна.
Аналогичный вопрос я задал на StackOverflow:
Reusable remote modal Rails
И:
jQuery UI autocomplete in remote modal RoR
Огромное спасибо за Ваше время и помощь.