Request.xhr? :)

Dobry wieczór. Mam taki problem - mianowicie chciałbym, żeby w okienku stworzonym przez colorbox’a ukazywał się niezrenerowany layout.
Zrobiłem tak:

layout Proc.new { |controller| controller.request.xhr? ? false : 'application' }

Problem jest taki, że request.xhr? zwraca cały czas false. I nawet, gdy otwieram stronę poprzez colorbox, to layout cały czas się renderuje.
Zrobiłem zaś tak:

$(document).ready(function() { $('.login').click(function() { new XMLHttpRequest(); $(".login").colorbox({iframe:true, width:"30%", height:"40%"}); }); });
Ale dalej nie działa, mógłby mi ktoś pomóc? :slight_smile: Byłbym wdzięczny.

W jednej ze starszych aplikacji umieściłem w ApplicationController mam coś takiego:

[code]layout :set_layout

def set_layout
if params.has_key? :skip_layout or params[:format] == “js”
nil
else
‘application’
end
end[/code]
i wszystkie requesty AJAX-a idą na ścieżkę z rozszerzeniem .js.

W Twoim przypadku, spróbuj sprawdzić, czy w nagłówkach zapytania z pluginu (w kontrolerze/widoku: request.headers) jest coś takiego:

“X-Requested-With” z wartością “XMLHttpRequest”

[quote=sbl]W jednej ze starszych aplikacji umieściłem w ApplicationController mam coś takiego:

[code]layout :set_layout

def set_layout
if params.has_key? :skip_layout or params[:format] == “js”
nil
else
‘application’
end
end[/code]
[/quote]
Działa. Ale nie tak jakbym sobie życzył (czyli nie niluje layoutu), choć w respond_to posiadam .js :frowning:

“X-Requested-With” z wartością “XMLHttpRequest”

Nie mam żadnej z tych wartości. I właśnie w tym tkwi problem, bo nie mam żadnego XHR’a.

To, co pokazujecie, to mniej lub bardziej hacki.

Jose Valim pisał gdzieś o responderach w rails 3. Najlepiej by było gdybyś stworzył respondera i tam nadpisał odpowiednie metody. Mogę mniej więcej napisać, ale po weekendzie, bo musiałbym trochę się kodem pobawić ;).

Pozdrawiam!

[quote=sarniak]To, co pokazujecie, to mniej lub bardziej hacki.

Jose Valim pisał gdzieś o responderach w rails 3. Najlepiej by było gdybyś stworzył respondera i tam nadpisał odpowiednie metody. Mogę mniej więcej napisać, ale po weekendzie, bo musiałbym trochę się kodem pobawić ;).

Pozdrawiam![/quote]
Dziękuję, bardzo mi pomogłeś! A ma ktoś może jakieś inne, bardziej treściwe propozycje? :slight_smile:

Które to railsy?

Nie kpij :wink:

Gdybyś zadał sobie choć odrobinę trudu i wpisał w googlu jose valim responders, to na pierwszym miejscu znalazłbyś:

:slight_smile:

A tam:

class ActionController::Responder def to_html if get? render elsif has_errors? render :action => (post? ? :new : :edit) else redirect_to resource end end end
A potem już krótka droga do:

def to_html if get? render :action => default_action, :layout => !request.xhr? elsif has_errors? render :action => (post? ? :new : :edit), :layout => !request.xhr? else redirect_to resource end end
Nie wiem, czy chcesz to tylko w get, czy też w put/post.

Zrób plik lib/responders.rb, a tam:

[code=ruby]require “responders/twoj_responder”

module Responders
class AppResponder < ActionController::Responder
include TwojResponder
end
end

ActionController::Base.responder = Responders::AppResponder[/code]
W pliku lib/responders/twoj_responer.rb:

module Responders module TwojResponder def to_html (...) end end end
Tak jak pisałem, przed weekendem nie mam czasu tego ruszyc, po weekendzie chciałem się tym pobawić. Teraz nie wiem czy to zadziała w 100% tak jak sobie to zaplanowałeś, ale na pewno coś takiego jest możliwe.

Więcej dociekliwości życzę na przyszłość :>

3.1.3

sarniak, dziękuję za odpowiedź. Ja zadałem pytanie, dlaczego mój request.xhr zawsze wynosi false.

3.1.3[/quote]
Tzn. że jest tak jak napisał sbl, musisz w javascripcie dodać odpowiedni header X-Requested-With. Railsy po tym już od dawna sprawdzają czy to jest ajax czy nie: https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/request.rb#L149-152

Poczytaj w dokumentacji jquery jak dodać headery. Chyba można też ustawić jakiś globalny callback wykonywany przed każdym requestem $.ajax, więc wystarczy, że ustawisz tam ten header.

jQuery.ajaxSetup({ 'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")} })
Cos w ten desen ?

Raczej:

jQuery.ajaxSetup({ 'beforeSend': function(xhr) {xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")} })
Header Accept mówi tylko jakiego typu odpowiedzi oczekuje klient, ale może to być dowolnie wykonany request. Kiedyś rzeczywiście używało się do tego accpet, bo można było założyć, że jeżeli ktoś pyta o js, to raczej nie jest to zwykłe zapytanie przeglądarkowe po kliknięciu w link, ale to jest na dłuższą metę kiepskie założenie.

Dzieki drogus przyda sie :]

drogus, to rozwiązało mój problem - wielkie dzięki. Ogólnie dziękuję wszystkim za zainteresowanie moim tematem :slight_smile:

3.1.3

sarniak, dziękuję za odpowiedź. Ja zadałem pytanie, dlaczego mój request.xhr zawsze wynosi false.[/quote]
pewnie :slight_smile: Tylko zastanów się, czy jesli i tak robisz tak w kazdym przypadku, to nie lepiej zadzialac magia responderow - wtedy bys nie musiał nic w before send ustawiac.