Kendo Grid - Dont allow certain records for editing - javascript

I have the below command button column in my Kendo grid..
How to disable the "Edit" button in the rows with empty "ItemValue".
$("#list485").kendoGrid({
dataSource: dataSource,
columns: [
{ command: [{ name: "edit" }], title: " ", width: "100px"},
{ field: "ItemValue", title: "Item Description" }
],
editable: "popup"
});

you may hide edit button by on dataBound function as below
dataBound: function (e) {
var grid = $("#list485").data("kendoGrid");
var gridData = grid.dataSource.view();
for (var i = 0; i < gridData.length; i++) {
var currentUid = gridData[i].uid;
if (gridData[i].ItemValue == "") {
var currenRow = grid.table.find("tr[data-uid='" + currentUid + "']");
var editButton = $(currenRow).find(".k-grid-edit");
editButton.hide();
}
}
}
i hope this will help you

Not sure if this can fulfill your need but it works fine for inline editing.
$("#list485").kendoGrid({
dataSource: dataSource,
columns: [
{ command: [{ name: "edit" }], title: " ", width: "100px"},
{ field: "ItemValue", title: "Item Description" }
],
editable: "popup",
edit: function(e) {
if(e.model.ItemValue == 100)//your condition
{
$("#grid").data("kendoGrid").refresh();
}
}
});
Anyway this is what I could able to find till now.
There must be some better solution for this.

Related

Why does KendoUI grid add a row to the beginning of the grid and not give the User a choice using rowindex?

