Kendo grid highlight all column by external value - javascript

I want to highlight the kendo grid cell by matching an external string text.
I googled a lot but found only searching a string in a particular column.
below is the code which works for one column
$("#grid").kendoGrid({
selectable: "multiple cell",
allowCopy: true,
columns: [
{ field: "productName" },
{ field: "category" }
],
dataSource: [
{ productName: "Tea", category: "Beverages" },
{ productName: "Coffeete", category: "Beverageste" },
{ productName: "Ham", category: "Foodte" },
{ productName: "Bread", category: "Food" }
]
});
var grid = $("#grid").data('kendoGrid');
var value = 'te';
var regex = new RegExp(value, "gi");
var colIndex = 0;
grid.tbody.find('tr[data-uid]').each(function () {
var td = $(this).find('td:eq(' + colIndex + ')');
var item = grid.dataItem(this);
td.html(item.productName.replace(regex, '<span style="background-color:yellow">' + value + '</span>'));
});
But I want the search the string text across all columns.
Can anyone help me on this?

The best for doing that IMO is to use templates, e.g.:
template: "#= findText(data.fieldName) #"
The template will use a function to create the search highlight which can be something similiar as you already done:
var findText = function findText(text) {
let index = text.indexOf(value),
result = text;
// If substring is found in current text
if (index > -1) {
let regex = new RegExp(value, "gi");
result = result.replace(regex, '<span style="background-color:yellow">' + value + '</span>');
}
return result;
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.1023/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.1023/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.1023/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.1023/styles/kendo.mobile.all.min.css">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.1023/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.1023/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.1023/js/kendo.all.min.js"></script></head>
<body>
<div id="grid"></div>
<script>
var value = 'co';
var findText = function findText(text) {
let index = text.toLowerCase().indexOf(value),
result = text;
// If substring is found in current text
if (index > -1) {
let regex = new RegExp(`(${value})`, "gi");
result = result.replace(regex, '<span style="background-color:yellow">$1</span>');
}
return result;
};
$("#grid").kendoGrid({
selectable: "multiple cell",
allowCopy: true,
columns: [
{ field: "productName", template: "#= findText(data.productName) #" },
{ field: "category", template: "#= findText(data.category) #" }
],
dataSource: [
{ productName: "Tea", category: "Beverages" },
{ productName: "Coffeete", category: "Beverageste" },
{ productName: "Ham", category: "Foodte" },
{ productName: "Bread", category: "Food" }
]
});
</script>
</body>
</html>
Demo in Dojo

Related

Copying data from a kendo treelist with keeping the table structure

I have an editable multi selectable kendo Treelist. I would like to be able to select part of the grid and copy paste its data in the same grid (other columns and rows) or to a text file. It is important to paste it with the same structure in the new table.
The copy feature is not supported for kendo Treelist.
Is there a way to do that with use of JavaScript and jQuery?
Kendo demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2023.1.117/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/2023.1.117/js/kendo.all.min.js"></script>
</head>
<body>
<div id="treeList"></div>
<script>
$("#treeList").kendoTreeList({
columns: [
{ field: "name" },
{ field: "age" }
],
selectable: "multiple, cell",
editable:"incell",
dataSource: [
{ id: 1, parentId: null, name: "Jane Doe", age: 22 },
{ id: 2, parentId: 1, name: "John Doe", age: 24 },
{ id: 3, parentId: 1, name: "Jenny Doe", age: 3 }
]
});
</script>
</body>
</html>
I have used two buttons, one for copying and one for pasting. The events functions are as below. This solved my problem and I can also paste the copied text in excel.
<button onClick="copying()" >Copy</button>
<button onClick="pasting()" >Paste</button>
<div id="treeList"></div>
<script>
$("#treeList").kendoTreeList({
columns: [
{ field: "name" },
{ field: "age" }
],
selectable: "multiple, cell",
editable:"incell",
dataSource: [
{ id: 1, parentId: null, name: "Jane Doe", age: 22 },
{ id: 2, parentId: 1, name: "John Doe", age: 24 },
{ id: 3, parentId: 1, name: "Jenny Doe", age: 3 }
]
});
</script>
var copiedText="";
function copying(){
if(copiedText !== ""){
return;
}
var grid = $("#treeList").data("kendoTreeList");
var selected = grid.select();
var previousRowID = selected.eq(0).parent().index();
var isNewLine = true;
selected.each(function() {
var row = $(this).closest("tr");
var dataItem = grid.dataItem(this);
if (previousRowID !== $(this).parent().index()) {
copiedText += "\r\n";
isNewLine = true;
}
previousRowID = $(this).parent().index();
var colIndx = $("td", row).index(this);
var column = grid.columns[colIndx];
var data = dataItem;
var value = dataItem[column.field];
if (!isNewLine) {
copiedText += "\t";
}
copiedText += value;
isNewLine = false;
});
var textarea = $("<textarea>");
var offset = $(this).offset();
// Position the textarea on top of the Treelist and make it transparent.
textarea.css({
position: 'absolute',
opacity:0,
border: 'none',
width: $(this).find("table").width(),
height: $(this).find(".k-grid-content").height()
});
textarea.val(copiedText)
.appendTo('body')
.focus()
.select();
document.execCommand('copy');
setTimeout(function(){
textarea.remove();
});
}
function pasting() {
var pasteVal = copiedText;
var grid = $("#treeList").data("kendoTreeList");
if (pasteVal) {
var selectedArr= Object.values($(".k-grid td.k-selected"));
var pasteArray = pasteVal.split("\r\n").filter(r => r !== "").map(r => r.split("\t"));
pasteArray.forEach(function( item, index) {
selectedArr[index].innerHTML = item;
});
grid.refresh();
}
copiedText= "";
}

Kendo Grid UI: Enable custom text copy with multiple row select feature

I am having a kendo grid where the multiple row selection is enabled. With multiple selection functionality, when users try to copy custom text like any value from the column, it enables multiple select features thus users cannot copy custom text.
Below is the sample:
https://dojo.telerik.com/#erpuneet507/ivAfoFup
The issue is, in the above example you can select text from a single cell/ or any partial text from the cell.
If you have multiple selection enabled, then your app has to handle the copy text to clipboard. In doing so, you'll need the clipboard.js library and add a Kendo ContextMenu. Handle the copy text in the ContextMenu select event. Copy Text should pop up on right click.
Try the code below in the Telerik DOJO:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2021.2.616/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/2021.2.616/js/kendo.all.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.7.1/clipboard.min.js"></script>
</head>
<body>
<div id="grid"></div>
<ul id="context-menu">
<li id="copyText">Copy Text</li>
</ul>
<script>
$(document).ready(function() {
$("#grid").kendoGrid({
selectable: "multiple row",
allowCopy: true,
columns: [
{ field: "productName" },
{ field: "category" }
],
dataSource: [
{ productName: "Tea", category: "Beverages" },
{ productName: "Coffee", category: "Beverages" },
{ productName: "Ham", category: "Food" },
{ productName: "Bread", category: "Food" }
]
});
$("#context-menu").kendoContextMenu({
target: "#grid",
filter: "td",
select: function (e) {
var cell = e.target;
var row = $(cell).parent()[0];
var grid = $("#grid").data("kendoGrid");
var itemId = e.item.id;
var cellText = cell.innerText;
if (itemId === 'copyText') {
new Clipboard('#copyText', {
text: function (trigger) {
return cellText;
}
});
};
}
});
});
</script>
</body>
</html>
Here's a revised version of the above. You'll no longer need the clipboard.js. This will show/pop up the text (e.g. coffee) when you right click so that you can copy the 'ffee'.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2021.2.616/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/2021.2.616/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid"></div>
<ul id="context-menu">
<li id="copyText">
<input id="valueText"></input>
<span id="closeValueText" class="k-icon k-i-close"></span>
</li>
</ul>
<script>
$(document).ready(function() {
$("#grid").kendoGrid({
selectable: "multiple row",
allowCopy: true,
columns: [
{ field: "productName" },
{ field: "category" }
],
dataSource: [
{ productName: "Tea", category: "Beverages" },
{ productName: "Coffee", category: "Beverages" },
{ productName: "Ham", category: "Food" },
{ productName: "Bread", category: "Food" }
]
});
var closeContextMenu = false;
var contextMenu = $("#context-menu").kendoContextMenu({
target: "#grid",
filter: "td",
close: function(e) {
if (!closeContextMenu) {
e.preventDefault();
}
},
open: function(e) {
var cell = e.target;
var row = $(cell).parent()[0];
var grid = $("#grid").data("kendoGrid");
var itemId = e.item.id;
var cellText = cell.innerText;
$(e.item).find("#valueText").val(cellText);
closeContextMenu = false;
}
}).data("kendoContextMenu");
$("#closeValueText").on("click", function(e) {
closeContextMenu = true;
contextMenu.close();
});
});
</script>
</body>
</html>

how to hide a commands.Custom in kendo?

I am building a partial view, where I have to hide a button depending on a value from the main view, the columns hides them well, but when hiding the button it does not work.
I have the following function
function onSelect(e) {
gridEstudiantesShowHide(false);
if ($('input[name="hd_idServicio"]').val($("#ddlServicios").val()) != "") {
if ($("#ddlServicios").val().split("#")[4] === "0") {
var grid = $("#Grid").data("kendoGrid");
grid.hideColumn(4);
}
else {
var grid = $("#Grid").data("kendoGrid");
grid.showColumn(4);
}
if ($("#ddlServicios").val().split("#")[2] == "4" || $("#ddlServicios").val().split("#")[2] == "9") {
var grid = $("#Grid").data("kendoGrid");
grid.showColumn(5);
}
else {
var grid = $("#Grid").data("kendoGrid");
grid.hideColumn(5);
}
if ($("#ddlServicios").val().split("#")[3] == "1") {
var grid = $("#Grid").data("kendoGrid");
grid.hideColumn(3);
columns: [
{ field: "name" },
{ command: [{ name: "AsignarGrupo", visible: false}] }
]
}
else {
console.log("Muestra botón");
var grid = $("#Grid").data("kendoGrid");
grid.showColumn(3);
{ command: [{ name: "AsignarGrupo", visible: false}] }
}
}
else {
}
it only works when hiding columns, and I have read all the dojo documentation to no avail.
Someone could help me?
The property visible in the column's command expects a function which have to return a boolean, so you can do this in your column definition:
{ command: [{ name: "AsignarGrupo", visible: function(dataItem) { return $("\\#ddlServicios").val().split("\\#")[3] == "1"; } }] }
Demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2021.1.330/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/2021.1.330/js/kendo.all.min.js"></script>
</head>
<body>
<select id="ddlServicios">
<option value="1#1#1#1">Opt 1</option>
</select>
<div id="grid"></div>
<script>
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{ command: "destroy" }, // displays the built-in "destroy" command
{ command: [{ name: "test", visible: function(dataItem) { return $("\\#ddlServicios").val().split("\\#")[3] == "1"; } }] }
],
editable: true,
dataSource: [ { name: "Jane Doe" } ]
});
</script>
</body>
</html>
Dojo

