Someone pointed me to Kendo Bind to Data Table, which has this code in the grid builder:
.Columns(columns =>
{
foreach (System.Data.DataColumn column in Model.Columns)
{
columns.Bound(column.ColumnName);
}
})
This works, but I also want to add an "edit" column, so I added this line before the foreach:
columns.Command(command => command.Edit().Text("Edit").UpdateText("Submit")).Width(70).HtmlAttributes(new { style = "text-align: right;" });
which throws "Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions."
How can I add an Edit column?
As it turns out, "How can I add an Edit column?" is the wrong question. There is nothing wrong with the code to add the Edit command; however, adding it surfaced the problem that was reported. In other words, the "Template" in the error message is the Edit template which doesn't know what column in the DataTable to use for its Id.
When defining the DataSource for the grid, I had this code:
.Model(model =>
{
foreach (System.Data.DataColumn column in Model.Columns)
{
model.Field(column.ColumnName, column.DataType);
}
})
as defined in a sample in a Telerik support forum. This was OK for simply displaying the data in a grid, but when I introduced the idea of Editing, it then mattered that there was no Model.Id. The question then became, how do I define an Id when the Model is a DataTable. That is a separate question, which I have posted here.
Related
I want to add a change event to all cells in a specified column using Kendo UI. Something like:
this.myGridVariable.table.on("change", "--InsertMyColumnNameHere--", (e) => { this.doStuff(e) });
I thought this worked:
this.myGridVariable.table.on("change", "[name=ColumnName]", (e) => { this.doStuff(e) });
but it doesn't, at least not with the latest update.
You need to specify what change event you mean:
The HTMLElement change event in JavaScript, which is fired for <input>, <select>, and <textarea>, but not a table cell, see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event
The Kendo Model or DataSource change event documented here: https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/events/change
I believe you'll want the second one. You can't bind it to a single field, but it has e.field and you can execute code depending on its value.
add .Events(e => { e.Change("onEdit"); }) under .DataSource(dataSource => dataSource
onEdit is a javascript function. In this function add this code -->
function onEdit(e) { if (e.action == "itemchange") { doStuff } }
I don't really know how to achieve my requirement which is:
Allowing users to user sorting/filtering on complete dataset
Server Side intially default filter
So basically I want to set the client filter control to a server side defined value. After page load the user could overwrite this setting and retrieve a list of the complete data set.
I am using following Grid:
#(Html.Kendo().Grid<SubscriptionViewModel>()
.DataSource(dataSource => dataSource
...
.ServerOperation(true)
)
.Name("subscriptionsGrid")
.Columns(columns =>
{
...
columns.Bound(p => p.SubscriptionValidStatus).Filterable(filterable=>filterable.UI("subscriptionStatusFilter")).HeaderHtmlAttributes(new { style = "white-space: normal; vertical-align: top" });
....
})
.Scrollable(a => a.Height("700px"))
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Single)
)
...
.Sortable()
.Filterable(filterable => filterable
.Extra(false)
)
)
thx for your possible solution Dinglemeyer
I just figured out how to do it server side; by adding:
.Filter(factory => factory.Add(model=> model.SubscriptionValidStatus).IsEqualTo("Aktiv"))
to datasource!
Rather than a server side default filtering, you could have a client side event add the filter on page load... The practical effect will be your filter in place, at which point a user could select the filter widget in the column header to remove it, or they could add more filters to other columns. I've taken some of my code that I use to do this and renamed it for your grid's name.
Try this out!
In your grid definition, add a events like the following:
.Events(events => events.DataBound("dataBoundSetFilter"))
Then have a javascript function to set the filter of a column with your preferred filtering:
<script type="text/javascript">
// hasBound variable set on page load to false, will be set true after Grid databound event
var hasBound = false;
function dataBoundSetFilter(e) {
// If the grid has not yet been data-bound, apply this here filter
if (hasBound === false) {
//alert("Start");
// Get a reference to the grid
var grid = $("#subscriptionsGrid").data("kendoGrid");
// Apply a filter to the grid's datasource
grid.dataSource.filter({ field: "SubscriptionValidStatus", operator: "eq", value: true });
// Set hasBound = true so this won't be triggered again...
hasBound = true;
}
}
</script>
I was looking for row filter, and add multiple filters in it. I found the following article very helpful. It is using [Kendo.Mvc.CompositeFilterDescriptor] to filter
https://www.telerik.com/forums/how-do-i-use-compositefilterdescriptor-to-set-the-initial-datasource
I have a TreeView that displays a list of database records. When a user selects a record, I populate a grid with the related record details. The foreign key is sourceid.
I pass the selected record's id like this:
.Read(read => read.Action("AquisitionNotes_Read", "AquisitionNotes").Data("GetCurrentSourceID"))
The GetCurrentSourceID function is simply:
function GetCurrentSourceID() {
return {sourceid: currentSourceID };
}
That works.
But when I want to add a new record, how do I get the currentSourceID value into the Post? If I try the obvious:
.Create(update => update.Action("AquisitionNotes_Create", AquisitionNotes").Data("GetCurrentSourceID"))
The value from the editor (0 of course) gets precedence and gets passed.
How do I force my actual sourceid to overwrite the editor's value? Or am I solving the problem in the wrong way?
Brad
To pass the default value to the create you should use DataSource
for example
#(Html.Kendo().Grid()
.DataSource(data=>data.Ajax()
.Model(m=>{
m.Field(field=>field.Whatever).DefaultValue(TheValue);
})))
Got it figured out thanks to the lead that #user5135401 gave me.
user5135401's solution works if you want to set a static default value. I do not know of a way to do a dynamic default value form Razor. This is how you do it per this forum post:
Call a JS function from the grid's .Edit event like:
.Events(events => events.Edit("SetDefaultSourceID"))
Then that function returns the value, in my case the foreign key value of the selected TreeView item:
function SetDefaultSourceID(e) {
if (e.model.isNew()) {
//set the required field value
e.model.set("sourceid", currentSourceID);
}
}
I am very new to Kendo UI. I am using grid control.
I have issue in selecting or changing background color of a particular row. Can anyone help me how can I do this?
My code goes something like this
#(Html.Kendo().Grid<EmpModel>()
.Name("tgrid")
.Columns(columns =>
{
columns.Bound(x => x.EmpId).Width(100).Title("Emp Id");
columns.Bound(x => x.EmpNameName).Width(100).Title("Emp Name");
columns.Bound(x => x.Comments).Width(100).Title("Comments”);
})
In ViewData["EmpId"] I have EmpId stored.
ViewData["EmpId"] = 110023
When the above grid is populated I want to highlight or select or expand the row has EmpId 110023.
What is the best way to do?
Thanks in advance
Param
Thanks in advance
Param
The question is not clear, please clarify. Basically the uid field of your model contains the unique identifier which is added to each TR automatically by the Grid. If you want to style the columns based on the data check this code library.
I'm trying to achieve a very common scenario whereas given a list of options to choose from, the last one says "Other" and when selected the user is presented with the input field to specify what "other" is.
In my case, it's a list of Person's titles:
public List<string> TitleList
{
get
{
return new List<string> { "Mr", "Mrs", "Miss", "Dr", "Other" };
}
}
and what I'm trying to do is this:
#Html.DropDownListFor(m => m.Title, new SelectList(Model.TitleList), "Please select...") #Html.TextBoxFor(m => m.Title)
I want the model to bind the TextBox value when "Other" is selected in the DropDownLis, and bind to selected item in DropDownList in all other cases.
Is this achievable without adding an extra property on the Model?
a better solution is not to bind to two fields, instead, copy selected item from a drop-down into bound textbox with some clever javascript:
#Html.DropDownList("ddlTitle", new SelectList(Model.TitleList), "Please select")
#Html.TextBoxFor(m => m.Title, new { maxLength = 10 })
Javascript:
ToggleTitleFields = function () {
var title, txtTitle;
title = $('select#ddlTitle').val();
txtTitle = $('input#Title');
if (title === "Other") {
txtTitle.val("");
txtTitle.show();
return txtTitle.focus();
} else {
txtTitle.hide();
txtTitle.val(title);
return $('span[data-valmsg-for="Title"]').empty();
}
};
$(document).on("change", "select#ddlTitle", function(e) {
return ToggleTitleFields();
});
hope this helps somebody
found a client-side solution: add/remove the "name" attribute from DropDownList. Here's my coffee script:
ToggleTitleFields = () ->
if $('select#Title').val() == "Other"
$('select#Title').removeAttr('name')
else
$('select#Title').attr('name','Title')
Tsar,
Being honest, this isn't a scenario that I've had to deal with before, but is nonetheless a good one. If I were faced with this dilemma and was allowed to use a javascript solution, i'd present a previously 'hidden' textbox when other was chosen. The user would then have to enter the new value into this texbox, which on loosing focus would populate the selectlist and be selected. Then when the form was submitted, you'd have this new value still as part of the exisiting model.
Of course, you could also do a similar logic of showing the textbox when selecting other but this time, do a little logic on the httpost controller action to determine if the 'other' item was selected and then populate the model from the 'textbox' value.
Of course, both scenarios would need a heap of validation, but in principle, either approach would 'work'