Voorwaardelijke CSS in nodes en views

Moeilijkheidsgraad

Maak je site aantrekkelijk door saaie inhoud zeer visueel voor te stellen. Ik werk de volgende case uit... In een inhoudstype kan je een dagdeel kiezen (voormiddag, namiddag of avond). Je kunt dit gebruiken voor een lokaalbezetting, cursus, bijeenkomst, boeking,...

We gebruiken een tekstlijst voor de input

Screen001685.png

Met Chosen ziet dit er zo uit.

Screen001683.png

In plaats van dit in letters weer te geven maken we er een overzichtelijke tabel van.

Voor een node ziet dit er zo uit:
Screen001689.png

Voor de view heb je deze print:

Screen001688.png

Hoe maak je nu zoiets...?

1) Voor een node

Maak in je inhoudstype een veld bij dat in de standaardwaarde de tabel weergeeft, zonder enig verband met de keuze van de dagdelen.

Screen001690.png

Zorg er ook voor dat elke cel van de tabel een eigen klasse heeft (vb 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>

 

Als er dus ergens op de pagina nu een stijl wordt gedefinieerd dat bvb mavm een oranje achtergrond geeft, dan zal de cel met de bijhorende klasse oranje kleuren. De vraag blijft natuurlijk hoe je dat dan weer instelt.

Daarvoor maken we een blok aan in PHP tekstformaat. We zorgen er voor dat dit blok op alle nodes van het inhoudstype van toepassing is.

Screen001692.png

De code bestaat slechts uit een paar lijnen... Eerst gaan we onze tabel wat meer opmaken. daarna gaan we de node ID ophalen. Vanuit een blok doe je dit via routeMatch(). We laden de node gegevens in en doorlopen het dagdeel veld dat meervoudig werd ingesteld. Vandaar de lus. Voor elke waarde definiëren we een stijl voor de achtergrond van de cel.

<?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) {
       $dagdeel=$item->value;
 echo '<style>.'.$dagdeel.'{background:#c25e03;}</style>';
     }

?>

Alhoewel in de tabel elke cel verwijst naar een klasse worden er enkel klassen gedefinieerd die voorkomen in de keuze van het veld dagdeel. Hier werden er vier items geselecteerd en worden er 4 stijlen aangemaakt. Andere stijlen bvb zovm krijgen geen code en zullen dus ook niets qua opmaak krijgen.

Screen001693.png

Het blok dat de stijlen definieert en de tabel die op de pagina aanwezig is worden gesynchroniseerd tijdens het laden. Het veld met de dagdelen in tekst kan bij de weergave verborgen worden. De standaardtabel kan dan weer voor de input verborgen worden.

2) Voor een view

In een view kan je velden herschrijven en/of PHP view velden toevoegen. Geen van bedien laat echter toe om de <style> tag te gebruiken om veiligheidsredenen. De discussie daaromtrent is er eentje die reeds 8 jaar aan de gang is: https://www.drupal.org/project/views/issues/853880&nbsp; Ik heb dit probleem kunnen omzeilen, zonder afbreuk te doen aan de veiligheid, maar je wilt niet weten hoeveel uur dat ik daar aan besteed heb.  Ik heb uiteindelijk volgende werkwijze uitgedacht:

Bij een overzicht heb je het bijkomend probleem dat er niet met de klassen mavm, manm, ,maav,... kan gewerkt worden aangezien ze voorkomen in verschillende rijen van de view. We moeten dus een identificatiemiddel hebben om specifiek naar de rij te verwijzen. Elke rij komt overeen met een node ID, vandaar dat dit voor de hand ligt om te gebruiken.

In de view gaan we dus deze velden gebruiken. 

Screen001694.png

Het Algemeen: aangepaste tekstveld krijgt dan deze code. Het is dezelfde tabel als bij de node, maar met een klasse die ook nog de token van de nid bevat: {{nid}}

Per rij krijg je dan een andere klasse en dit is precies wat we nodig hebben.

<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 de HTML code ziet dit er bvb zo uit (we kijken naar de tabel van node 43):

Screen001695.png

Een andere rij heeft bvb dit uitzicht:

Screen001696.png

Het komt er nu op neer op weer in een blok de stijlen aan te maken, deze keer met inbegrip van de node ID. Maak weer een blok aan en laat dit blokje verschijnen als de view wordt getoond.

Eerst wordt er weer een algemene stijl voor de cellen definieeerd. Daarna gaan we in een lus alle nodes van het inhoudstype (lokaalbezetting) laden die de status = 1 hebben (=gepubliceerd). Ge gaan de $nid (= node ID) halen en maken weer dezelfde lus om alle waarden die in de keuzelijst werden aangeduid te bekomen.

<?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) {
       $dagdeel=$item->value;
$waarde=$dagdeel.$nid;
 echo '<style>.'.$waarde.'{background:#c25e03;}</style>';
     }
     }
?>

Met als mogelijk resultaat (merk de verschillende node ID's op). Elke rij heeft dus zijn eigen klasse.

Screen001697.png

Bij het laden van het overzicht synchroniseren de tabel en het stijlblokje.

Screen001698.png