Im using KendoUi grids everywhere now and need some help ..
When my Kendo grid first loads I want the user to have the rows and an empty row at the BOTTOM not the top to indicate that they can add data . I dont want to use the in built "Add Row Button".
I have the following
Try1
$(document).ready(function ()
{
var grid = $("#grid").data("kendoGrid");
grid.addRow();
$(".k-grid-edit-row").appendTo("#grid tbody");
}
This is supposed to move the row to the bottom of the grid , but it doesnt, it remans on top ?
Try 2
I also tried to do something like
var newRow = { field: "FirstName", Value: "" };
var grid = $("#grid").data("kendoGrid");
grid.dataSource.add(newRow);
This did not work either.
Try 3
But with this try , im not sure if there is a 'load' with the Kendoui Grid, i know there is a keydown , etc
grid.tbody.on('load', function (e)
{
if ($(e.target).closest('tr').is(':last-child'))
{
setTimeout(function ()
{
var totalrows = grid.dataSource.total();
var data = grid.dataSource.data();
var lastItem = data[data.length - 1];
if (typeof lastItem !== 'undefined')
{
if (lastItem.FirstName.trim() != "")
grid.addRow();
}
})
}
}
any help would be great.
The full implementation details is below:
First i add the datasource, this is a simple implementation.
var data = $scope.userdetails;
var dataSource = new kendo.data.DataSource({
transport: {
read: function (e) {
e.success(data);
},
update: function (e) {
e.success();
},
create: function (e) {
var item = e.data;
item.Id = data.length + 1;
e.success(item);
}
},
schema: {
model: {
id: "Id",
fields: {
FirstName: { type: "string" }
}
}
}
});
Then i define the grid
let grid = $("#grid").kendoGrid({
dataSource: dataSource,
scrollable: false,
navigatable: true,
editable: {
createAt: "bottom"
},
dataBound: function (e) {
e.sender.tbody.find(".k-grid-Delete").each(function (idx,
element) {
$(element).removeClass("k-button");
});
},
columns: [
{
field: "FirstName", title: "First Name"
},
{
command: [{ name: "Delete", text: "", click: $scope.delete,
className: "far fa-trash-alt fa-fw" }],
title: " ",
width: "100px",
attributes: { class: "k-grid-column-text-centre" }
}
]
}).data("kendoGrid");
I do the below process to add a blank row only when the user clicks tab on the last cell of the last row, but also want to add a blank when the page first loads with the grid.
grid.tbody.on('keydown', function (e) {
i`enter code here`f (e.keyCode == 9) {
if ($(e.target).closest('tr').is(':last-child')) {
setTimeout(function () {
var totalrows = grid.dataSource.total();
var data = grid.dataSource.data();
var lastItem = data[data.length - 1];
if (typeof lastItem !== 'undefined') {
if (lastItem.FirstName.trim() == "")
return;
}
grid.addRow();
})
}
}
});
This code still adds the row at the top of the grid not the bottom.
$(document).ready(function () {
var newRow = { field: "FirstName", Value: "" };
grid.dataSource.add(newRow);
grid.editRow($("#grid tr").last());
}
There is no other place that i add a row
You try #2 is the right way to go. It probably added a row at the bottom, right? So you just need to programatically edit it:
var newRow = { field: "FirstName", Value: "" };
var grid = $("#grid").data("kendoGrid");
grid.dataSource.add(newRow);
grid.editRow($("#grid tr").last());
Demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.2.513/styles/kendo.default-v2.min.css"/>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.2.513/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid"></div>
<script>
let grid = $("#grid").kendoGrid({
toolbar: ["save"],
columns: [
{ field: "name" },
{ field: "age" }
],
dataSource: {
data: [
{ id: 1, name: "Jane Doe", age: 30 },
{ id: 2, name: "John Doe", age: 33 }
],
schema:{
model: {
id: "id",
fields: {
age: { type: "number"}
}
}
}
},
editable: true
}).data('kendoGrid');
grid.dataSource.add({});
grid.editRow($("#grid tr").last());
</script>
</body>
</html>
Dojo
If someone is using the built-in method, just use editable.createAt parameter.

Checkbox select all row with same field? Using kendo-ui

$(function () {
var grid = $("#grid").kendoGrid({
dataSource: { data: items, pageSize: 20 },
sortable: true,
pageable: true,
columns: [
{
title: "Select All",
template: '<input type="checkbox" class="chkbx" />',
{ field: "Test1", title: "A" },
{ field: "Test2", title: "B" },
{ field: "Test3", title: "C" },
}).data("kendoGrid");
For exemple when I select checkbox at Test1 I want to select all line who have same data in field test 3.
You can have a function on checkbox click:
$(document).on("click", ".chkbx", function() {
});
Check if the class is the same.
Then you can do your logic inside the function
if ($(this).is(':checked')) {
var grid = $("#grid").data("kendoGrid");
var selectedItem = grid.dataItem(grid.select());
console.log(selectedItem); // selected row object;
// loop elements, compare your values and and select lines/checkboxes
} else {
}
How to select a particular row problematically
var row = grid.element.find("... whatever your criteria will be");
grid.select(row);

How to show label value in cell dropdown instead of stored value?

I'm using Tabulator.js to create an interactive table. I have a dropdown cell (editor type: select) and have found out how to show different labels when selecting from the list (instructions can be found here, the third way).
When I select something, the stored value is shown, but not the label (which is shown when you click on the list). I'd like the stored value to be the ID from the database, and I don't want the user to see it at all, just the label text.
Here is some example code:
var table = new Tabulator("#example-table", {
data:tabledata, //load row data from array
layout:"fitColumns", //fit columns to width of table
responsiveLayout:"hide", //hide columns that dont fit on the table
tooltips:true, //show tool tips on cells
addRowPos:"top", //when adding a new row, add it to the top of the table
history:true, //allow undo and redo actions on the table
pagination:"local", //paginate the data
paginationSize:7, //allow 7 rows per page of data
movableColumns:true, //allow column order to be changed
resizableRows:true, //allow row order to be changed
initialSort:[ //set the initial sort order of the data
{column:"name", dir:"asc"},
],
columns:[ //define the table columns
{title:"Name", field:"name", editor:"select", editorParams:{
values:{
"steve":"Steve Boberson",
"bob":"Bob Jimmerson",
"jim":"Jim Stevenson",
}
}},
],
});
In similar situation like you, but I used a custom select or native dropdown.
Here are the code to explain all: (uses formatters, keeping the real value...)
Tabulator 4.6.3 DataList and DisplayList Demo for select editor
var userData = [{
"FullName": "",
"LoginName": "none"
}, {
"FullName": "Steve Boberson",
"LoginName": "steve"
}, {
"FullName": "Bob Jimmerson",
"LoginName": "bob"
}, {
"FullName": "Jim Stevenson",
"LoginName": "jim"
}];
var customNativeSelect = function(cell, onRendered, success, cancel) {
var cellRealValue = cell.getElement().dataset.loginName;
cellRealValue = (typeof cellRealValue === "undefined") ? "none" : cellRealValue;
//Create and append select list
var selectList = document.createElement("select");
selectList.style.width = "100%";
selectList.style.boxSizing = "border-box";
onRendered(function() {
selectList.focus();
selectList.style.height = "100%";
});
function onChange() {
if (selectList.selectedOptions[0].value != cellRealValue) {
success(selectList.selectedOptions[0].value);
// Store value to cell dataset; will be done by formatter
/* cell.getElement().dataset.loginName = selectList.selectedOptions[0].value */
alert("Here is what the actual looks like: " + JSON.stringify(cell.getTable().getData()))
} else { // No change
cancel();
}
}
//submit new value on blur or change
selectList.addEventListener("blur", onChange);
//submit new value on enter
selectList.addEventListener("keydown", function(e) {
if (e.keyCode == 13) {
onChange();
}
if (e.keyCode == 27) {
cancel();
}
});
//Create and append the options
for (var i = 0; i < userData.length; i++) {
var option = document.createElement("option");
option.value = userData[i].LoginName;
option.text = userData[i].FullName;
if (userData[i].LoginName === cellRealValue) {
option.selected = "selected";
}
selectList.appendChild(option);
}
return selectList;
};
var filterState = false;
var tabledata = [{
itemId: '3423'
},
{
name: 'steve'
},
{
lastDate: '34/56/0000'
},
{
completed: 'yes'
}
];
var table = new Tabulator("#html-table", {
data: tabledata, //assign data to table
layout: "fitColumns",
tooltips: true,
tooltipsHeader: true,
placeholder: "No Data Available", //display message to user on empty table
height: "300px",
columns: [{
title: "ID",
field: "itemId",
headerFilter: false
}, {
title: "Name",
field: "name",
headerFilter: false,
editor: customNativeSelect,
formatter: function(cell) {
var value = cell.getValue();
for (var i = 0; i < userData.length; i++) {
if (userData[i].LoginName === value) {
// Store value to cell dataset
cell.getElement().dataset.loginName = value;
value = userData[i].FullName;
break;
}
}
return value;
}
}, {
title: "Last Date",
field: "lastDate",
headerFilter: false
}, {
title: "Completed",
field: "completed",
headerFilter: false
}, ]
});
function showHideFilters() {
if (filterState == false) {
table.updateColumnDefinition("itemId", {
headerFilter: true
});
table.updateColumnDefinition("name", {
headerFilter: true
});
table.updateColumnDefinition("lastDate", {
headerFilter: true
});
table.updateColumnDefinition("completed", {
headerFilter: true
});
filterState = true;
} else {
table.updateColumnDefinition("itemId", {
headerFilter: false
});
table.updateColumnDefinition("name", {
headerFilter: false
});
table.updateColumnDefinition("lastDate", {
headerFilter: false
});
table.updateColumnDefinition("completed", {
headerFilter: false
});
filterState = false;
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.6.3/css/tabulator.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.6.3/js/tabulator.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<button onClick="showHideFilters()">
Show/Hide Filters
</button>
<div id="html-table">
</div>
</body>
</html>
Just swap the values then
const tabledata = [{
name: 'Steve Stevenson'
},
{
name: 'Bob Boberson'
},
{
name: 'Tim Timmersonn'
},
{
name: 'Steve Boberson'
}
];
const table = new Tabulator("#example-table", {
data: tabledata, //load row data from array
layout: "fitColumns", //fit columns to width of table
responsiveLayout: "hide", //hide columns that dont fit on the table
tooltips: true, //show tool tips on cells
addRowPos: "top", //when adding a new row, add it to the top of the table
history: true, //allow undo and redo actions on the table
pagination: "local", //paginate the data
paginationSize: 7, //allow 7 rows per page of data
movableColumns: true, //allow column order to be changed
resizableRows: true, //allow row order to be changed
initialSort: [ //set the initial sort order of the data
{
column: "name",
dir: "asc"
},
],
columns: [ //define the table columns
{
title: "Name",
field: "name",
editor: "select",
editorParams: {
values: {
"Steve Boberson": "steve",
"Bob Jimmerson": "bob",
"Jim Stevenson": "jim"
}
}
},
],
});
<!DOCTYPE html>
<html>
<head>
<link href="https://unpkg.com/tabulator-tables#4.2.7/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#4.2.7/dist/js/tabulator.min.js"></script>
</head>
<body>
<div id="example-table"></div>
</body>
</html>
I encountered the same issue and I found simpler walkaround than creating custom select control. You can create a Map collection or Record which will map select keys on select values and then set up formatter function on a specific select column definition in which you can override the default display value.
composeSelectFormatter(dictionary) {
return (cell) => {
const value = cell.getValue();
if (!value) return value;
return dictionary[value];
}
}
And then in your column definition:
columns: [ //define the table columns
{
title: "Name",
field: "name",
editor: "select",
formatter: composeSelectFormatter(YOUR_DICTIONARY_RECORD_GOES_HERE),
values: [ ... ]
}
I just found myself in the same scenario.
I used a formatter function and tracked down the values in the list created in the column definition with the editorParams: {values:{1: "xxxx", 2:"xxxx"}},.
formatter: function(cell) {
let cgv = cell.getValue();
let values = cell?._cell?.column?.definition?.editorParams?.values;
console.dir(values);
if (cgv && values && values[cgv]) { return values[cgv]; }
//If you are using the combo {label: "", value: ""} you need to loop through the object
/*if (cgv && values && values.length) {
for (const v of values) {
if (v?.value == cgv && v?.label) { return v.label;}
}
}*/
return '';
}

Kendo Grid keydown event

I have initiated a Kendo Grid using Kendo directives. How do I catch the keydown/keypress event of the grid? My final objective is to populate a grid column based on user input of another column. For example, populate the phone number when the first name is entered. For that I believe I have to use the Kendo Grid edit and the keypress events and do a search on the user input, unless there's a better way to do it. Is this possible?
This is how I initialized the grid:
<section id="dashboard-view" class="mainbar" data-ng-controller="dashboard as vm">
....
<div kendo-grid="vm.testGrid" k-options="vm.testGridOptions" k-rebind="vm.testGridDataSource.data" k-on-edit="vm.onEdit(kendoEvent)"></div>
....
</section>
Options defined in my JavaScript file:
vm.testGridOptions = {
columns: [
{ field: "Id", title: "ID" },
{ field: "FirstName", title: "First Name" },
{ field: "LastName", title: "Last Name" },
{ field: "Phone", title: "Phone" },
{ command: ["destroy"] }
],
toolbar: ["create", "save", "cancel"],
dataSource: vm.testGridDataSource,
editable: {
createAt: "bottom"
},
height: 400,
autoBind: false
};
vm.onEdit = function (e) {
//if grid column == Id && keypressed == Tab key
//search
};
The grid is on batch edit mode.
You can find current column/field name based on the index. Then filter the dropdown present in column next to it: (this is just a sample code, please replace DOM ids with your code)
vm.onEdit = function (e) {
var header = vm.thead;//grid header
var index = vm.cellIndex(e.container);//current cell index
var th = $(header).find("th").eq(index);
var colName = $(th).data("field");//fieldname for current cell
var dataItem = e.model;//row model
if(colName=='LastName')
{
var phoneDropDown = e.container.find("#PhoneDropDownId").data("kendoDropDownList");
if (phoneDropDown) {
phoneDropDown.dataSource.filter({ field: "Phone", operator: "eq", value: e.model.LastName });
}
}
};
Since the Kendo Grid doesn't have a native event for this I used the JQuery onBlur event.
vm.onEdit = function (e) {
alert("Edit event fired");
$('input.k-input.k-textbox').blur(function (f) {
alert("Blur event fired");
}
};

Slickgrid with only one row editable

Hello I have an editable grid using slickgrid library and I want to know if there is a way to have only the last row (the one that is added by default on the grid loading) editable and the rest of rows non editable?
The following code I'm using is from the library here : Slickgrid Editable with new row added
<script>
var grid;
var data = [];
var columns = [
{id: "title", name: "Title", field: "title", editor: Slick.Editors.Text},
{id: "desc", name: "Description", field: "description", editor: Slick.Editors.Text},
{id: "duration", name: "Duration", field: "duration", editor: Slick.Editors.Text}
];
var options = {
editable: true,
enableAddRow: true,
enableCellNavigation: true,
asyncEditorLoading: false,
autoEdit: false
};
$(function () {
for (var i = 0; i < 3; i++) {
var d = (data[i] = {});
d["title"] = "Task " + i;
d["description"] = "This is a sample";
d["duration"] = "5 days";
}
grid = new Slick.Grid("#myGrid", data, columns, options);
grid.setSelectionModel(new Slick.CellSelectionModel());
grid.onAddNewRow.subscribe(function (e, args) {
var item = args.item;
grid.invalidateRow(data.length);
data.push(item);
grid.updateRowCount();
grid.render();
});
})
</script>
try this code..to disable all rows except the last row
grid.onBeforeEditCell.subscribe(function(e,args) {
if (args.row === grid.getDataLength()-1) {
return true;
} else {
return false;
}
});
You can subscribe to the "onBeforeEditCell" event and return false based on the logic from args
grid.onBeforeEditCell.subscribe(function (e, args)
{
if (/*logic on args*/)
{
return false;
}
});
Check out this SO post: Disabling specific cell edit in Slick grid

Categories

Resources