slickgrid formatter and virtual scrolling resetting form - slickgrid

function linkFormatter(row, cell, value, columnDef, dataContext) {
var cell = "";
cell += '<input type="checkbox" id="cb' + dataContext['id'] + '" name="cb' + dataContext['id'] + '" value="' + dataContext['id'] + '" ' + (dataContext['Reviewer'] == 'Unassigned' ? 'class="unassignedLoan"' : "") + '> ';
cell += '' + value + '';
return cell;
};
I have this formatter function with a dataView. The checkbox the formatter creates gets reset when the user scrolls that row out of view and clicks on a different cell. I think the virtual scrolling is re rendering that cell with the formatter so it loses the values of the checkbox. Does anyone have a suggestion to get around this problem?
Thanks

On scrolling or sorting, the grid DOM is created again. So the initial values get reset.
You have to save the values (e.g. id's of the checkboxes checked) in an array and set it again on scroll and sort event.
Do it like this...
grid.onScroll.subscribe(function(e) {
grid.invalidate();
grid.render();
var $canvas = $(grid.getCanvasNode()), $allRows = $canvas
.find('.slick-row');
$($allRows).each(function() {
if(this row's checkbox is in selectedRowId){
set checkbox property to checked;
}
});
});
grid.onSort.subscribe(function(e) {
grid.invalidate();
grid.render();
var $canvas = $(grid.getCanvasNode()), $allRows = $canvas
.find('.slick-row');
$($allRows).each(function() {
if(this row's checkbox is in selectedRowId){
set checkbox property to checked;
}
});
});

Related

Why in multiselect grid with editable cell the setSelection of row not working when tries to edit already edited cell again in afterSaveCell event?

afterSaveCell: function (rowid, name, val, iRow, iCol) {
var grid = $("#" + subgrid_table_id);
if (parseFloat(val) > 0) {
//alert(val + ' ' + rowid);
//$(this.rows[rowid]).attr("aria-selected", true);
//$(this.rows[rowid]).addClass("ui-state-highlight");
grid.jqGrid('setSelection', rowid, false);
grid.jqGrid('setCell', rowid, 'Review', "True");
}
}
It should mark the row checked if editable cell value is greater than zero. Which it does first time but when I try to edit same cell it doesn't keep checkbox checked
You can try to resetSelection, before to do a set

How to implement checkbox and select option in datatables?

I populate the table with an ajax call. In the first column I have checkboxes for selecting and deselecting rows and submit data to a php script. I have also two columns with select fields.
The render function for the one (of the two) column with select:
{
targets: 6,
render: function(data, type, full, meta) {
if(data.length == 4) {
return '<select class="form-control" id="selectotpionmonths' + data[0].cataloguenumber + '"><option value="'+ data[3].months
+ '">' + data[3].months + '<option value="'+ data[2].months
+ '">' + data[2].months + '<option value="'+ data[1].months
+ '">' + data[1].months + '<option value="'+ data[0].months
+ '">' + data[0].months + '</select>';
} else {
return data[0].months;
}
}
},
And the handler for click event and on change event:
$('#results tbody').on('click', 'input[type="checkbox"]', function(e){
var $row = $(this).closest('tr');
// Get row data
var data = table.row($row).data();
$('#selectotpionmonths' + data['enc_unit']).change(function(){
e.preventDefault();
var selectedoptionformonths = $('#selectotpionmonths' + data['enc_unit']).find("option:selected").text();
if(selectedoptionformonths == 3) {
$('#selectoptionprice' + data['enc_unit']).find('option[value="' + data['price_rrp'][3].price + '"]').prop('selected', true);
} else if(selectedoptionformonths == 6) {
$('#selectoptionprice' + data['enc_unit']).find('option[value="' + data['price_rrp'][2].price + '"]').prop('selected', true);
} else if(selectedoptionformonths == 9) {
$('#selectoptionprice' + data['enc_unit']).find('option[value="' + data['price_rrp'][1].price + '"]').prop('selected', true);
} else if(selectedoptionformonths == 12) {
$('#selectoptionprice' + data['enc_unit']).find('option[value="' + data['price_rrp'][0].price + '"]').prop('selected', true);
}
});
if(data['price_numberofmonths'].length == 4) {
var monthsoption = $('#selectotpionmonths' + data['enc_unit']).find("option:selected").text();
var priceoption = $('#selectoptionprice' + data['enc_unit']).find("option:selected").text();
} else {
var monthsoption = data['price_numberofmonths'][0].months;
var priceoption = data['price_rrp'][0].price;
}
// Get row ID
var dataforserver = {name: data['enc_unit'], duration: monthsoption, price: priceoption};
var rowId = dataforserver.name;
// Determine whether row ID is in the list of selected row IDs
var index = $.inArray(rowId, rows_selected);
// If checkbox is checked and row ID is not in list of selected row IDs
if(this.checked && index === -1){
rows_selected.push(rowId);
units_selected.push(dataforserver);
// Otherwise, if checkbox is not checked and row ID is in list of selected row IDs
} else if (!this.checked && index !== -1){
rows_selected.splice(index, 1);
units_selected.splice(index, 1);
}
if(this.checked){
$row.addClass('selected');
} else {
$row.removeClass('selected');
}
order_total = 0;
for(i=0; i < units_selected.length; i++) {
order_total += parseFloat(units_selected[i].price);
}
//console.log(order_total.toFixed(2));
$( "#ukhoanswer" ).html(
"Number of units selected: " + units_selected.length + "<br/>" +
"Total cost of order: " + order_total.toFixed(2)
);
// Update state of "Select all" control
updateDataTableSelectAllCtrl(table);
// Prevent click event from propagating to parent
e.stopPropagation();
});
// Handle click on table cells with checkboxes
$('#results').on('click', 'tbody td, thead th:first-child', function(e){
$(this).parent().find('input[type="checkbox"]').trigger('click');
});
// Handle click on "Select all" control
$('thead input[name="select_all"]', table.table().container()).on('click', function(e){
if(this.checked){
$('#results tbody input[type="checkbox"]:not(:checked)').trigger('click');
} else {
$('#results tbody input[type="checkbox"]:checked').trigger('click');
}
// Prevent click event from propagating to parent
e.stopPropagation();
});
You may view the initial code for the checkboxes here
When I click on the cell with the select field I want to prevent the click event on the row. I have tried adding e.preventDefault but with no success. For the columns with the select option I want only the change event to be triggered.
Any ideas?
I did the following:
var selectField = $('.form-control');
selectField.on('click', function(event) {
event.stopPropagation();
});
The selector are for the cells with the select options. Now the first time that I click on the select field the row is selected. But next time I select an option the click event is prevented and the row is not selected/deselected.
I am looking on how to prevent the row being selected on the first click on a select field.

Remote update cell content in kendo grid

Here I have a code to update a cell contet when pressing a button.
It works fine, but it doesn't set the flag, that indicates, that the cell has been changed.
It should look like this with the litle red triangle:
The code:
<a id="button" href="#">Click me</a>
<div id="grid"></div>
<script>
var dataSource, grid;
$(document).ready(function () {
dataSource = new kendo.data.DataSource({
data: [
{ category: "Beverages", name: "Chai", price: 18},
{ category: "Seafood", name: "Konbu", price: 6}
],
})
grid = $("#grid").kendoGrid({
dataSource: dataSource,
editable: true,
}).data("kendoGrid");
$('#button').click(function (e) {
var data = grid.dataItem("tr:eq(1)");
data.set('category', 'Merchandice');
});
});
</script>
Update:
Here is the update based on #tstancin: Kendo example.
Thank you for the answer - I had thought of it to.
I am wondering if it's possible to do the update in a more clean way with some binding through som MVVM perhaps?
Kind regards from Kenneth
If that's all you want then you should expand your button click code with the following:
$('#button').click(function (e) {
var data = grid.dataItem("tr:eq(1)");
data.set('category', 'Merchandice');
$("#grid tr:eq(1) td:eq(1)").addClass("k-dirty-cell");
$("#grid tr:eq(1) td:eq(0)").prepend("<span class='k-dirty'></span>");
});
But if you, for instance, manually change the value of name column from Chai to something else, and then click the click me button, the dirty marker in the name column will disappear.
You should use flags for every cell and set them before data.set(). Then, in the grid's dataBound event you should inspect every cell's value and assign the dirty marker if it's needed. For manual changes you should handle the save event and set flags there.
I wrote a script that makes it posible to use a call like this:
SetCellData(id, columnName, value);
So with an id, a columnName and a value, I can update a value in a grid and the flag will be set on the cell.
function SetCellData(id, columnName, value) {
var dataItem = grid.dataSource.get(id);
dataItem.set(columnName, value);
var columnIndex = GetColumnIndex(columnName);
if (columnIndex > -1) {
var cell = $('tr[data-uid*="' + dataItem.uid + '"] td:eq(' + columnIndex + ')')
if (!cell.hasClass("k-dirty-cell")){
cell.prepend("<span class='k-dirty'></span>");
cell.addClass("k-dirty-cell");
}
}
}
function GetColumnIndex(columnName) {
var columns = grid.columns;
for (var i = 0; i < columns.length; i++)
if (columns[i].field == columnName)
return i;
return -1;
};
I have the code here : example

Add checkbox to the ckeditor toolbar to addClass/removeClass in img elements

I want to write a ckeditor plugin that adds a checkbox to the toolbar.
When an img element is selected, the checkbox should reflect whether the image has a certain class or not.
When something else than an image is selected, the checkbox should be
disabled, or maybe invisible.
When I check or uncheck the checkbox, the class should be added/removed to/from the img.
In other words, I want to add something else than a button to the toolbar (those that are added with editor.ui.addButton), and that something should be a checkbox.
How do I do that?
I managed to do it anyway, using editor.ui.add and editor.ui.addHandler. Here is a screenshot:
plugin.js:
CKEDITOR.plugins.add('add_zoomable_to_image',
{
init: function( editor )
{
var disabled_span_color = "#cccccc";
var enabled_span_color = "#000000";
var cb;
var span;
var html =
"<div style='height: 25px; display: inline-block'>" +
"<div style='margin: 5px'><input class='add_zoomable_cb' type='checkbox' disabled='disabled'>" +
"<span class='add_zoomable_span' style='color: " + disabled_span_color + "'> Add zoomable to image</span>" +
"</div>" +
"</div>";
editor.ui.add('add_zoomable_to_image', "zoomable_button", {});
editor.ui.addHandler("zoomable_button",
{
create: function ()
{
return {
render: function (editor, output)
{
output.push(html);
return {};
}
};
}
});
editor.on("selectionChange", function()
{
var sel = editor.getSelection();
var ranges = sel.getRanges();
if (ranges.length == 1)
{
var el = sel.getStartElement();
if (el.is('img'))
{
enable_input();
if (el.hasClass('zoomable'))
check_cb();
else
uncheck_cb();
}
else
disable_input();
}
else
disable_input();
});
editor.on("instanceReady", function ()
{
cb = $('.add_zoomable_cb');
span = $('.add_zoomable_span');
cb.change(function()
{
var element = editor.getSelection().getStartElement();
if (cb.is(':checked'))
element.addClass('zoomable');
else
element.removeClass('zoomable');
});
});
function enable_input()
{
cb.removeAttr('disabled');
span.css('color', enabled_span_color);
}
function disable_input()
{
uncheck_cb();
cb.attr('disabled', 'disabled');
span.css('color', disabled_span_color);
}
function check_cb()
{
cb.attr('checked', 'checked');
}
function uncheck_cb()
{
cb.removeAttr('checked');
}
}
});
CKEditor doesn't include the option to add a checkbox to the toolbar, so your first step is to look at their code and extend it to add the checkbox.
Then look at how other buttons work to modify the content and detect when the selection in the editor changes to reflect its new state, and apply those ideas to your checkbox.

Validation summary in Kendo Ui inline grid

Is there anyway to use validation summary inline kendo grid. please advise. if any link that i could follow.
No, you cannot use a validation summary with Kendo UI grid.
Here is a way to use a validation summary in KendoUI grid
Just make ul element above your grid like
<ul class="errorMessages"></ul>
Then in the edit function of the grid get a reference to the validator and add a click event to the update button
edit : function(e) {
var myValidator = e.sender.editable.validatable
e.container.find('.k-grid-update').click(function() {
if (!myValidator.validate()) {
displayErrors(myValidator)
}
});
}
Then the displayErrors function note I use a custom data attribute to make a friendly name for an input ie instead of using the id="firstName" I add data-myfriendly="First Name" you can use whatever you want title, id, name ect
function displayErrors(validator) {
var errorList = $('ul.errorMessages');
errorList.empty();
var myerrors = validator._errors;
var count = 0;
$.each(myerrors, function(field, errmsg) {
//Set focus on first field
if (count === 0) {
$('#' + field).focus();
count++;
}
//Set css
$('#' + field).css({
'box-shadow' : '0 0 5px #d45252',
'border-color' : '#b03535'
});
var titlerrmsg = $('#' + field).attr("title");
var friendly = $('#' + field).attr("data-myfriendly");
errorList.append('<li><span>' + friendly + ' is</span> ' + titlerrmsg + '</li>');
});
errorList.show();
}
Hope this helps!

Resources