JavaScript and cookies

Hi,

My app has a series of sidebar menus that are getting a bit long and
I’d like to compact them into an optional dropdown. I know how to do a
simple show/hide action, but I’d like to use cookies to store the user
preferences so that same sidebars stay open/closed when they navigate
around the site.

Does anybody know any good rails based tutorials that would help a
JavaScript novice get started on this one.

thank you,

Dan

DanC wrote:

My app has a series of sidebar menus that are getting a bit long and
I’d like to compact them into an optional dropdown. I know how to do a
simple show/hide action, but I’d like to use cookies to store the user
preferences so that same sidebars stay open/closed when they navigate
around the site.

Does anybody know any good rails based tutorials that would help a
JavaScript novice get started on this one.

I’m thinking you could simply store a bit-mask in the session where each
bit represents the state of each menu item.

For example if you had 5 collapsible menus and the second and fourth
menu were open then store 01010 = 10 in session[:menu_state] = 10. Pass
session[:menu_state] to your JavaScript on each request and use that to
control your menu.

Hi Robert,

Thank you for your response.

I understand the basic idea of what your suggesting.

I hope this isn’t a stupid question but I don’t understand the 01010 =
10 part?

Could you elaborate a little more on that please?

Thank you,

Dan

DanC wrote:

I hope this isn’t a stupid question but I don’t understand the 01010 =
10 part?

I was simply showing the 01010 in binary (0b01010) is equal to 10 in
decimal.

So in order to create a bit mask all you need to store is a simple
integer (Fixnum).

Example 1:

Say your bit mask value is:
x = 0b01010
=> 10

If you want to know if the second bit from the left is set create a mask
with the desired bit set:

mask = 0b01000
=> 8

then bit-wise AND the value with the mask:

x & mask > 0
=> true

mask = 0b00100
x & mask > 0 # is the third bit from left set?
=> false

Example 2:
http://pastie.textmate.org/private/acweqtdqm3jdhtufe4ag

Hi Robert,

The suggestion you made was bit beyond me, so I asked a friend of mine
to take a look and he implemented your binary suggested excellently
using jquery

He added a menu.js file that looks like this for my 6 menus

menu.js

var MENUS = 6;
var menu_state

// stops modification of the menu_state during collapse/expand
functions
// whilst the menu is being reconstructed
var init_state = true;

// Restores the menu’s state upon loading the document
$j(document).ready(restoreMenuState);

function restoreMenuState() {
menu_state = $j.cookie(‘menu_state’);

// Sets a default value of 1 if nothing is in the cookie
if(menu_state == null || menu_state == 0)
    menu_state = 1;

for(var i = 1, b = 1; i <= MENUS; i++, b = b << 1) {
    if((menu_state & b) > 0) {
        expand(i);
    } else {
        collapse(i);
    }
}

init_state = false;

}

/**

  • Saves the current state of the menu to the cookie
  • using a bitmask in which the first bit maps to
  • the first menu
  • number - menu number
    */
    function saveMenuState(number) {
    menu_state = menu_state ^ (1 << (number-1));
    $j.cookie(‘menu_state’, menu_state, { path: ‘/’});
    }

/**

  • Collapses the menu identified by the given number

  • i.e. collapse(2) will collapse the menu surrounded

  • by div#menu2

  • The image/link used to initiate this should have id

  • ‘toggle’ followed by the number
    */
    function collapse(number) {
    $j(’#toggle’ + number).html(“show”);
    $j(’#toggle’ + number).attr(“onClick”, “expand(” + number + “)”);

    if(init_state) {
    $j(’#menu’ + number).hide();
    } else {
    $j(’#menu’ + number).slideUp(400, null);
    saveMenuState(number);
    }
    }

/**

  • Expands the menu identified by the given number

  • i.e. expand(2) will expand the menu surrounded

  • by div#menu2

  • The image/link used to intiiate this should have

  • id ‘toggle’ followed by the number
    */
    function expand(number) {
    $j(’#toggle’ + number).html(“hide”);
    $j(’#toggle’ + number).attr(“onClick”, “collapse(” + number +
    “)”);

    if(init_state) {
    $j(’#menu’ + number).show();
    } else {
    $j(’#menu’ + number).slideDown(400, null);
    saveMenuState(number);
    }
    }


Also added a jquery-prototype-fix.js

/*

  • Both jQuery and Prototype javascript libraries use the $ variable,
    so
  • to keep them running smoothly together we must disable the jQuery
  • $ and assign it to another variable, $j, so it may still be
    accessible
    */

jQuery.noConflict();
var $j = jQuery;


Then in my view files it was as simple as

Words

content

Words

content

etc…


Thank you Robert and thank you James for writing this code for me.

Dan