﻿;
(function($) {
    $.extend({
        "cuiGrid":function(options){
            return new CuiGrid(options);
        }
    });
    $.fn.extend({
       "cuiGrid":function(options){
           var g = new CuiGrid(options);
           return g.show(this);
       }
    });
})(jQuery);


/***
 * -CLASS-
 * @name CuiGrid
 * @package cui.widget
 * @description grid列表类（数据分列显示及相关操作）
 * @pageTag <div></div>
 * @depend CuiGridView,CuiPaging,CuiToolbar,CuiForm,CuiCore
 * @paramType JSON
 * @param columns json <grid头，详细参数请查看setColumns方法参数说明>
 * @param data json <grid数据>
 * @param cellCallback json/function <cell显示回调函数,{'name':function}或者function>
 * @param sortCallback function <排序回调函数，函数传入的参数为(idx,type),idx为列的索引(数据的idx),type为排序方式(desc,asc)>
 * @param checkbox json <选择框设置，详细参数请查看addCheckboxColumn方法参数说明>
 * @param config json <grid设置，详细参数请查看setConfig方法参数说明>
 * @param autoSubmit json <grid自动提交设置，详细参数请查看setAutoSubmit方法参数说明>
 * @author ypu<ypu@cenonet.com>
 * @version 2011-08-03
 * @since 0.1
 */
