I'm using a DropDownList for a field that I'm editing in a Kendo UI grid popup, and though validation tooltips show up without problems, they don't disappear once the input has been corrected.
I'm creating the DropDownList like this:
function serviceDropDownEditor(container, options) {
$('<input data-bind="value:' + options.field + '" data-for="' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
optionLabel: "--- select a service ---",
dataTextField: "name",
dataValueField: "id",
dataSource: window.services, // an array I've already fetched from my DB
});
}
I apply this function to the field service_id when I define the data source, like this:
columns: [
{ field: "service_id",
title: "Service",
editor: serviceDropDownEditor,
template: "#= getServiceName(service_id) #" // display the name from the id
},
To make sure there's a place to put the validation message, I use the suggestion on this page and append a placeholder span below the DropDownList during the edit event:
edit: function(e) {
var grid = $("#grid").data("kendoGrid")
var container = grid.editable.element
var service_container= container.find("[data-container-for=service_id]")
service_container.append('<span class="k-invalid-msg", data-for="#= field #">')
},
When there's a server-side error that refers to this field (service_id), I find the placeholder that I created in the edit event and replace it with the actual message, like this:
var placeholder = container.find("[data-for=" + field + "].k-invalid-msg")
placeholder .replaceWith(validationMessageTmpl({ field: field, message: errors[field] }))
The validation message template contains the same classes and data-for attribute as the placeholder.
It works great when displaying an error for the DropDownList, but when I correct the error (and introduce another one on the same form, so the popup stays up), the original error doesn't disappear.
So... how do validation tooltips get cleared, and what do I need to do? Clear this one manually in an event?
Try to manually clear errors on drop down change eg:
function serviceDropDownEditor(container, options) {
$('<input data-bind="value:' + options.field + '" data-for="' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
optionLabel: "--- select a service ---",
dataTextField: "name",
dataValueField: "id",
dataSource: window.services, // an array I've already fetched from my DB
select: function (ev) {
var validatable = container.editable.validatable;
if (validatable) {
var dataItem = this.dataItem(ev.item.index());
if (dataItem === null || dataItem === undefined || dataItem.text == " " || dataItem.text == " ") {
// force validation is empty (simulate required)
validatable.validate();
} else {
// hide all error messages if not empty
validatable.hideMessages();
}
}
}
});
}
Related
I have setup a Kendo Grid with a column which contains a ComboBox editor template assigned. This works well and retrieves the items I am expecting:
columnSchema.push({ field: "Comment", title: 'Comment', editor: commentDropDownEditor, template: "#=Comment.Description#" });
Produces the following:
My issue is that I am now trying to extend the properties of the 'Comment' column so that users can enter new items i.e. comments that will, in turn, be saved to the database for reuse.
So far, I have done the following...
Setup the commentDropDownEditor function:
function commentDropDownEditor(container, options) {
$('<input name="' + options.field + '"/>')
.appendTo(container)
.kendoComboBox({
suggest: true,
change: onComboBoxChange,
autoBind: false,
optionLabel: "Select comment...",
dataTextField: "Description",
dataValueField: "ID",
dataSource: {
type: "json",
autoSync: true,
transport: {
read: "CommentsAsync_Read",
create: {
url: "CommentsAsync_Create",
dataType: "json"
}
}
}
});
$('<span class="k-invalid-msg" data-for="' + options.field + '"></span>').appendTo(container);
}
Hooked up the change event to the following function:
function onComboBoxChange(e) {
var combo = e.sender;
// check if new value is a custom one
if (!combo.dataItem()) {
// select the newly created dataItem after the data service response is received
combo.one("dataBound", function () {
combo.text(combo.text());
});
// create a new dataItem. It will be submitted automatically to the remote service (autoSync is true)
combo.dataSource.add({ Description: combo.text() });
}
}
I can see the onComboBoxChange function being hit through the Console Window (including the line where the new item is being added to the combo box datasource) but the associated Create transport function is not being executed nor is the item being added to the Combo Box.
Create function in the Controller is as follows:
[HttpPost]
public async Task<ActionResult> CommentsAsync_Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<Comment> comments)
{
if (comments.Any())
{
//await _manager.CreateCommentAsync(comments);
}
return Json(comments.ToDataSourceResult(request, ModelState));
}
Is there something I am missing/doing wrong here to get this to work?
I have a Kendo Grid where I am filtering one of the columns with a MultiSelect control. When I click the "Filter" button it sends [object Object] to the server as the filter value. How can I fix it so it sends the values of the selected item(s). Note, I am server filtering the grid not the multi select control.
Initialization of the multiselect
var regionddl = element.kendoMultiSelect({
dataTextField: "Value",
dataValueField: "Value",
optionLabel: "Select One...",
dataSource: {
transport: {
read: {
data: "",
dataFilter: function (data) {
var msg = eval('(' + data + ')');
if (msg.hasOwnProperty('d'))
return msg.d;
else
return msg;
},
contentType: "application/json; charset=utf-8",
type: "POST",
url: "SearchSites.aspx/GetRegions"
}
}
}
}).data("kendoMultiSelect");
Here is the JSON that Kendo is sending to the server. Notice there are two object Object items because I selected two items in the filter.
[{\\\"field\\\":\\\"Region\\\",\\\"operator\\\":\\\"eq\\\",\\\"value\\\":\\\"[object Object],[object Object]\\\"}]
If you want to see an example of what multiselect filtering looks like in a grid, you can see this jsbin
http://jsbin.com/upEPEqU/3/edit
To change this you need to set the valuePrimitive option to true.
I want to have multiple datatextField column as im returning a custom List which returns me list with property Name,Status and PID, but i can't use multiple columns on my DatatextField i-e Name and Status so that i can use them for my template property shown below,
Name and Status column is necessary for my template and PID is necessary for my datavalueField
it shows me error for Status is undefined
<script>
$(document).ready(function () {
$("#prog").kendoDropDownList({
dataTextField: "Name",
dataValueField: "PID",
optionLabel: "...select programme...",
headerTemplate: '<div class="dropdown-header">' +
'<span class="k-widget k-header">status</span>' +
'<span class="k-widget k-header">Name</span>' +
'</div>',
valueTemplate: '<span class="selected-value">#: Name#</span>',
template: '<span class="k-state-default">#: Status#</span>' +
'<span class="k-state-default"><h3>#: Name#</h3></span>',
dataSource: {
transport: {
read: {
dataType: "json",
url: "#Url.Action("GetProgrammesInfo", "Programme", new { ECID = ViewBag.ECID as int? })"
}
}
},
change: function (e) {
var value = this.value();
alert(value);
}
});
var dropdownlist = $("#prog").data("kendoDropDownList");
});
</script>
I think to reference a property inside the template that isn't the textfield or valuefield, you will need to use data.Status.
If I switch to that, it seems to work. Also if I switch the dataTextField to Status, I get the error on the Name, and if I change the Name to data.Name, it works again.
Somewhat working sample... http://jsbin.com/xemef/1/edit
I am binding the Combobox to a complex Object, the binding is such that ID field is available as a direct property on this object but the Text Property is coming from a child objects property.
I have been able to configure it show the values correctly, but running into problem to specify the optionLabel saying "select" not able to specify Parent.Childproperty getting runtime error (Uncaught TypeError: Cannot read property 'Childproperty' of undefined )
How can i specify Complex Objects in the Model defination and below for the empty selection ?
$('<input id="DegreeDDL" name="' + options.field + '"/>').appendTo(container).kendoDropDownList({
autoBind: true,
serverFiltering: true,
optionLabel: {
'Parent.Childproperty': "--- Select ---",
ABCD_PK: null
},
dataSource: {
transport: {
read: {
url: function (e) {
return "api/Org/XXXXXXXX?abcdPK=" + efgh;
},
dataType: "json" // <-- The default was "jsonp"
}
},
},
dataTextField: "Parent.ChildProperty",
dataValueField: "ABCD_PK"
});
Also running into similar propblem when defining model for the grid
var model = {
id: "ABCD_PK",
fields: {
Parent.Child.ChilProperty:
}
}
To answer your first question: use optionLabel as string if creating object here causes errors:
optionLabel: "--- Select ---",
Here is working JSFiddle: http://jsfiddle.net/a6Ek2/11/
To answer your second question just use dataSource.schema to parse your json for non complex object. More in this topic: How can I use nested Json to populate Kendo UI grid?. Grid official do not working with complex data objects. But if you wanna give a try you delclare only parent object in model eg:
fields: {
ABCD_PK: { editable: false },
Parent: { editable: true },
}
If you still got problem with this just update this JSFiddle and show exacly where this is. I'll try improve my answers then.
I am using jqGrid with ASP.NET MVC 3 and Razor.
I am looking to add 2 columns to the jqGrid along with the rest of the columns.
The columns I want to add are
Edit
Delete
These columns value I want to be ActionLink.
How do I add an ActionLink to a Column of a JqGrid ?
Please guide me on this.
Update 1: with help from #user1534482 I tried this but did not work
colModel: [
...
{ name: 'Open', formatter: 'prepareLinks' },
...
],
function prepareLinks(cellvalue, options, rowObject) {
return "#Html.ActionLink("Open this","Test")";
}
javascript error message :
SyntaxError: missing ; before statement
[Break On This Error]
return "Open this";
SomeController (line 92, col 41)
You should take a look at showlink predefined formatter.
There is no code in your question so I don't know how complex your scenario is, but in general code like this should be enough:
<script type="text/javascript">
jQuery("#gridId").jqGrid({
colNames: [..., 'Edit', 'Delete'],
colModel: [
...
{name:'EditAction', formatter:'showlink', formatoptions: { baseLinkUrl: '#Url.Action("Edit")' } },
{name:'DeleteAction', formatter:'showlink', formatoptions: { baseLinkUrl: '#Url.Action("Delete")' } }
],
...
});
</script>
The row id will be added automatically (you can control how with idName option). If you need to pass some additional parameters take a look at addParam option in the documentation.
UPDATE
For clarification on how the final link is generated, you can use this formula:
"<a " + ((op.target) ? "target=" + op.target : "") + " href=\"" + op.baseLinkUrl + op.showAction + "?" + op.idName + "=" + rowId + op.addParam + "\">" + cellvalue + "</a>"
Where op is the formatoptions object and cellvalue is the value for the column from data you have pasted to the jqGrid.
u can use ur own formater like
colModel: [
{ name: 'colname', formatter: linkbuilder },
],
and
and add function
function linkbuilder(cellval, opts, rwdat, _act) {
return "#Htm.ActionLink()";
}
Thanks to #tpeczek and #user1534482
I finally got the solution,
colModel: [
...
{ name: 'Open',
formatter: function (cellvalue, options, rowObject) {
return '' + "Open" + '';
}
},
...
],