2

I have a module that outputs 1 item by default, in its help.php file, there is something like

$items = 1;
$db->setQuery($query, 0, $items)

Now I want to detect if users' screen width is less than a certain value, if yes, then get only 1 item, else get 4 items. What is the best practice to do it?

I can just set $items to 4 and use javascript to eliminate the other 3 items, but this is not a perfect solution because excessive data will be downloaded. My questions are: 1) can PHP alone detect client's screen width? 2) If no and I have to use javascript/ajax, I am thinking add

<script>
    var w = screen.width;
    href = location.href;
    if (location.search){
       href = href + '&screenWidth=' + w;
    } else
    href = href + '?screenWidth=' + w;
</script>

to every page and use $_GET['screenWidth] to get the screen width value in the helper.php file, is this a good practice? Is this gonna mess up with output buffer(if there is any)?

  • Good question but is it related to Joomla? – jonboy Nov 10 '15 at 13:48
4

PHP can't detect screen size, since it runs on the server. I wouldn't also use ajax for something like this.

Use Joomla's Browser Detection Capabilities with the JApplicationWebClient class and adjust your php/queries for different devices, not particular for different screen sizes.

Sample code:

$client = JFactory::getApplication()->client;
$client->browser;
$client->mobile...

Some thoughts about your last comment:

And I don't understand why people tend to detect device type instead of screen width. In most cases(I usually do layout only) I encounter, I don't care what device users are using, but only the screen width....

It's not that is not possible to do it with AJAX. But considering your initial concern on saving excessive data... what would be the point if after every screen resize - even if you give it a delay so the resize is a bit more established, you would have a new request to download data (even if this happens in the background and and even if you get them from the cache). You would end up at least with the same amount of data. Then why not doing it from the beginning on the client side with CSS?

Another thing, is that after a screen size change (say the user switches his mobile device from portrait to landscape), reloading the data may bring different items, if there is a change in the database. The user might get confused and would have to search for the item he had previously in his screen.

Of course, there could be the option to go the way and specify cases for when a new data request should occur... But why all this hassle?

  • Thank you! I know my approach is not good, but for learning purpose I just want to know why it is a bad practice? Is there any lurking problem? – shenkwen Nov 10 '15 at 2:20
  • And I don't understand why people tend to detect device type instead of screen width. In most cases(I usually do layout only) I encounter, I don't care what device users are using, but only the screen width. And imo, there are too many types of devices to handle. For example, even for iphone only, there are 4/5/6/6 plus with all different screen sizes, and in JApplicationWebClient, it seems we can only know if people are using iPhone, but not its version. What if I want different layout in iPhone 4 and iPhone 6 plus? won't screen size be the best value to determine what layout it should be? – shenkwen Nov 10 '15 at 2:44
  • @shenkwen, I update my answer with my thoughts regarding your comment. – FFrewin Nov 10 '15 at 10:58
1

If it was me, I would actually approach this differently.

I would always get 4 items:

$items = 1;
$db->setQuery($query, 0, $items);
$rows = $db->loadObjectList();

Display them all:

foreach ($rows as $row)
{
    echo '<div class="item_"' . $row->id . '>' . $row->item . '</div>';
}

Which would output:

<div class="item_1">
    // row data
</div>
<div class="item_2">
    // row data
</div>
<div class="item_3">
    // row data
</div>
<div class="item_4">
    // row data
</div>

Then use CSS3 media queries to hide 3 of them:

@media (max-width: 767px) {
    .item_2, 
    .item_3,
    .item_4 {
        display: none;
    }
}

The way I have displayed the data is purely an example and concept.

I've always preferred using client side for detecting screen widths (the way it should be done), and it's also better performance.

Hope this helps

  • Most likely, I would also do the same - and maybe I wouldn't even hide the remaining items, but displayed one below the other. But the OP asked about the possibilities to let php know the browser and more specifically the screen size, so in my answer I tried to get as closer as possible to that. – FFrewin Nov 10 '15 at 10:48
  • 1
    @FFrewin, Yup yup, and you wrote a good answer (+1) ;) Just providing an alternative :) – Lodder Nov 10 '15 at 10:51
1

Best practice? Best practice is to not try to determine screen size, because ultimately it is futile. What will happen when a large screen user changes their browser window size, for example?

If you want to modify a layout, in relation to screen size on a users device, do it with responsive web design.

If you are concerned that the number of content items you deliver by default is unsuitable for mobile devices, then you should reduce your defaults and always assume mobile in the first instance; mobile-first development specifically addresses issues like this.

If you want to then give large screen users more content items then you should look at responsive conditional loading techniques to pull in the extra “desktop size” items.

  • If I rightly remember, doesn't document.documentElement.clientWidth which is referred to in the article, vary with different browsers? – Lodder Nov 11 '15 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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