Conditional CSS in nodes and views

Rating

Make your site attractive by presenting content as a table. I use the following case ... in a content type, one can choose a part of a day (morning, afternoon or evening). You can use this for a room occupation, courses, meetings, booking, ...

We use a text list for input

Screen001685.png

With Chosen it looks like this.

Screen001683.png

Instead of the display in text we present a  table.

For a node it looks like this:
Screen001689.png

For a view you have this:

Screen001688.png

How do you create something like that...?

1) For a node

Make in your content type a field that displays the table in default, without any connection layout or connection to other field content.

Screen001690.png

Make sure that each cell of the table has a unique class has (eg class = "mavm")

<table border="1" cellpadding="1" cellspacing="1" style="text-align:center;">
    <thead>
        <tr>
            <th scope="row">&nbsp;</th>
            <th scope="col"><strong>ma</strong></th>
            <th scope="col"><strong>di</strong></th>
            <th scope="col"><strong>wo</strong></th>
            <th scope="col"><strong>do</strong></th>
            <th scope="col"><strong>vr</strong></th>
            <th scope="col"><strong>za</strong></th>
            <th scope="col"><strong>zo</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row"><strong>vm</strong></th>
            <td class="mavm">&nbsp;</td>
            <td class="divm">&nbsp;</td>
            <td class="wovm">&nbsp;</td>
            <td class="dovm">&nbsp;</td>
            <td class="vrvm">&nbsp;</td>
            <td class="zavm">&nbsp;</td>
            <td class="zovm">&nbsp;</td>
        </tr>
        <tr>
            <th scope="row"><strong>nm</strong></th>
            <td class="manm">&nbsp;</td>
            <td class="dinm">&nbsp;</td>
            <td class="wonm">&nbsp;</td>
            <td class="donm">&nbsp;</td>
            <td class="vrnm">&nbsp;</td>
            <td class="zanm">&nbsp;</td>
            <td class="zonm">&nbsp;</td>
        </tr>
        <tr>
            <th scope="row"><strong>av</strong></th>
            <td class="maav">&nbsp;</td>
            <td class="diav">&nbsp;</td>
            <td class="woav">&nbsp;</td>
            <td class="doav">&nbsp;</td>
            <td class="vrav">&nbsp;</td>
            <td class="zaav">&nbsp;</td>
            <td class="zoav">&nbsp;</td>
        </tr>
    </tbody>
</table>

 

So if there is something on the page with the style that has been defined eg mavm as an orange background, the cell will be associated with the orange colors. The question remains how you set these classes.

Therefore we create a text block in PHP format. We ensure that this block appears on all nodes of the content type. 

Screen001692.png

The code consists of only a few lines ... First we put some style on our table. Then we'll pick the node ID. From a block you refer this via route match (). We load the node ID and then we use the multiple field. Hence the loop. For every value we define a style for the background of the cell.

<?php
echo '<style>
tr{height:40px;} 
td,th{width:40px;padding:5px;text-align:center;}
</style>';
$nid = \Drupal::routeMatch()->getParameter('node')->Id();
$node= node_load($nid);

foreach ($ node-> get ( 'field_dagdeel') as $ item) { 
       $ session = $ item-> value; 
 echo '<style>.' $ session '{background: # c25e03;} </ style>';.. 
     }

?>

Although, in the table, each cell refers to a class, there are only classes which occur in the selection of the field 'part of the day'. Here, four items were selected and there are being created four styles. Other styles eg zovm get no code and will also get nothing in the layout.

Screen001693.png

The block defining the styles and the table will be synchronized on the page during loading. The the text field can be hidden from display. The default table can be hidden for the input.

2) For a view

In a view you can rewrite fields and add PHP view fields. None of them allows you to use the <style> tag for security reasons. The discussion on this subject is one that has been going for eight years:  https://www.drupal.org/project/views/issues/853880  ; I can work around this problem without compromising security.I am following this method:

