I have a master-child setup and in my child grid rows, I have a multi-select that uses a list of strings as datasource. When I click to add/remove entries, the already selected items disappear completely and I can only see the drop down with all the values.
Here is the grid column definition in the child grid:
field: "Teams",
title: "Team",
editor: ChildItemEditor,
Here is the editor function that creates the multi-select:
...
var dataSource = ["Item A" , "Item B"];
...
function ChildItemEditor(container, options)
{
$('<select multiselect="multiselect" id="ddlItems" name="childItems" data-bind="value:' + options.field + '" />')
.appendTo(container)
.kendoMultiSelect({
autoBind: false,
dataSource: dataSource,
select: function (e) {
var dataItem = this.dataItem(e.item.index());
var selectedItem = this.gridMasterData.dataItem(this.gridMasterData.select());
if (selectedItem == null) {
return false;
}
options.model.Items = this.value();
$(selectedItem.Items).each(function (i, cItem) {
if (options.model.Id == cItem.Id) {
cItem.Items= options.model.Items;
selectedItem.dirty = true
}
});
},
});
}
Found the issue: When reading back data, the second field had a leading space and Multiselect did not automatically Trim the field to bind to it.
Related
I'm trying to customize my kendo multiselect control's group header. I have checked the documentation below,
https://demos.telerik.com/kendo-ui/multiselect/grouping
no matter how I change the groupTemplat, the group always display in top right. Please check my code below,
var checkInputs = function (elements) {
elements.each(function () {
var element = $(this);
var input = element.children("input");
input.prop("checked", element.hasClass("k-state-selected"));
});
};
function initData() {
$scope.dataOptions = {
dataSource: getDataSource(),
dataTextField: "value",
itemTemplate: "<input type='checkbox'/> #:data.value# ",
groupedTemplate: "<input type='checkbox'/> #:data#",
autoClose: false,
dataBound: function () {
var items = this.ul.find("li");
setTimeout(function () {
checkInputs(items);
});
},
change: function () {
var items = this.ul.find("li");
checkInputs(items);
}
}
}
I want to implement the multi-select dropdown like the Location option in this website.
When I checked the group, then all of the items in this group should be selected.
In this demo, if you click on the category, you'll see a dropdown list to choose the value. What I need is to have the values of the dropdown list depend on a condition, so when you open the dropdown list on different rows you may get different lists.
At the moment I create a row, I have the values to populate the dropdown list, but I'm not sure how to use these values.
This is how I defined the column (I won't be using a template):
{ field: "source", title: "Source", width: "180px", editor: srcEditor},
And this is the editor:
function srcEditor(container, options) {
$('<input required data-text-field="name" data-value-field="id"
data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
dataSource: sources,
dataTextField: "name",
dataValueField: "id"
});
}
This only works if all the rows have the same dropdown list, but how can I declare a different srcEditor for each row?
By this statement :
declare a different srcEditor for each row
You either mean to have
entirely different datasource for each row,
having same datasource but do some filter if certain condition meet, or
differ in styling (for this one simply add class/style)
Solution for number 1 modify your categoryDropDownEditor function, do some conditional to set the url for the datasource and add the different url :
function categoryDropDownEditor(container, options) {
var model = options.model;
var tempDataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: ( (model.UnitPrice > 20) ? urlConst.restServiceA : urlConst.restServiceB),
}
});
}
Solution for number 2 modify your categoryDropDownEditor function and add your condition and do (sor/filter) on parameter map, here's link :
function categoryDropDownEditor(container, options) {
var model = options.model;
var tempDataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Categories",
parameterMap: function (options, operation) {
console.log("test",operation,operation);
if (operation == "read" && options) {
//do your condition here
if(model.UnitPrice > 20){
tempDataSource.filter({field:"CategoryName", operator:"eq", value: "Condiments"});
}
return kendo.data.transports["odata"].parameterMap(options, operation);
}
}
},
});
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
I've added a custom icon using below code in jqgrid Actions column. When the cutom icon is clicked, a pop up is opened with Textarea, Save and Close buttons. When I click Save button I wanted to save the text entered in textarea to a hidden field column in jQgrid. I tried 'setRowData' and 'setCell' properties but nothing works. Am I missing something here?
afterInsertRow: function (rowid, rowdata, rowelem) {
$(this).triggerHandler("afterInsertRow.jqGrid", [rowid, rowdata, rowelem]);
//...//
//Start: Code for Notes Icon in Actions column
var iCol = getColumnIndexByName(grid, 'actions');
$(this).find(">tbody>tr#" + rowid + ">td:nth-child(" + (iCol + 1) + ")")
.each(function () {
$("<div>", {
title: "Custom",
mouseover: function () {
$(this).addClass('ui-state-hover');
},
mouseout: function () {
$(this).removeClass('ui-state-hover');
},
click: function (eve) {
$("#change_dialog").dialog({
buttons: {
'Save': function () {
var selRow = $(eve.target).closest("tr.jqgrow").attr("id");
var txtNotes = $("#mytext").val();
$("#gridJQ").setRowData(selRow, { 'notesHidden': txtNotes });
$("#gridJQ").jqGrid('setCell', selRow, 'notesHidden', txtNotes);
$("#gridJQ").jqGrid('setRowData', selRow, 'notesHidden', txtNotes);
$(this).dialog("close");
},
'Close':function() {
$(this).dialog("close");
}
}
});
return false;
}
}
).css({ "margin-right": "5px", float: "left", cursor: "pointer" })
.addClass("ui-pg-div ui-inline-custom")
.append('<span class="ui-icon ui-icon-document"></span>')
.prependTo($(this).children("div"));
});
Instead of using this code to get the row
var selRow = $(eve.target).closest("tr.jqgrow").attr("id");
Try something a more direct such as
var selRow = $("#gridJQ").jqGrid('getGridParam', 'selrow');
Or even just var selRow = rowid.
Does that help at all?
I have created columns dynamically in the kendo ui grid. The data displayed in the columns could be date , string integer, hyperlinks or any other type.
Data in the column can be integer/hyperlink at the same time. Means for a particular record the data in column can be integer. For next record same column can have a hyperlink value.
I have created fields and added that in the grid.
How can I do this.
You can always set a function against the template of the column you wish to format and conditionally return the content of what you want to appear.
This could look something like this:
var dataSource = new kendo.data.DataSource({
data: [
{ Id:1, val: "value" },
{ Id:"http://google.com", val: "another value" }
]
});
$(function () {
$("#grid").kendoGrid({
columns: [
{
field: "Id",
template: function (dataItem) {
if (typeof dataItem.Id == "string") {
return "" + dataItem.Id + "";
} else {
return dataItem.Id;
}
}
}],
dataSource: dataSource
});
});