var CuiGrid = function(options) {
    //表格头
    var _headers_ = [];
    //数据索引
    var _idxs_ = [];
    //数据
    var _data_;
    //数据队列
    var _queue_;
    //选择框
    var _checkbox_;
    //cell回调函数
    var _cellCallbacks_ = [];
    //视图
    var _view_ = new CuiGridView();
    //分页
    var _paging_ = new CuiPaging();
    _paging_.privateSetProxy(this);
    //工具栏
    var _toolbar_;
    //id生成器
    var _idGenerator_ = 1;
    //grid id
//    var _id_;

    var _hasClick_ = false;
    //自动提交工具
    var _autoSubmit_;
    //当前grid对象
    var _self_ = this;
    //grid 上下文
    var _context_ ;
    //设置
    var _setting_ = [];

    //todo 智能数据加载

    /**
     * -METHOD-
     * @summary 显示grid
     * @description 该方法用来生成grid并显示
     * @method show
     * @param id string <生成grid的id>
     * @return none
     * @since 0.1
     */
    this.show = function(id) {
//        if (id)_id_ = id;
        if (id) {
            if (typeof id == 'string') {
                _context_ = $("#" + id);
            } else if (id.jquery) {
                _context_ = id
            } else {
                _context_ = $(id);
            }
        }
        _context_.append(_view_.frameHtml);
        if(_setting_.width){
//            $(".cui_sortTable",_context_).css({"width":_setting_.width});
//            $(".cui_gridToolbarTop",_context_).css({"width":_setting_.width});
//            $(".cui_gridToolbarBottom",_context_).css({"width":_setting_.width});
            _context_.css({"width":_setting_.width});
        }

        if (_toolbar_) {
            _toolbar_.setPaging(_paging_);
            _toolbar_.show($( '.cui_gridToolbarTop, .cui_gridToolbarBottom',_context_));
        }
        this.refreshHeader();
        if (_autoSubmit_) {

            var num = _idxs_.length;
            if (_checkbox_)num += 1;
            $(".grid_body", _context_).append(_view_.noContentTip.replace('${colspan}', num));

            var obj = {};
            obj[_autoSubmit_.setting.kPageNo] = 1;
            this.updateAutoParameter(obj)
            this.remitAutoSubmit();
        } else {
            this.refreshData();
        }
        return _self_;
    }
    /**
     * -METHOD-
     * @summary 刷新grid头部信息
     * @description 该方法生成grid头部信息
     * @method refreshHeader
     * @return cuigrid
     * @since 0.1
     */
    this.refreshHeader = function() {
        $(".grid_head",_context_).empty();
        if (_checkbox_) {
            var cell = $(_view_.headCellHtml);
            if (_checkbox_.width) {
                cell.attr('width', _checkbox_.width);
            } else {
                cell.attr('width', '30');
            }
            if (_checkbox_.height)cell.attr('height', _checkbox_.height);
            $(".grid_head",_context_).append(cell.html($('<input>').addClass('checkAll').attr('name', 'checkAll').attr('type', 'checkbox')/*.bind('click', {id:_id_}, function(fn) {
                var flag = this.checked
                $('#' + fn.data.id + ' tbody input:enabled[type=checkbox]').each(function() {
                    this.checked = flag;
                    if(flag){
                        $(this).parents(_view_.rowTag).addClass(_view_.rowSelected);
                    }else{
                        $(this).parents(_view_.rowTag).removeClass(_view_.rowSelected);
                    }
                })
            })*/));

        }

        for (var i = 0; i < _idxs_.length; i++) {
            var id = _idxs_[i];
            if (_headers_[id]) {
                var cell = $(_view_.headCellHtml);
                if (_headers_[id].sortable) {
                    cell.addClass('headerSort');
                    cell.attr('sortIdx', id);
                    cell.click(function() {
                        _self_.privateClickSort($(this));
                    })
                }
                this.privateSetStyle(cell, _headers_[id]);

                $(".grid_head",_context_).append(cell.text(_headers_[id].name));
            }
        }

        return _self_;
    }
    /**
     * -METHOD-
     * @summary 刷新grid数据内容
     * @description 该方法用来刷新grid的内容数据
     * @method refreshData
     * @return cuigrid
     * @since 0.1
     */
    this.refreshData = function() {
        $(".grid_body",_context_).empty();
        if (_queue_ && _queue_.length > 0) {
            for (var i in _queue_) {
                if (_data_[_queue_[i]])this.privateAddRow(_data_[_queue_[i]],$(".grid_body",_context_));
            }
        } else {
            var num = _idxs_.length;
            if (_checkbox_)num += 1;
            $(".grid_body",_context_).append(_view_.noContentTip.replace('${colspan}', num));
            if (_setting_['noContentTip']) {
                $(".cui_noneShowTip",_context_).html(_setting_['noContentTip']);
            } else {
                $(" .cui_noneShowTip",_context_).html(CuiRes.NO_CONTENT_TIP);
            }
        }

        var op = {};
        if(typeof _setting_["tableColor"] != 'undefined'){
            op.color = _setting_["tableColor"];
        }
        if(typeof _setting_["rowSelect"] != 'undefined'){
            op.rowSelect = _setting_["rowSelect"];
        }
        $(".cui_sortTable",_context_).tableColor(op);
        return _self_;
    }
    /**
     * -METHOD-
     * @summary grid添加checkbox列
     * @description 如果需要checkbox列，可使用该方法生成
     * @method addCheckboxColumn
     * @param column json <列的json对象>
     * @param name string <checkbox的name> column
     * @param idx string <data中key为idx对应的值，作为该checkbox的值> column
     * @param title string <列的title,可选> column
     * @param css string <列的class，可选> column
     * @param style string <列的style样式，可选> column
     * @param width int <列的宽度，可选，默认为30px> column
     * @param func function <数据显示时checkbox显示的回调函数，标识该行checkbox是否被选中，返回true为选中，返回false则未选中，方法参数为(checkbox,obj),checkbox为该行checkbox的jquery对象，obj为该行数据> cloumn
     * @return cuigrid
     * @since 0.1
     */
    this.addCheckboxColumn = function (column,func) {
        _checkbox_ = {};
        if (column.name) {
            _checkbox_.name = column.name;
        } else {
            _checkbox_.name = '';
        }
        if (column.idx) {
            _checkbox_.idx = column.idx;
        } else {
            _checkbox_.idx = '';
        }
        _checkbox_.title = column.title;
        _checkbox_.css = column.css;
        _checkbox_.width = column.width;
        if(typeof column.func =='function'){
            _checkbox_.callback = column.func;
        }
        else if(typeof func =='function'){
            _checkbox_.callback = func;
        }
        return _self_;
    }
    /**
     * -METHOD-
     * @summary 设置checkbox全选或全不选
     * @description 如果有checkbox列，用来控制该列所有checkbox的状态
     * @method selectAllCheckbox
     * @param flag boolean <值true:全选，false:全不选>
     * @param func function <选择器函数，选择指定内容的checkbox，没有则范围为全部，函数参数为(obj,checkbox)，obj为该行数据，checkbox为该checkbox对象，返回true则该列生效>
     * @return cuigrid
     * @since 0.1
     */
    this.setAllCheckbox = function(flag,func) {
        if(func && typeof func =='function'){
            $('.grid_body input[type=checkbox]', _context_).each(function() {
                if(func.apply(_self_,[_self_.getData(this.value),this]))this.checked = flag;
            })
        }else{
            $('input[type=checkbox]', _context_).each(function() {
                this.checked = flag;
            })
        }
        return _self_;
    }
     /**
     * -METHOD-
     * @summary 自动切换checkbox全选或不选
     * @description 如果有checkbox列，用来控制该列所有checkbox的状态
     * @method toggleAllCheckbox
     * @param func function <选择器函数。选择指定内容的checkbox，没有则范围为全部。函数参数为(obj,checkbox)，obj为该行数据，checkbox为该checkbox对象，返回true则该列生效>
     * @return cuigrid
     * @since 0.1
     */
    this.toggleAllCheckbox = function(func) {
        if(func && typeof func =='function'){
            $('.grid_body input[type=checkbox]', _context_).each(function() {
                if(func.apply(_self_,[_self_.getData(this.value),this]))this.checked = !this.checked;
            })
        }else{
            $('input[type=checkbox]', _context_).each(function() {
                this.checked = !this.checked;
            })
        }
        return _self_;
    }
                         /**
     * -METHOD-
     * @summary grid添加列
     * @description 该方法生成grid的列
     * @method setColumns
     * @paramType array
     * @param columns  array <头部对象数组>
     * @param idx string <data中在该列显示的key> columns
     * @param name string <列头部的名称> columns
     * @param title string <头部的title> columns
     * @param css string <列的class样式> columns
     * @param style string <列的style样式> columns
     * @param width int <列的宽度> columns
     * @param height int <列的高度> columns
     * @param maxlength int <该列内容显示的最大长度> columns
     * @param align string <该列内容显示的对齐方式，默认为center> columns
     * @param sortable boolean <该列是否支持排序> columns
     * @return cuigrid
     * @since 0.1
     */
    this.setColumns = function(hInfos) {
        for (var i = 0; i < hInfos.length; i++) {
            var o = {};
            var hInfo = hInfos[i];
            if (hInfo.name) {
                o.name = hInfo.name;
            } else {
                o.name = '';
            }
            o.title = hInfo.title;
            o.css = hInfo.css;
            o.idx = hInfo.idx;
            o.width = hInfo.width;
            o.height = hInfo.height;
            o.sortable = hInfo.sortable;
            o.maxlength = hInfo.maxlength;
            o.align = hInfo.align;
            _headers_[o.idx] = o;
            _idxs_.push(o.idx);
        }
        return _self_;
    }

    /*该方法即将废弃，由setColumns替代*/

    this.setHeaders = function(hInfos) {
        for (var i = 0; i < hInfos.length; i++) {
            var o = {};
            var hInfo = hInfos[i];
            if (hInfo.name) {
                o.name = hInfo.name;
            } else {
                o.name = '';
            }
            o.title = hInfo.title;
            o.css = hInfo.css;
            o.idx = hInfo.idx;
            o.width = hInfo.width;
            o.height = hInfo.height;
            o.sortable = hInfo.sortable;
            o.maxlength = hInfo.maxlength;
            o.align = hInfo.align;
            _headers_[o.idx] = o;
            _idxs_.push(o.idx);
        }
        return _self_;
    }
//    /**
//     * -METHOD-
//     * @summary grid添加头部列
//     * @description 该方法生成一grid列
//     * @method addHeader
//     * @param hInfo json <列json对象>
//     * @param idx string <data中在该列显示的key> hInfo
//     * @param name string <头部的名称> hInfo
//     * @param title string <头部的title> hInfo
//     * @param css string <头部的class样式> hInfo
//     * @param style string <头部的style样式> hInfo
//     * @param width int <头部的宽度> hInfo
//     * @param height int <头部的高度> hInfo
//     * @param maxlength int <该列内容显示的最大长度> hInfo
//     * @param align string <该列内容显示的对齐方式，默认为center> hInfo
//     * @param sortable boolean <该列是否支持排序> hInfo
//     * @return cuigrid
//     * @since 0.1
//     */
//    this.addHeader = function(hInfo) {
//        var o = {};
//        if (hInfo.name) {
//            o.name = hInfo.name;
//        } else {
//            o.name = '';
//        }
//        o.title = hInfo.title;
//        o.css = hInfo.css;
//        o.idx = hInfo.idx;
//        o.width = hInfo.width;
//        o.height = hInfo.height;
//        o.sortable = hInfo.sortable;
//        o.maxlength = hInfo.maxlength;
//        o.align = hInfo.align;
//        _headers_[o.idx] = o;
//        _idxs_.push(o.idx);
//        return this;
//    }
    /**
     * -METHOD-
     * @summary 设置grid数据
     * @description 该方法设置grid的数据，通过refreshData展示
     * @method setData
     * @paramType array
     * @param datas json <对象json格式>
     * @return cuigrid
     * @since 0.1
     */
    this.setData = function(datas) {
        _data_ = [];
        _queue_ = [];
        if (typeof datas != 'undefined') {
            for (var i = 0; i < datas.length; i++) {
                if(!_setting_.autoId && _checkbox_ && _checkbox_.idx){
                    datas[i]._id_ = datas[i][_checkbox_.idx];
                    _data_[datas[i]._id_] = datas[i];
                    _queue_.push(datas[i]._id_);
                }else{
                    datas[i]._id_ = _idGenerator_;
                    _data_[_idGenerator_] = datas[i];
                    _queue_.push(datas[i]._id_);
                    _idGenerator_++;
                }
            }
        }
        return _self_;
    }


    /**
     * -METHOD-
     * @summary 获取data数据
     * @description  获取data数据
     * @method getData
     * @param id string/number <数据的_id_(数据对应grid的_id_)>
     * @return json
     * @since 0.1
     */
    this.getData = function(id) {
        return _data_[id];
    }

//    /**
//     * -METHOD-
//     * @summary grid添加行
//     * @description 该方法会在grid的最后动态生成多行内容
//     * @method addRows
//     * @paramType array
//     * @param obj json <对象json格式>
//     * @return cuigrid
//     * @since 0.1
//     */
//    this.addRows = function(objs) {
//        for (var i in objs) {
//            this.addRow(objs[i]);
//        }
//        return this;
//    }
    /**
     * -METHOD-
     * @summary grid添加行
     * @description 该方法会在grid的最后动态生成一行内容
     * @method addRow
     * @param obj json <对象json格式>
     * @param appand boolean <true为在grid尾部插入行，false在头部插入行，默认为false>
     * @return cuigrid
     * @since 0.1
     */
    this.addRow = function(obj,append) {
//        obj._id_ = _idGenerator_;
//        _data_[_idGenerator_] = obj;
//        _idGenerator_++;

        if (!_setting_.autoId && _checkbox_ && _checkbox_.idx) {
            obj._id_ = obj[_checkbox_.idx];
            _data_[obj._id_] = obj;
        } else {
            obj._id_ = _idGenerator_;
            _data_[_idGenerator_] = obj;
            _idGenerator_++;
        }

        if(append){
           _queue_.push(obj._id_);
        }else{
           _queue_.unshift(obj._id_);
        }

        this.privateAddRow(obj,$(".grid_body",_context_),!append);
        return _self_;
    }

    this.privateClickSort = function(src) {
        if (_hasClick_)return;
        _hasClick_ = true;
        var idx = src.attr('sortIdx');
        var type = 'desc';
        var css = 'headerSortDown';
        if (src.hasClass('headerSort')) {
            type = 'desc';
            css = 'headerSortDown';
        } else if (src.hasClass('headerSortUp')) {
            type = 'desc';
            css = 'headerSortDown';
        } else if (src.hasClass('headerSortDown')) {
            type = 'asc';
            css = 'headerSortUp';
        }

        if (_setting_['sortCallback']) {
            if (_setting_['sortCallback'].apply(_self_, [idx, type])) {
                $('.headerSortUp',_context_).removeClass('headerSortUp').addClass('headerSort');
                $('.headerSortDown',_context_).removeClass('headerSortDown').addClass('headerSort');
                $('.headerSortSelect',_context_).removeClass('headerSortSelect');
                src.removeClass('headerSort').addClass(css).addClass('headerSortSelect');
            }
        } else if (_autoSubmit_) {
            var setting = _autoSubmit_.setting;
            var params = new Object();
            params[setting.kSortName] = idx;
            params[setting.kSortType] = type;
            this.remitAutoSubmit(params, function(o, flag) {
                if (!flag)return;
                $('.headerSortUp',_context_).removeClass('headerSortUp').addClass('headerSort');
                $('.headerSortDown',_context_).removeClass('headerSortDown').addClass('headerSort');
                $('.headerSortSelect',_context_).removeClass('headerSortSelect');
                src.removeClass('headerSort').addClass(css).addClass('headerSortSelect');
            });
        }
        _hasClick_ = false;
    }

    this.privateAddRow = function(obj,body,prepand) {

        if(_setting_['rowCallback']){
            if(!_setting_['rowCallback'].apply(_self_,[obj,body])){
                return;
            }
        }
        var row = $(_view_.rowHtml).attr('rowid', obj._id_);
        if (_setting_['rowStyleCallback'])this.privateSetStyle(row, _setting_['rowStyleCallback'].apply(_self_,[obj]));

        var cell = _view_.rowCellHtml;

        if (_checkbox_) {
            var checkbox = $('<input>').attr('name', _checkbox_.name).attr('type', 'checkbox').attr('checkid', obj._id_).val(obj[_checkbox_.idx]);
            if(_checkbox_.callback){
                checkbox.attr('checked',_checkbox_.callback.apply(_self_,[obj,checkbox]));
            }
            row.append($(cell).html(checkbox));
        }

        for (var j = 0; j < _idxs_.length; j++) {
            var c = $(cell);
            var id = _idxs_[j];
            if (_headers_[id].align)c.css("text-align", _headers_[id].align);
            if (_setting_['cellStyleCallback'])this.privateSetStyle(c, _setting_['cellStyleCallback'](id, obj));
            if (_cellCallbacks_[id]) {
                row.append(c.html(_cellCallbacks_[id].apply(_self_, [id,obj,c])));
            } else if (typeof obj[id] != 'undefined' && obj[id] != null) {
                if (_headers_[id] && _headers_[id].maxlength) {
                    var maxlength = _headers_[id].maxlength;
                    var value = obj[id];
                    c.attr('title', value);
                    if (typeof value == "string" && value.length > maxlength) {
                        value = $.cuiShortStr(value,maxlength);
                    }
                    row.append(c.text(value));
                } else {
                    row.append(c.text(obj[id]));
                }
            } else {
                row.append(c.text(""));
            }
        }
        if(prepand){
            body.prepend(row);
        }else{
            body.append(row);
        }
    }

    this.privateSetStyle = function(obj, styles) {
        if (!styles)return;
        if (styles.width)obj.attr('width', styles.width);
        if (styles.height)obj.attr('height', styles.height);
        if (styles.title)obj.attr('title', styles.title);
        if (styles.style)obj.css(styles.style);
        if (styles.css)obj.addClass(styles.css);
        if (styles.click)obj.click(styles.click);
    }
    /**
     * -METHOD-
     * @summary grid删除行
     * @description 该方法动态删除grid一行
     * @method removeRow
     * @param id string <删除行的id>
     * @return cuigrid
     * @since 0.1
     */
    this.removeRow = function(id) {
        $(_view_.rowTag + '[rowid=' + id + ']',_context_).remove();
        var t = [];
        for(var i in _queue_){
            if(_queue_[i] != id){
                t.push(_queue_[i]);
            }
        }
        _queue_ = t;
        _data_[id] = undefined;
        return _self_;
    }
    /**
     * -METHOD-
     * @summary grid删除选中行
     * @description 如果grid有checkbox列，该方法动态删除checkbox选中的行
     * @method removeSelectedRows
     * @return cuigrid
     * @since 0.1
     */
    this.removeSelectedRows = function() {
        var d = []
        $(':checkbox:enabled:checked',_context_).each(function() {
            var id = $(this).attr("checkid");
            if (id) {
                //self.removeRow(id);
                $(this).parents(_view_.rowTag).remove();
                d[id] = id;
                _data_[id] = undefined;
            }
        }) ;
        var t = []
        for(var i in _queue_){
            if(typeof d[_queue_[i]] == 'undefined'){
                t.push(_queue_[i]);
            }
        }
        return _self_;
    }

    /**
     * -METHOD-
     * @summary 获取选中状态的值
     * @description 如果grid有checkbox列，该方法获取所有选中状态的checkbox的值数组
     * @method getSelectedValues
     * @return array
     * @since 0.1
     */
    this.getSelectedValues = function() {
        var rt = [];
        $('.grid_body :checkbox:enabled:checked',_context_).each(function() {
            var value = $(this).val();
            if (value) {
                rt.push(value);
            }
        })
        return rt;
    }
    /**
     * -METHOD-
     * @summary 获取选中状态的data对象
     * @description 如果grid有checkbox列，该方法获取所有checkbox选中状态的data对象的数组
     * @method getSelectedDatas
     * @return array
     * @since 0.1
     */
    this.getSelectedDatas = function() {
        var rt = [];
        $('.grid_body :checkbox:enabled:checked',_context_).each(function() {
            var id = $(this).attr("checkid");
            if (id) {
                var obj = this.getData(id);
                if (obj)rt.push(rt);
            }
        })
        return rt;
    }
    /**
     * -METHOD-
     * @summary 更新grid行
     * @description 更新grid中的一行，
     * @method updateRow
     * @param id string <更新行的id>
     * @param obj json <更新的内容对象>
     * @return cuigrid
     * @since 0.1
     */
    this.updateRow = function(id, obj) {
        if (_data_[id]) {
            obj._id_ = id;
            _data_[id] = obj;
            var row = $(_view_.rowTag + '[rowid=' + id + ']',_context_);
            row.empty();
            var cell = _view_.rowCellHtml;
            if (_checkbox_) {
                var checkbox =$('<input>').attr('name', _checkbox_.name).attr('type', 'checkbox').attr('checkid', obj[_checkbox_.idx]).val(obj[_checkbox_.idx]);;
                if (_checkbox_.callback) {
                    checkbox.attr('checked', _checkbox_.callback.apply(_self_, [obj,checkbox]));
                }
                row.append($(cell).html(checkbox));
            }
            for (var j = 0; j < _idxs_.length; j++) {
                var c = $(cell);
                var id = _idxs_[j];
                if (_headers_[id].align)c.css("text-align", _headers_[id].align);
                if (_setting_['cellStyleCallback'])this.privateSetStyle(c, _setting_['cellStyleCallback'](id, obj));
                if (_cellCallbacks_[id]) {
                    row.append(c.html(_cellCallbacks_[id].apply(_self_, [id,obj,c])));
                } else if (typeof obj[id] != 'undefined' && obj[id] !=null) {
                    if (_headers_[id].maxlength) {
                        var maxlength = _headers_[id].maxlength;
                        var value = obj[id];
                        c.attr('title', value);
                        if (typeof value =="string" && value.length > maxlength) {
                            value = value.substr(0, maxlength) + "...";
                        }
                        row.append(c.text(value));
                    } else {
                        row.append(c.text(obj[id]));
                    }
                } else {
                    row.append(c.text(""));
                }
            }
        }
        return _self_;
    }

    /**
     * -METHOD-
     * @summary 设置cell回调方法
     * @description 设置cell回调方法，设置后该列会根据回调返回内容来显示内容
     * @method setCellCallback
     * @param idx string <列的idx，对应该列header的idx>
     * @param func function <cell回调函数，返回的内容将会显示在该cell中，可包含html代码>
     * @param idx string <该列的数据索引，该列header的idx> func
     * @param obj json <该行的数据(json)> func
     * @param cell object <grid cell的jquery对象，可通过cell插入数据或修改样式> func
     * @return cuigrid
     * @since 0.1
     */
    this.setCellCallback = function(idx, func) {
        if (typeof idx == 'object') {
            for (var i in idx) {
                if (typeof idx[i] == 'function') {
                    _cellCallbacks_[i] = idx[i];
                }
            }
        }
        else if (typeof func == "function") {
            _cellCallbacks_[idx] = func;
        }
        return _self_;
    }
    /**
     * -METHOD-
     * @summary 设置cell排序的回调方法
     * @description 设置cell排序的回调方法，设置后排序事件会调用该方法
     * @method setSortCallback
     * @param func function <回调函数，回调函数需要返回boolean来通知grid排序是否成功，函数的参数为idx,type>
     * @param idx string <排序该列的idx> func
     * @param type string <排序的类型，返回desc或asc> func
     * @return cuigrid
     * @since 0.1
     */
    this.setSortCallback = function(func) {
        if (typeof func == "function") {
            _setting_['sortCallback'] = func;
        }
        return _self_;
    }

//    this.loadData = function(setting, params, func) {
//        if (typeof setting == 'string') {
//            var url = setting;
//            setting = {};
//            setting.url = url;
//        }
//        var self = this;
//        if (!setting.dataType)setting.dataType = 'json';
//        if (!setting.type)setting.type = 'post';
//        $.cuiAjax(setting, params, function(o, flag) {
//            if (!flag)return;
//            self.setData(o);
//            self.refreshData();
//            if (func && typeof func == 'function') {
//                func(o, flag);
//            }
//        });
//    }

    /**
     * -METHOD-
     * @summary 设置grid自动提交分页及排序事件
     * @description  设置grid自动提交分页及排序事件，相关事件grid会自动提交并显示返回数据
     * @method setAutoSubmit
     * @param url string/json <表单设置,仅为url时可直接用string>
     * @param url string <表单url> url
     * @param dataType string <数据类型，可选，默认json> url
     * @param type string <提交类型，可选，默认post> url
     * @param params json <提交参数，可选>
     * @param setting json <自动提交设置，可选>
     * @param kData string <返回数据中，grid显示data的key值,可选，默认为data> setting
     * @param kParam string <返回数据中，参数的key值，可选，默认为params> setting
     * @param kSortName string <提交数据中，排序列的key值，可选，默认为sortName> setting
     * @param kSortType string <提交数据中，排序类型的key值，可选，默认为sortType> setting
     * @param kPageNo string <提交数据中，分页页数的key值，可选，默认为pageNo> setting
     * @param dataAdapter function <用以处理返回数据的适配器，参数(o)，可选> setting
     * @param callback function <每次数据更新后回调函数，参数(data,param)，可选> setting
     * @return cuigrid
     * @since 0.1
     */
    this.setAutoSubmit = function(url, params, set) {
        var form;
        if (typeof url == 'string') {
            form = {};
            form.url = url;
        } else {
            form = url;
        }

        _autoSubmit_ = {};
        _autoSubmit_.form = form;

        if (params) {
            _autoSubmit_.data = params;
        } else {
            _autoSubmit_.data = {};
        }

        var setting = {};
        setting.kData = 'data';
        setting.kParams = 'params';
        setting.kSortType = "sortType";
        setting.kSortName = "sortName";
        setting.kPageNo = "pageNo";
        if (set) {
            if (set.kData)setting.kData = set.kData;
            if (set.kParams)setting.kParams = set.kParams;
            if (set.kSortName)setting.kSortName = set.kSortName;
            if (set.kSortType)setting.kSortType = set.kSortType;
            if (set.kPageNo)setting.kPageNo = set.kPageNo;
            if (set.dataAdapter && typeof set.dataAdapter == 'function')setting.dataAdapter = set.dataAdapter;
            if (set.callback && typeof set.callback == 'function')setting.callback = set.callback;
        }
        _autoSubmit_.setting = setting;
        if (_paging_) {
            _paging_.setHandler(function(pageNo) {
                var param = new Object();
                param[setting.kPageNo] = pageNo;
                _self_.remitAutoSubmit(param);
            });
        }
        return _self_;
    }
    /**
     * -METHOD-
     * @summary 提交autoSubmit
     * @description  主动提交autoSubmit，更新grid data。必须设置过setAutoSubmit
     * @method remitAutoSubmit
     * @param params json <更新autoSubmit的提交参数>
     * @param func function <autoSubmit提交后执行函数，参数（o,flag）>
     * @param o object <autoSubmit提交后的返回内容> func
     * @param flag boolean <autoSubmit是否提交成功> func
     * @return none
     * @since 0.1
     */
    this.remitAutoSubmit = function(params, func) {
        if (!_autoSubmit_) {
            if (_setting_.callback)_setting_.callback(o);
            if (func && typeof func == 'function')func(o, false);
            return null;
        }
        _self_.loadingOn();
        _self_.updateAutoParameter(params);
        var form = _autoSubmit_.form;
        var setting = _autoSubmit_.setting;
        $.cuiAjax(form, _autoSubmit_.data, function(o, flag) {
            _self_.loadingOff();
            if (!flag)return;
            if (setting.dataAdapter)o = setting.dataAdapter(o);
            var data = o[setting.kData];
            var params = o[setting.kParams];
            params = _self_.updateAutoParameter(params);
            if (_self_.getCuiPaging())_self_.getCuiPaging().updatePaging(params);
            _self_.setData(data);
            _self_.refreshData();
            if (setting.callback)setting.callback(o);
            if (func && typeof func == 'function')func(o, flag);
        });
        return _self_;
    }
    /**
     * -METHOD-
     * @summary 绑定autoSubmit
     * @description  绑定autoSubmit到指定元素，元素触发event后，autoSubmit自动提交更新。必须设置过setAutoSubmit
     * @method bindAutoSubmit
     * @param obj object <需要绑定元素的jquery对象>
     * @param event string <绑定触发事件，如'click'>
     * @param afterFunc function <autoSubmit提交后的函数，参数为(o,flag)>
     * @param o object <autoSubmit提交返回的内容> afterFunc
     * @param flag boolean <autoSubmit是否提交成功> afterFunc
     * @parma preFunc function <autoSubmit提交前的执行函数，参数为（eventObj,grid）,函数返回false时autoSubmit不提交，函数返回json对象时会更新autoSubmit的提交参数>
     * @param eventObj object <触发事件的jqeruy对象，先前的obj对象> preFunc
     * @param grid object <被绑定的Cuigrid对象> preFunc
     * @return none
     * @since 0.1
     */
    this.bindAutoSubmit = function(obj, event, afterFunc,preFunc) {
        if (!_autoSubmit_)return null;
        if (obj && typeof obj == 'object' && event && typeof event == 'string') {
            obj.bind(event, function() {
                var params = {};
                if (typeof preFunc == 'function') {
                    params = preFunc($(this), _self_);
                    if (typeof params == 'undefined') {
                        params = {};
                    } else if (typeof params == 'boolean') {
                        if (!params)return;
                    } else if (typeof params != 'object') {
                        params = {};
                    }
                }
                _self_.remitAutoSubmit(params, afterFunc);
            });
        }
        return _self_;
    }

    /**
     * -METHOD-
     * @summary 获取autoSubmit的参数
     * @description  获取autoSubmit的参数，使用setAutoSubmit时该方法有效。
     * @method getAutoParameter
     * @return json <autoSubmit当前参数>
     * @since 0.1
     */
    this.getAutoParameter = function() {
        if (_autoSubmit_)return _autoSubmit_.data;
        return {};
    }
    /**
     * -METHOD-
     * @summary 更新autoSubmit的参数
     * @description  更新autoSubmit的参数，使用setAutoSubmit时该方法有效。
     * @method updateAutoParameter
     * @param params json <更新参数>
     * @return json <autoSubmit当前参数>
     * @since 0.1
     */
    this.updateAutoParameter = function(params) {
        if (_autoSubmit_ && params) {
            _autoSubmit_.data = $.extend(_autoSubmit_.data,params);
            return _autoSubmit_.data;
        }
        return {};
    }

    /**
     * -METHOD-
     * @summary 清空autoSubmit的参数
     * @description  清空autoSubmit的所有参数，使用setAutoSubmit时该方法有效。
     * @method clearAutoParameter
     * @return cuigrid
     * @since 0.1
     */
    this.clearAutoParameter = function() {
        if (_autoSubmit_)_autoSubmit_.data = {};
        return _self_;
    }

    /**
     * -METHOD-
     * @summary 设置gridview
     * @description  设置gridview
     * @method setView
     * @param obj CuiGridView <CuiGridView对象>
     * @return cuigrid
     * @since 0.1
     */
    this.setView = function(obj) {
        _view_ = obj;
        return _self_;
    }

    /**
     * -METHOD-
     * @summary 设置toolbar对象
     * @description  设置toolbar对象
     * @method setCuiToolbar
     * @param toolbar CuiToolbar <CuiToolbar对象>
     * @return cuigrid
     * @since 0.1
     */
    this.setCuiToolbar = function(toolbar) {
        _toolbar_ = toolbar;
        _toolbar_.privateSetProxy(_self_);
        return _self_;
    }
    /**
     * -METHOD-
     * @summary 获取toolbar对象
     * @description  获取toolbar对象
     * @method getCuiToolbar
     * @return CuiToolbar
     * @since 0.1
     */
    this.getCuiToolbar = function() {
        if (_toolbar_) {
            return _toolbar_;
        } else {
            _toolbar_ = new CuiToolbar();
            _toolbar_.privateSetProxy(_self_);
            return _toolbar_;
        }
    }
    /**
     * -METHOD-
     * @summary 获取CuiForm对象，可用于提交整个grid中的checkbox。
     * @description  获取CuiForm对象
     * @method getCuiForm
     * @return CuiForm
     * @since 0.1
     */
    this.getCuiForm = function() {
        var form = $('form',_context_);
        if (form.length == 0) {
            _context_.wrapInner('<form method="post"></form>');
            form = $('form',_context_);
        }
        return  new CuiForm(form);
    }
    /**
     * -METHOD-
     * @summary 设置CuiPaging对象
     * @description  设置CuiPaging对象
     * @method setCuiPaging
     * @param paging CuiPaging <CuiPaging对象>
     * @return cuigrid
     * @since 0.1
     */
    this.setCuiPaging = function(paging) {
        _paging_ = paging;
        if (_paging_)_paging_.privateSetProxy(_self_);
        return _self_;
    }
    /**
     * -METHOD-
     * @summary 获取CuiPaging对象
     * @description  获取CuiPaging对象
     * @method getCuiPaging
     * @return CuiPaging
     * @since 0.1
     */
    this.getCuiPaging = function() {
        if (_paging_) {
            return _paging_;
        } else {
            _paging_ = new CuiPaging();
            _paging_.privateSetProxy(_self_);
            return _paging_;
        }
    }
    /**
     * -METHOD-
     * @summary 设置row style回调方法
     * @description  设置row style回调方法，根据回调返回内容显示row样式
     * @method setRowStyleCallback
     * @param func function <回调方法,回调参数func(obj)>
     * @param obj object <obj为该行对象，对象中有_id_属性(操作grid行的id)> func
     * @return cuigrid
     * @since 0.1
     */
    this.setRowStyleCallback = function(func) {
        if (typeof func == 'function')_setting_['rowStyleCallback'] = func;
        return _self_;
    }
    /**
     * -METHOD-
     * @summary 设置cell style回调方法
     * @description  设置cell style回调方法，根据回调返回内容显示cell样式
     * @method setCellStyleCallback
     * @param func function <回调方法,回调参数func(idx,obj)>
     * @param idx string <idx为列的idx属性> func
     * @param obj object <obj为该行对象对象中有_id_属性(操作grid行的id)> func
     * @return cuigrid
     * @since 0.1
     */
    this.setCellStyleCallback = function(func) {
        if (typeof func == 'function')_setting_['cellStyleCallback'] = func;
        return _self_;
    }

    /**
     * -METHOD-
     * @summary 设置插入row时的回调方法
     * @description  设置插入row时的回调方法，函数返回true插入该行数据，false则不插入
     * @method setRowCallback
     * @param func function <回调方法,回调参数func(idx,obj)>
     * @param obj object <将要插入的行数据> func
     * @param body object <grid body的jquery对象，可以通过body插入元素与数据> func
     * @return cuigrid
     * @since 0.1
     */
    this.setRowCallback = function(func){
        if (typeof func == 'function')_setting_['rowCallback'] = func;
        return _self_;
    }
     /**
     * -METHOD-
     * @summary 添加grid设置
     * @description  添加grid设置
     * @method setConfig
     * @param config json <配置项>
     * @param width int <表格宽度，默认为自动> config
     * @param tableColor boolean <表格是否隔行变色，默认为true> config
     * @param rowSelect boolean <表格是否选中行也同时选中该行checkbox，默认为false> config
     * @param autoId boolean <是否让grid自动生成数据id，默认为false。数据如果没有设置checkbox中的idx，则会自动打开该功能，如果数据没有主键id，也可以打开该功能> config
     * @param noContentTip string <没有数据时显示内容> config
     * @param cellStyleCallback func <cell style的回调函数，参数为(idx,o)> config
     * @param rowStyleCallback func <row style的回调函数，参数为(o)> config
     * @param rowCallback func <插入一行前的回调函数，参数为(o，tbody)，需要返回boolean，标识是否插入这条数据> config
     * @return cuigrid
     * @since 0.1
     */
    this.setConfig = function(config){
        _setting_ = $.extend(_setting_,config);
        return _self_;
    }
    /**
     * -METHOD-
     * @summary 没有数据时grid显示的内容
     * @description  没有数据时grid body部分显示的内容
     * @method setNoContentTip
     * @param content string <显示内容，可包含html代码>
     * @return cuigrid
     * @since 0.1
     */
    this.setNoContentTip = function(content) {
        _setting_['noContentTip'] = content;
        return _self_;
    }
     /**
     * -METHOD-
     * @summary 打开在grid中显示加载数据的样式
     * @description  在grid中显示加载数据的样式，通常在自己加载grid数据时使用，使用autoSubmit则会自动开启与关闭
     * @method loadingOn
     * @return cuigrid
     * @since 0.1
     */
    this.loadingOn = function(){
        var table =  $('.cui_sortTable',_context_);
        var offset = table.offset();
        $('.cui_gridLoading',_context_).css({"left":table.width()/2-80 ,"top":table.height()/2-5});
        $('.cui_gridLoading',_context_).fadeIn("fast");
        return _self_;
    }
     /**
     * -METHOD-
     * @summary 关闭grid中显示加载数据的样式
     * @description  关闭grid中显示加载数据的样式，数据加载完后可掉用该方法关闭加载数据的样式
     * @method loadingOff
     * @return cuigrid
     * @since 0.1
     */
    this.loadingOff = function(){
        $('.cui_gridLoading',_context_).fadeOut("fast");
        return _self_;
    }

    if (options) {
        if(typeof options == 'string'){
//            _id_ = p;
            _context_ = $("#" + options);
        }else {
            if (options.columns) {
                this.setHeaders(options.columns);
            }
            if (options.checkbox) {
                this.addCheckboxColumn(options.checkbox);
            }
            if (options.cellCallback) {
                this.setCellCallback(options.cellCallback);
            }
            if (options.sortCallback) {
                this.setSortCallback(options.sortCallback);
            }
            if (options.config) {
                this.setConfig(options.config);
            }
            if (options.data) {
                this.setData(options.data);
            }
            if(options.autoSubmit){
                this.setAutoSubmit(options.autoSubmit.url,options.autoSubmit.params,options.autoSubmit.setting);
            }
        }
    }

}
///EndClass
/***
 * -CLASS-
 * @name CuiGridView
 * @package cui.widget
 * @description grid列表的显示类（grid显示的相关html框架）
 * @pageTag <div></div>
 * @author ypu
 * @version 2011-08-03
 * @since 0.1
 */
