How to set up Kendo UI mvc grid with checkbox control - telerik

I am using Kendo UI MVC grid. One of the properties of the model is bool, so I need to present it in grid as checkbox. By default Kendo UI present it as "true" and "false" values in the column. So you need to first time to click to get checkbox, then second time to click to change value of the combobox. Instead of having default values from grid, I set ClientTemplate, so I got checkbox instead of "true" and "false" values.
c.Bound(p => p.GiveUp)
.Title("Giveup")
.ClientTemplate("<input type='checkbox' id='GiveUp' name='GiveUp' #if(GiveUp){#checked#}# value='#=GiveUp#' />")
.Width(50);
This grid uses batch editing and in-grid editing (GridEditMode.InCell)
.Editable(x => x.Mode(GridEditMode.InCell))
.DataSource(ds => ds.Ajax()
.ServerOperation(false)
.Events(events => events.Error("error"))
.Batch(true)
.Model(model => model.Id(p => p.Id))
.Read(read => read.Action("Orders", "Order").Data("formattedParameters"))))
So what I would like to have is ability for user to click on checkbox and change value of my model, but unfortunately that doesn't work. I can see visually checkbox's value is changed but I don't see red triangle that marks cell as changed, and when I click on add new item button, value from checkbox disappear.
Please advice on what I am doing wrong.
Thanks in advance.

