0
votes

I have a grid and use rowactions grouping plugin to have an action button in the grouping header. The fist visible column in the grid is a checkbox column. I need to make the checkboxes in the same group behave the same way. 1) if a user checks one of the checkboxes, all boxes in the same group has to be checked. 2) Also I need to look at another field in the same row and if it doesn't have a value, disable checkboxes (all in the same group), otherwise all checkboxes should be enabled.

I also tried xtype:checkbox. For #1 I just cannot figure out how to get the siblings. I tried using the checkchange - I could get a record there - but I don't know how to get other records from the same group. For #2 - how do I get the record - I need to check one of the values and set the ckeckbox enabled/disabled.

Any ideas? Thank you.

EDIT: for #2 I went with disable checkcolumn for some rows answer here

This is my index.cshtml

     <script type="text/javascript">
          Ext.require([
          'Ext.container.Viewport',
          'Ext.grid.*',
          'Ext.util.*',
          'Ext.Date.*',
          'Ext.ux.CheckColumn',

          'ACTGRID.ui.GroupPanelGrid'
         ]);

      Ext.onReady(function () {
          initialize();
      });


      function initialize() {
          Ext.Ajax.timeout = 60000; // 60 seconds

         var myGrid = Ext.create('ACTGRID.ui.GroupPanelGrid');
         var viewport = Ext.create('Ext.container.Viewport', {
              layout: 'border',
              items: [{
                      region: 'center',
                      title: 'Grid',
                      items: myGrid }]
          });
      };
   </script>

This is the GroupPanelGrid.js:

 Ext.Date.patterns = {
    ISO8601Long: "Y-m-d H:i:s",
    ISO8601Short: "Y-m-d",
    ShortDate: "n/j/Y",
    LongDate: "l, F d, Y",
    FullDateTime: "l, F d, Y g:i:s A",
    MonthDay: "F d",
    ShortTime: "g:i A",
    LongTime: "g:i:s A",
    SortableDateTime: "Y-m-d\\TH:i:s",
    UniversalSortableDateTime: "Y-m-d H:i:sO",
    YearMonth: "F, Y"
};


Ext.define('ACTGRID.ui.TransactionsLateModel', {
extend: 'Ext.data.Model',
fields: [
    { name: 'Id', type: 'int' },
    { name: 'Approval', type: 'boolean' },
    { name: 'ErrorComment', type: 'string' },
    { name: 'ErrorSource', type: 'string'},
    { name: 'RecordDate', type: 'date', dateFormat: 'MS' }],


idProperty: 'Id'
});

Ext.define("ACTGRID.ui.GroupPanelGrid", {
    extend: "Ext.grid.Panel",
    requires: ['ACTGRID.ui.TransactionsLateModel',
              'Ext.ux.grid.RowActions',
              'Ext.grid.feature.Grouping'],

    initComponent: function () { 
        var me = this;
        me.features = [Ext.create('Ext.grid.feature.Grouping', {
                      groupHeaderTpl: 'Grouping Header: {name} ({rows.length} 
                      Item{[values.rows.length > 1 ? "s" : ""]})',
                      enableGroupingMenu: false })];

        me.columns = me.buildColumns();
        me.store = Ext.create('Ext.data.Store', {
            model: 'ACTGRID.ui.TransactionsLateModel',
            remoteSort: true,
            storeId: 'TransactionsLateStoreId',
            autoLoad: true,
            buffered: true,
            autoSync: true,
            groupField: 'RecordDate',
            pageSize: 70,
            proxy: {
                type: 'rest',
                timeout: 600000,

                url: '/Home/ActionsGrid/',
                reader: {
                    type: 'json',
                    root: 'transaction',
                    totalProperty: "Total"
                },
                writer: {
                    type: 'json',
                    root: 'transaction'
                }
            }
        });


       me.autoSizeColumns = true;
       me.autoScroll = true;
       me.forcefit = true;
       me.callParent(arguments);

  },


buildColumns: function () {
    var me = this;

    return [
    {
        xtype: 'rowactions', hidden: true, hideable: false,
        actions: [{}],
        keepSelection: true,
        groupActions: [{
            iconCls: 'icon-grid',
            qtip: 'Action on Group',
            align: 'left',
            callback: function (grid, records, action, groupValue) {
                var rec = [].concat(records);
                /*does something unrelated*/
            }
        }]
    },
    {
        text: 'Approval', dataIndex: 'Approval', sortable: true,
        width: 50,
        xtype: 'checkcolumn',
        listeners: {
            checkchange: function (column, recordIndex, checked) {
                var record = me.getStore().data.items[recordIndex].data;
                /* Do something here? - How do I get all the siblings */
            },

            beforerender: function (e, eOpts) {
                /* How do I check another cell in this row to see if it has a value
                   And disable the ckeckbox and set it read only?  */
            }
        }
    },
    { text:'ErrorComment', dataIndex: 'ErrorComment' },
    { text:'ErrorSource', dataIndex: 'ErrorSource'},
    { text:'RecordDate', dataIndex: 'RecordDate', renderer: Ext.util.Format.dateRenderer        (Ext.Date.patterns.ShortDate)}];
    },
   height: 600,
   width: 'auto'

   });

Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        return View();
    }


    [AcceptVerbs(HttpVerbs.Get)]
    [ActionName("ActionsGrid")]
    public ActionResult GetActionsGrid()
    {
        DetailsViewModel model = new DetailsViewModel();
        List<ExtJsTreeGrid.Models.ActionGrid> ActionsFromDB = model.GetActionsGrid();

        model.transaction = ActionsFromDB;
        model.success = true;
        return Json(model, JsonRequestBehavior.AllowGet);
    }
    [AcceptVerbs(HttpVerbs.Put)]
    [ActionName("ActionsGrid")]
    public ActionResult SetActionsGrid()
    {
       // do something 
    }

}

