0

I have an EXT grid that has an additional checkbox and radio in the last 2 columns using the renderer. When I check an item in the grid and view the source I am not seeing the checked:checked designation in the HTML so I am having a hard time targeting the element.

When a row is selected I want to be able to check to see if the checkbox is checked, I am doing something like this:

if (document.getElementById("#isFull-"+record['index']+"").checked == true){
    var myVar = true;
}

Is there another way I can target this element to see if it is checked?

Here is the full code:

Ext.onReady(function () {

    Ext.QuickTips.init();

    // Data store
    var data = Ext.create('Ext.data.JsonStore', {
        autoLoad: true,
        fields: ['name', 'market', 'expertise', 'id', 'isFull', 'isPrimary'],
        proxy: {
            type: 'ajax',
            url: '/opsLibrary/getLibraryJson'
        }
    });

    // Selection model
    var selModel = Ext.create('Ext.selection.CheckboxModel', {
        columns: [{
            xtype: 'checkcolumn',
            text: 'Active',
            dataIndex: 'id'
        }],
        listeners: {
            selectionchange: function (value, meta, record, rowIndex, colIndex) {
                var selectedRecords = grid4.getSelectionModel().getSelection();
                var selectedParams = [];

                // Clear hidden input
                $('#selected-libraries').empty();
                var record = null;
                var myVar = null;
                var myVar2 = null;

                for (var i = 0, len = selectedRecords.length; i < len; i++) {
                    record = selectedRecords[i];

                    // Is full library checked?
                    myVar = !Ext.fly("isFull-" + data.indexOf(record)).dom.checked;

                    // Build data object
                    selectedParams.push({
                        id: record.getId(),
                        full: myVar

                    });
                }
                // JSON encode object and set hidden input
                $('#selected-libraries').val(JSON.stringify(selectedParams));

            }
        }
    });

    // Render library grid
    var grid4 = Ext.create('Ext.grid.Panel', {
        xtype: 'gridpanel',
        id: 'button-grid',
        store: data,
        columns: [{
            text: "Library",
            width: 170,
            sortable: true,
            dataIndex: 'name'
        }, {
            text: "Market",
            width: 125,
            sortable: true,
            dataIndex: 'market'
        }, {
            text: "Expertise",
            width: 125,
            sortable: true,
            dataIndex: 'expertise'
        }, {
            text: 'Full',
            dataIndex: 'isFull',
            width: 72,
            renderer: function (value, meta, record, rowIndex, colIndex) {
                return '<center><input type="checkbox" onclick="var s = Ext.getCmp(\'button-grid\').store; s.getAt(s.findExact(\'id\',\'' + record.get('id') + '\')).set(\'isFull\', this.value)"'
            }
        }, {
            text: 'Primary',
            dataIndex: 'isPrimary',
            width: 72,
            renderer: function (value, meta, record, rowIndex, colIndex) {
                return '<center><input type="radio" id="isPrimary-' + rowIndex + '"/></center>';
            }
        }, ],
        columnLines: false,
        selModel: selModel,
        width: 600,
        height: 300,
        frame: true,
        title: 'Available Libraries',
        iconCls: 'icon-grid',
        renderTo: Ext.get('library-grid')
    });
});

UPDATED SELECTION MODEL:

// Selection model
var selModel = Ext.create('Ext.selection.CheckboxModel', {
    columns: [{
        xtype: 'checkcolumn',
        text: 'Active',
        dataIndex: 'id'
    }],
    listeners: {
        selectionchange: function (value, meta, record, rowIndex, colIndex) {
            var selectedRecords = grid4.getSelectionModel().getSelection();
            var LastSelectedRecords = grid4.getSelectionModel().getLastSelected();
            var selectedParams = [];

            // If user unselected ID then make sure Full & Primary boxes cleared
            if (grid4.getSelectionModel().getSelection() == "") {
                // Get row ID
                Ext.fly('isFull-' + LastSelectedRecords['index']).dom.checked = false;
                Ext.fly('isPrimary-' + LastSelectedRecords['index']).dom.checked = false;
            }

            // Clear input and reset vars
            $('#selected-libraries').empty();
            var record = null;
            var myVar = null;
            var myVar2 = null;

            // Loop through selected records
            for (var i = 0, len = selectedRecords.length; i < len; i++) {
                record = selectedRecords[i];

                // Is full library checked?
                myVar = record.get('isFull');

                // Is this primary library?
                myVar2 = record.get('isPrimary');

                // Build data object
                selectedParams.push({
                    id: record.getId(),
                    full: myVar,
                    primary: myVar2
                });
            }
            // JSON encode object and set hidden input
            $('#selected-libraries').val(JSON.stringify(selectedParams));
            console.log(JSON.stringify(selectedParams));
        }
    }
});
Darin Kolev
  • 3,401
  • 13
  • 31
  • 46
