Friday, December 4, 2015

JavaScript Constructor Prototype

At first it's important to understand that in JavaScript every function is an Object. Ok - then, what is a Constructor function?

The Construction function in javascript is just like any other function. Except, the convention it follows - Capitalization. The first character is in capital format. Another difference is that it uses the 'this' keword of javascript, which is the most important and confusing keyword of all.

This is how we create the constructor function:
function Student(name){
  this.name = name;
  this.getName = function(){
    return this.name;    
  }
}
var s1 = new Student("Leo");
var s2 = new Student("Lara");

console.log(s1.getName()); //Leo
console.log(s2.getName()); //Lara
This is not an appropriate way because if you create 500 Student objects then there will be 500 copies of the getName() function in memory.

Approach 2:
function Student(name){
  this.name = name;
}
var s1 = new Student("Leo");
s1.getName = function(){
  return this.name;
}
var s2 = new Student("Lara");

console.log(s1.getName()); //Leo
console.log(s2.getName()); //TypeError: s2.getName is not a function
The problem with this approach is that you have to repeat the same function for each object you create which will be arror prone.

Approach 3:
function Student(name){
  this.name = name;
}
Student.getName = function(){
  return this.name;
}
var s1 = new Student("Leo");
var s2 = new Student("Lara");

console.log(s1.getName()); //TypeError: s1.getName is not a function
console.log(s2.getName()); // 
The problem with this approach is that our newly created objects don't have access to the getName function.

Let's use the prototype property to associate the function
function Student(name){
  this.name = name;
}
Student.prototype.getName = function(){
  return this.name;
}
var s1 = new Student("Leo");
var s2 = new Student("Lara");

console.log(s1.getName()); //Leo
console.log(s2.getName()); //Lara

1. The benefits of this approach is that no matter how many objects you create, functions are loaded only once in the memory.
2. It allows you to override the function if necessary



Thursday, December 3, 2015

JavaScript: Prototype Object Vs Reference Object Explained

What is an Object?
It is a set of key and value pairs. You can use any number of keys with any name as long as it is a String. And each key can be associated with any value, those values can be of any Types, such as: Primitive Types, Function Objects and object itself.
var myObject = {
  a: undefined, //Primitive
  b: null, //Primitive
  c: true, //Primitive
  d: "foo", //Primitive
  e: 4.33, //Primitive
  f: function bar() { /**/ }, //Object
  g: {
    h: baz
  } //Object
}

The difference:

In case of Objects - values are passed by reference, and the changes are bi-directional:
var a = { x: 1, y: 2}
var b = a;
console.log(b); // Object {x: 1, y: 2} 

//
b.x = 10;
console.log(a.x); // 10

//
a.y = 20;
console.log(b.y); //20

While in Primitive - the values are passed by value, and the changes are uni-directional:
//Prototype Object
var object1 = {x: 11, y: 22};
var object2 = Object.create(object1);
console.log(object2); //Object {}

//
object2.x = 100; 
console.log(object1.x); //11 
console.log(object2.x); //100 

//
object1.y = 200; 
console.log(object2.y); //200 
console.log(object1.y); //200 

Fiddle: http://jsfiddle.net/sL6q0742/



Sunday, December 28, 2014

Vertical text / tabs with CSS3 transform matrix

These days the UI trends are changing rapidly, everyone is trying to implement something different than regular. For a long time we have always implemented the tabs in horizontal format, we did try to keep the tabs in vertical format but it wasn't easily possible with creepy IE browsers. CSS3 transforms have made the web a lot different than before. Scaling, skewing, rotating, translates are doing beautiful magic with their capabilities.

Today, implementing vertical text / tabs is possible with CSS3 transform matrix. Here is the code -

Browser compatibility: IE 9+

HTML:
  • Tab 3
  • Tab 2
  • Tab 1

CSS:
.tabs-vertcal{ 
 transform-origin: 0% 0% 0px; 
 transform: matrix(0, -1, 1, 0, 0, 350); 
}
.tabs{
 list-style-type: none;
}
.tab{
 float: left; 
 width: 92px; 
 padding: 6px; 
 border: 1px solid pink; 
 background: indigo; 
 color: white;
 text-align: right;
}

Demo: http://jsfiddle.net/oy3gnuxr/1/



Note: It's just a vertical text for now, I'll add the tabs functionality with jQuery soon.


Thursday, November 20, 2014

CSS Tabs Navigation Tricks

Developing a tabs navigation with CSS holds some simple tricks, but most of the front-end guys end up getting the results in an inappropriate way. Here's what you need to know about it -
I. The margin-bottom: -1px to the <li> element
II. The border and background to the <a> element
III. Change in border and background in the <a> element when <li> has .active class

