           matched = if match[2] then match[2] else match[1]
         matched
 
-      filter: (key) ->
-        data = this.data_source()
+      filter: (query, data, search_query) ->
         if $.isArray(data) and data.length != 0
           items = $.map data, (item,i) =>
             try
-              name = if $.isPlainObject item then item[this.data_value()] else item
-              regexp = new RegExp(key.text.replace("+","\\+"),'i')
+              name = if $.isPlainObject item then item[search_query] else item
+              regexp = new RegExp(query.replace("+","\\+"),'i')
               match = name.match(regexp)
             catch e
               return null
             return if match then item else null
         items
 
-      tpl_eval = (tpl, map) ->
+      remote_filter: (params, url, render_view) ->
+        $.ajax url, params, (data) ->
+          names = $.parseJSON(data)
+          render_view(names)
+
+      tpl_eval: (tpl, map) ->
         try
           el = tpl.replace /\$\{([^\}]*)\}/g, (tag,key,pos) ->
             map[key]
         catch error
           ""
 
-      highlighter = (li, query) ->
+      highlighter: (li, query) ->
         return li if not query
         li.replace new RegExp(">\\s*(\\w*)(" + query.replace("+","\\+") + ")(\\w*)\\s*<", 'ig'), (str,$1, $2, $3) ->
             '> '+$1+'<strong>' + $2 + '</strong>'+$3+' <'
 
-      sorter = (query, items) ->
-        data_value = this.data_value()
+      sorter: (query, items, search_key) ->
         results = []
 
         for item in items
-            text = item[data_value]
-            continue if text.toLowerCase().indexOf(query) is -1
-            item.order = text.toLowerCase().indexOf query
-            results.push(item)
+          text = item[search_key]
+          continue if text.toLowerCase().indexOf(query) is -1
+          item.order = text.toLowerCase().indexOf query
+          results.push(item)
 
         results.sort (a,b) ->
-            a.order - b.order
+          a.order - b.order
         return results
+
+      data_refactor: (data) ->
+        $.map data, (item, k) ->
+          if not $.isPlainObject item
+            item = {id:k, name:item}
+          return item
 
 
     class At

        $ul.find("li:eq(0)").addClass "cur"


    _objectify = (list) ->
        $.map list, (item,k) ->
            if not $.isPlainObject item
                item = {id:k, name:item}
            return item

    ###
      maybe we can use $._unique.
      But i don't know it will delete li element frequently or not.
      I think we should not change DOM element frequently.
      more, It seems batter not to call evalTpl function too much times.
    ###
    _unique = (list,query) ->
        record = []
        $.map list, (v, id) ->
            value = if $.isPlainObject(v) then v[query] else v
            if $.inArray(value,record) < 0
                record.push value
                return v

    _DEFAULT_TPL = "<li id='${id}' data-value=name'>${name}</li>"

    log = () ->
        #console.log(arguments)

        # Parameter: choose
        ## specify the attribute on customer tpl,
        ## so that we could append different value to the input other than the value we searched in
        data: null
        search_key: "name"
        choose_key: "name"
        callbacks: {}
        cache: yes
        limit: 5