xXPhenom22Xx
  • 1,265
  • 5
  • 29
  • 63
  • Checkcolumn will not render true checkbox instances as you might guess. It just renders images with a applied click listener. If you need to know what is selected I recommend you to use a appropriate selection model. You can then easily get all information that way. – sra Jul 24 '13 at 20:26
  • How would I go about changing the selection model to also render a checkbox and radio in the last 2 columns? I went through all of EXT's site examples but couldnt find a clear answer or example? – xXPhenom22Xx Jul 24 '13 at 21:01
  • If you really have multiple simulated input elements (I saw just a check box column) in your grid go with the [beforecellclick](http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.grid.Panel) event of the grid that will allow you to identify which cell,was clicked and directly enable you to modify the record.... – sra Jul 24 '13 at 21:19
  • Why don't you use a regular CheckColumn? That would save you all that troubles... – rixo Jul 24 '13 at 23:01
  • @rixo that was my first guess to but that won't work for the radio... – sra Jul 25 '13 at 05:43
  • 2
    @sra It could work: https://fiddle.sencha.com/#fiddle/32 – rixo Jul 25 '13 at 05:50
  • 1
    @rixo nice one as always ;) And yeah, I missed my first coffee.. I thought about the checkbox selection model after reading your comment, so my answer to it was wrong... So yes, this is the easiest and cleanest solution! you should post it as answer cause this would also work with multiple t´column of that type. – sra Jul 25 '13 at 05:56

3 Answers3

1

Data in records is accessed using the get() function, not object notation:

if (document.getElementById("isFull-"+record.get('index')).checked == true)
{
    var myVar = true;
}

A couple other points... You are checking a truth value using == true, which will return true for any "truthie". You'll want to use === if you want to check that it equals true.

Also, you may want to consider Ext.fly() to get your element, it's more Ext-friendly:

if (Ext.fly("isFull-"+record.get('index')).dom.checked === true)
{
    var myVar = true;
}

For simplicity, you can even just do this:

var myVar = Ext.fly("isFull-"+record.get('index')).dom.checked;

EDIT:

I was under the impression that you had index as one of your store fields, but I just noticed that it is not. You will want to use store.indexOf(record) to get the index you need:

var myVar = Ext.fly("isFull-" + data.indexOf(record)).dom.checked;
kevhender
  • 4,285
  • 1
  • 13
  • 16
  • I am getting the following error when I try to implement either of these -- Uncaught TypeError: Cannot read property 'dom' of null – xXPhenom22Xx Jul 24 '13 at 15:15
  • I had a typo in my response - you should not use the `#` when using `getElementById` or `Ext.fly()`. Try it again without the `#`. – kevhender Jul 24 '13 at 15:32
  • No dice, when I check one of the boxes the event is firing but am still getting back -- Uncaught TypeError: Cannot read property 'dom' of null. When I view the source in Firebug I DO NOT see 'checked:checked' or anything like that – xXPhenom22Xx Jul 24 '13 at 15:39
  • Does the `id` of the checkbox you see in firebug match `"isFull-"+record.get('index')` that you are checking? That error seems to suggest that it doesn't. Check the `id` in firebug and do `console.log("isFull-"+record.get('index'))` in your function to see if the IDs match. – kevhender Jul 24 '13 at 15:42
  • Actually, I am just now seeing that you don't have an "index" property in your record. You will want to use `store.indexOf(record)`. I'll update the answer. – kevhender Jul 24 '13 at 15:44
  • Ok I think we are close, now when I check a box I am seeing False first then if I uncheck it I get back true... var myVar = Ext.fly("isFull-" + data.indexOf(record)).dom.checked; console.log(myVar); – xXPhenom22Xx Jul 24 '13 at 16:04
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/34090/discussion-between-xxphenom22xx-and-kevhender) – xXPhenom22Xx Jul 24 '13 at 16:13
  • 1
    I'm blocked from chatting, but `selectionchange` is probably getting fired before the box is checked, so just negate the checked value and you should be good to go: `var myVar = !Ext.fly("isFull-" + data.indexOf(record)).dom.checked;` – kevhender Jul 24 '13 at 17:13
  • That worked like a charm! Thanks again for your help on this one... To target the radio can I also use the .checked? – xXPhenom22Xx Jul 24 '13 at 17:34
  • Radio and Checkbox both use `checked`, yes. – kevhender Jul 24 '13 at 17:57
  • Think I may have jumped the gun... The grid has a column of checkboxes as well on the far left, when I click that I get a TRUE response to myVar being checked, then if I click on the checkbox I am targeting myVar remains TRUE then if I unclick the checkbox I am targeting myVar changes to FALSE. Then if I click in my targeted checkbox it seems to respond accurately, definitely seems like the order in which this is firing may not be right? – xXPhenom22Xx Jul 24 '13 at 18:38
