2015-07-22 11 views
10

Attualmente sto cercando di aggiungere una classe CSS se una pagina è attiva. Qual è il modo migliore per farlo al momento a Phoenix? C'è un aiuto per questo caso?Applicare la classe CSS sull'elemento se la pagina corrente in Phoenix

def active(option, conn) do 
    if option == conn.request_path do 
    " class=\"active\"" 
    else 
    "" 
    end 
end 

Nel modello:

<%= "contact" |> active(@conn) |> raw %> 

risposta

4

ho creato un aiutante per questo che assomiglia:

defmodule LinkHelper 
    @doc """ 
    Calls `active_link/3` with a class of "active" 
    """ 
    def active_link(conn, controllers) do 
    active_link(conn, controllers, "active") 
    end 

    @doc """ 
    Returns the string in the 3rd argument if the expected controller 
    matches the Phoenix controller that is extracted from conn. If no 3rd 
    argument is passed in then it defaults to "active". 

    The 2nd argument can also be an array of controllers that should 
    return the active class. 
    """ 
    def active_link(conn, controllers, class) when is_list(controllers) do 
    if Enum.member?(controllers, Phoenix.Controller.controller_module(conn)) do 
     class 
    else 
     "" 
    end 
    end 

    def active_link(conn, controller, class) do 
    active_link(conn, [controller], class) 
    end 
end 

ho quindi importare questo nella funzione def view interno della web/web.ex

def view do 
    ... 
    import LinkHelper 
    ... 
end 

Uso:

<li class="<%= active_link(@conn, PageController)%>"><a href="<%= page_path(@conn, :index) %>">Home</a></li> 
<li class="<%= active_link(@conn, [FooController, BarController])%>"><a href="<%= foo_path(@conn, :index) %>">Foo or Bar</a></li> 
+0

Questa sembra una buona scelta per l'integrazione nel sistema Controller. Alcuni problemi con il tuo codice di esempio. 'defmodule LinkHelper do' e' importa LinkHelper' – rockerBOO

+0

@rockerBOO buon punto - deve aver dimenticato di aggiornare l'importazione quando l'ho copiato! – Gazler

+0

Questo approccio non imposta un collegamento a "attivo" per tutte le azioni del controller che si passa ad esso? Ad esempio, 'page_path (@conn,: index)' e 'page_path (@conn,: show)' saranno entrambi impostati su attivo se si passa 'PageController' a' active_link/3'. Non vogliamo che la pagina di presentazione sia "attiva" solo se siamo in page.show? – Gjaldon

15

useremo conn.path_info che restituisce il percorso attuale, come una lista di stringhe invece di conn.request_path. Potremmo usarlo per ottenere il nostro aiutante active_class.

def active_class(conn, path) do 
    current_path = Path.join(["/" | conn.path_info]) 
    if path == current_path do 
    "active" 
    else 
    nil 
    end 
end 

Poi lo usano come:

<%= link "Users", to: user_path(@conn, :index), class: active_class(@conn, user_path(@conn, :index))%> 

noti che user_path/2 due volte sopra. Potremmo a secco che con un altro aiutante:

def active_link(conn, path, opts) do 
    class = [opts[:class], active_class(conn, path)] 
      |> Enum.filter(& &1) 
      |> Enum.join(" ") 
    opts = opts 
     |> Keyword.put(:class, class) 
     |> Keyword.put(:to, path) 
    link text, opts 
end 

Perché utilizzare conn.path_info invece di conn.request_path? Questo perché conn.request_path restituirà il percorso esatto richiesto dall'utente. Se l'utente visita il percorso /foo/, quindi conn.request_path restituirà /foo/. Il problema è che l'helper del router che confronteremo restituirà sempre un percorso /foo senza il trailing /.

Spero che questo aiuti! Fammi sapere se qualcosa non è chiaro.

+0

Questo sembra abbastanza chiaro e piuttosto semplice e funziona direttamente con i percorsi. 'conn.request_path' è in 0.15 master su github in questo momento, ma non è in <0.15. – rockerBOO

+0

@rockerBOO hai ragione. È in plug master. Provato ma suggerirei comunque di usare 'conn.path_info'. Aggiornerò la mia risposta con il perché – Gjaldon

+0

Molto utile, ma la variabile 'text' non è definita. –

Problemi correlati