Creating A Fluid Site UI: Draggable DIVs and Handling Them on The Client Side

Nishant Arora 09/Dec/2012
Facebook
Twitter
LinkedIn
Reddit

hi All

Long Time No See. I have been receiving and overwhelming number of queries related to my previous posts and have been keeping busy a lot at my new Job. I won't be discussing anything about what I do or develop as it is Top Secret internal projects. For now, I was planning to create something which has been maybe around for long, but have never caught up with web masters.

Lately I just wanted to create menus and structures on a page movable. Well if you are using jQuery on your site, achieving this becomes a child play if you see what I mean.

But the problem with this is, as soon as you refresh the page, the div move backs to it's initial position. Which I think won't work if we are planning to build a UI for a website. So more research reveals that this can be implemented if we can communicate the coordinates of the elements back to the server, again people have already discussed about this too.

But I do not understand the need of increasing web traffic just for persistence. The idea is to handle all the persistence on the client side. That means we can use client side features of browser to implement this in a simple manner. For this example I will be using simple functions for reading and writing cookies mentioned on w3schools:

function setCookie(c_name,value,exdays){
  var exdate=new Date();
  exdate.setDate(exdate.getDate() + exdays);
  var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString());
  document.cookie=c_name + "=" + c_value;
  console
}
function getCookie(c_name){
  var i,x,y,ARRcookies=document.cookie.split(";");
  for (i=0;i<ARRcookies.length;i++){
    x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
    y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
    x=x.replace(/^\s+|\s+$/g,"");
    if (x==c_name){
      return unescape(y);
    }
  }
}

Now we can simply use the example mentioned for the draggable feature on jQueryUI:

<!doctype html>

<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>jQuery UI Draggable - Default functionality</title>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
  <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
  <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
  <link rel="stylesheet" href="/resources/demos/style.css" />
  <style>
  #draggable { width: 150px; height: 150px; padding: 0.5em; }
  </style>
  <script>
  $(function() {
    $( "#draggable" ).draggable();
  });
  </script>
</head>
<body>

<div id="draggable" class="ui-widget-content">
    <p>Drag me around</p>
</div>

</body>
</html>

and now we can change the draggable functions to store coordinate data into cookies, which would like this:

$( "#draggable" ).draggable().mouseup(function(){
  var coord    = $(this).offset();
  var offset_json  = '{"top":'+coord.top+',"left":'+coord.left+'}';
  setCookie("menu_offset",offset_json,365);
});

and to read the data from the cookie at the page render we can simply write a read function:

var existing=getCookie("menu_offset");
if(existing!=null &amp;&amp; existing!=""){
  offset_vals  = JSON.parse(existing);
  $("#draggable").css({
    top    : offset_vals.top,
    left  : offset_vals.left
  });
}

Now combining it all gives us:

<html>
  <head>
    <script src="jquery.min.js"></script>
    <script src="jquery-ui.min.js"></script>
    <script>
      function setCookie(c_name,value,exdays){
        var exdate=new Date();
        exdate.setDate(exdate.getDate() + exdays);
        var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString());
        document.cookie=c_name + "=" + c_value;
        console
      }
      function getCookie(c_name){
        var i,x,y,ARRcookies=document.cookie.split(";");
        for (i=0;i<ARRcookies.length;i++){
          x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
          y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
          x=x.replace(/^\s+|\s+$/g,"");
          if (x==c_name){
            return unescape(y);
          }
        }
      }
    </script>
    <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
    <style>
      #draggable { width: 150px; height: 150px; padding: 0.5em; }
    </style>
    <script>
      $(document).ready(function(){
        var existing=getCookie("menu_offset");
        if(existing!=null && existing!=""){
          offset_vals  = JSON.parse(existing);
          $("#draggable").css({
            top    : offset_vals.top,
            left  : offset_vals.left
          });
        }
        $( "#draggable" ).draggable().mouseup(function(){
          var coord    = $(this).offset();
          var offset_json  = '{"top":'+coord.top+',"left":'+coord.left+'}';
          setCookie("menu_offset",offset_json,365);
        });
      });
    </script>
  </head>
  <body>
    <div id="draggable" class="ui-widget-content">
      <p>Drag me around and try refreshing. You should see me at the same position.</p>
    </div>
  </body>
</html>

I would like you to check out a working example here (No More Here).
Hope you liked it

Cheers!