1 /**
  2  * @fileOverview Remote datasource for ComboBox
  3  * @author yiminghe@gmail.com
  4  */
  5 KISSY.add("combobox/RemoteDataSource", function (S, IO, Component) {
  6 
  7     /**
  8      * @name RemoteDataSource
  9      * @class
 10      * dataSource which wrap {@link IO} utility.
 11      * xclass: 'combobox-RemoteDataSource'.
 12      * @extends Base
 13      * @memberOf ComboBox
 14      */
 15     function RemoteDataSource() {
 16         var self = this;
 17         RemoteDataSource.superclass.constructor.apply(self, arguments);
 18         self.io = null;
 19         self.caches = {};
 20     }
 21 
 22     RemoteDataSource.ATTRS =
 23     /**
 24      * @lends ComboBox.RemoteDataSource#
 25      */
 26     {
 27         /**
 28          * Used as parameter name to send combobox input's value to server
 29          * @type String
 30          */
 31         paramName:{
 32             value:'q'
 33         },
 34         /**
 35          * whether send empty to server when input val is empty.default:false
 36          * @type Boolean
 37          */
 38         allowEmpty:{},
 39         /**
 40          * Whether server response data is cached.default:false
 41          * @type Boolean
 42          */
 43         cache:{},
 44         /**
 45          * Serve as a parse function to parse server
 46          * response to return a valid array of data for comboBox.
 47          * @type Function
 48          */
 49         parse:{},
 50         /**
 51          * IO configuration.same as {@link} IO
 52          * @type Object
 53          */
 54         xhrCfg:{
 55             value:{}
 56         }
 57     };
 58 
 59     S.extend(RemoteDataSource, S.Base,
 60         /**
 61          * @lends ComboBox.RemoteDataSource#
 62          */{
 63             /**
 64              * Data source interface. How to get data for comboBox
 65              * @function
 66              * @name ComboBox.RemoteDataSource#fetchData
 67              * @param {String} inputVal current active input's value
 68              * @param {Function} callback callback to notify comboBox when data is ready
 69              * @param {Object} context callback 's execution context
 70              */
 71             fetchData:function (inputVal, callback, context) {
 72                 var self = this,
 73                     v,
 74                     paramName = self.get("paramName"),
 75                     parse = self.get("parse"),
 76                     cache = self.get("cache"),
 77                     allowEmpty = self.get("allowEmpty");
 78                 if (self.io) {
 79                     // abort previous request
 80                     self.io.abort();
 81                     self.io = null;
 82                 }
 83                 if (!inputVal && allowEmpty !== true) {
 84                     return callback.call(context, []);
 85                 }
 86                 if (cache) {
 87                     if (v = self.caches[inputVal]) {
 88                         return callback.call(context, v);
 89                     }
 90                 }
 91                 var xhrCfg = self.get("xhrCfg");
 92                 xhrCfg.data = xhrCfg.data || {};
 93                 xhrCfg.data[paramName] = inputVal;
 94                 xhrCfg.success = function (data) {
 95                     if (parse) {
 96                         data = parse(inputVal, data);
 97                     }
 98                     self.__set("data", data);
 99                     if (cache) {
100                         self.caches[inputVal] = data;
101                     }
102                     callback.call(context, data);
103                 };
104                 self.io = IO(xhrCfg);
105             }
106         });
107 
108     Component.Manager.setConstructorByXClass("combobox-RemoteDataSource", RemoteDataSource);
109 
110     return RemoteDataSource;
111 }, {
112     requires:['ajax', 'component']
113 });