4

Edit: see the Update below for the current status of the problem.

I have a module that has to display a variable number of rows, based on how the user configures it in the back-end, and several instances of the module need to be displayed on the same page (with potentially different numbers of rows). My approach is to use a grid layout. The main challenge is styling it so the rows appear at the bottom of the div rather than the top, in a way that can be applied to all instances at once. My first attempt was to pass the number of rows to my CSS in the form of a CSS variable, as well as the padding. This is roughly what my code looked like:

$document = JFactory::getDocument();
$modulePath = JURI::base() . 'modules/mod_my_module/';
$document->addScript($modulePath.'media/script.js');
$document->addStyleSheet($modulePath.'media/stylesheet.css');
...
$rows_array = $params->get("rows");
$number_of_divs = count($rows_array);
$padding = 100 - (10 * $number_of_divs);
$style = ":root { --rowNum: " . $number_of_divs . "; --padding: " . $padding . "%;}";
$document->addStyleDeclaration($style);

Then in my CSS I'm using these variables in a grid layout, like

...
display: grid;
grid-template-rows: var(--padding) repeat(var(--rowNum), 10%); 
...

When I have a single instance of my module this works fine, but if I have several instances rendered in the same page then these variable declarations collide and it doesn't work anymore. I think the issue is that $document->addStyleDeclaration($style); is applying the style rule to a global style-sheet, but I need to do something that only affects the style of the particular instance.

How can I style the different instances of the module with different numbers of rows? Should I be dynamically adding the rows using Javascript instead?


Update: I've also tried an approach that doesn't use CSS variables, by adding unique ids to the divs I'm trying to style by fetching their module ids, like id="my-module-<?php echo $module->id ?>". Then instead of having the grid style rules in my style.css file I add the php

$style = 
    "#my-module-" . $module->id . "{ " .
        "display: grid; " . 
        "grid-template-rows: " . $padding . "% repeat(" . $number_of_divs . ", 10%); " .
        "grid-template-columns: 60% 40%; " .  
        "justify-content: end;" .
        "}";
$document->addStyleDeclaration($style);

Now the problem is that this works for the first module rendered, but not the second. I have no clue why. I've inspected the containers and they have the right ids, I've also tried moving this code from my_module.php to default.php to see if it made a difference and it doesn't.

Why is it adding the style declaration and using the right styling for the first rendered instance but not the second?

1 Answer 1

4

I figured out my problems, so I thought I would answer my own question.

1) Different styling for different instances of the same module

Don't forget Joomla has unique module ids! And there's an extremely easy way to access them! You can give the elements in your module instances unique ids by doing something like

<div class="my-module-container"
     id="my-module-container-<?php echo $module->id ?>"> 
    <p>content</p>
</div>

and now you can uniquely target this element with styling rules, using your module instance's id. (There are probably lots of other great ways of doing this and I don't know about any particular conventions.)

2) Grid layout being weird

The second problem was because I guess grid is kind of weird! I managed to resolve my problem by keeping the grid declaration in my CSS, and then adding the other style rules using Joomla. Basically in my style.css file I have

.my-module-container {
   display: grid;
}

which adds the grid display property to all of the instances of the container, and in my pre-processing I add the particular style rules to my instance with the following:

$number_of_rows = MyModuleHelper::NumberOfRows($params);
$padding = 100 - (10 * $number_of_rows);
$style = 
    "#my-module-container-" . $module->id . "{ " .
        "grid-template-rows: " . $padding . "% repeat(" . $number_of_rows . ", 10%); " .
        "grid-template-columns: 60% 40%; " .  
        "justify-content: end;" .
    "}";
$document->addStyleDeclaration($style);

Like I said, now it works (at least in Chrome and Firefox), but I don't fully understand why. Before, when I didn't have display: grid; in the CSS for the class and would have Joomla add it to the particular instance by its id, it would correctly apply the style to the first rendered instance of it, but then none of the others. I know grid is very particular about the order in which you add the rules, but I don't know all the subtleties. Maybe someone who knows more about how grid works can explain?


If anyone has comments or criticisms about my current solution I would really appreciate it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.