bootgrid修改成可以全勾选和全取消勾选操作

1. 引言

由于项目需要,需要在不同页面上选择全勾选能全部勾选所有的记录,反勾选也如此。这个需求可以解决了一个样例:如果有150条记录,当前页就10条,你又在每一个页面勾选部分的记录,然后,如果你要全部全选,需要在每一个页面上勾上全选checkbox,全部反选也有这个问题。

2.修改的代码

基于jQuery Bootgrid v1.3.1这个版本。

bootgrid.js修改的部分如下:

//原有的select和deselect方法
 /**
     * Selects rows by ids. Selects all visible rows if no ids are provided.
     * In server-side scenarios only visible rows are selectable.
     *
     * @method select
     * @param [rowsIds] {Array} An array of rows ids to select
     * @chainable
     **/
    Grid.prototype.select = function(rowIds)
    {
        if (this.selection)
        {
            rowIds = rowIds || this.currentRows.propValues(this.identifier);

            var id, i,
                selectedRows = [];

            while (rowIds.length > 0 && !(!this.options.multiSelect && selectedRows.length === 1))
            {
                id = rowIds.pop();
                if ($.inArray(id, this.selectedRows) === -1)
                {
                    for (i = 0; i < this.currentRows.length; i++)
                    {
                        if (this.currentRows[i][this.identifier] === id)
                        {
                            selectedRows.push(this.currentRows[i]);
                            this.selectedRows.push(id);
                            break;
                        }
                    }
                }
            }

            if (selectedRows.length > 0)
            {
                var selectBoxSelector = getCssSelector(this.options.css.selectBox),
                    selectMultiSelectBox = this.selectedRows.length >= this.currentRows.length;

                i = 0;
                while (!this.options.keepSelection && selectMultiSelectBox && i < this.currentRows.length)
                {
                    selectMultiSelectBox = ($.inArray(this.currentRows[i++][this.identifier], this.selectedRows) !== -1);
                }
                this.element.find("thead " + selectBoxSelector).prop("checked", selectMultiSelectBox);

                if (!this.options.multiSelect)
                {
                	//this.element.find("tbody > tr " + selectBoxSelector + ":checked")
                    //    .trigger("click" + namespace);
                    var lastId = this.selectedRows[this.selectedRows.length-1];
                    var checkboxes = this.element.find("tbody > tr " + selectBoxSelector + ":checked");
                    for (i = 0; i < checkboxes.length; i++) {
                        var $checkbox = $(checkboxes[i]);
                        if (lastId != $checkbox.val()) {
                            $checkbox.trigger("click" + namespace);
                        }
                    }
                }

                for (i = 0; i < this.selectedRows.length; i++)
                {
                    this.element.find("tbody > tr[data-row-id="" + this.selectedRows[i] + ""]")
                        .addClass(this.options.css.selected)._bgAria("selected", "true")
                        .find(selectBoxSelector).prop("checked", true);
                }

                this.element.trigger("selected" + namespace, [selectedRows]);
            }
        }

        return this;
    };

    /**
     * Deselects rows by ids. Deselects all visible rows if no ids are provided.
     * In server-side scenarios only visible rows are deselectable.
     *
     * @method deselect
     * @param [rowsIds] {Array} An array of rows ids to deselect
     * @chainable
     **/
    Grid.prototype.deselect = function(rowIds)
    {
        if (this.selection)
        {
            rowIds = rowIds || this.currentRows.propValues(this.identifier);

            var id, i, pos,
                deselectedRows = [];

            while (rowIds.length > 0)
            {
                id = rowIds.pop();
                pos = $.inArray(id, this.selectedRows);
                if (pos !== -1)
                {
                    for (i = 0; i < this.currentRows.length; i++)
                    {
                        if (this.currentRows[i][this.identifier] === id)
                        {
                            deselectedRows.push(this.currentRows[i]);
                            this.selectedRows.splice(pos, 1);
                            break;
                        }
                    }
                }
            }

            if (deselectedRows.length > 0)
            {
                var selectBoxSelector = getCssSelector(this.options.css.selectBox);

                this.element.find("thead " + selectBoxSelector).prop("checked", false);
                for (i = 0; i < deselectedRows.length; i++)
                {
                    this.element.find("tbody > tr[data-row-id="" + deselectedRows[i][this.identifier] + ""]")
                        .removeClass(this.options.css.selected)._bgAria("selected", "false")
                        .find(selectBoxSelector).prop("checked", false);
                }

                this.element.trigger("deselected" + namespace, [deselectedRows]);
            }
        }

        return this;
    };

