MVC Kendo UI Grid - 100 + columns - asp.net-mvc

I have a Kendo UI GRID (MVC) with 100+ columns.
Not all the columns are visible on load. The default columns visible are 10.
There are checkboxes on the page, next to the grid, which list all the columns. If you click on a checkbox, depending on whether it is checked or unchecked, the column appears or is hidden.
The trouble is that the grid takes almost 20 seconds to render, when the number of rows is also huge (and the time increases).
What is the best way to handle a large number of columns?

I think that bring all the 100 columns for a record is not the best way to work. Maybe you must most important information (10 column at max) for all the records and have a detailed view (with the rest of the information for the specific record you want to inspect)
If you want to see a more detailed example take a look here
my approach is the following
#(Html.Kendo().Grid<YOURCLASS>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(e => e.imporantColumn1);
columns.Bound(e => e.imporantColumn2);
columns.Bound(e => e.imporantColumn3);
})
.Sortable()
.Pageable()
.Scrollable()
.ClientDetailTemplateId("template")
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.Read(read => read.Action("HierarchyBinding_theBasicData", "Grid"))
)
.Events(events => events.DataBound("dataBound"))
)
and a detailed template
<script id="template" type="text/kendo-tmpl">
#(Html.Kendo().TabStrip()
.Name("tabStrip_#=ID#")
.SelectedIndex(0)
.Items(items =>
{
items.Add().Text("details").Content(#<text>
#(Html.Kendo().Grid<YOURCLASS>()
.Name("grid_#=ID#")
.Columns(columns =>
{
// the order columns
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.Read(read => read.Action("HierarchyBinding_theRestOfInfo", "Grid", new { ID= "#=ID#" }))
)
.Pageable()
.Sortable()
.ToClientTemplate())
</text>
);
})
.ToClientTemplate())
</script>

Related

Make Kendo ASP.NET MVC inCell Editable based on Viewbag condition

Is it possible to make a Kendo MVC grid .Editable() based on a function that allows editing ONLY if you have a certain Viewbag?
I have a viewbag that is Viewbag.DisplayButton. That viewbag is only 'true' if you have a dev role (so non-devs cannot edit anything). How can I make this work with .Editable() so that you can only edit cells if you have that viewbag?
Currently if I set Editable(true) then anyone (devs, customers, literally anyone) can edit the cell. If I set it to Editable(false) then no one, including devs, can edit it. So I need a function that does it only if you have that specific viewbag.
Use a Razor code block for this. You can assign the Grid definition to a variable, then execute the conditional logic and add the additional configurations, if any. Finally call the Render method. Here is an example:
<h3>Some content</h3>
#{
var isAdmin = true;
var grid = (Html.Kendo().Grid<MyModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.MyModelID).Filterable(false);
columns.Bound(p => p.SomeModelProperty);
})
.Pageable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Model(m=>m.Id("MyModelID"))
.Read(read => read.Action("Read", "Grid"))
)
);
if (User.IsInRole("Admin"))
{
grid.Editable(e=>e.Mode(GridEditMode.InCell));
}
grid.Render();
}
<h3>Some other content</h3>

ASP.NET MVC Kendo UI Foreign Key

Hello I am new to Kendo UI, And I have the same question as Kendo UI Foreign Key
but, I cannot grasp the point of the answer. About the Foreign Key, can you tell me about step by step of accessing Foreign Key in the Grid. if you provide me with your example, that would be great!
Thank you for your help.. :))
There is a good documentation with Examples available each component wise in Kendo UI itself. Here is sample about the Foreign Key in the Grid.
In this sample they have two tables category and products. By clicking on the "Add new record" you can add the products based on the "Category" wise. Here the "foreign key relationship" is needed, to identify what are the products comes under which category.
Based on this relationship they add and delete the specific products. This is just to categorize the products rather than mixing all the products.
Sample: see my commented explanations.
#(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.ProductViewModel>()
.Name("grid")
.Columns(columns => // Fetch available categorizes from the table. which will have the relation ship with products table.
{
columns.Bound(p => p.ProductName);
columns.ForeignKey(p => p.CategoryID, // Creating the relationship here
(System.Collections.IEnumerable)ViewData["categories"], "CategoryID", "CategoryName")
.Title("Category").Width(150);
columns.Bound(p => p.UnitPrice).Width(150);
columns.Command(command => command.Destroy()).Width(110);
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Filterable()
.Groupable()
.Pageable()
.Scrollable()
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.PageSize(20)
.ServerOperation(false)
.Events(events => events.Error("errorHandler"))
.Model(model =>
{
model.Id(p => p.ProductID); // Get/set unique id for the product
model.Field(p => p.ProductID).Editable(false); // 1st column editable. since we are going to add product names.
model.Field(p => p.CategoryID).DefaultValue(1); // Makes default category selection.
})
.Read(read => read.Action("ForeignKeyColumn_Read", "Grid"))
.Update(update => update.Action("ForeignKeyColumn_Update", "Grid"))
.Create(create => create.Action("ForeignKeyColumn_Create", "Grid"))
.Destroy(destroy => destroy.Action("ForeignKeyColumn_Destroy", "Grid"))
)
)
hope i have given enough information. :)

ASP.NET MVC Telerik Grid: How to make one column read only on edit?