1

Let's try a different approach. What if you set your check columns to do something like this:

{
    text: 'Full',
    dataIndex:'isFull',
    width: 70,
    renderer: function (value, meta, record, rowIndex, colIndex) {
        return '<center><input type="checkbox" onclick="var s = Ext.getCmp(\'button-grid\').store; s.getAt(s.findExact(\'id\',\'' + record.get('id') + '\')).set(\'isFull\', this.value)" /></center>';
    }
},

This should set the value directly into the record.

kevhender
  • 4,285
  • 1
  • 13
  • 16
  • Uncaught TypeError: Cannot read property 'dom' of null buildLibraryGrid.js:41 Uncaught TypeError: Object -1 has no method 'set' [VM] new (7607):1 onclick – xXPhenom22Xx Jul 24 '13 at 19:17
  • Are your ID's not `int`s? Put quotes around that param if so: `return '
    ';`
    – kevhender Jul 24 '13 at 19:26
  • id is an INT. Tried the snippet you just sent but came back with the same error. – xXPhenom22Xx Jul 24 '13 at 19:32
  • For error: Uncaught TypeError: Cannot read property 'dom' of null it is pointing to myVar = !Ext.fly("isFull-" + data.indexOf(record)).dom.checked; – xXPhenom22Xx Jul 24 '13 at 19:34
  • 1
    Bah, my mistake. Need to surround the `findExact` with `getAt`: `onclick="var s = Ext.getCmp(\'button-grid\').store; s.getAt(s.findExact(\'id\',\'' + record.get('id') + '\')).set(\'isFull\', this.value)"` – kevhender Jul 24 '13 at 19:36
  • Uncaught TypeError: Cannot read property 'dom' of null .... Updated my code above. Also the behavior changed a little, now when I try to click an item you get that red triangle in the top left then if I click a second time it will select the box – xXPhenom22Xx Jul 24 '13 at 19:44
  • 1
    Why are you still trying to set `myVar` that way? The value should already be set at that point, you can just use `record.get('isFull')`. – kevhender Jul 24 '13 at 19:55
  • You lost me on that, which point of the code are you talking about, when I clear out myVar to null or set it with the !Ext.fly bit? – xXPhenom22Xx Jul 24 '13 at 21:26
  • 1
    The `Ext.fly` part should no longer be necessary, since the checkbox code sets the value directly on the record. You should be able to use `myVar = record.get('isFull')` instead of the `Ext.fly(...)` line. – kevhender Jul 24 '13 at 23:52
  • Ahh ok I missed that, made the change and it appears to be working! Thanks again for all your help! – xXPhenom22Xx Jul 25 '13 at 15:01
  • Would it be fairly easy to do the following: If the main ID checkbox on the left is unchecked to automatically uncheck both the radio and second checkbox? Sorry about all the noob questions, backend Python guy here so not to versed in the wild ways of JS. – xXPhenom22Xx Jul 25 '13 at 15:31
  • 1
    You could add the ID back to the check/radio, then just set `Ext.fly(checkboxId).dom.checked = true/false` on those elements as needed. – kevhender Jul 25 '13 at 16:57
  • I updated my selection model above. If there is an empty selection it goes and gets the last selected record and I can reliably fetch the last ID that was unchecked. But I am getting an error when trying to unset the radio or the checkbox. -- Uncaught TypeError: Cannot read property 'dom' of null – xXPhenom22Xx Jul 25 '13 at 19:05
0

Maybe, you can use one listener on grid view:

Sencha api [4.2]: Listeners on grid/columns

 listeners: {
        click: {
            element: 'el', //bind to the underlying el property on the panel
            fn: function(){ 
                 console.log('click el'); 
            }
        },
mfruizs
  • 770
  • 14
  • 20