Wednesday, March 23, 2016

jQuery Plugin and special javascript literal

When you read javascript codes written by other developers, chances are those code may contain jQuery plugin codes. Usually those codes containing following format:
Type 1:
(function($) {
    $.fn.jPluginName = {
    },

    $.fn.jPluginName.defaults = {
    }
})(jQuery);
Type 2:
(function($) {
    $.jPluginName = {
    }
})(jQuery);
Type 3:
(function($){
    //Attach this new method to jQuery
    $.fn.extend({ 
        var defaults = {  
        }  
        var options =  $.extend(defaults, options);  
        //This is where you write your plugin's name
        pluginname: function() {
            //Iterate over the current set of matched elements
            return this.each(function() {
                //code to be inserted here
            });
        }
    }); 
})(jQuery);
A js code block looks like (function(){})()  actually defined a function and execute it. The parameter $ means the parameter is a reference. 

In jQuery, the fn property is just an alias to the prototype property.
So jQuery.fn === jQuery.prototype

Following is a simple javascript constructor function using prototype to extend the original class:
function Test() {
  this.a = 'a';
}
Test.prototype.b = 'b';

var test = new Test(); 
test.a; // "a", own property
test.b; // "b", inherited property
Following is a normal structure similar to the architecture of jQuery:
(function() {
  var foo = function(arg) { // core constructor
      // ensure to use the `new` operator
      if (!(this instanceof foo))
          return new foo(arg);
      // store an argument for this example
      this.myArg = arg;
      //..
  };

  // create `fn` alias to `prototype` property
  foo.fn = foo.prototype = {
      init: function () {/*...*/}
    //...
  };

  // expose the library
  window.foo = foo;
})();

// Extension:
foo.fn.myPlugin = function () {
    alert(this.myArg);
    return this; // return `this` for chainability
};

foo("bar").myPlugin(); // alerts "bar"
Type 1: This is actually not a plugin, it's an object passed as a function, and new functions added to the object using prototype.

Type 2: This is again not a plugin as it does not extend the $.fn object. It's just an extension of the jQuery core, although the outcome is the same. This is if you want to add traversing functions such as toArray and so on.

Type 3: This is the best method to add a plugin, the extended prototype of jQuery takes an object holding your plugin name and function and adds it to the plugin library for you.

Reference:

Tuesday, March 22, 2016

Applying Node.js in ASP.Net MVC 4.5

Node.js is a server side javascript framework which mainly used for real time web application. The core idea is event driving with asynchronous programming. When  you develop your dashboard web applications, it's so great to let your web page to show real time charts and statistic data. There is also real time programming framework named Signal R from Microsoft, which is purely under ASP.Net and a great contender compared with Node.js.

Compared with Signal R, Node.js has another feather that all javascript code you wrote for client side can be easily reused on the server side.  When I worked with a Online Web Reporting project, I applied Chart.js javascript to create vivid charts on the front web end, and also I applied jsPDF javascript library on client side to create PDF report for those vivid charts. All these worked fine but we also have a requirement that the server side can create same PDF reports and deliver them to our client's email. To make those PDF reports have same look and feel, the server side should call the same client side javascript code to create the PDF doc. The difference is the server side service will not be launched from client web side. And Node.js offered great chance to show their shinning part for sharing same client code on server side.

So we finally choose Node.js, to do above 2 great jobs.

The following blog link would compare Node.js and Signal R.
http://sim4all.com/blogging/?p=454

Monday, March 14, 2016

JQuery UI Drag and Drop Introduction

This is an interesting javascript drag and drop game.
<!doctype html>
<html lang="en">
<head>

<title>A jQuery Drag-and-Drop Number Cards Game</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<link rel="stylesheet" type="text/css" href="style.css">

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>
<script type="text/javascript">

var correctCards = 0;
$( init );

