2017-12-28 135 views
15

मैं एक पुन: प्रयोज्य रिमोट मोडल बनाने की कोशिश कर रहा हूं। विचार एक मॉडल कंटेनर बनाना और yield के साथ सामग्री प्रस्तुत करना है और आवश्यकता होने पर सामग्री प्रस्तुत करना है।पुन: प्रयोज्य रिमोट मोडल रेल

नोट: सभी HTML कोड HAML में लिखा जाएगा। मैं अपने मॉडलों को संभालने के लिए bootstrap-modal-rails मणि का उपयोग कर रहा हूं।

मेरे मोडल कंटेनर लेआउट (एक आंशिक नहीं): है

-# ... 
%div(id="modal-holder") 

- unless params[:nojs] 
    = javascript_include_tag 'desktop' 

-# ... 

यहाँ जहां मेरी समस्या आता है:

%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 कि मोडल स्थान इस प्रकार परिभाषित करता है से। मेरे पास book controller है जहां उपयोगकर्ता पुस्तकें जोड़ सकता है। मेरे पास एक बहु-चरण पंजीकरण है और मेरी new कार्रवाई को मेरा मोडल होना चाहिए। जब उपयोगकर्ता New book लिंक पर क्लिक करता है, तो मैं एक नया मोडल लोड कर रहा हूं।

मेरे New book लिंक:

= link_to "New book", new_book_path, class: "c-link--navbar", data: { modal: true } 

CoffeeScript (jQuery में फिर से लिखा) मोडल के लिए (this article से इस कोड):

$(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; 
    }); 
}); 

और अब मेरी new actionyield के लिए किया जाएगा कि मेरे रिमोट मोडल के अंदर लोड किया गया:

= form_for(@book, remote: remote, html: {role: :form}, class: "c-form") do |f| 
    -# Forms here... 
    = f.submit "Add a new book", class: "c-btn" 

यदि उपयोगकर्ता की जानकारी सही है, तो मेरा मॉडल उपयोगकर्ता को general action पर रीडायरेक्ट करेगा अन्यथा मैं उसी पृष्ठ पर रहना चाहता हूं और एक त्रुटि संदेश फ्लैश करें लेकिन समस्या यह है कि मैं partial का उपयोग नहीं कर रहा हूं और यह स्वचालित रूप से मुझे एक को रीडायरेक्ट करता है new action के साथ नया पृष्ठ।

मेरे books_controller.rb:

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 

मोडल प्रतिसादी:

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 

मैं अपने create विधि के लिए

respond_to do |format| 
    format.html 
    format.json { render json: @book } 
end 

की तरह कुछ जोड़ने की कोशिश की, लेकिन यह काम नहीं करता है और अभी भी पुनर्निर्देश मुझे नए पेज पर। इसके अलावा, मैंने पहले से ही question से पूछा है और मैंने देखा है कि मेरा JavaScript कोड एक अलग पृष्ठ पर काम करता है। जब तक मैं समझता हूं कि समस्या मेरे रिमोट मोडल एक्शन पेज के साथ है। क्या कोई मुझे यह जानने में मदद कर सकता है कि उसी पृष्ठ पर कैसे रहना है जब उपयोगकर्ता गलत इनपुट दर्ज करता है और मेरी जावास्क्रिप्ट चालू करता है?

+0

यदि आप चाहते हैं कि आपका पृष्ठ रीडायरेक्ट नहीं किया जा रहा हो। हेडर के बिना बस अपनी AJAX प्रतिक्रिया वापस करें: स्थान – plonknimbuzz

+0

@plonknimbuzz मैं 'AJAX: सफलता' पर रीडायरेक्ट करना चाहता हूं और उसी पृष्ठ पर रहना चाहता हूं जब' AJAX: त्रुटि' ... मुझे लगता है कि मेरे AJAX और नियंत्रक सेटिंग्स के साथ समस्या है। प्रतिक्रिया के लिए बहुत बहुत धन्यवाद :) –

+0

हैलो .. मैंने आपकी जिथब प्रोफाइल की जांच की है। यह एक ओपनसोर्स परियोजना नहीं है? यह डिबगिंग करके समाधान ढूंढना शायद आसान होगा ... अगर आप मुझे अपनी परियोजना को फोर्क करते हैं अन्यथा मैं गहरा दिख सकता हूं –

उत्तर

1

TBH एक सार समाधान जो आपके सवाल का सीधे से संबंधित नहीं है कि, यह हालांकि काम करता है (बूटस्ट्रैप + JQ, उत्पादन कोड के आधार पर)

Coffe स्क्रिप्ट

$.showModal = (title, body) -> 
    $("#modal").find(".modal-title").html(title) 
    $("#modal").find(".modal-body").html(body) 
    $("#modal").modal("show") 
$("#modal").find(".modal-submit").click() -> 
    $("#modal").find("form").submit() 

एचटीएमएल - ठेठ बूटस्ट्रैप मोडल

<div id="modal" class="modal" tabindex="-1" role="dialog"> 
    <div class="modal-dialog modal-lg" role="document"> 
    <div class="modal-content"> 
     <div class="modal-header"> 
     <h5 class="modal-title"></h5> 
     <button type="button" class="close" data-dismiss="modal" aria-label="<%= t :close %>" title="<%= t :close %>"> 
      <span aria-hidden="true"></span> 
     </button> 
     </div> 
     <div class="modal-body"> 
     <p></p> 
     </div> 
     <div class="modal-footer"> 
     <button type="button" class="btn btn-danger" data-dismiss="modal"><%= t :close %></button> 
     <button type="button" class="btn btn-success modal-submit"><%= t :save %></button> 
     </div> 
    </div> 
    </div> 
</div> 

new.js.erb या किसी अन्य रेल

$.showModal(
    "<%= escape_javascript t :edit_comment %>", 
    "<%= escape_javascript(render 'form', :comment => @comment) %>" 
); 

लिंक देखने मोडल खोलने के लिए

<%= link_to t(:new), [:new, comment], :remote => true, class: "btn" %> 

आप शायद अपने स्वयं के ajax अनुरोध उपयोग करना चाहते हैं - यह एक सर्वर के मामले में कुछ भी नहीं करना होगा त्रुटि/समय समाप्ति

+0

आपके उत्तर के लिए बहुत बहुत धन्यवाद! वास्तव में अपने समय की सराहना करते हैं। आपके समाधान को लागू करने का प्रयास करेंगे। –

संबंधित मुद्दे