Archive | Developer RSS feed for this section

Unleash the true power of YQL

What is YQL

It is a SQL like language created by Yahoo that harvests the information from the Net like how you interface the relational database. Underneath the hood, someone has done the job to bind the data sources and expose it as open table. As many has shared their works, more open tables are created for your usage. Apart from solving integration headaches, its async processing plus parallelism provides you a highly performed data hub. With the nice abstraction provided by YQL, we now can easily and quickly tap into the data from various sources for our app.

Taste the power of YQL

There are tons of information in the Net that tells people how to use the YQL. So, I don’t plan to repeat it here. If you are interested in learning it, you can read the YQL guide here. If you are impatient like me, you may want to see it in action first before diving in. Below is a great presentation from Nagesh Susarla.

Leave a comment Continue Reading →

Design Robust Restful API

This article is to summarize some key design decisions related to exposing some in-house services through REST API to the public. It involves url path design based on “resource oriented model”, version control, authentication and authorization and asynchronous call handling.

URL Path Design

Check out this video first:

  • Use resource oriented model - Every resource type should be a Noun that is normally represented as a collection. On the other hand, HTTP verbs (GET, PUT, POST, DELETE) will be used to manipulate the resources.
    • GET: read (cacheable)
    • PUT: modify (caller provides id)
    • POST: create the resource and use to call method as RPC.
    • DELETE: remove
  • Each resource should have 2 apis only: one for the collection in plural form, one for a particular entity.
  • The collection one can have ?search=… for locate the set of entities you want.
  • No verb should be in the url path.
  • Complex variation should use ?xxxx to take care of. Don’t complicate your url.
  • Pagination prefers to use ?offset=50&limit=200
  • Field extraction: field extraction uses ?fields=xxx,yyy
  • Formatting: take advantage of file extension like dogs.json
  • For input parameters, put everything into the URL and not using the HTTP headers, which is used for OAuth headers.
  • Error handling: Use HTTP error code to indicate error in the server side. (ie. 200 = succeed, 400=application error and 500 = wrong request, is used if the API). A human readable error message, together with the hint to fix that, should be sent back in the HTTP body response.
  • Operations can be sync vs async.
  • In GET operation, by default the container only return the URL reference of its immediate children. An optional parameter “expand” can be used to request the actual representation of all children and descendant.
  • API should only expose the function semantics but nothing about its implementation details, which allows the implementation to continuously evolve without breaking the client interface. And a good API should focus to do one thing well, rather than multiple things of different purposes. Each API must be self-contained and not relying on any specific call sequence to work correctly.

Example:

  1. List all persons. GET /persons
  2. Find a person with a particular id. GET /persons/123
  3. Get partial fields. GET /persons/123?fields=(name,age)
  4. Find a person’s particular friend. GET/persons/123/friends/456
  5. Find all persons named John. GET /persons/search?q=(name,eq,John)
  6. Find all dogs whose master is John. GET /persons/search?q=(name,eq,John)/dogs
  7. Create a person with a server assigned id. POST /persons?name=Dave&age=10
  8. Create a person with a client assigned id. PUT /persons/123?name=Dave&age=10
  9. Ask the person to perform an action. POST /persons/123/action/travel?location=Euro
  10. Remove a person. DELETE /persons/123
  11. Return a page of result. GET /persons/search?q=(name,eq,John)&offset=1&limit=25

Async call handling

In case when the operation takes a long time to complete, an asynchronous mode should be used. In a polling approach, a transient transaction object is return immediately to the caller. The caller can then use GET request to poll for the result of the operation. We can also use a notification approach. In this case, the caller pass along a callback URI when making the request. The server will invoke the callback URI to POST the result when it is done.