function init() {
  // Hide the success message
  $('#successMessage').hide();
  $('#successMessage').css( {
    left: '580px',
    top: '250px',
    width: 0,
    height: 0
  } );

  // Reset the game
  correctCards = 0;
  $('#cardPile').html( '' );
  $('#cardSlots').html( '' );

  // Create the pile of shuffled cards
  var numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];

  // Sort the array with a randomizing sort function to shuffle the numbers
  numbers.sort( function() { return Math.random() - .5 } );
  
  // loop through each element in the numbers array, creating a div card element
  // for each number. Inside the div we place the number, so that it appears on 
  // the card in the page.
  for ( var i=0; i<10; i++ ) {
    $('<div>' + numbers[i] + '</div>').data( 'number', numbers[i] )
      .attr('id', 'card'+numbers[i] ).appendTo( '#cardPile' ).draggable({
          containment: '#content',
          //to ensure that the dragged card always sits on top of the other cards
          stack: '#cardPile div',  
          cursor: 'move',

          //to make the card slide back to its initial position when dropped, 
          //so that the user can try again. When the card has been dragged to the correct
          //the option will be set as false.
          revert: true 
      });
  }

  // Create the card slots
  var words = [ 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 
'eight', 'nine', 'ten' ];

  for ( var i=1; i<=10; i++ ) {
    // store the card's number in a 'number' key inside the object by 
    // using jQuery's data() method.
    $('<div>' + words[i-1] + '</div>').data( 'number', i ).appendTo( 
'#cardSlots' ).droppable( {
      accept: '#cardPile div',
      hoverClass: 'hovered',
      drop: handleCardDrop
    } );
  }
}

function handleCardDrop( event, ui ) {
  var slotNumber = $(this).data( 'number' );
  var cardNumber = ui.draggable.data( 'number' );

  // If the card was dropped to the correct slot,
  // change the card colour, position it directly
  // on top of the slot, and prevent it being dragged
  // again
  if ( slotNumber == cardNumber ) {
    ui.draggable.addClass( 'correct' );
    ui.draggable.draggable( 'disable' );
    $(this).droppable( 'disable' );
    ui.draggable.position( { of: $(this), my: 'left top', at: 'left top' } );
    ui.draggable.draggable( 'option', 'revert', false );
    correctCards++;
  } 
  
  // If all the cards have been placed correctly then display a message
  // and reset the cards for another go
  if ( correctCards == 10 ) {
    $('#successMessage').show();
    $('#successMessage').animate( {
      left: '380px',
      top: '200px',
      width: '400px',
      height: '100px',
      opacity: 1
    } );
  }
}
</script>

<body>
<div class="wideBox">
  <h1>Drag-and-Drop with jQuery: Your Essential Guide</h1>
  <h2>A Number Cards Game</h2>
</div>

<div id="content">
  <div id="cardPile"> </div>
  <div id="cardSlots"> </div>

  <div id="successMessage">
    <h2>You did it!</h2>
    <button onclick="init()">Play Again</button>
  </div>
</div>
</body>
</html>
      
The HTML part:

In the head area we've included the jQuery and jQuery UI libraries, and linked to a style.css file. In the body we have:
  • A "#content" div to contain the game
  • A "#cardPile" div that will contain the set of 10 unsorted cards
  • A "#cardSlots" div that will contain the 10 slots to drop the cards into
  • A "#successMessage" div to display a "You did it!" message, along with a button to play again. 
The init() function:
  1. $( init ) is to call our init() function when the document is ready.
  2. To create the pile of cards, we first make an array, numbers, containing the numbers 1 to 10, then sort the array with a randomizing sort function to shuffle the numbers.
  3. Then loop through each element in the numbers array, creating a div card element for each number. Inside the div we place the number, so that it appears on the card in the page. Once we've created the divobject, we store the card's number in a 'number' key inside the object by using jQuery's data() method.
  4. Give the card div an id of 'cardn', where n is the card number. This lets us give each card a different colour in the CSS. We then append the card to the #cardPile div.
  5. The interesting bit in the loop is, of course, the call to the draggable()method. This:
    • Makes the card draggable
    • Uses containment to constrain it to the #content div
    • Uses stack to ensure that the dragged card always sits on top of the other cards
    • Uses cursor to turn the mouse cursor into a move cursor during the drag, and
    • Sets the revert option to true. This makes the card slide back to its initial position when dropped, so that the user can try again. We'll turn this option off when the user has dragged the card to the correct slot, as we'll see in a moment.
  6. The last part of the init() function creates the 10 slots to drag the cards onto. We create an array called words that contains the words "one" to "ten", then loop through the elements of the words array, creating a slot div for each number. As before, we use data() to record the number of the slot, so we can test if the user has dragged the correct card to the correct slot, and we append the slot to the #cardSlots div.
  7. This time, we call the droppable() method so that the slot can receive a draggable card. We use the accept option with the selector "#cardPile div" to ensure that the slot will only accept our number cards, and not any other draggable element. The hoverClass option adds a CSS class to a droppable when a draggable is hovered over it — we use this option to add a class of 'hovered' to the element, which we'll highlight using CSS. Finally, we set up a drop event handler called handleCardDrop(), which is triggered when the user drops a card on the droppable. We'll write this handler next.