I have an ASP.NET MVC Telerik Grid (not Kendo). I have a grid with two columns. The first column is a drop down list of items I can select from, and the second column is just an editable textbox.
I want to set the first column to READ ONLY on edits, meaning I can only edit the second column but not the first column. I set the first column to read only in both the model ([ReadOnly] tag in the model class) and in the view (i.e. Editable(false)).
When I do this, I'm not allowed to edit the first column in edit mode like I want. However, when I go to insert/create a new record... the first column is blank and I can only enter values for the second column.
I've tried everything and looked around, but couldn't find a solution.
try this :
model.Field(p => p.Name).Editable(false)
Example:
#(Html.Kendo().Grid<OrderViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.Id).Sortable(false).Visible(false);
columns.Bound(p => p.Name);
columns.Bound(p => p.Notes);
columns.Command(command => { command.Edit(); }).Width(172);
})
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.HtmlAttributes(new { style = "height:550px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Read(read => read.Action("Orders_Read", "Grid"))
.Model(model => {
model.Id(p => p.Id);
model.Field(p => p.Name).Editable(false);
})
.Update(update => update.Action("EditingInline_Update", "Grid"))
)
)
Ref: http://docs.telerik.com/kendo-ui/aspnet-mvc/helpers/grid/configuration#model
I had a similar issue with a text field. I solved it by hooking the Edit event.
#Html.Kendo().Grid<MyViewModel>()...Events(e => e.Edit("onGridEdit"))
<script type="text/javascript">
function onGridEdit(e) {
if (!e.model.isNew())
e.container.find('input#ID').prop('disabled', true);
}
</script>
In this example I wanted my ID field to be unchangeable after it's created. Your mileage and jQuery may vary, but I suspect the solution would be similar.
TL;DR;
If you are using grid template columns, keep the EditItemTemplate empty as follows:
<telerik:GridTemplateColumn DataField="opt_id" UniqueName="opt_id" DataType="System.Int32">
<ItemTemplate>
<telerik:RadLabel Text='<%# DataBinder.Eval(Container.DataItem, "opt_id") %>' runat="server" />
</ItemTemplate>
<EditItemTemplate></EditItemTemplate>
</telerik:GridTemplateColumn>
So by using above, when entered into edit mode, the item will still be read only.

Kendo Grid - Reordering columns with two columns containing the same data

A little background on how my grid works:
My grid is making use of .Sortable(), .Reorderable(), .Filterable() and .ColumnMenu(). On the dataBound event, the grid saves the state of the grid (column order, items per page, current pagination page, and column sorting [asc and desc]). This is so when a user comes back to that page, their settings are reloaded in the grid when some initializing Javascript makes a query on the grid.
My issue comes into play when I have the same data for two columns:
#(Html.Kendo().Grid<GridDataType>()
.Name("ActiveThreats_Grid")
.AutoBind(false)
.Columns(columns =>
{
columns.Bound(r => r.Id).Title("<input id='checkAll', type='checkbox', class='check-box' />")
.Sortable(false)
.ClientTemplate("<input type='checkbox' class='check_row' id='#= Id#' />")
.Filterable(false);
columns.Bound(r => r.OtherField).Title("Other Field");
columns.Bound(r => r.Id).Title("ID").Hidden(true);
})
.Resizable(resize => resize.Columns(true))
.Scrollable()
.Sortable()
.Reorderable(reorder => reorder.Columns(true))
.Filterable()
.ColumnMenu()
.DataSource(dataSource => dataSource
.Ajax()
// Other HtmlHelpers here
)
What I've noticed, is if I have the same data-field attribute and I am using the .Reorderable() HtmlHelper, the grid reorders the first r.Id column to the same position where the second r.Id column appears.
Q: Is there an HtmlHelper or way to change the data-field attribute output to prevent .Reorderable() from ordering the two identical columns next to each other?

Extra Paging Section at the Top of Kendo UI Grid using Razor

I'm relatively new to Kendo so I'm hoping I'm using the right terminology and my apologies if this is confusing. I've created a kendo ui grid in Razor and it would appear that my paging is creating a paging section correctly at the bottom of the grid and a second more default paging section at the top of the grid. I have a png image but not sure how to load it so here's a description. At the bottom of the grid, the paging is displayed correctly. There are next and previous arrows, numeric buttons 1-3 on the bottom left and the correct messaging on the bottom right displaying "Showing items from 1 to 10. Total Items 30.
At the top of the grid, there is another paging section showing next and previous arrows on the top left with 1 numeric button and on the top right a message displaying "No items to display."
Here is the code for the Kendo grid:
#(Html.Kendo().Grid<myModels.Models.QuotesSearchViewModel>()
.Name("quotesGrid")
.Columns(columns =>
{
columns.Bound(c => c.AccountNumber);
columns.Bound(c => c.QuoteNumber);
columns.Bound(c => c.CustomerName);
columns.Bound(c => c.TimeIn).Format("{0:hh:mm:ss tt}");
columns.Bound(c => c.DateIn).Format("{0:MM/dd/yyyy}");
columns.Bound(c => c.QuoteNumber).ClientTemplate(
Html.ActionLink("Edit", "Edit", new { id = "#= QuoteNumber #" }, new { #class = "k-button" }).ToHtmlString()
);
})
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Single))
.Sortable()
.Pageable(pageable => pageable
.Messages(messages => messages.Display("Showing items from {0} to {1}. Total items: {2}"))
.ButtonCount(5))
.Navigatable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Model(model => model.Id("QuoteNumber"))
.Read(read => read.Action("Quotes_Read", "Quotes").Data("filters"))
)
)
I have no problem populating the grid, selection works fine, everything is functioning properly with the exception of an extra paging section at the very top of the grid. I'm not creating a kendo grid anywhere else on this page and I'm stumped about how this is getting there. Has anyone else come across this? Let me know if you need any further information.
Thank you for your time-Shaun

Resources