Model:

 public class ActionGrid
 {
    public Int32 Id { get; set; }
    public bool Approval { get; set; }
    public string ErrorComment { get; set; }
    public string ErrorSource { get; set; }
    public DateTime RecordDate { get; set; }
}



 public class DetailsViewModel
 {
    public List<ActionGrid> transaction = new List<ActionGrid>();
    public bool success = true;

    public List<ActionGrid> GetActionsGrid()
    {
       return new List<ActionGrid> {
             new ActionGrid { Id = 1, 
                        Approval = true, 
                        ErrorComment = "Comment", 
                        ErrorSource = string.Empty,
                        RecordDate = new DateTime(1979, 11, 23)
             },
              new ActionGrid { Id = 5, 
                        Approval = true, 
                        ErrorComment = "Comment", 
                        ErrorSource = "brodas",
                        RecordDate = new DateTime(1979, 11, 23)
             },
              new ActionGrid { Id = 6, 
                        Approval = true, 
                        ErrorComment = "Comment", 
                        ErrorSource = string.Empty,
                        RecordDate = new DateTime(1979, 11, 23)
             },
              new ActionGrid { Id = 7, 
                        Approval = true, 
                        ErrorComment = string.Empty, 
                        ErrorSource = "brodas",
                        RecordDate = new DateTime(1979, 11, 23)
             },
             new ActionGrid { Id = 2, 
                        Approval = true, 
                        ErrorComment = string.Empty, 
                        ErrorSource = string.Empty,
                        RecordDate = new DateTime(1980, 05, 20)
             },
             new ActionGrid { Id = 3, 
                        Approval = true, 
                        ErrorComment = "Comment", 
                        ErrorSource = "brodas",
                        RecordDate = new DateTime(1995, 01, 12)
             },
             new ActionGrid { Id = 4, 
                        Approval = true, 
                        ErrorComment = string.Empty, 
                        ErrorSource = string.Empty,
                        RecordDate = new DateTime(2010, 09, 02)
             },
             new ActionGrid { Id = 8, 
                        Approval = true, 
                        ErrorComment = string.Empty, 
                        ErrorSource = "brodas",
                        RecordDate = new DateTime(2010, 09, 02)
             },
             new ActionGrid { Id = 9, 
                        Approval = true, 
                        ErrorComment = "Comment Errors", 
                        ErrorSource = string.Empty,
                        RecordDate = new DateTime(2010, 09, 02)
             },
             new ActionGrid { Id = 10, 
                        Approval = true, 
                        ErrorComment = "Comment Errors", 
                        ErrorSource = "brodas",
                        RecordDate = new DateTime(2010, 09, 02)
             },
             new ActionGrid { Id = 11, 
                        Approval = true, 
                        ErrorComment = string.Empty, 
                        ErrorSource = "brodas",
                        RecordDate = new DateTime(2010, 09, 02)
             }};

    }
2
I don't understand your second requirement. When do you want to enable/disable the group's checkboxes? When a row in the group is checked? Or do you want that step to happen when the data are loaded?rixo
@rixo when the data is loadedBoroda
Then you need to listen for the load event of your store. You can get all the records loaded in the store with the getRange method in there. Is there still something blocking you for that second requirement?rixo

2 Answers

1
votes

For requirement #1, the checkchange listener is indeed the right place to implement it.

To get all the records in the group, you need to grab a reference to the grid's store, and then use its query method, with your grouping field, and the value in the checked record.

Here's an example:

checkchange: function(col, index, checked) {
    var grid = col.up('tablepanel'), 
        store = grid.getStore(),
        record = store.getAt(index),
        group = record.get('group'),
        // returns a MixedCollection (not a simple array)
        groupRecords = store.query('group', group);

    // apply the same check status to all the group
    groupRecords.each(function(record) {
        record.set('checked', checked);
    });
}

For your second requirement, I don't really understand when you want it to happen.

Anyway, the check column doesn't support disabling at the row level, so you'll have to implement that first.

The simplest way to do that is to add a field to your model to hold the disabled state. Let's call it 'disabled'. Then, you need two things.

First, render the checkbox disabled state. For that, let's override the renderer of the check column:

,renderer: function(value, meta) {
    // Adding disabled class according to record's checkable
    // field
    if (meta.record.get('disabled')) {
        meta.tdCls += ' ' + this.disabledCls;
    }

    // calling the overridden method (cannot use callParent
    // since we haven't define a new class)
    return Ext.grid.column.CheckColumn.prototype.renderer.apply(this, arguments);
}

Next, we need to prevent checking or unchecking disabled records. That can be done in the beforecheckchange event:

,beforecheckchange: function(col, index) {
    var grid = col.up('tablepanel'), 
        store = grid.getStore(),
        record = store.getAt(index);

    if (record.get('disabled')) {
        return false;
    }
}

Now, you can just enable/disable a record's checkbox by setting the record's 'disabled' field.

record.set('disabled', true); // enable
record.set('disabled', false); // disable

Complete Example

Here's a complete example that implements your first requirement and, maybe, your second one. If that not what you meant for the second requirement, that should take you almost there...

The example can be seen running in this fiddle.

Ext.widget('grid', {
    renderTo: Ext.getBody()
    ,height: 300

    ,features: [{ftype: 'grouping'}]

    ,store: {
        proxy: {type: 'memory', reader: 'array'}
        ,fields: [
            'name', // something to see
            'group', // grouping field
            'checkable', // for req #2
            'checked', // for check column
            'disabled' // for disabled state
        ]
        ,groupField: 'group'
        ,data: [
            ['Foo 1', 'foo', true],
            ['Foo 2', 'foo', false],
            ['Foo 3', 'foo', true],
            ['Bar 1', 'bar', false],
            ['Bar 2', 'bar', true],
            ['Baz 1', 'baz', false],
            ['Baz 2', 'baz', false],
            ['Baz 3', 'baz', true]
        ]
    }

    ,columns: [{
        xtype: 'checkcolumn'
        ,width: 50
        ,dataIndex: 'checked'

        ,listeners: {
            checkchange: function(col, index, checked) {
                var grid = col.up('tablepanel'), 
                    store = grid.getStore(),
                    record = store.getAt(index),
                    group = record.get('group'),
                    // returns a MixedCollection (not a simple array)
                    groupRecords = store.query('group', group),
                    // for req #2
                    disableGroup = !record.get('checkable');

                groupRecords.each(function(record) {
                    record.set('checked', checked);

                    // Here's how to disable the group... If that's
                    // really what you want.
                    record.set('disabled', disableGroup);
                });
            }

            // Returning false from this listener will prevent the
            // check change. This is used to implement disabled
            // checkboxes.
            ,beforecheckchange: function(col, index) {
                var grid = col.up('tablepanel'), 
                    store = grid.getStore(),
                    record = store.getAt(index);

                if (record.get('disabled')) {
                    return false;
                }
            }
        }

        ,renderer: function(value, meta) {
            // Adding disabled class according to record's checkable
            // field
            if (meta.record.get('disabled')) {
                meta.tdCls += ' ' + this.disabledCls;
            }

            // calling the overridden method (cannot use callParent
            // since we haven't define a new class)
            return Ext.grid.column.CheckColumn.prototype.renderer.apply(this, arguments);
        }
    },{
        dataIndex: 'name'
        ,text: "Name"
        ,flex: 1
    },{
        dataIndex: 'checkable'
        ,text: "Checkable"
    }]
});
0
votes

as for my case, i have a separate checkbox outside my gridpanel which controls the selection of the checkcolumn.

//Avoid view update after each row
grid.store.suspendEvents();
grid.store.each(function(rec) {
    rec.set('ctrl_select_flag', ctrl.value);
});
grid.store.resumeEvents();
grid.getView().refresh();

ctrl.value refers to the component which controls my checkcolumn selection. ctrl_select_flag refers to the dataIndex of my checkcolumn.