HTML: 

CSS: 
ul{ margin: 0; padding: 0; list-style: none; border-bottom: 1px solid #ddd; 
}
ul:before, ul:after{
    content: ""; display: table;
}
ul:after{
    clear: both;
}
/**/
ul li{ 
    float: left; 
    margin: 0 4px -1px 4px;                /*Trick 1*/
}
ul li a{ 
    display: block; 
    text-decoration: none; 
    padding: 10px 15px; 
    border: 1px solid transparent;         /*Trick 2*/
    background: transparent;               /*Trick 2*/ 
}
ul li a:hover{
    background: #eee;
}
ul li.active a{ 
    border-radius: 4px 4px 0 0;
    border: 1px solid #ddd; 
    border-bottom: 1px solid transparent; /*Trick 3*/ 
    background: #fff;                     /*Trick 3*/ 
}

jQuery: 
$(function(){
    $('li a').on('click', function(e){
        e.preventDefault(); // to avoid page refresh because a elements have # in href 
        $('li').removeClass('active');
        $(this).parent('li').addClass('active');
    });
});


Demo: http://jsfiddle.net/dipaks2011/o35c8yxt/

Note: The fiddle demo is creating a ghost border on the right side of the tabs which doesn't appear in real HTML page.


Saturday, November 15, 2014

JavaScript text selection popover

Those who have read some articles on Medium.com are aware of how they can select text anywhere on a page and share it on Twitter or write a short comment about the selected text right on that page.

That's a nice popover to have, if the requirement is to select the text and show some information related to it on the same spot. I thought of posting a simple demo of it here, so that others can use it.

Here's the code 

HTML:
    
Having been in the field, most recently in India, I have seen that access to safe water is just a few dollars away for many people. A small loan can create a pathway to a household water tap. Making access to capital ubiquitous and affordable for those living in poverty would go a long way towards eliminating water stress.
CSS:
::selection{
  background: SeaGreen;
  color: White;
}
::-moz-selection{
  background: SeaGreen;
  color: White;
}
#textDescription{
  line-height:1.9em; font-size:16px; margin:10px; border:1px #333 solid; padding:5px; width: 450px;
 }
 .selectedText{
  position: relative;
  background-color: SeaGreen; color:#fff; line-height: 1.2em;
 } 
 .popDiv{
  background: ForestGreen; color: white; padding: 6px; width: 180px; height: 80px;  
  position: absolute; top: 18px; left: 0;
  border-radius: 4px; box-shadow: 2px 3px 4px #444;

  -webkit-animation: slideIn .5s;
  animation: slideIn .5s;
 }

 @-webkit-keyframes slideIn{
  from{
   top: 8px; opacity: 0; height: 40px;
  }
  to{
   top: 18px; opacity: 1; height: 80px;
  }
 }

 @-moz-keyframes slideIn{
  from{
   top: 8px; opacity: 0; height: 40px;
  }
  to{
   top: 18px; opacity: 1; height: 80px;
  }
 }

 @keyframes slideIn{
  from{
   top: 8px; opacity: 0; height: 40px;
  }
  to{
   top: 18px; opacity: 1; height: 80px;
  }
 }
JavaScript / jQuery:
 


 var parentContainerId = "textDescription"
  
 if(!window.CurrentSelection){
  CurrentSelection = {}
 }
 
 CurrentSelection.Selector = {}
 
 //get the current selection
 CurrentSelection.Selector.getSelected = function(){
  var sel = '';
  if(window.getSelection){
   sel = window.getSelection()
  }
  else if(document.getSelection){
   sel = document.getSelection()
  }
  else if(document.selection){
   sel = document.selection.createRange()
  }
  return sel
 }
 //function to be called on mouseup
 CurrentSelection.Selector.mouseup = function(){
  
  var st = CurrentSelection.Selector.getSelected()
  if(document.selection && !window.getSelection){
    var range = st
    range.pasteHTML("" + range.htmlText + "");   
  }
  else{
    var range = st.getRangeAt(0)    
    var newNode = document.createElement("span");
    newNode.setAttribute("class", "selectedText");
    range.surroundContents(newNode);
    //
    var getTitle = newNode.innerHTML;
    newNode.setAttribute("title", getTitle);

    //
    var popDiv = document.createElement('span');
    popDiv.setAttribute('class', 'popDiv');
    popDiv.innerHTML = getTitle;

    if(newNode.innerHTML.length > 0) {
     newNode.appendChild(popDiv);
    }     
    //Remove Selection: To avoid extra text selection in IE  
    if (window.getSelection) {
      window.getSelection().removeAllRanges();
    }
        else if (document.selection){ 
         document.selection.empty();
        }
        //
  }
 }
        
 $(function(){

  $("#"+parentContainerId).on('mouseup', function(){
    $('span.selectedText').contents().unwrap();
    $(this).find('span.popDiv').remove();
  });

  $("#"+parentContainerId).bind("mouseup",CurrentSelection.Selector.mouseup); 
 })        


