11

I've seen this posted a few times, but I wasn't able to get the code working at all. I need help making this drop down menu save its settings to a cookie, so when the user visits the site again, their previous selection is retained.

Dropdown:

<select id="ThemeSelect">
    <option value="zelda">Zelda</option>
    <option value="smb2">SMB 2</option>
</select>

For reference, this code is with some Javascript in a Wordpress widget that changes the css code, like a theme selector.

How would I make this save as a cookie? I feel like I've tried everything!

EDIT: I should have said, but I use this code to change the CSS:

var saveclass = null;
var sel = document.getElementById('ThemeSelect');
sel.onchange = function(){
    saveclass = saveclass ? saveclass : document.body.className;
    document.body.className = saveclass + ' ' + sel.value;
};
DANCUBE
  • 145
  • 1
  • 2
  • 8

3 Answers3

12

Something along these lines should work for you. The function to create a cookie via javascript was found in Setting a Cookie from JavaScript, a post on javascripter.net.

HTML:

<select id="ThemeSelect" onchange="setCookie('theme', this.value, 365);">
    <option value="zelda">Zelda</option>
    <option value="smb2">SMB 2</option>
</select>

Javascript:

function setCookie(cookieName, cookieValue, nDays) {
    var today = new Date();
    var expire = new Date();

    if (!nDays) 
        nDays=1;

    expire.setTime(today.getTime() + 3600000*24*nDays);
    document.cookie = cookieName+"="+escape(cookieValue) + ";expires="+expire.toGMTString();
}

Edit:

Save the cookie

I have merged the two functions into one for you.

HTML:

<select id="ThemeSelect" onchange="saveTheme(this.value);">
    <option value="zelda">Zelda</option>
    <option value="smb2">SMB 2</option>
</select>

Javascript:

var saveclass = null;

function saveTheme(cookieValue)
{
    var sel = document.getElementById('ThemeSelect');

    saveclass = saveclass ? saveclass : document.body.className;
    document.body.className = saveclass + ' ' + sel.value;

    setCookie('theme', cookieValue, 365);
}

function setCookie(cookieName, cookieValue, nDays) {
    var today = new Date();
    var expire = new Date();

    if (nDays==null || nDays==0)
        nDays=1;

    expire.setTime(today.getTime() + 3600000*24*nDays);
    document.cookie = cookieName+"="+escape(cookieValue) + ";expires="+expire.toGMTString();
}

Live DEMO

Read the cookie on return to the page

Thanks to dunsmoreb

We can get the cookie using this function, shamelessly stolen from this question.

function readCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i = 0; i < ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') c = c.substring(1, c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
  }
  return null;
}

Then we need to select the value when the page loads. The following code will accomplish just that:

document.addEventListener('DOMContentLoaded', function() {
    var themeSelect = document.getElementById('ThemeSelect');
    var selectedTheme = readCookie('theme');

    themeSelect.value = selectedTheme;
    saveclass = saveclass ? saveclass : document.body.className;
    document.body.className = saveclass + ' ' + selectedTheme;
});

Live DEMO

Community
  • 1
  • 1
