Je dois parfois ajouter une classe à un élément html en fonction d'une condition. Le problème est que je ne peux pas trouver une manière propre de le faire. Voici un exemple de ce que j'ai essayé:
<div <%= if @status = 'success'; "class='ok'"; end %>>
some message here
</div>
OU
<% if @status == 'success' %>
<div class='success'>
<% else %>
<div>
<% end %>
some message here
</div>
Je n'aime pas la première approche car elle est encombrée et difficile à lire. Je n'aime pas la deuxième approche car l'emboîtement est foiré. Ce serait bien de le mettre dans le modèle, (quelque chose comme @status.css_class
), mais cela n'y appartient pas. Que font la plupart des gens?
J'utilise la première façon, mais avec une syntaxe un peu plus succincte:
<div class="<%= 'ok' if @status == 'success' %>">
Bien qu'en général, vous devriez représenter le succès avec booléen true
ou un ID d'enregistrement numérique, et l'échec avec booléen false
ou nil
. De cette façon, vous pouvez simplement tester votre variable:
<div class="<%= 'ok' if @success %>">
Un deuxième formulaire utilisant le ternaire ?:
L'opérateur est utile si vous souhaitez choisir entre deux classes:
<div class="<%= @success ? 'good' : 'bad' %>">
Enfin, vous pouvez utiliser Rail's record tag helpers comme div_for
, qui définira automatiquement votre ID et votre classe en fonction de l'enregistrement que vous lui fournissez. Étant donné un Person
avec l'ID 47:
# <div id="person_47" class="person good">
<% div_for @person, class: (@success ? 'good' : 'bad') do %>
<% end %>
Le problème avec l'approche standard est qu'elle nécessite une logique sous la forme d'instructions if
ou de ternaires dans la vue. Si vous avez plusieurs classes CSS conditionnelles mélangées avec des classes par défaut, vous devez mettre cette logique dans une interpolation de chaîne ou une balise ERB.
Voici une approche mise à jour qui évite de mettre toute logique dans les vues:
<div class="<%= class_string(ok: @success) %>">
some message here
</div>
class_string
méthodeLe class_string
helper prend un hachage avec des paires clé/valeur composées de chaînes de nom de classe CSS et valeurs booléennes . Le résultat de la méthode est une chaîne de classes où la valeur booléenne est évaluée à true.
class_names(foo: true, bar: false, baz: some_truthy_variable)
# => "foo baz"
Cette aide peut être utilisée dans les balises ERB
ou avec les aides Rails telles que link_to
.
<div class="<%= class_string(ok: @success) %>">
some message here
</div>
<% div_for @person, class: class_string(ok: @success) do %>
<% end %>
<% link_to "Hello", root_path, class: class_string(ok: @success) do %>
<% end %>
Pour les cas d'utilisation où un ternaire serait nécessaire (par exemple @success ? 'good' : 'bad'
), passez un tableau où le premier élément est la classe pour true
et l'autre est pour false
<div class="<%= [:good, :bad] => @success %>">
Cette technique est inspirée d'un module complémentaire appelé classNames
(anciennement classSet
) du framework front-end React
de Facebook.
À partir de maintenant, le class_names
la fonction n'existe pas dans Rails, mais cet article vous montre comment l'ajouter ou l'implémenter dans vos projets.
Vous pouvez également utiliser l'assistant content_for, en particulier si le DOM est situé dans une présentation et que vous souhaitez définir la classe css en fonction de la charge partielle.
Sur la mise en page:
%div{class: content_for?(:css_class) ? yield(:css_class) : ''}
Sur le partiel:
- content_for :css_class do
my_specific_class
C'est ça.