Demo: http://jsfiddle.net/dipaks2011/uz0gsu8a/1/



Related Posts:

jQuery tab navigation:
http://dipaksblogonline.blogspot.in/2012/03/simple-jquery-tab-navigation.html

Defer third party scripts:
http://dipaksblogonline.blogspot.in/2012/06/defer-third-party-scriptsads-until.html

Using multiple iScrolls in one page:
http://dipaksblogonline.blogspot.in/2013/06/using-multiple-iscroll-in-one-page.html



Wednesday, September 17, 2014

HTML5 details element

Have you ever wondered if you could achieve that jQuery Accordion widget effect without jQuery or JavaScript? Did you think it will be ever possible to create it with just HTML? If no, well, you can achieve that with the HTML5 <details> element.

The details element is used as a widget to show/hide additional information.
Click me to toggle more information
The details element is used as a widget to show/hide additional information.
Demo: http://jsfiddle.net/8mthoj5g/

Attributes:

It comes with one additional attribute that is 'open'. By default it appears in closed state, but if you want to keep the hidden information visible on-load, you can use the 'open' attribute -
Click me to toggle more information
The details element is used as a widget to show/hide additional information.
Demo: http://jsfiddle.net/8mthoj5g/1/

Nesting:

Nesting multiple details in details is possible -
Click me to toggle more information
The details element is used as a widget to show/hide additional information.
More links to help
Demo: http://jsfiddle.net/8mthoj5g/2/

Styling:

This is the area where you can make the widget look beautiful with CSS. If you want to style the marker you can use ::-webkit-details-marker pseudo class  -
details{
    border: 1px solid #666; 
    border-radius: 4px; 
    margin: 0 0 4px 0;
}
summary{ 
    background: linear-gradient(to top, #f1efef 0%, #e8e9e9 50%, #e8e8e8 100%); 
    padding: 8px; 
    outline: none; 
}
.more-info{ 
    border-top: 1px solid #666; 
    padding: 8px; 
}
details[open] summary{ 
    background: none; 
}
summary::-webkit-details-marker {
  color: #818b94;
}
Demo: http://jsfiddle.net/czs29fd3/

To replace the default marker with some fancy icon, you can use the CSS :before and :after pseudo classes with summery element, but before using a replacement for marker you must hide it first -
summary::-webkit-details-marker {
  display: none; /*Hide the default marker*/
}
summary:after {  
  content: "+";   
  float: left; 
  font-size: 1em; 
  font-weight: bold;       
  width: 22px;
}
details[open] summary:after {
  content: "-";
}
What about the browsers that don't support details element?
Use this Bulletproof HTML5 <details> fallback using jQuery by @MathiasBynens

Browser Support:

You can see the latest browser support at caniuse.com




Monday, August 18, 2014

Understanding HTML5 Pattern Attribute

What is HTML5 Pattern?
The HTML5 pattern attribute is nothing but a JavaScript Regular Expression. It is used to match form field's value against the specified format. Patterns are used to validate email addresses, dates, credit card numbers, zip codes and so on.

For example, the following pattern requires one number and three uppercase character, if you didn't enter the said format it will prompt you with a message:
  pattern="[0-9][A-Z]{3}"
Demo: http://jsfiddle.net/aoq22s54/

Similarly, if you have a field to accept only five numeric values, use this pattern:
pattern="\d{5}" in this pattern the '\d' stands for numeric values and '{5}' to accept only five characters.
Demo: http://jsfiddle.net/fhcox947/

Let's validate a DD/MM/YYYY date format:
Here's the pattern we need to use for validating this date format - pattern="(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}" 

The first section of this pattern (0[1-9]|[12][0-9]|3[01]) says - use 0 before the first value 1-9 except when the first value is 1/2, and use 0-9 after the first 1/2 value, and when the first values is 3 use only 0/1 after it. Sounds simple? I guess yes :)
Demo: http://jsfiddle.net/j8qpe3ca/

I hope you have understood how the patterns workplease refer this HTML5 pattern website for some common regular expression styles.