var CuiGridView = function() {
    /**
     * -PROPERTY-
     * @summary grid框架html
     * @description grid框架html，必须包含cui_toolbar,grid_head,grid_body样式
     * @param frameHtml string
     * @since 0.1
     */
    this.frameHtml =
            '<div class="cui_gridToolbarTop"></div>' +
            '<div class="cui_Scroll">' + '<div class="cui_gridLoading" style="display:none" >' + CuiRes.LOADING + '</div>'+
            '<table class="cui_sortTable">' +
            '<thead><tr class="grid_head"></tr></thead>' +
            '<tbody class="grid_body"></tbody>' +
            '</table>' +
            '</div><div class="cui_gridToolbarBottom"></div>';
    /**
     * -PROPERTY-
     * @summary grid头部cell html
     * @description grid头部cell html，根据该html生成头部cell
     * @param headCellHtml string
     * @since 0.1
     */
    this.headCellHtml = '<th></th>';

    /**
     * -PROPERTY-
     * @summary grid数据行html
     * @description grid数据行html，根据该html生成数据行
     * @param rowHtml string
     * @since 0.1
     */
    this.rowHtml = '<tr></tr>';
    /**
     * -PROPERTY-
     * @summary grid行标记
     * @description grid行标记,根据此标记来统计行数。
     * @param rowTag string
     * @since 0.1
     */
    this.rowTag = 'tr';
    /**
     * -PROPERTY-
     * @summary grid数据行cell html
     * @description grid数据行cell html，根据此html生成数据行cell
     * @param rowCellHtml string
     * @since 0.1
     */
    this.rowCellHtml = '<td></td>';
    /**
     * -PROPERTY-
     * @summary grid无数据时的内容
     * @description grid无数据时的内容html
     * @param noContentTip string
     * @since 0.1
     */
    this.noContentTip = '<tr><td colspan="${colspan}"><div class="cui_noneShowTip"></div></td></tr>';

//    this.rowSelected = 'Rowsselected';
}
///EndClass