Josh Mein
  • 28,107
  • 15
  • 76
  • 87
  • 1
    May I suggest changing: `if (nDays == null || nDays == 0)` to `if (!nDays)`? That way it checks against null, zero, and undefined. –  Jun 09 '12 at 02:40
  • To me, that looks completely perfect, however, when I put it on a test page, I have no idea why it doesn't work. http://dcvidya.com/testing/ is the page, by the way. Am I doing anything wrong? – DANCUBE Jun 09 '12 at 02:42
  • 2
    @DANCUBE The name of the function is `SetCookie` and you are calling `setCookie`. Case matters. –  Jun 09 '12 at 02:46
  • Strange, it doesn't work for me or a friend of mine. It doesn't work on the main site either. http://dcvidya.com/ does it work here for you too? – DANCUBE Jun 09 '12 at 02:58
  • As far as I know, that other onchange function is needed, otherwise the css doesn't get changed correctly. Is there a way to call them both without interference? – DANCUBE Jun 09 '12 at 03:04
  • 1
    @JoshMein I added another answer that expands upon your answer. Feel free to edit it in. –  Jun 09 '12 at 03:05
  • All right, I think I'm just simply interpreting this incorrectly, but if you check my test page, it isn't working for me, what did I do wrong? I'm not sure which code to use. Sorry, I'm totally new to this, haha. Plus, how do the values 0 and 1 work? I need them to point to zelda and SMB3, so it loads the .zelda and .smb3 css. – DANCUBE Jun 09 '12 at 03:23
  • @DANCUBE His answer has been merged into mine as he requested. There are two parts to this problem. There is the initial saving of the cookie and then the reading of the cookie when you return to the page. Both parts can be found in my answer thanks to the heko if dunsmoreb. – Josh Mein Jun 09 '12 at 03:27
  • Ah yes, it saves now. However, 0 and 1 are not the values I need. I need them to use smb3 and zelda for this to work. I'm sorry if this is a really simple problem. – DANCUBE Jun 09 '12 at 03:33
  • 1
    @DANCUBE I have updated the code to work off of zelda and smb3 – Josh Mein Jun 09 '12 at 03:46
  • That works! Unfortunately, of course, there's other problems now. For some reason, the site doesn't change class when you refresh, it seems to load the default, even though it remembers the selection. Any idea why that would happen? – DANCUBE Jun 09 '12 at 03:46
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/12325/discussion-between-dancube-and-josh-mein) – DANCUBE Jun 09 '12 at 03:48
  • @JoshMein You need to check if `selectedTheme` doesn't equal null or else nothing will be selected when the user first visits the page. You can just copy the updated code from my answer. –  Jun 09 '12 at 16:27
3

Note: This answers adds to Josh Mein's answer. Feel free to merge it.

We can get the cookie using this function, shamelessly stolen from this question.

function readCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i = 0; i < ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') c = c.substring(1, c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
  }
  return null;
}

Then we need to select the value when the page loads. The following code will accomplish just that.

document.addEventListener('DOMContentLoaded', function() {
  var themeSelect = document.getElementById('ThemeSelect');
  var selectedTheme = readCookie('theme');

  if (selectedTheme) {
    themeSelect.value = selectedTheme;
  }
});
Community
  • 1
  • 1
  • This is totally bizarre to me, even this doesn't work. I've added the code I need in the original question, but even when I remove this code from the example page, the choice still isn't saved. – DANCUBE Jun 09 '12 at 03:13
  • Ah, I just copied your source, it's working now. However, how could I integrate the other script I posted in my question? I need that to happen, otherwise the css doesn't display correctly. – DANCUBE Jun 09 '12 at 03:17
  • Just append the code to the callback. So basically copy and paste the code right after: `themeSelect.selectedIndex = selectedTheme;`. –  Jun 09 '12 at 03:18
  • @DANCUBE Look at my updated answer. I included the other code you had. – Josh Mein Jun 09 '12 at 03:20
-1

You should look into creating Session variables in PHP.

http://www.w3schools.com/php/php_sessions.asp

You can save variables to a session and when you load the page, you check the value of the variable you set, depending on it's value, the dropdown could behave a certain way. Maybe store the name of the dropdown item as a session variable?

Farzad A
  • 578
  • 1
  • 5
  • 15
  • He wants to know how he can set a cookie via Javascript. –  Jun 09 '12 at 02:39
  • 2
    If he stores it in the session, it will no longer be accessible if he leaves the site and return later. – Josh Mein Jun 09 '12 at 02:40
  • Ah that's right, sorry. Although if anyone is interested in doing it in PHP, using cookie might be better... http://www.w3schools.com/php/php_cookies.asp – Farzad A Jun 09 '12 at 02:46
  • -1 -> His code has nothing to do with PHP, so this is not a relevant answer. – BryanH Jun 09 '12 at 04:08