In an overview you have the problem that you can not use the classes mavm, manm, maav ... as they appear in different rows of the view. So we must have an identifier to refer specifically to the row. Each row corresponds to a node ID, which is why it seems obvious to use the node ID..

In the view we will use these fields. 

Screen001694.png

Global: customized text use fullt HTML source code an add a token for the NID. It is the same table as in the node, but with a class which also contains the token of the nid: {{}} nid

For each row you get a different class and this is exactly what we need.

<table border="1" cellpadding="1" cellspacing="1" style="height:125px; width:250px; text-align:center;">
    <thead>
        <tr>
            <th scope="row">&nbsp;</th>
            <th scope="col"><strong>ma</strong></th>
            <th scope="col"><strong>di</strong></th>
            <th scope="col"><strong>wo</strong></th>
            <th scope="col"><strong>do</strong></th>
            <th scope="col"><strong>vr</strong></th>
            <th scope="col"><strong>za</strong></th>
            <th scope="col"><strong>zo</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row"><strong>vm</strong></th>
            <td class="mavm{{ nid }}">&nbsp;</td>
            <td class="divm{{ nid }}">&nbsp;</td>
            <td class="wovm{{ nid }}">&nbsp;</td>
            <td class="dovm{{ nid }}">&nbsp;</td>
            <td class="vrvm{{ nid }}">&nbsp;</td>
            <td class="zavm{{ nid }}">&nbsp;</td>
            <td class="zovm{{ nid }}">&nbsp;</td>
        </tr>
        <tr>
            <th scope="row"><strong>nm</strong></th>
            <td class="manm{{ nid }}">&nbsp;</td>
            <td class="dinm{{ nid }}">&nbsp;</td>
            <td class="wonm{{ nid }}">&nbsp;</td>
            <td class="donm{{ nid }}">&nbsp;</td>
            <td class="vrnm{{ nid }}">&nbsp;</td>
            <td class="zanm{{ nid }}">&nbsp;</td>
            <td class="zonm{{ nid }}">&nbsp;</td>
        </tr>
        <tr>
            <th scope="row"><strong>av</strong></th>
            <td class="maav{{ nid }}">&nbsp;</td>
            <td class="diav{{ nid }}">&nbsp;</td>
            <td class="woav{{ nid }}">&nbsp;</td>
            <td class="doav{{ nid }}">&nbsp;</td>
            <td class="vrav{{ nid }}">&nbsp;</td>
            <td class="zaav{{ nid }}">&nbsp;</td>
            <td class="zoav{{ nid }}">&nbsp;</td>
        </tr>
    </tbody>
</table>

in the HTML code this looks like this (looking at the table of node 43)

Screen001695.png

Another row has this HTML code.:

Screen001696.png

No we have to create a block again, this time including the node ID. Create a block and let it appear if the view is displayed.

First we make an overall style for the cells. After that, we go in a loop for all the nodes of the content type that have the status = 1 (= unpublished). Then we capture the $nid (= node ID), and pick up again to make the same loop in order to obtain all the values ​​which have been selected in the selection list.

<?php
echo '<style>tr{height:40px;}td,th{width:40px;padding:5px;text-align:center;}</style>';
$nids = \Drupal::entityQuery('node')
  ->condition('status', 1)$
  ->condition('type', 'lokaalbezetting')
  ->execute();
$nodes = \Drupal\node\Entity\Node::loadMultiple($nids);
foreach ($nodes as $node) {
    $nid = $node->id();

foreach ($ node-> get ( 'field_dagdeel') as $ item) { 
       $ session = $ item-> value; 
value = $ $ $ nid part of the day.; 
 echo '<style>.' $ value '{background: # c25e03;} </ style>';.. 
     } 
     } 
?>

A possible result (note the different node IDs). Each views row has its own class, according to the node.

Screen001697.png

When displaying the view, the table and the block style synchronise.

Screen001698.png