Monday, January 16, 2012

Create Sticky Notes Using HTML5, CSS3, and jQuery


Create Sticky Notes Using HTML5, CSS3, and jQuery

Don’t you think it would be nice to emulate Windows sticky notes in a web page? Well, thanks to the combined powers of HTML5, CSS3, and a bit of jQuery tutorials for the masses that I found, we can do just that.



Let’s being with the HTML markup:

< !DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>Posticks</title>
  <link rel="stylesheet" rev="stylesheet" href="styles.css">
  <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.3/themes/base/jquery-ui.css" type="text/css" media="all" />
</link></head>
<body>
  <header>
      <h1>posticks</h1>
        <input type="button" value="Add Postick" id="btn-addNote" />
  </header>
<div id="board"></div>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js"></script>
  <script type="text/javascript" src="js/scripts.js"></script>
</body>
</html>

As you can see, it is pretty much straightforward. We have the input element “button” to create the sticky notes, and a container <div> with an id (“board”) in which to place them. This also includes the reference tags to the CSS style sheets and the JavaScript file.

The HTML for our posticks will be as follows:

<div class="postick">
  <div class="toolbar"><span class="delete" title="Close">x</span></div>
  <div contenteditable class="editable"></div>
</div>

Each postick <div> will have a subdiv called “toolbar” so we will have a place for us to put a close (x) button in. We’ll also have another subdiv called “editable” with an HTML5 attribute “contenteditable”; this will contain the text that the user will input in the sticky note.
And now for the CSS part, which is a lengthy one:

/************ Tags ************/

/* Just some basic reset for the body tag */
body {
      background:#F1C387;
      padding:0;
      margin:0;
      font-family: Helvetica, Verdana, Geneva, sans-serif
}

header {
      padding-left:20px;
      height:50px;
      display:block;
      background:#0E0300;
      -webkit-box-shadow:0px 2px 5px gray;
      -moz-box-shadow:0px 2px 5px gray;
      box-shadow:0px 2px 5px gray;
      text-align:right;
}

h1 {
        color:white;   
        display:inline;
        font-size:210%;
        padding:15px 10px 0px 0px;
      text-shadow: 1px -1px 0px #999;
        text-transform:capitalize;
}


input[type="button"] {
        background:#EFE4DC;
        border:1px solid black;
        -moz-border-radius:5px;
        border-radius:5px;
        color:black;
        font-weight:bold;
        float:left;    
        padding:10px;
     margin:5px 10px 0 0;
        text-shadow: 1px 1px 0px white;
}

input[type="button"]:hover {
     background:#E03A00;
     color:white;
     text-shadow: 1px 1px 0px black;
     cursor:pointer;
}

/************ Classes ************/

.postick {
     border:1px solid gray;
     width:200px;
     height:200px;
     padding:4px;
     font-size:85%;
     background:#FFFC7F;
     -moz-box-shadow:2px 2px 2px #999999;
     -webkit-box-shadow:2px 2px 2px #999999;
     box-shadow:2px 2px 2px #999999;
     position:absolute;
}

.toolbar {
     text-align:right;
     font-weight:bold;
}

/* Postick's button "delete" */
.delete {
     cursor:pointer;
     font-size:120%;
}

/* Content to be editable inside the postick */
.editable {
     cursor:pointer;
     height:180px;
     marging:0 auto;
     width:100%;
     overflow:hidden;
     position:relative;
     -moz-text-shadow: 1px 1px 0px white;
     text-shadow: 1px 1px 0px white;
}

.editable:hover{
     border:1px dotted gray;
}

Like the HTML code, the CSS code is also pretty straight forward. We first reset the body tag, then we stylized the button (input) that creates the posticks, and then stylized the postick itself and the elements inside it (i.e. the delete button, toolbar, etc.).

And now for the JavaScript:

(function ($, $S) {
    //$ jQuery
    //$S window.localStorage
    //Variables Declaration
    var $board = $('#board'),
        //Board where the Posticks are sticked
        Postick, //Singleton Object containing the Functions to work with the LocalStorage
        len = 0, //Length of Objects in the LocalStorage
        currentNotes = '', //Storage the html construction of the posticks
        o; //Actual Postick data in the localStorage



    //Manage the Posticks in the Local Storage
      //Each postick is saved in the localStorage as an Object 
    Postick = {
        add: function (obj) {
            obj.id = $S.length;
            $S.setItem(obj.id, JSON.stringify(obj));
        },

        retrive: function (id) {
            return JSON.parse($S.getItem(id));
        },

        remove: function (id) {
            $S.removeItem(id);
        },

        removeAll: function () {
            $S.clear();
        }

    };

    //If exist any postick, Create it/them
    len = $S.length;
    if (len) {
        for (var i = 0; i < len; i++) {
            //Create all posticks saved in localStorage
            var key = $S.key(i);
            o = Postick.retrive(key);
            currentNotes += '<div class="postick"';
            currentNotes += ' style="left:' + o.left;
            currentNotes += 'px; top:' + o.top;
                  //data-key is the attribute to know what item delete in the localStorage
            currentNotes += 'px"><div class="toolbar"><span class="delete" data-key="' + key;
            currentNotes += '">x</span></div><div contenteditable="true" class="editable">';
            currentNotes += o.text;
            currentNotes += '</div>';
        }

        //Append all the posticks to the board
        $board.html(currentNotes);
    }

    //When the document is ready, make all posticks Draggable
    $(document).ready(function () {
        $(".postick").draggable({
            cancel: '.editable',
          "zIndex": 3000,
          "stack" : '.postick'
        });
    });

    //Remove Postick
    $('span.delete').live('click', function () {
        if (confirm('Are you sure you want to delete this Note?')) {
            var $this = $(this);
                  //data-key is the attribute to know what item delete in the localStorage
            Postick.remove($this.attr('data-key'));
            $this.closest('.postick').fadeOut('slow', function () {
                $(this).remove();
            });
        }
    });

    //Create postick
    $('#btn-addNote').click(function () {
        $board.append('<div class="postick" style="left:20px;top:70px"><div class="toolbar"><span class="delete" title="Close">x</span></div><div contenteditable class="editable"></div></div>');
        $(".postick").draggable({
            cancel: '.editable'
        });
    });

    //Save all the posticks when the user leaves the page
    window.onbeforeunload = function () {
        //Clean the localStorage
        Postick.removeAll();
        //Then insert each postick into the LocalStorage
            //Saving their position on the page, in order to position them when the page is loaded again
        $('.postick').each(function () {
            var $this = $(this);
            Postick.add({
                top: parseInt($this.position().top),
                left: parseInt($this.position().left),
                text: $this.children('.editable').text()
            });
        });
    }
})(jQuery, window.localStorage);

I believe the JavaScript is pretty much self-explanatory since it also already contains some notes about each part of the code, and especially if you already know enough about JavaScript. ;)
Anyway, you can check the demo of the tutorial here. Also, you can get the full source code (.zip) here. Credit and thanks goes to Tyler Feliz for sharing his code to all of us!

1 comment: