Adding bindeable checkbox column to grid

53,001

Solution 1

There are some previous considerations:

  1. When you click in a cell for editing you are switching it to edit mode and then is when editor function get executed.
  2. If you are not in edition mode despite of the HTML used, the changes are not transferred in the model.
  3. Kendo UI render boolean as checkboxes for editing but not while not in edit mode.

What you need to do is:

  1. Define a template for displaying a checkbox.
  2. If you do not want to click twice the checkbox (the first to enter edit mode and the second to change it's value), you need to define a checkbox but bind a change event that intercepts clicks on it and change the model.

Template definition:

{
    title   : "Fully Paid",
    field   : "fullyPaid",
    template: "<input name='fullyPaid' class='ob-paid' type='checkbox' data-bind='checked: fullyPaid' #= fullyPaid ? checked='checked' : '' #/>"
}

As you can see I'm not defining an editor function since we will change the value of the checkbox without entering in edition mode.

Define a handler that detect changes in the checkbox that I defined in the template and update the model.

grid.tbody.on("change", ".ob-paid", function (e) {
    var row = $(e.target).closest("tr");
    var item = grid.dataItem(row);
    item.set("fullyPaid", $(e.target).is(":checked") ? 1 : 0);
});

Your JSBin modified here : http://jsbin.com/ebadaj/12/edit

Solution 2

I had the same problem with my batch edited grid. The solutions I found were only for one specific column (as the solution mentioned above). So I changed

item.set("fullyPaid", $(e.target).is(":checked") ? 1 : 0);

to

var col = $(this).closest('td');
dataItem.set(grid.columns[col.index()].field, checked);

So you can use it for any checkbox columns.

The next problem was the dirty flag which is not set correctly when using the "one click edit" option of checkbox.

So I've tested various things to get it work and endet up with this:

In column definition:

.ClientTemplate("<input type='checkbox' #= CheckboxColumn? checked='checked': checked='' # class='chkbx' />");

And script below:

<script>
    $(function () {
        $('#GridName').on('click', '.chkbx', function () {
            var checked = $(this).is(':checked');
            var grid = $('#GridName').data().kendoGrid;
            grid.closeCell();
            var dataItem = grid.dataItem($(this).closest('tr'));
            var col = $(this).closest('td');
            grid.editCell(col);
            dataItem.set(grid.columns[col.index()].field, checked);
            grid.closeCell(col);
        });
    });
</script>

Solution 3

Updated example for 2018!!

with themes. Kendo uses Themes so using the standard "browser-checkbox-look" (different in every browser) is not so nice.

https://dojo.telerik.com/IluJosiG/14

$(document).ready(function () {
     
                    $("#grid").kendoGrid({
                        dataSource: {
                          transport: {
                    				read: function(options){
                              var data = [
                                {
                                	include: true,
                                  Amount: 20
                                },
                                {
                                	include: true,
                                  Amount: 30
                                },
                                {
                                	include: false,
                                  Amount: 0
                                }
                              ];
                            	options.success(data);
                            }
                          },
                          schema:{
                            model: {
                              fields: {
                                include: { type: 'boolean' },
                                Amount: { type: "number", },
                              }
                            }
                          }
                        },
                        columns: [
                            { 
                              field: "include", 
                              editor: function(container, options){

                                var grid = $(container).closest('[data-role=grid]').data('kendoGrid');
                                var row = grid.dataItem(container.closest('tr'));

                                //console.log('grid', grid);
                                console.log('row', row);
                                if(row.include){
                                  row.set('include', false);
                                  row.set('Amount', 0);
                                } else {
                                	row.set('include', true);
                                  row.set('Amount', 1);
                                }

                                grid.closeCell();
                              },
                              template: function(items){
                                var guid = kendo.guid();
                                
                                var checked = ''; // = ' disabled="disabled" ';
                                if(items.include){
                                  checked = ' checked="checked" ';
                                }
                                return '<input class="k-checkbox" id="' + guid + '" type="checkbox" ' + checked + ' />' + 
                                  '<label class="k-checkbox-label" for="' + guid + '">&#8203;</label>';
                              },
                              attributes:{ align:"center" },
															headerAttributes: { 'class': 'k-header-centeralign' }
                            },
                          {
                            field: "Amount",
                            format: "{0:n6}",
                            editor: function(container, options){
                            	$('<input data-bind="value:' + options.field + '"/>')
                                .appendTo(container)
                                .kendoNumericTextBox({
                                  decimals: 6,
                                  min: 0,
                                  restrictDecimals: true // Specifies whether the decimals length should be restricted during typing. The length of the fraction is defined by the decimals value
                                }
                              );
                            }
                          }
                        ],
                        editable: true,
                      	save: function(e){
                      		console.log('save', e);
			
                          var model = e.model;
                          console.log('save model', model);

                          var items = this.dataSource.data();
                          var item = $.grep(items, function(e){ return e.uid == model.uid; })[0];
                          //console.log('item uid', items);

                          var userAmount = e.values.Amount;

                          if(userAmount>0){
                            item.set('include', true);
                            console.log('set include true');
                          } else {
                            item.set('include', false);
                            console.log('set include false');
                          }
                          
                          // redraw row for checkbox
                          // timeout because qty is not updated before
                          var grid = e.sender;
                          setTimeout(function(){
                            var row = grid.element.find('tr[data-uid=' + model.uid + ']');
                            console.log('redraw row for checkbox', row);
                            kendoFastReDrawRow(grid, row);
                          },0);
                          
                        },
                        dataBound: function(e){
                          console.log('dataBound');
                        },
                    });
                });

              
            function kendoFastReDrawRow(grid, row) {
	var dataItem = grid.dataItem(row);
	var rowChildren = $(row).children('td[role="gridcell"]');
	for (var i = 0; i < grid.columns.length; i++) {
		var column = grid.columns[i];
		var template = column.template;
		var cell = rowChildren.eq(i);
		if (template !== undefined) {
			var kendoTemplate = kendo.template(template);
			// Render using template
			cell.html(kendoTemplate(dataItem));
		} else {
			var fieldValue = dataItem[column.field];
			var format = column.format;
			var values = column.values;
			if (values !== undefined && values != null) {
				// use the text value mappings (for enums)
				for (var j = 0; j < values.length; j++) {
					var value = values[j];
					if (value.value == fieldValue) {
						cell.html(value.text);
						break;
					}
				}
			} else if (format !== undefined) {
				// use the format
				cell.html(kendo.format(format, fieldValue));
			} else {
				// Just dump the plain old value
				cell.html(fieldValue);
			}
		}
	}
}
td[role=gridcell] .k-checkbox + label.k-checkbox-label {
	cursor: pointer !important;
	
}
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.2.620/styles/kendo.common-bootstrap.min.css" />
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.2.620/styles/kendo.bootstrap.min.css" />
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.2.620/styles/kendo.bootstrap.mobile.min.css" />

    <script src="https://kendo.cdn.telerik.com/2018.2.620/js/jquery.min.js"></script>
    <script src="https://kendo.cdn.telerik.com/2018.2.620/js/kendo.all.min.js"></script>

<div id="example">
  <div id="grid"></div>
</div>
Share:
53,001

Related videos on Youtube

Tuthmosis
Author by

Tuthmosis

Software engineer Project manager Fly fishing expert

Updated on August 30, 2020

Comments

  • Tuthmosis
    Tuthmosis almost 4 years

    Have this column in a Kendo grid that currently display a MySQL Boolean value so we have either 1 or 0.

    Made this demo to play on...

    This in an autosync and inline:true grid.

    I would like this column to be of type "Checkbox" but, for some weird reasons, i just cannot find a demo or an example on the web that displays "enabled" checkbox that changes 1 to 0 when unchecked and Vice-Versa.

  • Tuthmosis
    Tuthmosis almost 11 years
    That is a most appreciated proactive hint... If only there were more like you. !
  • Tuthmosis
    Tuthmosis almost 11 years
    Just used this solution on my real application which involves remote datasource... How to trigger an update ? Everything works except the changes aren't persisted to database.
  • Tuthmosis
    Tuthmosis almost 11 years
    Also, i see that it is still possible to click to the right of the check-box and edit the 0-1 value behind it... and that it doesn't affect the check mark...
  • OnaBai
    OnaBai almost 11 years
    You can trigger the update by invoking saveChanges in the grid object.
  • Tuthmosis
    Tuthmosis almost 11 years
    And for my other comment... do you know a way to fix this ?
  • OnaBai
    OnaBai almost 11 years
    I see that for the checkbox you can still click on the cell and enter in edit mode but I do not understand it doesn't affect the check mark Why do you say it does not affect the check mark? The question is that you click first for entering in edit mode and then again for changing the value but that's the same that you do for a text field where you first select the field and then type the value. It is not nice but it is consistent.
  • Tuthmosis
    Tuthmosis almost 11 years
    I probably made a mistake in my last phrasing. :-) The thing is that there are now two ways to change the value and it isn't good practice as i do not want the user to see 1 and 0... Only by checking or unchecking should we be able to change the internal value. (1 to 0 and ViceVersa)
  • OnaBai
    OnaBai almost 11 years
    Probably is not your phrasing but my understanding, likely that we have different questions in mind and that's why we don't understand each other. I'm not getting those two modes of setting it. I see two ways but both are based on clicking in the checkbox. You do it directly or enter edit mode and the click on the checkbox. Is this what you mean? I cannot see how the user can set 0 or 1. BTW: did you remove the editor function, don't you?
  • Tuthmosis
    Tuthmosis almost 11 years
    Do you know how to set the checkboxs ReadOnly ? (jsbin.com/ebadaj/12/edit)
  • DontVoteMeDown
    DontVoteMeDown over 10 years
    @OnaBai this solution in some way "refreshes" the grid(or dataSource, not sure about it) and: 1- make the "change" slow in big grids; 2- modifies some grid properties(e.g custom css classes on rows). I can't figure out what is happening indeed. Can you help with this stackoverflow.com/q/19657764/1267304 ?
  • Dev
    Dev almost 10 years
    OnaBai's answer will not work for IE. This answer works for IE too, really an excellent workaround for IE.
  • Chris
    Chris about 9 years
    How would you prevent checking / unchecking the tick when using InLine editing and the line is not being edited?
  • Francis
    Francis about 7 years
    This worked for me with UI for ASP.Net Core. Made the checkbox dirty and model binding was successful for incell batch editing.
  • Snehal
    Snehal about 7 years
    @OnaBai I have one issue please suggest what could be solution. We are using Kendo Grid with AngularJs binding. Same like your example we both have template & editor (in editor we put checkbox only not the text box). Everything works perfect but getting issue when on other field selection am selecting/unselecting checkbox. E.g. If am ticking first check box, second checkbox should be untick. In this case datasource value for second checkbox is updating but only display template not showing correct checkbox value. For resolving issue we are refreshing grid which is not correct.