1. #1
    Ext User
    Join Date
    Jan 2008
    Posts
    1
    Vote Rating
    0
    mehtadata is on a distinguished road

      0  

    Default Disable Row Select But Keep Checkbox Selections

    Disable Row Select But Keep Checkbox Selections


    Hi.. Hope someone can help me here..

    I have a grid with a checkboxselectionmodel.. All is well.. However, let's say you select like 10 rows, and then when clicking on the checkbox, you miss by a few pixels and click on a data column, and not the checkbox. Now all your selections are lost, and only that one row is selected.

    So my question.. How can you disable a single row select to trigger a checkbox selection, but still keep the checkbox selection working? Better yet, can you have that clicking a row, adds to the currently already selected rows?

    I have purged all listeners which works fine, however, then you can't click on a column header to sort anymore.. I've tried playing with overriding the rowclick and on click methods/events, but it doesn't work.

    Please advise. Any help is greatly appreciated. Thanks!

  2. #2
    Ext JS Premium Member NOSLOW's Avatar
    Join Date
    Feb 2008
    Location
    Morrisville, NC
    Posts
    162
    Vote Rating
    -1
    NOSLOW is an unknown quantity at this point

      0  

    Default


    Thanks for asking this. I've noticed this also after using the checkbox selection model for the first time the other day. I'm interested in hearing the answer.

  3. #3
    Ext JS Premium Member NOSLOW's Avatar
    Join Date
    Feb 2008
    Location
    Morrisville, NC
    Posts
    162
    Vote Rating
    -1
    NOSLOW is an unknown quantity at this point

      -1  

    Wink [SOLVED]

    [SOLVED]


    Ok, decided to look into this one myself and was able to come up with a working solution. The trick is the "keepExisting" parameter of the selectRow method of the checkboxSelectionModel. Use that to override the default behavior:

    Code:
    sm = new Ext.grid.CheckboxSelectionModel({
        singleSelect:false,
        listeners: {
            beforerowselect: function (sm, row_index, keepExisting, record) {            
                sm.suspendEvents();
                if (sm.isSelected(row_index)) {
                    // row already selected, deselect it (note: other selections remain intact on deselect).
                    sm.deselectRow(row_index);
                } else {
                    sm.selectRow(row_index, true)
                }
                sm.resumeEvents();
                return false;
            }
        }
        });
    Seems like there should just be a simple property to set to get this behavior. But I guess I'm just spoiled by this awesome framework, since so much other functionality is just a boolean option away .

  4. #4
    Ext User
    Join Date
    Mar 2008
    Posts
    8
    Vote Rating
    0
    jackhlp is on a distinguished road

      0  

    Default


    that's very good, but how can I disable the rowselect?

  5. #5
    Ext JS Premium Member NOSLOW's Avatar
    Join Date
    Feb 2008
    Location
    Morrisville, NC
    Posts
    162
    Vote Rating
    -1
    NOSLOW is an unknown quantity at this point

      0  

    Default


    Looks like this is a bit trickier than I thought. First off, my code is flawed. The following check will never be true inside a "beforerowselect" event handler:

    Code:
    beforerowselect: function (sm, row_index, keepExisting, record) {
        if (sm.isSelected(row_index)) {
            alert("not gonna happen"); //--- will never hit this line
        }
    }
    That means that my suggested fix only allows a selected row to be deselected via the checkbox column. Clicking anywhere else on the selected row will not select it. That means you'll have to look for another event handler to work with, like the grid's click or rowmousedown (which gives you the column index to work with). But then things get much more difficult when your dealing with multiple events to handle the same basic action of selecting/deselecting a row.

    I suspect it's doable, but a bit more involved than I have time to play with. Unless there's a clean simple way to solve this, I don't think it's worth mucking with all the events for trivial functionality.

  6. #6
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,546
    Vote Rating
    64
    Animal is a jewel in the rough Animal is a jewel in the rough Animal is a jewel in the rough

      0  

    Default


    I'm working on a checkbox plugin for Grids that is independent of selection. It adds getChecked(), setChecked(rec), and checkAll() and uncheckAll() to the Grid.

    I'll have some code ready tomorrow morning (BST)

  7. #7
    Ext User
    Join Date
    Jan 2008
    Posts
    8
    Vote Rating
    0
    martijn is on a distinguished road

      0  

    Default


    Amazing, I just came here to post about this! Can't wait to see your plugin Animal. I'd be pleased to test something tomorrow.

    ciao,

    Martijn

  8. #8
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,546
    Vote Rating
    64
    Animal is a jewel in the rough Animal is a jewel in the rough Animal is a jewel in the rough

      0  

    Default


    Drop this into examples/grid as array-grid.js

    Code:
    Ext.onReady(function(){
    
        Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
    
        var myData = [
            ['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
            ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
            ['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am'],
            ['American Express Company',52.55,0.01,0.02,'9/1 12:00am'],
            ['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am'],
            ['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am'],
            ['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'],
            ['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am'],
            ['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am'],
            ['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am'],
            ['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am'],
            ['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am'],
            ['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am'],
            ['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'],
            ['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am'],
            ['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am'],
            ['International Business Machines',81.41,0.44,0.54,'9/1 12:00am'],
            ['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am'],
            ['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am'],
            ['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am'],
            ['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am'],
            ['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am'],
            ['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am'],
            ['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am'],
            ['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am'],
            ['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am'],
            ['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am'],
            ['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am'],
            ['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am']
        ];
    
        // example of custom renderer function
        function change(val){
            if(val > 0){
                return '<span style="color:green;">' + val + '</span>';
            }else if(val < 0){
                return '<span style="color:red;">' + val + '</span>';
            }
            return val;
        }
    
        // example of custom renderer function
        function pctChange(val){
            if(val > 0){
                return '<span style="color:green;">' + val + '%</span>';
            }else if(val < 0){
                return '<span style="color:red;">' + val + '%</span>';
            }
            return val;
        }
    
        // create the data store
        var store = new Ext.data.SimpleStore({
            fields: [
               {name: 'company'},
               {name: 'price', type: 'float'},
               {name: 'change', type: 'float'},
               {name: 'pctChange', type: 'float'},
               {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
            ]
        });
        store.loadData(myData);
        
        Ext.ux.GridRowChecker = Ext.extend(Object, {
    	    header: "",
    	    width: 23,
    	    sortable: false,
    	    fixed: true,
    	    menuDisabled: true,
    	    dataIndex: '',
       		id: 'selection-checkbox',
    	    rowspan: undefined,
    
        	init: function(grid) {
        		this.grid = grid;
        		this.gridSelModel = this.grid.getSelectionModel();
        		this.gridSelModel.originalMouseDown = this.gridSelModel.handleMouseDown;
    			this.gridSelModel.handleMouseDown = this.onGridMouseDown;
        		grid.getColumnModel().config.unshift(this);
        		grid.getChecked = this.getChecked.createDelegate(this);
        		grid.checkAll = this.checkAll.createDelegate(this);
        		grid.uncheckAll = this.uncheckAll.createDelegate(this);
        	},
    
    		renderer: function() {
    			return '<input class="x-row-checkbox" type="checkbox">';
    		},
    
    		getChecked: function() {
    			var result = [];
    			var cb = this.grid.getEl().query("div.x-grid3-col-selection-checkbox > input[type=checkbox]");
    			var idx = 0;
    			this.grid.store.each(function(rec) {
    				if (cb[idx++].checked) {
    					result.push(rec);
    				}
    			});
    			delete cb;
    			return result;
    		},
    
    		checkAll: function() {
    			this.grid.getEl().select("div.x-grid3-col-selection-checkbox > input[type='checkbox']").each(function(e){
    				e.dom.checked = true;
    			});
    		},
    
    		uncheckAll: function() {
    			this.grid.getEl().select("div.x-grid3-col-selection-checkbox > input[type='checkbox']").each(function(e){
    				e.dom.checked = false;
    			});
    		},
    
    		onGridMouseDown: function(g, rowIndex, e) {
    			if (e.getTarget('div.x-grid3-col-selection-checkbox')) {
    				e.stopEvent();
    				return false;
    			}
        		this.originalMouseDown.apply(this, arguments);
    		}
        });
    
        // create the Grid
        window.grid = new Ext.grid.GridPanel({
            store: store,
            plugins: [ new Ext.ux.GridRowChecker() ],
            columns: [
                {id:'company',header: "Company", width: 160, sortable: true, dataIndex: 'company'},
                {header: "Price", width: 75, sortable: true, renderer: 'usMoney', dataIndex: 'price'},
                {header: "Change", width: 75, sortable: true, renderer: change, dataIndex: 'change'},
                {header: "% Change", width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
                {header: "Last Updated", width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
            ],
            stripeRows: true,
            autoExpandColumn: 'company',
            height:350,
            width:600,
            title:'Array Grid'
        });
    
        grid.render('grid-example');
        grid.getSelectionModel().selectFirstRow();
    });
    If you need to disable standard row selection, use http://extjs.com/deploy/dev/docs/?cl...sableSelection

  9. #9
    Ext User
    Join Date
    Jan 2008
    Posts
    8
    Vote Rating
    0
    martijn is on a distinguished road

      0  

    Default


    Nice Animal, looks good.

    However, together with the disableSelection option (thanks for the pointer), I think a column like this is sufficient for me:

    PHP Code:

         
    {
                
    id'checkbox',
                
    renderer: function(valuecellrecord) {
                    return 
    '<input class="x-row-checkbox" onclick="toggleSomething(this);" checked="checked" type="checkbox" value="' record.id '">';
                },
                
    header'',
                
    menuDisabledtrue,
                
    resizablefalse,
                
    width23
                
            
    }, 
    Can confirm that yours works btw.

    Martijn

  10. #10
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,546
    Vote Rating
    64
    Animal is a jewel in the rough Animal is a jewel in the rough Animal is a jewel in the rough

      0  

    Default


    Yes, that's basically what the plugin does. But it adds some utility methods to make the checking of Grid rows usable. I mean what are you going to do with the checked rows?