//修改后的select和deselect方法
 /**
     * Selects rows by ids. Selects all visible rows if no ids are provided.
     * In server-side scenarios only visible rows are selectable.
     *
     * @method select
     * @param [rowsIds] {Array} An array of rows ids to select
     * @chainable
     **/
    Grid.prototype.select = function(rowIds,flag)
    {
    	var selectAllFlag = false;
    	var selectBoxSelector = getCssSelector(this.options.css.selectBox);
    	
        if (this.selection)
        {
        	
            //rowIds = rowIds || this.currentRows.propValues(this.identifier);
            var id, i,
                selectedRows = [];
            
            
        	if(typeof rowIds == 'undefined'){//select All
        		selectAllFlag = true;
        		 this.element.find("thead " + selectBoxSelector).prop("indeterminate", false).prop("checked", true).val('all');
        		 //selectedRows = this.currentRows;
        		 var this_currentRows = this.currentRows;
        		 this.selectedRows = Object.keys(this_currentRows).map(function(i){return this_currentRows[i].Id});
        		 
        	}else if(typeof flag != 'undefined' && flag == 'load'){//load selected rowIds 
            	selectedRows = Object.keys(rowIds).map(function(i){return rowIds[i]});
            	this.selectedRows = Object.keys(rowIds).map(function(i){return rowIds[i]});
            }else{
	            while (rowIds.length > 0 && !(!this.options.multiSelect && selectedRows.length === 1))
	            {
	                id = rowIds.pop();
	                if ($.inArray(id, this.selectedRows) === -1)
	                {
	                    for (i = 0; i < this.currentRows.length; i++)
	                    {
	                        if (this.currentRows[i][this.identifier] === id)
	                        {
	                            selectedRows.push(this.currentRows[i]);
	                            this.selectedRows.push(id);
	                            break;
	                        }
	                    }
	                }
	            }
            }
            
            if (selectedRows.length > 0 || selectAllFlag)
            {
            	//var selectBoxSelector = getCssSelector(this.options.css.selectBox),
                /*  var selectMultiSelectBox = this.selectedRows.length >= this.currentRows.length;

                i = 0;
                while (!this.options.keepSelection && selectMultiSelectBox && i < this.currentRows.length)
                {
                    selectMultiSelectBox = ($.inArray(this.currentRows[i++][this.identifier], this.selectedRows) !== -1);
                }*/
                //this.element.find("thead " + selectBoxSelector).prop("checked", selectMultiSelectBox);
                
                //PR1098 by fanbi
                if(!selectAllFlag){
	                if(this.getTotalRowCount()== this.selectedRows.length){
	                	 this.element.find("thead " + selectBoxSelector).prop("indeterminate", false).prop("checked", true).val("all");
	                }else{
	                	 this.element.find("thead " + selectBoxSelector).prop("indeterminate", true).val("part");
	                }
                }
               

                if (!this.options.multiSelect)
                {
                	//this.element.find("tbody > tr " + selectBoxSelector + ":checked")
                    //    .trigger("click" + namespace);
                    var lastId = this.selectedRows[this.selectedRows.length-1];
                    var checkboxes = this.element.find("tbody > tr " + selectBoxSelector + ":checked");
                    for (i = 0; i < checkboxes.length; i++) {
                        var $checkbox = $(checkboxes[i]);
                        if (lastId != $checkbox.val()) {
                            $checkbox.trigger("click" + namespace);
                        }
                    }
                }

                for (i = 0; i < this.selectedRows.length; i++)
                {
                    this.element.find("tbody > tr[data-row-id="" + this.selectedRows[i] + ""]")
                        .addClass(this.options.css.selected)._bgAria("selected", "true")
                        .find(selectBoxSelector).prop("checked", true);
                }

                this.element.trigger("selected" + namespace, [selectedRows]);
            }
        }

        return this;
    };

    /**
     * Deselects rows by ids. Deselects all visible rows if no ids are provided.
     * In server-side scenarios only visible rows are deselectable.
     *
     * @method deselect
     * @param [rowsIds] {Array} An array of rows ids to deselect
     * @chainable
     **/
    Grid.prototype.deselect = function(rowIds)
    {
    	var deSelectAllFlag = false;
    	var selectBoxSelector = getCssSelector(this.options.css.selectBox);
    	
    	if (this.selection)
        {
            //rowIds = rowIds || this.currentRows.propValues(this.identifier);

            var id, i, pos,
                deselectedRows = [];
            
        	if(typeof rowIds == 'undefined'){//Deselect All
        		deSelectAllFlag = true;
        		this.element.find("thead " + selectBoxSelector).prop("indeterminate", false).prop("checked", false).val('none');
        		this.selectedRows= [];
        		deselectedRows = this.currentRows;
        	}else{//single deSelect
	            while (rowIds.length > 0)
	            {
	                id = rowIds.pop();
	                pos = $.inArray(id, this.selectedRows);
	                if (pos !== -1)
	                {
	                    for (i = 0; i < this.currentRows.length; i++)
	                    {
	                        if (this.currentRows[i][this.identifier] === id)
	                        {
	                            deselectedRows.push(this.currentRows[i]);
	                            this.selectedRows.splice(pos, 1);
	                            break;
	                        }
	                    }
	                }
	            }
            }

            if (deselectedRows.length > 0 ||deSelectAllFlag == true)
            {
                //var selectBoxSelector = getCssSelector(this.options.css.selectBox);

                //PR1098 by fanbi
            	if(!deSelectAllFlag){
	                if(0 != this.selectedRows.length){
	                	 this.element.find("thead " + selectBoxSelector).prop("indeterminate", true).val("part");
	                }else{
	                	 this.selectedRows = [];
	                	 this.element.find("thead " + selectBoxSelector).prop("indeterminate", false).prop("checked", false).val("none");;
	                }
                }
                //this.element.find("thead " + selectBoxSelector).prop("checked", false);
                for (i = 0; i < deselectedRows.length; i++)
                {
                    this.element.find("tbody > tr[data-row-id="" + deselectedRows[i][this.identifier] + ""]")
                        .removeClass(this.options.css.selected)._bgAria("selected", "false")
                        .find(selectBoxSelector).prop("checked", false);
                }

                this.element.trigger("deselected" + namespace, [deselectedRows]);
            }
        }

        return this;
    };


