1

I've written a module that allows users to alter the display of a Date/Time object by allowing them to change their timezone via a front-end block.

It does it's primary function properly, changes the time display as expected, however, what is supposed to happen is that once you pick a timezone, the page reloads, and the dropdown form will default to the timezone you selected. Except it doesn't, it stays on a single default value

Timezone Dropdown Issue

The array is the #options list for the dropdown item, and the single item underneath is the #default_value key for that dropdown.

As you can see, the default value should be set to Australia/Melbourne, but in the dropdown it's not, it's set to America/Creston Mountain time.

I cannot figure out what's going wrong, have I done the default value code incorrectly or something?

EDIT

This is the code for the select element

$timezone = mymodule_timezone_get_user_timezone();
$options = variable_get('mymodule_timezone_select', system_time_zones());
$options = array_filter($options);

// doing a dpm($timezone) comes back with Australia/Melbourne
// doing a dpm($options) comes back with the arrow shown above

$form['timezone_select'] = array(
  '#type' => 'select',
  '#title' => '',
  '#options' =>  $options,
  '#default_value' => $timezone,
  '#prefix' => t('<div class="description">Please select your timezone from the drop down box below and click update to convert your viewing times accordingly.</div>'),
);
$form['submit'] = array(
  '#type' => 'submit',
  '#value' => t('Update') ,
);

And the code referenced in this snippet

function mymodule_timezone_get_user_timezone() {
  $retrieved_timezone = session_cache_get('mymodule_timezone_user_timezone');
  if (empty($retrieved_timezone)) {
    $retrieved_timezone = drupal_get_user_timezone();
  }
  return $retrieved_timezone;
}

The variable for 'mymodule_timezone_select' is just from the default system_time_zones() but the admin has been given the option to delete ones they don't want the user to see (since they are several hundred options by default)

5
  • 2
    Could you share the code relevant the select form element?
    – osman
    Sep 4, 2017 at 17:48
  • 1
    Since this is on a registration page, I assume you are not logged in. Could it be that you are getting some cached version of the form/page, in which the default is fixed? Do you have any server or site caching that you could clear to see if switches to another default? Other than that the provided code looks fine. If you cleaned it up for the example, double check that you do not override $timezone somewhere in between. Sep 9, 2017 at 22:35
  • @Neograph734, I actually managed to figure out the reason, and you're the closest to the answer. I'd set the block caching to be DRUPAL_CACHE_PER_USER, because that seemed like the right thing to do, that each person would set their own value, except that was what the problem was, that even though I could debug the values it was supposedly setting for the dropdown, the caching superseded that. If you want to pose your comment as an answer, I'll give you the bounty, I feel bad that I put a bounty on it, but the solution wasn't part of my question.. Sep 11, 2017 at 10:27
  • Also, what's double crazy is that I've actually got this code on 2 sites, both have the same caching settings, same session cache settings, on the same server etc. Except one of them worked, one didn't. Made me think there should be nothing wrong with how I set the original caching for the block. Sep 11, 2017 at 10:28
  • @AndrewMorris, I could write an answer telling you to look at the cache... But I do not know what you have changed exactly, making it quite a useless answer. Could you write your own answer including what you have changed to make it work? That way the post will be more informative for others facing similar problems. Nobody will get the bounty, but I can live with that. Glad you got it sorted out :) Sep 11, 2017 at 10:32

2 Answers 2

0

Are you providing #default_value when loading form? If yes, you need to make sure that you're providing what is selected by user first. Check example below:

global $user;
// Check if user has set the timezone,
// if yes use that else set to default 'America/Creston'

$timezone = isset($user->timezone) ? $user->timezone : 'America/Creston';
$form['timezone'] = array(
  '#type' => 'select',
  '#title' => 'Select Timezone',
  '#options' => $options,
  '#default_value' => $timezone,
);

As per Form API Reference Documentation, it says #default value is:

The value of the form element that will be displayed or selected initially if the form has not been submitted yet.

2
  • I've made an amend to the code above, but yea that's almost exactly what it already was Sep 5, 2017 at 7:21
  • I've tried the code you've shared in question, and if I comment $retrieved_timezone = session_cache_get('mymodule_timezone_user_timezone'); line in mymodule_timezone_get_user_timezone() function, the default value is properly set to user current timezone. You can further see if the session_cache is properly getting updated/retrieved or not.
    – Yogesh
    Sep 5, 2017 at 9:10
0

Managed to figure out what was wrong, and my own apologies to those who tried to help me, it turns out that the culprit was with the caching settings for my custom block, which wasn't something I'd included in the description of the question.

Originally my block_info code looked like this

function mymodule_timezone_block_info() {
    $blocks['mymodule_timezone'] = array(
        'info' => t('Timezone'),
        'cache' => DRUPAL_CACHE_PER_USER,
    );
    return $blocks;
}

Which should in my mind have been the correct setting, since I wanted it to cache the users response. The weird part is that it did work locally like this, and the same code even worked on another site, on the same server, with the same drupal caching/session caching settings etc.

The correct solution was to do this instead

function mymodule_timezone_block_info() {
    $blocks['mymodule_timezone'] = array(
        'info' => t('Timezone'),
        'cache' => DRUPAL_NO_CACHE,
    );
    return $blocks;
}

Again, apologies to those who tried to help and couldn't, it's my fault for not including all parts of the block setup in the original request.

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.