For those who would like to see how full code looks like.
Home.cshtml
#(Html.Kendo().Grid<OrdersViewModel>()
.Name("Orders")
.Columns(c =>
{
c.Bound(p => p.Error)
.Title("Error")
.ClientTemplate("<input type='checkbox' #= Error ? checked='checked': '' # class='chkbx' />")
.HtmlAttributes(new {style = "text-align: center"})
.Width(50);
<script>
$(function() {
$('#Orders').on('click', '.chkbx', function() {
var checked = $(this).is(':checked');
var grid = $('#Orders').data().kendoGrid;
var dataItem = grid.dataItem($(this).closest('tr'));
dataItem.set('Error', checked);
});
});
</script>

Basically when you add/remove records from the Grid the red triangles always disappear (or when you sort/page/filter etc), the checkbox is not the problem with the red triangles.
Now for the checkbox if you create a ClientTemplate which is again a checkbox you will need to click one time to put the cell into edit mode (you will see no difference because the editor template is again a checkbox) so you will need to click second time to actually change the value.
What I suggest you as best practice is to use the approach covered here - it is way more faster (less operations for the Grid) and it easier than applying extra logic to handle the two clicks with the approach above.

Related

Kendo MVC - Need DatePicker in a Grid

I have the following grid with a date picker:
#(Html.Kendo().Grid<ScheduleViewModel>()
.Name("ScheduleGrid")
.AutoBind(true)
-
)
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Columns(columns =>
{
columns.Bound(s => s.Name).Title("Schedule").Filterable(true).Width(150).HtmlAttributes(new { style = "text-align: left" });
columns.Bound(s => s.StartTime).Width(100).Title("Start Time").ClientTemplate((
#Html.Kendo().DatePicker()
.Name("StartTimePicker")
.Value("#=StartTime#")
//.Format("{0:dd/MM/yyyy}")
.ToClientTemplate()).ToHtmlString());
columns.Bound(s => s.Enabled).Width(100).ClientTemplate("<input type='checkbox' #=Enabled ? checked='checked' : '' # class='sda-checkbox' />").HtmlAttributes(new { #class = "text-center" });
columns.Command(command => command.Custom("Save").Click("saveSchedules")).Width(80).HtmlAttributes(new { #class = "text-center" });
})
However, the date picker doesn't display correctly. Instead it is just a text box. What am I doing wrong?
EDIT (and I also switched to use a Time Picker instead of a Date Picker):
I did as #FrozenButcher suggested, but this still doesn't work. This is what happens now:
Bring up page and you get this, which does not LOOK like a Time Picker, but is. No clock icon, and you can't see the value:
Click in the box and you get this:
Obviously you can now see the time, but no clock icon.
Finally, click in the Time Picker on the second line and you get this:
Any help in resolving this is greatly appreciated.
You have to ensure unique ids for your inputs, wrapper for datepicker is defined through the name property.
change it to a dynamic name .Name("StartTimePicker"+ lineNumber)

Kendo Grid first row just for searching

I have a project which uses Telerik Kendo.
In the Kendo Grid, we need to make the first row editable so the user can type inside it to use it to search the data. Actually, the Kendo grid provides this functionality when you click on the header of the of the grid, but my requirement is to provide this functionality.
I searched the web for hours, without reaching any Result.
I do not think I need to provide any code here, because I really do not know the way to go.
The project is ASP.NET MVC, and I am using Telerik MVC wrapper.
I used the row-filter feature which provided by Telerik, and it was good for me.
but I have small problem.
here it is what I used,
function templateMethod (args) {
args.element.kendoDropDownList({
dataSource: args.dataSource,
dataTextField: "color",
dataValueField: "color",
valuePrimitive: true
});
}
The previous example is from documentation of the Telerik from here
Keep in mind that the passed dataSource instance may still not be populated at the time the template function is called, if the Grid uses remote binding.
I am really using remote binding, and the data is NOT coming ,as the documentation state, the problem is that the documentation warned from this problem but it did not provide any solution for it.
How can I repupolate the kendoDropDownList again, after the data is coming from the remote server?
#(Html.Kendo().Grid<SomeClassName>()
.BTGrid(GridName)
.Resizable(e => e.Columns(true))
.Filterable(e => e.Mode(GridFilterMode.Row))
.Columns(columns =>
{
columns.Bound(x => x.VardiyaGrubu).Filterable(e => e.Cell(r => r.Template("templateMethod").ShowOperators(false).Operator("contains").SuggestionOperator(FilterType.Contains) ));
})
.Groupable(config => config.Enabled(true))
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(true)
.Model(x => x.Id(r => r.RefKey))
.Events(ev => ev.RequestEnd("onRequestEnd"))
.Read(read => read.Action("CevrimZamaniRaporu", "Raporlar").Data(GridName + "_LoadData"))))
I tried to set ServerOperation to true and false in both cases it does not change.

Kendo Server Side Grid Filtering/Sorting

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

Kendo grid pager issue after loading new data

I have a problem with the Kendo grid pager misbehaving after loading new data into a grid. The grid is loaded when the page loads, configured as follows:
#(Html.Kendo().Grid<MyModel>()
.Name("Grid")
.Columns(columns =>
{
//snipped
})
.Scrollable()
.Sortable(sort => sort.Enabled(true))
.Pageable(pager => pager.PageSizes(new int[] {10, 25, 50, 100}))
.Events(events => events.DetailExpand("detailExpand").DetailCollapse("detailCollapse").DataBinding("onDataBinding"))
.ClientDetailTemplateId("template")
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
.Sort(sort => sort.Add(Model.sort).Order(Model.Direction))
.PageSize(Model.PageSize)
.Events(events=>events.Error("onError"))
.Read(read => read.Action("Summary", "Summary").Data("getFilterModel")))
.Events(events => events.DataBound("dataBound"))
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
);
I have some controls on the page that serve as filters for the grid content. the getFilterModel function returns the values of those filters. When the user clicks the "Filter" button, I call read on the grid data source.
<button class="k-button" id="get" type="button" onclick="$('#Grid').data('kendoGrid').dataSource.read();return false;">Filter</button>
This works OK on initial page load, and if I reload the grid with a number of rows <= the original number of rows. If I reload with a larger number of rows, the pager shows the correct count. But, if I try to click to advance to the next page, the pager reverts to showing 1 page only, and the grid shows empty.
Example: initial load contains 3 records, page size 25. Pager shows 1 page. OK. Change filters so the grid loads 42 rows. Pager shows 2 pages, set to page 1, and "1-25 of 42 items". Click to advance to page 2; grid shows no rows, pager shows 1 page and "26-25 of 25 items"
Does the pager need to be explicitly reset somehow?
This is an older version of Kendo MVC...DLL shows version 2013.3.1119.340.
In this case, Kendo MVC and I outsmarted ourselves.
The getFilterModel function returned an object that contained both Page and PageSize properties, which get translated into query param names in the HTTP request. Those in turn become properties on the FilterModel object that is the model for the controller action. On the server side, the controller action calls the Kendo ToDataSourceResult extension method which apparently interpreted Page and PageSize and only returned the first page of the results.
Changing the names of those properties to GridPage and GridPageSize solved the problem. I had included them because I wanted to persist them as part of the grid state, but I may be better off finding another way to do that.

Kendo UI Grid highlight selected row

I have a Kendo (2013.2.716) grid with an Edit command (the edit button is in the first column) and 40+ other columns. I do NOT have Selectable set for the Grid. When the grid is populated, I can run my mouse down the Edit command column and each Edit button is highlighted in turn, and when I click on one, my editor comes up right away.
However, without the .Selectable option, I cannot tell which row I am on if I scroll the grid to see the 40+ columns. So, I set .Selectable(). This gave me the background highlighting that I expected whenever I clicked in a row. However, I have two negative side-effects: one, the selection of a new row takes about six seconds just to change (and highlight) a new row, and two, clicking the Edit button now accomplishes nothing: no editor comes up.
The documentation says, "Selection can be enabled in the grid simply by setting the selectable option to true." But there must be more to it than this... It shouldn't take any time to change the background color, and it shouldn't kill my edit buttons. What did I miss?
#(Html.Kendo().Grid(Model.Data)
.Columns(columns =>
{
columns.Command(command => command.Edit().Text("Edit").UpdateText("Submit")).Width(97).HtmlAttributes(new { style = "text-align: center;" });
...
})
.Selectable( )
.Editable(editable => editable
.Mode(GridEditMode.PopUp)
.TemplateName("MyEditor")
.Window(w => w.Width(500))
.Window(w => w.Title("My Editor")))
Provide a global variable to store the previously-highlighted row:
var previousHighlightedRow;
Provide a style for the desired highlighting:
.highlightTR {
background-color: #99CCFF;
}
In the GridBound event, wire the mouseup events for the rows to use removeClass on the previously-highlighted row, and addClass on the 'selected' row.
$('.k-grid-content tbody').off('mouseup');
$('.k-grid-content tbody').on('mouseup', 'tr', function () {
if (previousHighlightedRow != undefined) {
previousHighlightedRow.removeClass("highlightTR");
}
$(this).addClass("highlightTR");
previousHighlightedRow = $(this);
});
This approach is quick (with 500+ rows), and does not kill the Edit Command.

Resources