//原renderTableHeader方法里的变量赋值.
//在这个版本,不管全勾选或者反勾选,勾选中的html代码都是 value ="all",就像是一个bug,这个value值没有什么作用 var selectBox = (this.options.multiSelect) ? tpl.select.resolve(getParams.call(that, { type: "checkbox", value: "all" })) : ""; //修改成默认是part var selectBox = (this.options.multiSelect) ? tpl.select.resolve(getParams.call(that, { type: "checkbox", value: "part" })) : "";

html里的修改如下:

var checkBoxVal = "none;//增加变量来保存当前是全选,部分选还是全不全状态

checkBoxVal =$('#yourGridId .select-box').val();
ajax{
    data:{
        checkBoxVal :checkBoxVal 
    }
}

//从后台的数据返回的值赋值给checkBoxs,存储数据可以用文件,数据库或者Localstorage来储存,按需来处理
$("#yourGridId ").bootgrid("select", checkBoxs, "load");    

java代码

String checkBoxVal = request.getParameter("checkBoxVal ");
    
if("all".equalsIgnoreCase(checkBoxVal )){
        checkBox = Utils.getAllXXXIds();
        //something to do
}else if("none".equalsIgnoreCase(checkBoxVal )){
        checkBox = "";
       //something to do
}            

3. 使用修正后的版本的结果

 部分选中的图标如下:

3.1 不管在那一页全选,当前页都会选上,而且当你切换到其它记录页时,checkbox也是全选的,表头的checkbox都是打钩√

3.2 不管在那一页全反选,当前页都会去掉√,而且当你切换到其它记录页时,checkbox也是全没选中的,表头的checkbox都是没选中状态

3.3 不管在哪一页部分选,而且当你切换到其它记录页时,表头的checkbox都是显示部分选的,不同浏览器差异如上图。

  

  

原文地址:https://www.cnblogs.com/fanbi/p/7434631.html