Related
I use kendo grid and want to show kendo tooltip for icon in header cells.
I have the following code:
<div id="grid"></div>
<script>
$(document).ready(function () {
var grid = $("#grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: {
url: "#Html.Raw(Url.Action("List", "i3screenResult"))",
type: "POST",
dataType: "json",
data: function () {
var data = {
};
addAntiForgeryToken(data);
return data;
}
}
},
schema: {
data: "Data",
total: "Total",
errors: "Errors"
},
},
dataBinding: function (e) {
$('.questionmark').on("hover", function () {
var tooltip = $(this).kendoTooltip({
content: $(this).attr('tooltip'),
width: 120,
position: "top",
animation: {
open: {
effects: "zoom",
duration: 150
}
}
}).data("kendoTooltip");
});
},
scrollable: false,
columns: [
{
field: "BackgroundReportAccount",
headerTemplate: "#T("DrugConsortium.i3screen.Fields.BackgroundReportAccount") <img src='/images/question-mark-icon.png' class='questionmark' tooltip='#T("DrugConsortium.i3screen.Fields.BackgroundReportAccount.Details")' />",
width: 150
},
{
field: "ProviderReferenceId",
headerTemplate: "#T("DrugConsortium.i3screen.Fields.ProviderReferenceId") <img src='/images/question-mark-icon.png' class='questionmark' tooltip='#T("DrugConsortium.i3screen.Fields.ProviderReferenceId.Details")' />",
width: 150
},
//....
]
});
});
</script>
It works, but only since second hover event for img.
Why so and how to fix?
Try this AFTER grid initialization:
$('#grid').kendoTooltip({
content: function(e) {
return $(e.target).attr('tooltip');
},
filter: 'img.questionmark',
width: 120,
position: "top",
animation: {
open: {
effects: "zoom",
duration: 150
}
}
});
Also, you should change the attribute name from tooltip to data-tooltip since tooltip is not a standard HTML attribute. Then you can get it's value with $(e.target).data('tooltip');
Demo
Currently free-jqgrid has feature that supports multiselect toolbar, same feature i want to create in jqgrid also.
http://www.ok-soft-gmbh.com/jqGrid/OK/MultiselectIn.htm
More recent code of usage multiselect with free jqGrid can be seen on the demo https://jsfiddle.net/OlegKi/ty4e68pm/16/. The most important parts of the demo I include below:
var dataInitMultiselect = function (elem, searchOptions) {
var $grid = $(this);
setTimeout(function() {
var $elem = $(elem),
id = elem.id,
inToolbar = searchOptions.mode === "filter",
options = {
selectedList: 2,
height: "auto",
checkAllText: "all",
uncheckAllText: "no",
noneSelectedText: "Any",
open: function() {
var $menu = $(".ui-multiselect-menu:visible");
$menu.width("auto");
$menu.css({
width: "auto",
height: "auto"
});
$menu.children("ul").css({
maxHeight: "300px",
overflow: "auto"
});
}
},
$options = $elem.find("option");
if ($options.length > 0 && $options[0].selected) {
$options[0].selected = false; // unselect the first selected option
}
if (inToolbar) {
options.minWidth = "auto";
}
$grid.triggerHandler("jqGridRefreshFilterValues");
$elem.multiselect(options);
// replace icons ui-icon-check, ui-icon-closethick, ui-icon-circle-close
// and ui-icon-triangle-1-s to font awesome icons
var $header = $elem.data("echMultiselect").header;
$header.find("span.ui-icon.ui-icon-check")
.removeClass("ui-icon ui-icon-check")
.addClass("fa fa-fw fa-check");
$header.find("span.ui-icon.ui-icon-closethick")
.removeClass("ui-icon ui-icon-closethick")
.addClass("fa fa-fw fa-times");
$header.find("span.ui-icon.ui-icon-circle-close")
.removeClass("ui-icon ui-icon-circle-close")
.addClass("fa fa-times-circle");
$elem.data("echMultiselect")
.button
.find("span.ui-icon.ui-icon-triangle-1-s")
.removeClass("ui-icon ui-icon-triangle-1-s")
.addClass("fa fa-caret-down")
.css({
float: "right",
marginRight: "5px"
});
}, 50);
},
multiselectTemplate = {
stype: "select",
searchoptions: {
generateValue: true,
//noFilterText: "Any",
sopt: ["in"],
attr: {
multiple: "multiple",
size: 3
},
dataInit: dataInitMultiselect
}
};
declares multiselectTemplate template. The next code fragment uses the template in colModel
colModel: [
...
{
name: "ship_via", width: 85, align: "center",
template: multiselectTemplate
},
...
],
Finally loadComplete include the code, which create filter toolbar after the data are loaded from the server:
loadComplete: function () {
if (!this.ftoolbar) {
// create filter toolbar if it isn't exist
$(this).jqGrid("filterToolbar", {
defaultSearch: "cn",
beforeClear: function() {
$(this.grid.hDiv)
.find(".ui-search-toolbar button.ui-multiselect")
.each(function() {
$(this).prev("select[multiple]").multiselect("refresh");
});
}
});
$(this).triggerHandler("jqGridRefreshFilterValues");
$(this.grid.hDiv)
.find(".ui-search-toolbar button.ui-multiselect")
.each(function() {
$(this).prev("select[multiple]")
.multiselect("refresh");
});
}
},
If required one can reload the data in filter toolbar by destroying it by destroyFilterToolbar method and executing the same code fragment which create it once more (I mean above code inside of loadComplete).
I have the following project. There you can click on the individual checkboxes and the ID is written (see Console).
Then I have tested the ServerPaging. This works in another project (there are no checkboxes). If I change the above project to ServerPaging, I can click on the checkbox, but it reloads the DataSource. What can I do here?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Grid with checkboxes</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.911/styles/kendo.bootstrap-v4.min.css" />
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.3.911/js/kendo.all.min.js"></script>
<script src="https://demos.telerik.com/kendo-ui/content/shared/js/console.js"></script>
</head>
<body>
<style>
html {
font-size: 14px;
font-family: Arial, Helvetica, sans-serif;
}
label {
float: left;
line-height: 1;
}
[role='gridcell'] {
box-shadow: none !important;
}
.checkColumnCenter {
text-align: center;
width: 20px;
}
.fieldlist {
margin: 0 0 -1em;
padding: 0;
}
.fieldlist li {
list-style: none;
padding-bottom: 1em;
}
</style>
<div id="example">
<div id="grid"></div>
</div>
<script>
$(document).ready(function() {
var MainArray = [];
var subArray = [];
var selectedItems = [];
var pageNum;
var initialLength = 0;
var confirmedArray = [];
var crudServiceBaseUrl = "https://demos.telerik.com/kendo-ui/service",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Products",
dataType: "jsonp"
},
update: {
url: "https://demos.telerik.com/kendo-ui/service/products/update",
dataType: "jsonp"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
return kendo.data.transports["odata"].parameterMap(options, operation);
}
},
pageSize: 10,
type: "odata",
batch: true,
serverPaging: false,
serverSorting: false,
/*serverPaging: true,
serverFiltering: true,
serverSorting: true,
batch: true,*/
schema: {
model: {
id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
ProductName: { validation: { required: true } },
UnitPrice: { type: "number", validation: { required: true, min: 1 } },
Discontinued: { type: "boolean" },
UnitsInStock: { type: "number", validation: { min: 0, required: true } }
}
},
data: function (response) {
return response.d ? response.d.results: response;
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
height: 350,
navigatable: true,
pageable: true,
sortable: true,
persistSelection: true,
filterable: {
extra: false,
mode: 'row',
operators: {
string: {
contains: "Contains",
startswith: "Starts with",
eq: "Equal",
neq: "Not equal"
}
},
messages: {
isTrue: "checked",
isFalse: "selectable"
}
},
resizable: true,
columns: [{
field: "Discontinued",
width: 150,
template: "<input type='checkbox' onclick='checkOne()' data-bind='checked:Discontinued' />",
headerTemplate: "<input id='checkAll' type='checkbox' onclick='checkAll(this)'/><span id='checkAllPtext'></span>",
attributes: {
"class": "checkColumnCenter",
style: "color:\\#0c0"
}
},
{
field: "ProductName",
title: "Product",
width: 150
},
{
field: "UnitPrice",
title: "Unit",
width: 120
},
{
field: "UnitsInStock",
title: "Costplace",
width: 120
},
],
dataBound: function(e) {
if(this.dataSource.filter()){
$('#checkAll').show();
$('#checkAllPtext').show().html("All");
} else {
$('#checkAll').hide();
$('#checkAllPtext').hide();
}
selectedItems = [];
var selectedItemsPage = [];
e.sender.items().each(function() {
var dataItem = e.sender.dataItem(this);
kendo.bind(this, dataItem);
if (dataItem.Discontinued) {
var grid = $("#grid").data("kendoGrid");
var dataItem = grid.dataItem(this);
selectedItemsPage.push(dataItem);
$(this).addClass("k-state-selected");
}
});
if (pageNum == e.sender.dataSource._page) {
// kendoConsole.log('initialLength', initialLength)
if (initialLength !== 0) {
// MainArray.splice(-initialLength);
// kendoConsole.log('subArray', MainArray.indexOf(subArray[0]))
subArray.forEach(function(item, i) {
MainArray.splice(MainArray.indexOf(item), 1);
});
}
if (selectedItemsPage.length > 0) {
selectedItems = selectedItemsPage;
}
subArray = selectedItemsPage;
initialLength = selectedItems.length;
} else {
selectedItemsPage.forEach(function(item) {
if (MainArray.indexOf(item) > -1) {
MainArray.splice(MainArray.indexOf(item), 1);
}
});
pageNum = e.sender.dataSource._page;
if (selectedItemsPage.length > 0) {
selectedItems = selectedItemsPage;
}
subArray = selectedItemsPage;
initialLength = selectedItems.length;
}
MainArray = MainArray.concat(selectedItems);
// kendoConsole.log(MainArray);
$("#checkAll")[0].checked = e.sender.items().find(":checked").length == e.sender.dataSource.view().length;
}
});
setTimeout(function() {
getMarked();
}, 500);
getMarked = function() {
dataSource.fetch(function() {
confirmedArray = dataSource._data.filter(function(item) {
return item.Discontinued;
})
var confirmedIDs = confirmedArray.map(function(item) {
return item.ProductID;
});
kendoConsole.log(JSON.stringify("Selected ID's: " + confirmedIDs));
})
}
// setTimeout(function () {
// getMarked();
// }, 200);
});
var getMarked;
function checkOne() {
setTimeout(function() {
getMarked();
}, 100);
}
function checkAll(input) {
var grid = $("#grid").data("kendoGrid");
var items = grid.items();
items.each(function() {
var dataItem = grid.dataItem(this);
if (dataItem.Discontinued != input.checked) {
dataItem.Discontinued = input.checked;
dataItem.dirty = true;
}
})
grid.dataSource.sync();
setTimeout(function() {
getMarked();
}, 100);
}
</script>
<div class="box wide">
<h4>Console log</h4>
<div class="console"></div>
</div>
<style>
.console div {
height: 6em;
}
</style>
</body>
</html>
I helped it with a simple check array.length > 0
getMarked = function() {
if (array.length > 0) {
// foo nothing
}
dataSource.fetch(function() {
confirmedArray = dataSource._data.filter(function(item) {
return item.Discontinued;
})
var confirmedIDs = confirmedArray.map(function(item) {
return item.ProductID;
});
})
}
The problem was that the grid was reloaded every time after an action. Since the changes in the grid have not been saved yet, he has discarded the changes each time. Is a good workaround for me.
I am using two kendo inline grid parent and child. child grid contains the list of products,when user select the products(multiple selection) from child grid and clicked to save button,it's inserted into an parent grid.
Child grid:
var selectedIds = {};
var ctlGrid = $("#KendoWebDataGrid3");
ctlGrid.kendoGrid({
dataSource: {
data:data1,
schema: {
model: {
id: 'id',
fields: {
select: {
type: "string",
editable: false
},
Qty: {
editable: true,
type: "number",
validation: { min: 1, required: true }
},
Unit: {
editable: false,
type: "string"
},
StyleNumber: {
editable: false,
type: "string"
},
Description: {
editable: false,
type: "string"
}
}
}
},
pageSize: 5
},
editable: 'inline',
selectable: "multiple",
sortable: {
mode: 'single',
allowUnsort: false
},
pageable: true,
columns: [{
field: "select",
title: " ",
template: '<input type=\'checkbox\' />',
sortable: false,
width: 35},
{
title: 'Qty',
field: "Qty",
width:90},
{
field: 'Unit',
title: 'Unit',
width: 80},
{
field: 'StyleNumber',
title: 'Style Number',
},
{
field: 'Description',
width: 230},
{command: [<!---{text:"Select" ,class : "k-button",click: selectProduct},--->"edit" ], title: "Command", width: 100 }
],
dataBound: function() {
var grid = this;
//handle checkbox change
grid.table.find("tr").find("td:first input")
.change(function(e) {
var checkbox = $(this);
var selected = grid.table.find("tr").find("td:first input:checked").closest("tr");
grid.clearSelection();
//persist selection per page
var ids = selectedIds[grid.dataSource.page()] = [];
if (selected.length) {
grid.select(selected);
selected.each(function(idx, item) {
ids.push($(item).data("id"));
});
}
})
.end()
.mousedown(function(e) {
e.stopPropagation();
})
//select persisted rows
var selected = $();
var ids = selectedIds[grid.dataSource.page()] || [];
for (var idx = 0, length = ids.length; idx < length; idx++) {
selected = selected.add(grid.table.find("tr[data-id=" + ids[idx] + "]") );
}
selected
.find("td:first input")
.attr("checked", true)
.trigger("change");
}
});
var grid = ctlGrid.data("kendoGrid");
grid.thead.find("th:first")
.append($('<input class="selectAll" type="checkbox"/>'))
.delegate(".selectAll", "click", function() {
var checkbox = $(this);
grid.table.find("tr")
.find("td:first input")
.attr("checked", checkbox.is(":checked"))
.trigger("change");
});
save button clicked Event
function selectProduct()
{
//Selecting child Grid
var gview = $("#KendoWebDataGrid3").data("kendoGrid");
//Getting selected rows
var rows = gview.select();
//Selecting parent Grid
var parentdatasource=$("#grid11").data("kendoGrid").dataSource;
var parentData=parentdatasource.data();
//Iterate through all selected rows
rows.each(function (index, row)
{
var selectedItem = gview.dataItem(row);
var selItemJson={id: ''+selectedItem.id+'', Qty:''+selectedItem.Qty+'',Unit:''+selectedItem.Unit+'',StyleNumber:''+selectedItem.StyleNumber+'',Description:''+selectedItem.Description+''};
//parentdatasource.insert(selItemJson);
var productsGrid = $('#grid11').data('kendoGrid');
var dataSource = productsGrid.dataSource;
dataSource.add(selItemJson);
dataSource.sync();
});
closeWindow();
}
Parent Grid:
var data1=[];
$("#grid11").kendoGrid({
dataSource: {
data:data1,
schema: {
model: { id: "id" ,
fields: {
Qty: { validation: { required: true } },
Unit: { validation: { required: true } },
StyleNumber: { validation: { required: true } },
Description: { validation: { required: true } }
}
}
},
pageSize: 5
},
pageable: true,
height: 260,
sortable: true,
toolbar: [{name:"create",text:"Add"}],
editable: "inline",
columns: [
{field: "Qty"},
{field: "Unit"},
{field: "StyleNumber"},
{field: "Description"},
{ command: ["edit", "destroy"], title: " ", width: "172px" }]
});
$('#grid11').data().kendoGrid.bind("change", function(e) {
$('#grid11').data().kendoGrid.refresh();
});
$('#grid11').data().kendoGrid.bind('edit',function(e){
if(e.model.isNew()){
e.container.find('.k-grid-update').click(function(){
$('#grid11').data().kendoGrid.refresh();
}),
e.container.find('.k-grid-cancel').click(function(){
$('#grid11').data().kendoGrid.refresh();
})
}
})
Adding data into parent grid work nicely,no issue,but when i select the parent grid add new row to edit then trigger the cancel button row was deleted.
I am not able to figure out the problem.please help me.
I found the error, hope can help you.
If you did not config the dataSource: schema: model's "id" field, when click edit in another row before update or click cancel, it will delete the row.
var dataSource = new kendo.data.DataSource({
...
schema: {
model: {
id:"id", // Look here, if you did not config it, issue will happen
fields: {...
...}
}
}
...
})
I have the same issue, and I config cancel like :
...
cancel: function(e) {
this.refresh();
},
...
I don't think it's the best way, but it's working.
Hope another people can give us a better way.
after saving I call $('#grid').data('kendoGrid').dataSource.read();
that cancels the edit row and reads any changes.
Still doesn't seem to be fixed.
I'm addressing it with 'preventDefault()'. This may require explicit closing of window as a consequence.
cancel: function (e) {
// Not sure why this is needed but otherwise removes row...
e.preventDefault();
e.container.data("kendoWindow").close();
},
schema: {
model: { id: "StyleNumber" // "Any ID Field from the Fields list" ,
fields: {
Qty: { validation: { required: true } },
Unit: { validation: { required: true } },
StyleNumber: { validation: { required: true } },
Description: { validation: { required: true } }
}
}
}
This will solve your problem.
I am using a Kendo UI grid, which looks like this:
function refreshGrid()
{
$(".k-pager-refresh.k-link").click();
}
var editWindow;
var fields= {FullName: {type: "string"}, Email: {type: "string"}, LogCreateDate: {type: "date"}};
var gridColumns =
[{
width: 90,
command: {
name: "edit",
text: "Edit",
click: function(e) {
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
editWindow = $("#edit").kendoWindow({
title: "Edit User",
modal: true,
visible: false,
resizable: false,
width: 800,
height: 400,
content: 'myediturl' + dataItem.ID
});
editWindow.data("kendoWindow").center().open();
return false;
}
}
},
{
width: 90,
command: {
name: "delete",
text: "Delete",
click: function(e) {
//alert(this.dataItem($(e.currentTarget).closest("tr")).ID);
var id = this.dataItem($(e.currentTarget).closest("tr")).ID;
if (confirm("Are you sure you want to delete this user?"))
{
$.ajax({
type: 'POST',
url: '#Url.Action("deleteuser","admin",null, "http")' + "/" + this.dataItem($(e.currentTarget).closest("tr")).ID,
success: function (param) { refreshGrid(); },
async: false
});
}
return false;
}
}
},
{
field: "FullName",
title: "Full Name",
type: "string"
},
{
field: "Email",
title: "Email",
type: "string"
},
{
field: "LogCreateDate",
title: "Created",
type: "date",
template: '#= kendo.toString(LogCreateDate,"MM/dd/yyyy") #'
}];
//getSorts the columns of the grid
function getColumns() {
//Parsing the set of columns into a more digestable form
var columns = "";
for (var col in gridColumns) {
if (!!gridColumns[col].field)
{
if (columns.length > 0) {
columns += ";";
}
columns += gridColumns[col].field + "," + gridColumns[col].type;
}
}
return columns;
}
function getSorts(sortObject) {
if (!(sortObject)) {
return "";
}
//Getting the row sort object
var arr = sortObject;
if ((arr) && (arr.length == 0)) {
return "";
}
//Parsing the sort object into a more digestable form
var columnSet = getColumns();
var returnValue = "";
for (var index in arr) {
var type = "";
for (var col in gridColumns) {
if (gridColumns[col].field === arr[index].field) {
type = gridColumns[col].type;
}
}
returnValue += ((returnValue.length > 0) ? (";") : ("")) + arr[index].field + "," + (arr[index].dir === "asc") + "," + type;
}
return returnValue;
}
var grid;
$(function () {
$("#grid").kendoGrid({
dataSource: {
transport: {
read: {
url: "mydatasourceurl",
type: "POST",
},
parameterMap: function (data, type) {
data.filters = JSON.stringify(data.filter);
data.columns = JSON.stringify(getColumns());
data.sorts = JSON.stringify(getSorts(data.sort));
console.log(data);
return data;
}
},
schema: {
fields: fields,
data: "Data",
total: "Total"
},
pageSize: 10,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
toolbar: [{
name: "Add",
text: "Add new record",
click: function(e){console.log("foo"); return false;}
}],
height: 392,
groupable: false,
sortable: true,
filterable: true,
pageable: {
refresh: true,
pageSizes: true
},
columns: gridColumns
});
grid = $("#grid").data("kendoGrid");
});
My create toolbar action is not triggered on click. How can I resolve this problem, is Kendo UI able to handle toolbar click events? The best solution I came up with looks like this:
$(".k-button.k-button-icontext.k-grid-add").click(function () {
//If the window doesn't exist yet, we create and initialize it
if (!grids[gridContainerID].addWindow.data("kendoWindow")) {
grids[gridContainerID].addWindow.kendoWindow({
title: "Add " + entityName,
width: "60%",
height: "60%",
close: onClose,
open: onAddOpen,
content: addUrl
});
}
//Otherwise we just open it
else {
grids[gridContainerID].addWindow.data("kendoWindow").open();
}
//Centralizing and refreshing to prepare the layout
grids[gridContainerID].addWindow.data("kendoWindow").center();
grids[gridContainerID].addWindow.data("kendoWindow").refresh();
return false;
});
Thanks in advance.
Instead of using that complex selector use the one that Kendo UI creates from name:
toolbar: [
{
name: "Add",
text: "Add new record",
click: function(e){console.log("foo"); return false;}
}
],
and then:
$(".k-grid-Add", "#grid").bind("click", function (ev) {
// your code
alert("Hello");
});
In kendogrid docs here shows that there is no click configuration for grid toolbar buttons like grid.colums.commands.
To solve this problem you can reference following steps:
create a template for toolbar
<script id="grid_toolbar" type="text/x-kendo-template">
<button class="k-button" id="grid_toolbar_queryBtn">Query</button>
</script>
apply tempate to toolbar
toolbar:[{text:"",template: kendo.template($("#grid_toolbar").html())}]
add event listener to button
$("#grid_toolbar_queryBtn").click(function(e) {
console.log("[DEBUG MESSAGE] ", "query button clicked!");
});