Versioning

  • If you follow the minimal API design approach, the newer version is usually about adding parameters to your original API rather than removing parameters.
  • Backward compatibility via using the same URL. (e.g. http://xyz.com/v1/path/…). On the implementation side, you only have the implementation that takes the latest version API parameters as input. In other words, you are prepared to receive request of the older version as well as the latest version. But you substitute the default value of the parameters of the newer version that is missing in the older version. And then send this request (with all the parameters filled) to the latest implementation.
  • For incompatible change, use a different URL endpoint for the new version (e.g. http://xyz.com/v2/path/…). You also keep the corresponding implementation (v1 and v2) behind those endpoints. Depends on your decision whether to keep supporting the older version, you may want to introduce a deprecation process. Unfortunately there is no standard way to indicate an API will be deprecated in the response. One possible way is to put a flag in the HTTP header of the response to indicate when the API will be deprecated.
  • Most people put versioning info as part of url like (e.g. http://xyz.com/v1/path/…). But it is debatable as others see versioning shouldn’t be part of url instead you can play trick in content type to specify what version of content you want.
Reference
  1. http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html

Authentication and Authorization

Authentication call which must the first call to make and precede any other application API calls. As far as API security, App level key, with OAuth2.0 protocol should be used for authentication and authorization purpose.

Leave a comment Continue Reading →

Function Currying in Scala – Part 4

When I first read function currying, I had no idea what is the use of it. Why someone wants to break down its argument list into multiple () with one argument per each. Luckily, I finally came across an article that provides a great explanation of it. Given what you have learnt so far from my series, you should have good foundation to understand this article. I will try to walk through this example with you here and hope you will grasp it as well.

Review the example

1

You can see some syntax rules are applied here. Let me go through with you one after one.

  1. testRule1() method has return type Unit, so ‘=’ sign is not necessary. Since it is > 1 statement in the function body, we still need to have the { }.
  2. parserRule must be an instance variable from class Parser.
  3. The return type of parserRule is instance of one of the case class “Success” or “NoSuccess” and they extend ParseResult abstract class. The return result will be used in the pattern matching like regular function chaining.
  4. “apply” method name can be omitted and author wants to factor out the routine for Success as a separate function.

The author creates a method tryMatch and refactor out the assertion routine as below:

1

There are some interesting points I want to bring up:

  1. ParseResult has [T] next to it. I haven’t talked about that in my series. It is generic in Scala way.
  2. The 2nd parameter is a function type that allows you to pass the function to handle the success case.

How to use the new function above to make your test cleaner and easier

1

According to pattern matching rules, the value in the ParseResult will assign to r if case Success is matched. And the r will be the “result” of the function literal passed in. So far so good?

Function Currying

OK, I finally get to point to talk about function currying. The example in this blog saying that if there are multiple statement in success case routine, it will look ugly if you try to encapsulate all of these inside the function literal like below:

1

<
So, the author suggested to use function currying as it will transform a method taking multiple parameters into a chain of singular parameter. Here is what he can achieve after the function currying:

1

However, I don’t really feel the power of function currying simply just convert () to {}. If the author can format the previous code a bit, he can achieve the one like below. To me, it is about the same in term of clarity.

1

I believe function currying should possess the power better than this example. The reason I picked this example because I like the refactoring process from the author. I have googled more and notice this example may be a good one. However, to be honest, I am still not quite clear about the pivot syntax. So, I googled more and found out this statement from this article, “… Sometimes it makes sense to let people apply some arguments to your function now and others later”. Sounds like curried function allowing you to partially apply the parameter to the function.

1

Too bad that I still cannot figure out a real life example that we need to use curried function. If you know one, please comment this post.

Leave a comment Continue Reading →

Power of Scala – Part 3

Enough comparison between Scala and Java. The first two articles in the series just helps you to get familiar with Scala syntax but not telling you the actual power of Scala. In fact, I have no motivation to pick up Scala if it doesn’t give me the power big enough to scarify my time with my family. From this onward, I will put down the key features in Scala that differentiate it from Java.

Pattern Matching

Extend the power of switch/cases

  1. Support more than simple primitive type switch/cases
  2. Support case class
  3. Type match and assignment
Simple switch/cases

//primitive
def checkPrime(number:Int) = number match {
case 1 => true
case 2 => true

case _ => false
}

// you can condense cases in one line and return other data type
def toYesOrNo(choice: Int): String = choice match {
case 1 | 2 | 3 => “yes”
case 0 => “no”
case _ => “error”
}

//you can compare different data types
def f(x: Any): String = x match {
case i:Int => “integer: ” + i
case _:Double => “a double”
case s:String => “I want to say ” + s
}

//just check type. If match, assign x with obj and assign it with type Color. Then return it and assign to cast variable.
var obj = performOperation()
var cast:Color = obj match {
case x:Color => x
case _ => null
}

//with this addon, you can make it looks very similar to formula definition:
def fact(n: Int): Int = n match {
case 0 => 1
case n => n * fact(n – 1)
}


Example of case class

case class Number(value:Int)

def checkPrime(n:Number) = n match {
case Number(1) => true
case Number(2) => true
case Number(3) => true
case Number(5) => true
case Number(7) => true
case Number(_) => false
}

checkPrime(Number(12))

  1. The first statement is the key to the whole thing: defining a new case class “Number” with a single property.
  2. Case classes are a special type of class in Scala which can be matched directly by pattern matching.
  3. You can also create a new instance of a case class without the new operator
  4. For each case, we’re actually creating a new instance of Number, each with a different value.
  5. When Scala sees that the instances are the same type during comparison, it introspects the two instances and compares the property values.
  6. Case class supports inheritance.

How exception handling uses this?

Scala does not have checked exceptions and it does not force you to catch exceptions as well. Basically, it is up to you to catch it. To catch various exception, you don’t need multiple catch block in Scala. See the example below. You can see it just uses one catch block with switch/cases to do the job.

Box title

import java.sql._
import java.net._

Connection conn = DriverManager.getConnection(“jdbc:hsqldb:mem:testdb”, “sa”, “”)
try {
PreparedStatement stmt = conn.prepareStatement(“INSERT INTO urls (url) VALUES (?)”)
stmt.setObject(1, new URL(“http://www.codecommit.com”))

stmt.executeUpdate()
stmt.close()
} catch {
case e:SQLException => println(“Database error”)
case e:MalformedURLException => println(“Bad URL”)

case e => {
println(“Some other exception type:”)
e.printStackTrace()
}
} finally {
conn.close()
}

Leave a comment Continue Reading →

Class in Scala – Part 2

Common knowledge in this space

When I first dealt with class, the main concept I learnt was that it encapsulates both related properties and behaviors. Then I started learning the constructor, access scope, mutability, type constraints, inheritance and etc. I would like Scala addressing those OO concepts as well or it could provide a better abstraction of this concept.

Define a regular class

First, let me take the example used by a blog as a starting point.

Regular class definition

//default primary constructor
class Person {
  private var name = "Daniel Spiewak" // private field that could be changed
  val ssn = 1234567890    // public constant field
  var age = 0             // public field

  // public method
  def firstName() = splitName()(0)   // public method

  // import with method scope and round() from math can only be used in this method.
  // visible to subclass and enclosing class
  protected def guessAge() = {
    import Math._
    round(random * 20)
  }

  //private method that can be accessed by object of the same class
  private def splitName() = name.split(" ")  

  //access-restricted to both the enclosing class <em>and</em> the enclosing package
  private[mypackage] def myMethod = "test" 

  //access-restricted to this instance but no others.
  private[this] def myMethod2 = "test2"
}


Rules:

  1. The primary constructor for a class is coded in-line in the class definition. Parameters of the primary constructor turn into fields that are initialized with the construction parameters.
  2. The primary constructor can be made private by adding the access modifier private before the parameter list.
  3. Class parameters:
    • val to make them immutable instance value whereas
    • var to make them mutable.
  4. Class parameters can be preceded by an access modifier such as private or protected. By default, it is public on both class and method.
    • protected by default limits access to only subclasses, unlike Java which also allows access to other classes in the same package.
    • modifier[package] notation in Scala gives you more control of visibility.
    • Scala has far fewer method modifiers than Java does, primarily because it doesn’t need so many.  For example, Scala supports the final modifier, but it doesn’t support abstract, native or synchronized:
  5. auto-generate get/set methods but in different forms. To generate the setXxx and getXxx as Java Bean,  you need to use annotation: @BeanProperty.
    • If the field is private, the getter and setter are private. (NOTE: other object under the same class can access the private field. ie class-private)
    • If the field is a val, only a getter is generated.
    • If you don’t want any getter or setter, declare the field as private[this]. (Note: other object under the same class cannot access this. ie. object-private).
  6. A class can have a companion “object” (ie. singleton) with the same name but both of them must be at the same source file. They can access each other private features.
  7. Scala doesn’t force you to declare the return type for your methods.  Once again the type inference mechanism can come into play and the return type will be inferred.  The exception to this is if the method can return at different points in the execution flow (so if it has an explicit return statement).  In this case, Scala forces you to declare the return type to ensure unambiguous behavior. This “returnless” form becomes extremely important when dealing with anonymous methods.
  8. Access scope difference between Java and Scala

An example demonstrate all modifiers in Scala

In Scala

abstract class Person {
  private var age = 0

  def firstName():String
  final def lastName() = "Spiewak"

  def incrementAge() = {
    synchronized {
      age += 1
    }
  }

  @native
  def hardDriveName():String
}

In Java

public abstract class Person {
    private int age = 0;

    public abstract String firstName();

    public final String lastName() {
        return "Spiewak";
    }

    public synchronized void incrementAge() {
        age += 1;
    }

    public native String hardDriveAge();
}

Rules

  1. abstract is used in the class but not method level. No body method definition is considered to be abstract.
  2. final can be used in the method level but not at the field level
  3. native method needs to use annotation to specify
  4. synchronized method no longer there in Scala. But you can use code block level synchronized to achieve the same. However, we should consider to move to Scala actor-based concurrency model instead.

Singleton

Scala doesn’t support static member/methods. But you can use “object” to get the same capability. Basically, you can see object as singleton but there is no instance been created.

Companion object

    class MyString(val jString:String) {
      private var extraData = ""
      override def toString = jString+extraData
    }
    object MyString {
      def apply(base:String, extras:String) = {
        val s = new MyString(base)
        s.extraData = extras
        s
      }
      def apply(base:String) = new MyString(base)
    }
    println(MyString("hello"," world"))
    println(MyString("hello"))

Leave a comment Continue Reading →

Function in Scala – Part 1

Function Definition

def methodName(paramName: paramType, …): returnType = {//function body}

Rules:

  1. single statement doesn’t need {}
  2. semicolon after statement is optional
  3. return type is optional as scala interpreter will look at the last line as return type (no need return keyword)
  4. return type and the “=” can be omitted when the type is Unit (ie. void in Java)
  5. recursive function must specify the return type.
  6. A function with no parameters can be declared without parentheses, in which case it must be called with no parentheses.
  7. Vararg parameters are declared by appending an asterisk to the argument
  8. You can specify default arguments
Example

//this function will return true if character ‘l’ is passed in
def lls(p: Char): Boolean = { p == ‘l’ }

//return void but >1 statement, so braces are needed
def box(s : String) {
val border = “-” * s.length + “–\n”
println(border + “|” + s + “|\n” + border)
}

//varag parameters
def sum(args: Int*) = {
var result = 0
for (arg <- args) result += arg
result
}

//call it:
val s = sum(1, 4, 9, 16, 25)
//1 to 5 is a range not Int as expected for single argument. Use _* to tell it is arg sequence
val s = sum(1 to 5: _*)

//bounded array input -  T is subclass of Number, input is T varying array
def sum[T <: Number] (as: T*): Double = as.foldLeft(0d)(_+_.doubleValue)

//default arguments
def decorate(str: String, left: String = “[", right: String = "]“) = left + str + right

Function Call

Now you should have a good idea how to define a function in Scala. Lets look at some interesting areas related to anonymous function and compile syntax sugar.

Lets start from defining a function:

def lls(p: Char): Boolean = { p == ‘l’ }

In StringOps, there is a count function that takes the function type specified above:
def count (p: (Char) ⇒ Boolean): Int

StringOps is a scala way to extend the capability of Java String.
“Hello”.count(lls) // outputs 2

Functions with zero or one argument can be called without the dot and ( ). If it is single argument, you can use {} instead of ( ).
“Hello” count lls  // outputs 2

Syntax Sugar

This kind of syntax sugar is quite confusing for an newbie like me. I believe it is created for a reason and I notice that it is used quite extensively in the area of DSL. Hopefully, there is syntax style standard develops on top of this and make life easier. Before seeing this, I need to try out all possible combinations and see how far Scala can take.

Here I demonstrate the rules are correct and > 1 space can be added as long as it doesn’t confuse the compiler.

Function Literal

(x:Int, y:Int) => //function body

Use of function literal – is like an anonymous function in java.
“Hello” count { p:Char => p == ‘l’ } // outputs 2

Function literal is shorthand of object of class FunctionN where N is number of input parameter)
new Function1[Char, Boolean] {
def apply(p: Char): Boolean = { p == ‘l’}
}

You can bind Function Literal to variables:
val add = (a:Int, b:Int) => a + b
add(1, 2) // Result is 3

Function literals are useful for passing as arguments to higher-order functions. They’re also useful for defining one-liners or helper functions nested within other functions.
“Hello” count { p => p == ‘l’ } // outputs 2 (type inference knowing p is character)
“Hello” count { _ == ‘l’ } // still outputs 2 (if one parameter passed in and the name has no significant, you can use _)

Leave a comment Continue Reading →

Unit Testing – Async method

Most Unit testing frameworks assumes a synchronous call model that the calling thread will block until the called method returns. So a typical test method will look like the following …

1

However, this model doesn’t fit if the call is asynchronous; ie: the calling thread is not blocked and the result will come later from a separated callback thread. For example, if you have the following AsyncService, where the “call()” method returns immediately and the result comes back from a callback interface.

1

The test method need to be changed. You need to block the calling thread until the result comes back from the callback thread. The modified test code will look like the following …

1

In this test method, the calling thread is waiting for the callback thread. A latch is used for the synchronization. You cannot use Thread.wait() and Thread.notify() for this purpose because there is a possibility that notify can be called before the wait and then one thread will wait indefinitely. Latch is a once-off switch and if the “release” is called first, then all subsequent “attempt” call will return immediately.

Leave a comment Continue Reading →

CSS Cheat Sheet

CSS Selector

  1. *  //universal selector
  2. #container *  //everything under #container element
  3. X  //all elements according to their type like ul, a, li, etc
  4. X:visited, X:link  //pseudo-class targeting – eg. input[type=radio]:checked
  5. #X : id selector    //target single element
  6. .X : class selector //target multiple elements
  7. X Y: descendant selector //select only a set of elements under X
  8. X > Y  //only direct children Y of X
  9. X + Y //first adjacent sibling selector: select only the Y that is preceded by X (eg. ul + p)
  10. X ~ Y //all sibling selector
  11. X[Y]  //attribute selector (select X if it has Y as attribute)
  12. X[Y="Z"] //conditional attribute selector : exact
  13. X[Y*="Z"] //conditional attribute selector: contains
  14. X[Y^="Z"] //conditional attribute selector: begins with
  15. X[Y$="Z"] //conditional attribute selector: end with
  16. X[Y~="Z"] //target an attribute which has a spaced-separated list of values
  17. X:not(selector)

Use those tag to help you generated content around the selected elements

  1. X:after
  2. X:before
  3. X:hover (div:hover, a:hover)

Use pseudo-elements

  1. p::first-line
  2. p::first-letter

Use hierarchical notation

  1. X:nth-child(n)   -  eg. li:nth-child(100)
  2. X:nth-last-child(n)
  3. X:nth-of-type(n)
  4. X:nth-of-last-of-type(n)
  5. X:first-child
  6. X:last-child
  7. X:only-child
  8. X:first-of-type (eg. ul:first-of-type)
  9. X:only-of-type //no sibling from its parent container

Absolute positioning inside relative positioning

Without a relative positioned direct parent, the absolutely positioned children elements are positioning themselves in relation to the body element instead of their direct parent.

Reference: Absolute positing inside relative positioning

CSS positioning

The Box Model

To understand positioning in CSS you must first understand the box model. For display purposes, every element in a document is considered to be a rectangular box which has a content area surrounded by padding, a border and margins.

There are two basic types of boxes, block and inline.

  • inline: follow the flow without add new line.
  • block: always starts an new line before and after. (override via display: inline)

Default inline elements

  • <span>, <a>, <img>, <input>

Default block element

  • <div>, <p>, <ul>, <li>, <table>, <pre>, <blockquote>, <form>

Rules

  1. Block elements may contain both inline elements and other block elements, but inline elements may contain only other inline elements.
  2. CSS features a property called display, which allows you to change a block element into an inline one and vice versa.

 

Float

Float

  • A common problem with float-based layouts is that the floats’ container doesn’t want to stretch up to accomodate the floats. To do that, you need:

div.container {
  border: 1px solid #000000;
<strong> overflow: hidden; width: 100%;</strong>
}

div.left {
  width: 45%;
  float: left;
}

div.right {
  width: 45%;
  float: right;
}

 

Leave a comment Continue Reading →

Set up Mac for local WordPress development

Recently, I have bought myself a theme and plugin and I would like to extend my christian website “christianrelive.com“.  To do that, I need to get my local dev environment ready (ie. Mac). At the beginning, I thought it is an easy task. But I did come across several issues that I would like to document them out for my peers who have the same need as me. Below are the steps I took to create a local env that allows me to run and debug my wordpress website locally.

Steps to follow

Download and install XAMPP

Create loopback domain name

sudo vi /etc/hosts and add the followings:

127.0.0.1       christianrelive.local

Configure Apache

sudo vi /Applications/XAMPP/etc/httpd.conf and add the following lines:

NameVirtualHost *:80
<VirtualHost *:80>
ServerName http://christianrelive.local
DocumentRoot “/Users/rayhon/Sites/christianrelive.com”
<Directory /Users/rayhon/Sites/christianrelive.com>
DirectoryIndex index.php
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

Get your site configured locally

  • Download Wordpress from Production and put it under ~/Sites/christianrelive.com
  • Backup my production db (ie. mysql_db.sql)
  • Set up my local db with the production data.

mysql> create database relivedb;
mysql -u root relivedb < mysql_db.sql

  • Edit wp-config.php (change DB_HOST= 127.0.0.1 and DB_USER and DB_PASS accordingly)

update wp_options set option_value = ‘http://christianrelive.local’ where option_name = ‘siteurl’ or option_name = ‘home’;

NOTE: if you forget the update line above, your login will forward to your live site instead of local.

Restart Apache from XAMPP control to take effect!

Debug the php code

I am using phpstorm 2 for the work and you may have your own IDE. But either one, you may need to enable xDebug in order to do step thru debugging. I use the links below to get this working.

  1. Download the xdebug.so from this link.
  2. Following this post to set it up.
Key steps

Move the xdebug.so to /Applications/XAMPP/xamppfiles/lib/php/php-5.3.1/extensions/no-debug-non-zts-20090626

Edit /Applications/XAMPP/etc/php.ini and add the followings:

[xdebug]
zend_extension=”/Applications/XAMPP/xamppfiles/lib/php/php-5.3.1/extensions/no-debug-non-zts-20090626/xdebug.so”
xdebug.remote_enable=1

Now I can run my phpstorm in debug mode pointing to the ~/Sites/christianrelive.com

Hope it is helpful

Leave a comment Continue Reading →

How to Write JQuery Plugin – Part 2

After I understand the JQuery basic, the first thing I would like to learn is how to write a JQuery plugin as I have seen so much cool widgets are written in this style. I believe this will give me a ticket to get into this land. When I first looked at the code of a JQuery plugin, I am quite confused at its syntax. After I went through some articles, I eventually got some ideas how it works. So, my goal in this tutorial is to jump start  you on writing your first plugin. If not, at least I hope it will help you to peel off the syntax and get you right to the core of a plugin.

JQuery Plugin Template

To read a plugin, you first need to understand its general structure. Here is the JQuery template you normally see.

1

What is in this template?

  • It defines the name of the plugin as “myplugin” and this plugin is written as function object with options as parameter to pass in.
  • The .extend method provides you a way to define the default options in your plugin and a mechanism to override it.
  • With this plugin included in your JQuery code, you now can do $(selector).myplugin(xxx). This will pass the matching element(s) one by one to the each() method in the plugin. And the magic normally happen in this method.

Write my first plugin to highlight my text

Below is a simple plugin that uses this structure:

1

Once you define the plugin, lets see how we can override the default properties.

1

This plugin has 2 additional methods, one is private and one is public. Public function has the format like: $.fn.myplugin.format = function(xxx){…}. The reason why we expose a function to public b/c it gives a way for users to override it. With this, users can extend the functionality of the plugin.

Metadata Plugin

You may have noticed another thing in the plugin code. That is the “.meta”.
1
Imagine that if you want the selected elements to be highlight in specific color. How can you do that with the control I showed you? It is simply impossible as what I have shown you so far is global options. Thanks that JQuery allows you to add metadata at the element level that can be used inside the each() method. The code above check if metadata plugin is installed. If yes, it will extract the metadata using $this.data() and have it overridden the default options. If no, it will just use the default options.


1
You can now do $(.abc).myplugin() in your JQuery code and have each div with class=”abc” doing different color of highlight.

Conclusion

So far so good? Most of content here I borrowed from here. All I do here is to organize it and provide some of my own explanation. Now I think I am ready to look at some of the cool widgets.

Leave a comment Continue Reading →