Uncaught TypeError: showItems is not a function

I didn't know what had went wrong where i had defined the function but it still giving error.
var sampleData = [
{ id: 1, name: "name", items: ["foo", "bar"] }
];
var defaultColumns=[
{ field: "id" },
{ field: "name" },
{ field: "items", "template":kendo.template("#= showItems(items) #") }
];
$("#grid").kendoGrid({
dataSource: {data:sampleData},
columns:defaultColumns
});
function showItems(arr) {
return arr.join("</br>") ;
}
My sample code
Make sure that showItems is defined in the global JavaScript scope in your actual application. This is required for custom functions called from inside Kendo UI templates:
http://docs.telerik.com/kendo-ui/framework/templates/overview#handle-external-templates-and-expressions
var sampleData = [
{ id: 1, name: "name", items: ["foo", "bar"] }
];
var defaultColumns=[
{ field: "id" },
{ field: "name" },
{ field: "items", template: showItems }
];
$("#grid").kendoGrid({
dataSource: {data:sampleData},
columns:defaultColumns
});
function showItems(arr) {
return arr.items.join("</br>") ;
}
I was able to solve the solution by declaring the showItems in global and it perfectly fine.
function showItems(arr) {
return arr.join("</br>");
}
var sampleData = [{
id: 1,
name: "name",
items: ["foo", "bar"]
}];
var defaultColumns = [{
field: "id"
}, {
field: "name"
}, {
field: "items",
"template": kendo.template("#= showItems(items) #")
}];
$("#grid").kendoGrid({
dataSource: {
data: sampleData
},
columns: defaultColumns
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Kendo UI Grid</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.914/styles/kendo.common.min.css" />
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.914/styles/kendo.silver.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.3.914/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid"></div>
</body>
</html>

How to copy data of html formatted cell instead of markup

I have some cells in Handsontable, that are displayed using "html" renderer. When I copy these cells and paste them in Excel, I get html content instead of data. Is there a way to display cells as they are, and get their value when copying ?
JSFiddle example:
example
document.addEventListener("DOMContentLoaded", function() {
var
data = [
{
title: "Title 1",
description: "<div style='text-align:right'>148</div>"
},
{
title: "Title 2",
description: "<div style='text-align:right'>2002</div>"
}
],
container1,
hot1;
container1 = document.getElementById('example1');
hot1 = new Handsontable(container1, {
data: data,
colWidths: [200, 200],
colHeaders: ["Title", "Description"],
columns: [
{data: "title", renderer: "html"},
{data: "description", renderer: "html"}
]
});
});
You can try converting your input data into json format and have a custom renderer which displays the value from json. Add a toString property to the data which will return exactly what you want to get copied.
Here is an updated fiddle: http://jsfiddle.net/mpusarla/gng4wqzy/6/
document.addEventListener("DOMContentLoaded", function() {
var item1 = {};
item1.title = "Title 1 ";
item1.description = {};
item1.description.text = "Desc 1";
item1.description.toString = function() {
return 'Updated Desc for 1';
}
var item2 = {};
item2.title = "Title 2";
item2.description = {};
item2.description.text = "Desc 2";
item2.description.toString = function() {
return 'Updated Desc for 2 ';
}
var data = [];
data.push(item1);
data.push(item2);
var container1, hot1;
function customRenderer(instance, td, row, col, prop, value, cellProperties) {
td.innerHTML = '<div style="text-align:right">' + value.text;
}
container1 = document.getElementById('example1');
hot1 = new Handsontable(container1, {
data: data,
colWidths: [200, 200],
colHeaders: ["Title", "Description"],
columns: [{
data: "title",
renderer: "text"
}, {
data: "description",
renderer: customRenderer
}]
});
});
</style><!-- Ugly Hack due to jsFiddle issue --> <script src="http://docs.handsontable.com/0.15.0/scripts/jquery.min.js"></script> <script src="http://docs.handsontable.com/0.15.0/bower_components/handsontable/dist/handsontable.full.js"></script> <link type="text/css" rel="stylesheet" href="http://docs.handsontable.com/0.15.0/bower_components/handsontable/dist/handsontable.full.min.css">
<div id="example1" class="hot handsontable"></div>

Categories