diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 90c417d..da494b4 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,6 +1,10 @@
 X-editable changelog
 =============================
-          
+       
+Version 1.0.2 wip
+----------------------------   
+[enh] updated docs: inputs dropdown menu, global templates section (vitalets)      
+                            
 
 Version 1.0.1 Nov 22, 2012
 ----------------------------          
diff --git a/src/editable-form/editable-form.js b/src/editable-form/editable-form.js
index 8a975b0..d93042a 100644
--- a/src/editable-form/editable-form.js
+++ b/src/editable-form/editable-form.js
@@ -17,7 +17,7 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'.
 
     EditableForm.prototype = {
         constructor: EditableForm,
-        initInput: function() {
+        initInput: function() {  //called once
             var TypeConstructor, typeOptions;
             
             //create input of specified type
@@ -247,7 +247,18 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'.
         
        option: function(key, value) {
           this.options[key] = value;
-       }        
+          if(key === 'value') {
+              this.setValue(value);
+          }
+       },
+       
+       setValue: function(value, convertStr) {
+          if(convertStr) {
+              this.value = this.input.str2value(value);
+          } else {
+              this.value = value;
+          }
+       }               
     };
 
     /*
diff --git a/src/inputs/checklist.js b/src/inputs/checklist.js
new file mode 100644
index 0000000..158d509
--- /dev/null
+++ b/src/inputs/checklist.js
@@ -0,0 +1,150 @@
+/**
+Checklist input. Internally value stored as array.
+
+@class checklist
+@extends list
+@final
+@example
+<a href="#" id="status" data-type="checklist" data-pk="1" data-url="/post" data-original-title="Select options"></a>
+<script>
+$(function(){
+    $('#options').editable({
+        value: [2, 3],    
+        source: [
+              {value: 1, text: 'Active'},
+              {value: 2, text: 'Blocked'},
+              {value: 3, text: 'Deleted'}
+           ]
+        }
+    });
+});
+</script>
+**/
+(function ($) {
+
+    var Checklist = function (options) {
+        this.init('checklist', options, Checklist.defaults);
+    };
+
+    $.fn.editableform.utils.inherit(Checklist, $.fn.editableform.types.list);
+
+    $.extend(Checklist.prototype, {
+        renderList: function() {
+            var $label, $div;
+            if(!$.isArray(this.sourceData)) {
+                return;
+            }
+
+            for(var i=0; i<this.sourceData.length; i++) {
+                $label = $('<label>').text(' '+this.sourceData[i].text)
+                                     .prepend($('<input>', {
+                                           type: 'checkbox',
+                                           value: this.sourceData[i].value, 
+                                           name: this.options.name
+                                     }));
+                
+                $('<div>').append($label).appendTo(this.$input);
+            }
+        },
+       
+       value2str: function(value) {
+           return $.isArray(value) ? value.join($.trim(this.options.separator)) : '';
+       },        
+       
+       //parse separated string
+        str2value: function(str) {
+           var reg, value = null;
+           if(typeof str === 'string' && str.length) {
+               reg = new RegExp('\s*'+$.trim(this.options.separator)+'\s*');
+               value = str.split(reg);
+           } else if($.isArray(str)) {
+               value = str; 
+           }
+           return value;
+        },       
+       
+       //set checked on required checkboxes
+       value2input: function(value) {
+            var $checks = this.$input.find('input[type="checkbox"]');
+            $checks.removeAttr('checked');
+            if($.isArray(value) && value.length) {
+                $checks.each(function(i, el) {
+                    if($.inArray($(el).val(), value) !== -1) {
+                        $(el).attr('checked', 'checked');
+                    }
+                }); 
+            }  
+        },  
+        
+       input2value: function() { 
+           var checked = [];
+           this.$input.find('input:checked').each(function(i, el) {
+               checked.push($(el).val());
+           });
+           return checked;
+       },            
+          
+       //collect text of checked boxes
+        value2htmlFinal: function(value, element) {
+           var selected = [], html = '';
+           if($.isArray(value) && value.length <= this.options.limit) {
+               for(var i=0; i<value.length; i++){
+                   item = this.itemByVal(value[i]);
+                   if(item) {
+                       selected.push($('<div>').text(item.text).html());
+                   }
+               }
+               html = selected.join(this.options.viewseparator);
+           } else {  
+               html = this.options.limitText.replace('{checked}', $.isArray(value) ? value.length : 0).replace('{count}', this.sourceData.length); 
+           }
+           $(element).html(html);
+        }
+    });      
+
+    Checklist.defaults = $.extend({}, $.fn.editableform.types.list.defaults, {
+        /**
+        @property tpl 
+        @default <div></div>
+        **/         
+        tpl:'<div></div>',
+        
+        /**
+        Separator of values in string when sending to server
+
+        @property separator 
+        @type string
+        @default ', '
+        **/         
+        separator: ',',
+        /**
+        Separator of text when display as element content.
+
+        @property viewseparator 
+        @type string
+        @default ', '
+        **/         
+        viewseparator: '<br>',
+        /**
+        Maximum number of items shown as element content. 
+        If checked more items - <code>limitText</code> will be shown.
+
+        @property limit 
+        @type integer
+        @default 4
+        **/         
+        limit: 4,
+        /**
+        Text shown when count of checked items is greater than <code>limit</code> parameter.
+        You can use <code>{checked}</code> and <code>count</code> placeholders.
+
+        @property limitText 
+        @type string
+        @default 'Checked {checked} options of {count}'
+        **/         
+        limitText: 'Checked {checked} options of {count}'        
+    });
+
+    $.fn.editableform.types.checklist = Checklist;      
+
+}(window.jQuery));
\ No newline at end of file
diff --git a/src/inputs/date/date.js b/src/inputs/date/date.js
index 38680e8..5081db2 100644
--- a/src/inputs/date/date.js
+++ b/src/inputs/date/date.js
@@ -5,6 +5,7 @@ For localization you can include js file from here: https://github.com/eternicod
 
 @class date
 @extends abstract
+@final
 @example
 <a href="#" id="dob" data-type="date" data-pk="1" data-url="/post" data-original-title="Select date">15/05/1984</a>
 <script>
diff --git a/src/inputs/dateui/dateui.js b/src/inputs/dateui/dateui.js
index 53ee858..38cc2d3 100644
--- a/src/inputs/dateui/dateui.js
+++ b/src/inputs/dateui/dateui.js
@@ -5,6 +5,7 @@ Do not use it together with bootstrap-datepicker.
 
 @class dateui
 @extends abstract
+@final
 @example
 <a href="#" id="dob" data-type="date" data-pk="1" data-url="/post" data-original-title="Select date">15/05/1984</a>
 <script>
diff --git a/src/inputs/list.js b/src/inputs/list.js
new file mode 100644
index 0000000..8dba070
--- /dev/null
+++ b/src/inputs/list.js
@@ -0,0 +1,255 @@
+/**
+List - abstract class for inputs that have source option loaded from js array or via ajax
+
+@class list
+@extends abstract
+**/
+(function ($) {
+
+    var List = function (options) {
+       
+    };
+
+    $.fn.editableform.utils.inherit(List, $.fn.editableform.types.abstract);
+
+    $.extend(List.prototype, {
+        render: function () {
+            List.superclass.render.call(this);
+            var deferred = $.Deferred();
+            this.error = null;
+            this.sourceData = null;
+            this.prependData = null;
+            this.onSourceReady(function () {
+                this.renderList();
+                deferred.resolve();
+            }, function () {
+                this.error = this.options.sourceError;
+                deferred.resolve();
+            });
+
+            return deferred.promise();
+        },
+
+        html2value: function (html) {
+            return null; //can't set value by text
+        },
+        
+        value2html: function (value, element) {
+            var deferred = $.Deferred();
+            this.onSourceReady(function () {
+                this.value2htmlFinal(value, element);
+                deferred.resolve();
+            }, function () {
+                List.superclass.value2html(this.options.sourceError, element);
+                deferred.resolve();
+            });
+
+            return deferred.promise();
+        },  
+
+        // ------------- additional functions ------------
+
+        onSourceReady: function (success, error) {
+            //if allready loaded just call success
+            if($.isArray(this.sourceData)) {
+                success.call(this);
+                return; 
+            }
+
+            // try parse json in single quotes (for double quotes jquery does automatically)
+            try {
+                this.options.source = $.fn.editableform.utils.tryParseJson(this.options.source, false);
+            } catch (e) {
+                error.call(this);
+                return;
+            }
+
+            //loading from url
+            if (typeof this.options.source === 'string') {
+                var cacheID = this.options.source + (this.options.name ? '-' + this.options.name : ''),
+                cache;
+
+                if (!$(document).data(cacheID)) {
+                    $(document).data(cacheID, {});
+                }
+                cache = $(document).data(cacheID);
+
+                //check for cached data
+                if (cache.loading === false && cache.sourceData) { //take source from cache
+                    this.sourceData = cache.sourceData;
+                    success.call(this);
+                    return;
+                } else if (cache.loading === true) { //cache is loading, put callback in stack to be called later
+                    cache.callbacks.push($.proxy(function () {
+                        this.sourceData = cache.sourceData;
+                        success.call(this);
+                    }, this));
+
+                    //also collecting error callbacks
+                    cache.err_callbacks.push($.proxy(error, this));
+                    return;
+                } else { //no cache yet, activate it
+                    cache.loading = true;
+                    cache.callbacks = [];
+                    cache.err_callbacks = [];
+                }
+
+                //loading sourceData from server
+                $.ajax({
+                    url: this.options.source,
+                    type: 'get',
+                    cache: false,
+                    data: {name: this.options.name},
+                    dataType: 'json',
+                    success: $.proxy(function (data) {
+                        cache.loading = false;
+                        // this.options.source = data;
+                        this.sourceData = this.makeArray(data);
+                        if($.isArray(this.sourceData)) {
+                            this.doPrepend();
+                            //store result in cache
+                            cache.sourceData = this.sourceData;
+                            success.call(this);
+                            $.each(cache.callbacks, function () { this.call(); }); //run success callbacks for other fields
+                        } else {
+                            error.call(this);
+                            $.each(cache.err_callbacks, function () { this.call(); }); //run error callbacks for other fields
+                        }
+                    }, this),
+                    error: $.proxy(function () {
+                        cache.loading = false;
+                        error.call(this);
+                        $.each(cache.err_callbacks, function () { this.call(); }); //run error callbacks for other fields
+                    }, this)
+                });
+            } else { //options as json/array
+                this.sourceData = this.makeArray(this.options.source);
+                if($.isArray(this.sourceData)) {
+                    this.doPrepend();
+                    success.call(this);   
+                } else {
+                    error.call(this);
+                }
+            }
+        },
+
+        doPrepend: function () {
+            if(this.options.prepend === null || this.options.prepend === undefined) {
+                return;  
+            }
+            
+            if(!$.isArray(this.prependData)) {
+                //try parse json in single quotes
+                this.options.prepend = $.fn.editableform.utils.tryParseJson(this.options.prepend, true);
+                if (typeof this.options.prepend === 'string') {
+                    this.options.prepend = {'': this.options.prepend};
+                }              
+                this.prependData = this.makeArray(this.options.prepend);
+            }
+
+            if($.isArray(this.prependData) && $.isArray(this.sourceData)) {
+                this.sourceData = this.prependData.concat(this.sourceData);
+            }
+        },
+
+        /*
+         renders input list
+        */
+        renderList: function() {
+            // this method should be overwritten in child class
+        },
+       
+         /*
+         set element's html by value
+        */
+        value2htmlFinal: function(value, element) {
+            // this method should be overwritten in child class
+        },        
+
+        /**
+        * convert data to array suitable for sourceData, e.g. [{value: 1, text: 'abc'}, {...}]
+        */
+        makeArray: function(data) {
+            var count, obj, result = [], iterateEl;
+            if(!data || typeof data === 'string') {
+                return null; 
+            }
+
+            if($.isArray(data)) { //array
+                iterateEl = function (k, v) {
+                    obj = {value: k, text: v};
+                    if(count++ >= 2) {
+                        return false;// exit each if object has more than one value
+                    }
+                };
+            
+                for(var i = 0; i < data.length; i++) {
+                    if(typeof data[i] === 'object') {
+                        count = 0;
+                        $.each(data[i], iterateEl);
+                        if(count === 1) {
+                            result.push(obj); 
+                        } else if(count > 1 && data[i].hasOwnProperty('value') && data[i].hasOwnProperty('text')) {
+                            result.push(data[i]);
+                        } else {
+                            //data contains incorrect objects
+                        }
+                    } else {
+                        result.push({value: i, text: data[i]}); 
+                    }
+                }
+            } else {  //object
+                $.each(data, function (k, v) {
+                    result.push({value: k, text: v});
+                });  
+            }
+            return result;
+        },
+        
+        //search for item by particular value
+        itemByVal: function(val) {
+            if($.isArray(this.sourceData)) {
+                for(i=0; i<this.sourceData.length; i++){
+                    /*jshint eqeqeq: false*/
+                    if(this.sourceData[i].value == val) {
+                    /*jshint eqeqeq: true*/                            
+                        return this.sourceData[i];
+                    }
+                }
+            }
+        }        
+
+    });      
+
+    List.defaults = $.extend({}, $.fn.editableform.types.abstract.defaults, {
+        /**
+        Source data for dropdown list. If string - considered ajax url to load items. Otherwise should be an array.
+        Array format is: <code>[{value: 1, text: "text"}, {...}]</code><br>
+        For compability it also supports format <code>{value1: text1, value2: text2 ...}</code> but it does not guarantee elements order.      
+
+        @property source 
+        @type string|array|object
+        @default null
+        **/         
+        source:null, 
+        /**
+        Data automatically prepended to the begining of dropdown list.
+        
+        @property prepend 
+        @type string|array|object
+        @default false
+        **/         
+        prepend:false,
+        /**
+        Error message when list cannot be loaded (e.g. ajax error)
+        
+        @property sourceError 
+        @type string
+        @default Error when loading list
+        **/          
+        sourceError: 'Error when loading list'
+    });
+
+    $.fn.editableform.types.list = List;      
+
+}(window.jQuery));
\ No newline at end of file
diff --git a/src/inputs/select.js b/src/inputs/select.js
index 8cda196..89b4265 100644
--- a/src/inputs/select.js
+++ b/src/inputs/select.js
@@ -2,7 +2,8 @@
 Select (dropdown) input
 
 @class select
-@extends abstract
+@extends list
+@final
 @example
 <a href="#" id="status" data-type="select" data-pk="1" data-url="/post" data-original-title="Select status"></a>
 <script>
@@ -25,160 +26,10 @@ $(function(){
         this.init('select', options, Select.defaults);
     };
 
-    $.fn.editableform.utils.inherit(Select, $.fn.editableform.types.abstract);
+    $.fn.editableform.utils.inherit(Select, $.fn.editableform.types.list);
 
     $.extend(Select.prototype, {
-        render: function () {
-            Select.superclass.render.call(this);
-            var deferred = $.Deferred();
-            this.error = null;
-            this.sourceData = null;
-            this.prependData = null;
-            this.onSourceReady(function () {
-                this.renderOptions();
-                deferred.resolve();
-            }, function () {
-                this.error = this.options.sourceError;
-                deferred.resolve();
-            });
-
-            return deferred.promise();
-        },
-
-        html2value: function (html) {
-            return null; //it's not good idea to set value by text for SELECT. Better set NULL
-        },
-
-        value2html: function (value, element) {
-            var deferred = $.Deferred();
-            this.onSourceReady(function () {
-                var i, text = '';
-                if($.isArray(this.sourceData)) {
-                    for(i=0; i<this.sourceData.length; i++){
-                        /*jshint eqeqeq: false*/
-                        if(this.sourceData[i].value == value) {
-                        /*jshint eqeqeq: true*/                            
-                            text = this.sourceData[i].text;
-                            break; 
-                        }
-                    } 
-                }
-                Select.superclass.value2html(text, element);
-                deferred.resolve();
-            }, function () {
-                Select.superclass.value2html(this.options.sourceError, element);
-                deferred.resolve();
-            });
-
-            return deferred.promise();
-        },  
-
-        // ------------- additional functions ------------
-
-        onSourceReady: function (success, error) {
-            //if allready loaded just call success
-            if($.isArray(this.sourceData)) {
-                success.call(this);
-                return; 
-            }
-
-            // try parse json in single quotes (for double quotes jquery does automatically)
-            try {
-                this.options.source = $.fn.editableform.utils.tryParseJson(this.options.source, false);
-            } catch (e) {
-                error.call(this);
-                return;
-            }
-
-            //loading from url
-            if (typeof this.options.source === 'string') {
-                var cacheID = this.options.source + (this.options.name ? '-' + this.options.name : ''),
-                cache;
-
-                if (!$(document).data(cacheID)) {
-                    $(document).data(cacheID, {});
-                }
-                cache = $(document).data(cacheID);
-
-                //check for cached data
-                if (cache.loading === false && cache.sourceData) { //take source from cache
-                    this.sourceData = cache.sourceData;
-                    success.call(this);
-                    return;
-                } else if (cache.loading === true) { //cache is loading, put callback in stack to be called later
-                    cache.callbacks.push($.proxy(function () {
-                        this.sourceData = cache.sourceData;
-                        success.call(this);
-                    }, this));
-
-                    //also collecting error callbacks
-                    cache.err_callbacks.push($.proxy(error, this));
-                    return;
-                } else { //no cache yet, activate it
-                    cache.loading = true;
-                    cache.callbacks = [];
-                    cache.err_callbacks = [];
-                }
-
-                //loading sourceData from server
-                $.ajax({
-                    url: this.options.source,
-                    type: 'get',
-                    cache: false,
-                    data: {name: this.options.name},
-                    dataType: 'json',
-                    success: $.proxy(function (data) {
-                        cache.loading = false;
-                        // this.options.source = data;
-                        this.sourceData = this.makeArray(data);
-                        if($.isArray(this.sourceData)) {
-                            this.doPrepend();
-                            //store result in cache
-                            cache.sourceData = this.sourceData;
-                            success.call(this);
-                            $.each(cache.callbacks, function () { this.call(); }); //run success callbacks for other fields
-                        } else {
-                            error.call(this);
-                            $.each(cache.err_callbacks, function () { this.call(); }); //run error callbacks for other fields
-                        }
-                    }, this),
-                    error: $.proxy(function () {
-                        cache.loading = false;
-                        error.call(this);
-                        $.each(cache.err_callbacks, function () { this.call(); }); //run error callbacks for other fields
-                    }, this)
-                });
-            } else { //options as json/array
-                this.sourceData = this.makeArray(this.options.source);
-                if($.isArray(this.sourceData)) {
-                    this.doPrepend();
-                    success.call(this);   
-                } else {
-                    error.call(this);
-                }
-            }
-        },
-
-        doPrepend: function () {
-            if(this.options.prepend === null || this.options.prepend === undefined) {
-                return;  
-            }
-            
-            if(!$.isArray(this.prependData)) {
-                //try parse json in single quotes
-                this.options.prepend = $.fn.editableform.utils.tryParseJson(this.options.prepend, true);
-                if (typeof this.options.prepend === 'string') {
-                    this.options.prepend = {'': this.options.prepend};
-                }              
-                this.prependData = this.makeArray(this.options.prepend);
-            }
-
-            if($.isArray(this.prependData) && $.isArray(this.sourceData)) {
-                this.sourceData = this.prependData.concat(this.sourceData);
-            }
-        },
-
-        renderOptions: function() {
+        renderList: function() {
             if(!$.isArray(this.sourceData)) {
                 return;
             }
@@ -187,83 +38,24 @@ $(function(){
                 this.$input.append($('<option>', {value: this.sourceData[i].value}).text(this.sourceData[i].text)); 
             }
         },
-
-        /**
-        * convert data to array suitable for sourceData, e.g. [{value: 1, text: 'abc'}, {...}]
-        */
-        makeArray: function(data) {
-            var count, obj, result = [], iterateEl;
-            if(!data || typeof data === 'string') {
-                return null; 
+       
+        value2htmlFinal: function(value, element) {
+            var text = '', item = this.itemByVal(value);
+            if(item) {
+                text = item.text;
             }
-
-            if($.isArray(data)) { //array
-                iterateEl = function (k, v) {
-                    obj = {value: k, text: v};
-                    if(count++ >= 2) {
-                        return false;// exit each if object has more than one value
-                    }
-                };
-            
-                for(var i = 0; i < data.length; i++) {
-                    if(typeof data[i] === 'object') {
-                        count = 0;
-                        $.each(data[i], iterateEl);
-                        if(count === 1) {
-                            result.push(obj); 
-                        } else if(count > 1 && data[i].hasOwnProperty('value') && data[i].hasOwnProperty('text')) {
-                            result.push(data[i]);
-                        } else {
-                            //data contains incorrect objects
-                        }
-                    } else {
-                        result.push({value: i, text: data[i]}); 
-                    }
-                }
-            } else {  //object
-                $.each(data, function (k, v) {
-                    result.push({value: k, text: v});
-                });  
-            }
-            return result;
-        }
-
+            Select.superclass.constructor.superclass.value2html(text, element);   
+        }        
     });      
 
-    Select.defaults = $.extend({}, $.fn.editableform.types.abstract.defaults, {
+    Select.defaults = $.extend({}, $.fn.editableform.types.list.defaults, {
         /**
         @property tpl 
         @default <select></select>
         **/         
-        tpl:'<select></select>',
-        /**
-        Source data for dropdown list. If string - considered ajax url to load items. Otherwise should be an array.
-        Array format is: <code>[{value: 1, text: "text"}, {...}]</code><br>
-        For compability it also supports format <code>{value1: text1, value2: text2 ...}</code> but it does not guarantee elements order.      
-
-        @property source 
-        @type string|array|object
-        @default null
-        **/         
-        source:null, 
-        /**
-        Data automatically prepended to the begining of dropdown list.
-        
-        @property prepend 
-        @type string|array|object
-        @default false
-        **/         
-        prepend:false,
-        /**
-        Error message shown when list cannot be loaded (e.g. ajax error)
-        
-        @property sourceError 
-        @type string
-        @default Error when loading options
-        **/          
-        sourceError: 'Error when loading options'
+        tpl:'<select></select>'
     });
 
     $.fn.editableform.types.select = Select;      
 
-}(window.jQuery));
+}(window.jQuery));
\ No newline at end of file
diff --git a/src/inputs/text.js b/src/inputs/text.js
index 702c3f6..8d2f259 100644
--- a/src/inputs/text.js
+++ b/src/inputs/text.js
@@ -3,6 +3,7 @@ Text input
 
 @class text
 @extends abstract
+@final
 @example
 <a href="#" id="username" data-type="text" data-pk="1">awesome</a>
 <script>
diff --git a/src/inputs/textarea.js b/src/inputs/textarea.js
index c4d867e..eb4cd3c 100644
--- a/src/inputs/textarea.js
+++ b/src/inputs/textarea.js
@@ -3,6 +3,7 @@ Textarea input
 
 @class textarea
 @extends abstract
+@final
 @example
 <a href="#" id="comments" data-type="textarea" data-pk="1">awesome comment!</a>
 <script>
diff --git a/test/loader.js b/test/loader.js
index 136ba5b..ba91063 100644
--- a/test/loader.js
+++ b/test/loader.js
@@ -31,9 +31,11 @@ function getAssets(f, c, src, libs) {
     containers+'editable-container.js',
     element+'editable-element.js',
     inputs+'abstract.js',
+    inputs+'list.js',
     inputs+'text.js',
     inputs+'textarea.js',
-    inputs+'select.js'  
+    inputs+'select.js',  
+    inputs+'checklist.js'  
     ],
 
     css = [