1

I want to save the state of my side-menu in rails session variable, so that if my user collapses the side-menu, that collapsed state will persist when the view is changed. I have my js set up so that an uncollapsed state will send "0" through to the controller, and if the side menu is in a collapsed state, the ajax will send a "1" through to the controller action. If the controller action receives "1", I want that session variable set in my app.

I currently have an ajax request to the respective controller action, and the collapsed side-nav is sending a "1" through successfully, but the session variable does not seem to persist. Here is what I see in the console when the side-nav is collapsed:

CONSOLE: (When the side-nav is collapsed)

Started POST "/dashboard/side_nav_state" for 10.0.2.2 at 2015-06-02 15:58:08 +0000
Processing by DashboardController#side_nav_state as */*
  Parameters: {"hide_side_nav"=>"1"}
Completed 200 OK in 2ms (Views: 0.2ms | ActiveRecord: 0.0ms)

(When the side-nav is expanded)

Started POST "/dashboard/side_nav_state" for 10.0.2.2 at 2015-06-02 16:02:56 +0000
Processing by DashboardController#side_nav_state as */*
  Parameters: {"hide_side_nav"=>"0"}
Completed 200 OK in 2ms (Views: 0.2ms | ActiveRecord: 0.0ms)

JavaScript:

The sendSideNav(); function actually sends the 1 or the 0 through to the controller. As you can see, the collapsedSideNav(); function sends the 1. If you look at the sendSideNav(); function you can see that the 1 is passed through to the data key value pair in the ajax request.

// collapsible side-nav functionality
function collapsedSideNav(){
  $('.side-nav').toggle(300);
  $('#collapse-side-nav').css('display', 'none');
  $('#expand-side-nav').css('display', 'inherit');
  $('.container').animate({
    'padding-left' : 0
  }, "slow");
  $('.row').css({
    'max-width' : '98%',
    'margin-left' : '1.15rem'
  });
  sendSideNavStatus(1);
};

// expandable side-nav functionality
function expandedSideNav(){
  $('.side-nav').toggle(325);
  $('#expand-side-nav').css('display', 'none');
  $('#collapse-side-nav').css('display', 'inherit');
  $('.container').animate({
    'padding-left' : 200
  }, "slow");
  $('.row').animate({
    'max-width' : '95%',
    'margin-left' : 'auto'
  });
  sendSideNavStatus(0);
};

// sends the state of the side-menu (if not default) to the controller so it can be stored in a session
// 1 for true, and 0 for false.
function sendSideNavStatus(trueOrFalse){
  $.ajax({
    url: '/dashboard/side_nav_state',
    method: 'POST',
    data: {hide_side_nav: trueOrFalse}
  });
};

// DOM Events for collapsing and expanding side-nav
$('#collapse-side-nav').click(function() {
  collapsedSideNav();
});
$('#expand-side-nav').click(function() {
  expandedSideNav();
});

ROUTES

post 'dashboard/side_nav_state'

CONTROLLER ACTION

def side_nav_state
    session[:hide_side_nav] = params[:hide_side_nav] == "1" 
    render json: {success: true}
end

EDIT:

I should note that all of this is happening in my dashboard controller. I want this session to persist regardless of what controller I am in. Is that possible? I know you cannot route to your application controller which is why I set up the logic to the dashboard controller. I am not sure what the solution is here.

7
  • What is this line doing: session[:hide_side_nav] = params[:hide_side_nav] == "1" Commented Jun 2, 2015 at 16:09
  • It looks wrong to me, like the session var would never be set, unless I'm ready it wrong Commented Jun 2, 2015 at 16:09
  • What I am attempting to do with that line is set the session variable if the ajax sends a "1". I'm positive this is the line where my error is as well, I just honestly am not sure how to set this up correctly, and I have not used rails sessions before. How would you go about setting up that method if it were you, @RichardAE? Commented Jun 2, 2015 at 16:11
  • @RichardAE You're reading it wrong ;) It sets the session var to the result of the equality expression. But it's the wrong expression if the OP wants a 0 or 1, maybe that's what you meant. Commented Jun 2, 2015 at 16:14
  • @RichardAE I have tried sesssion[:hide_side_nav] ||= "1" as well. Commented Jun 2, 2015 at 16:14

1 Answer 1

2

For anyone else that ends up having this problem and can't find an answer, I have finally come to conclusion on how to resolve the problem.

I have found that rails sessions are primarily used for backend logic (user authentication, user preferences, etc etc). The problem with my code above was that my javascript did not receive the session variable anywhere.. The session variable was setting correctly and persisting, but because I needed the javascript acted upon by the session variable, having the variable was kind of a moot point.

One solution could be for me to set up a post end point and create a second ajax request. But this would create a lot of extra code including another end point, and another controller action, along with the javascript.

Because Rails doesn't really provide a good way to have your javascript interact with session variables, for this particular problem I decided that it would be better to handle the problem 100% on the client side and create a browser cookie. I used the cookie.js library and set the cookie up accordingly. My finalized code ended up looking like this:

JAVASCRIPT:

$(document).ready(function(){
  Cookies.get();
  initializeSideNav();
});

// Checks the current status of the side menu
function initializeSideNav() {
  if (Cookies.get("collapsed-side-nav") === "true") {
    collapsedSideNav();
  }
}

// collapsible side-nav functionality
function collapsedSideNav(){
  $('.side-nav').toggle(300);
  $('#collapse-side-nav').css('display', 'none');
  $('#expand-side-nav').css('display', 'inherit');
  $('.container').animate({
    'padding-left' : 0
  }, "slow");
  $('.row').css({
    'max-width' : '98%',
    'margin-left' : '1.15rem'
  });
  Cookies.set('collapsed-side-nav', true, {path: '/'})
  console.log(Cookies.get());
};

// expandable side-nav functionality
function expandedSideNav(){
  $('.side-nav').toggle(325);
  $('#expand-side-nav').css('display', 'none');
  $('#collapse-side-nav').css('display', 'inherit');
  $('.container').animate({
    'padding-left' : 200
  }, "slow");
  $('.row').animate({
    'max-width' : '95%',
    'margin-left' : 'auto'
  });
  Cookies.set('collapsed-side-nav', false, {path: '/'});
  console.log(Cookies.get());
};

// DOM Events for collapsing and expanding side-nav
$('#collapse-side-nav').click(function() {
  collapsedSideNav();
});
$('#expand-side-nav').click(function() {
  expandedSideNav();
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.