The CSS Part: 
body {

  margin: 30px;

  font-family: "Georgia", serif;

  line-height: 1.8em;

  color: #333;

}



/* Give headings their own font */



h1, h2, h3, h4 {

  font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;

}



/* Main content area */



#content {

  margin: 80px 70px;

  text-align: center;

  -moz-user-select: none;

  -webkit-user-select: none;

  user-select: none;

}



/* Header/footer boxes */



.wideBox {

  clear: both;

  text-align: center;

  margin: 70px;

  padding: 10px;

  background: #ebedf2;

  border: 1px solid #333;

}



.wideBox h1 {

  font-weight: bold;

  margin: 20px;

  color: #666;

  font-size: 1.5em;

}



/* Slots for final card positions */



#cardSlots {

  margin: 50px auto 0 auto;

  background: #ddf;

}



/* The initial pile of unsorted cards */



#cardPile {

  margin: 0 auto;

  background: #ffd;

}



#cardSlots, #cardPile {

  width: 910px;

  height: 120px;

  padding: 20px;

  border: 2px solid #333;

  -moz-border-radius: 10px;

  -webkit-border-radius: 10px;

  border-radius: 10px;

  -moz-box-shadow: 0 0 .3em rgba(0, 0, 0, .8);

  -webkit-box-shadow: 0 0 .3em rgba(0, 0, 0, .8);

  box-shadow: 0 0 .3em rgba(0, 0, 0, .8);

}



/* Individual cards and slots */



#cardSlots div, #cardPile div {

  float: left;

  width: 58px;

  height: 78px;

  padding: 10px;

  padding-top: 40px;

  padding-bottom: 0;

  border: 2px solid #333;

  -moz-border-radius: 10px;

  -webkit-border-radius: 10px;

  border-radius: 10px;

  margin: 0 0 0 10px;

  background: #fff;

}



#cardSlots div:first-child, #cardPile div:first-child {

  margin-left: 0;

}



#cardSlots div.hovered {

  background: #aaa;

}



#cardSlots div {

  border-style: dashed;

}



#cardPile div {

  background: #666;

  color: #fff;

  font-size: 50px;

  text-shadow: 0 0 3px #000;

}



#cardPile div.ui-draggable-dragging {

  -moz-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);

  -webkit-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);

  box-shadow: 0 0 .5em rgba(0, 0, 0, .8);

}



/* Individually coloured cards */



#card1.correct { background: red; }

#card2.correct { background: brown; }

#card3.correct { background: orange; }

#card4.correct { background: yellow; }

#card5.correct { background: green; }

#card6.correct { background: cyan; }

#card7.correct { background: blue; }

#card8.correct { background: indigo; }

#card9.correct { background: purple; }

#card10.correct { background: violet; }





/* "You did it!" message */

#successMessage {

  position: absolute;

  left: 580px;

  top: 250px;

  width: 0;

  height: 0;

  z-index: 100;

  background: #dfd;

  border: 2px solid #333;

  -moz-border-radius: 10px;

  -webkit-border-radius: 10px;

  border-radius: 10px;

  -moz-box-shadow: .3em .3em .5em rgba(0, 0, 0, .8);

  -webkit-box-shadow: .3em .3em .5em rgba(0, 0, 0, .8);

  box-shadow: .3em .3em .5em rgba(0, 0, 0, .8);

  padding: 20px;

}

Source: http://www.elated.com/articles/drag-and-drop-with-jquery-your-essential-guide/
Game Link: http://www.elated.com/res/File/articles/development/javascript/jquery/drag-and-drop-with-jquery-your-essential-guide/card-game.html