I tried to post on Telerik forum, but now each time I try to open my thread, I get
"Oops...
It seems there was a problem with our server."
So I posted this question here.
I am pretty new to Telerik and RadGrid. I am trying to modify existing project because client needs custom sorting. There is a data field which may contain numbers or text so it is a string type but sometimes it has to be sorted as numbers. So I went to this link:
http://demos.telerik.com/aspnet-ajax/grid/examples/programming/sort/defaultcs.aspx
and
http://www.telerik.com/help/aspnet-ajax/grdapplycustomsortcriteria.html
The example says:
"With custom sorting turned on, RadGrid will display the sorting icons but it will not actually sort the data."
but it seems it is not enough to add AllowCustomSorting to disable default sorting.
When implementing SortCommand, I noticed that I have to do
e.Canceled = true;
because else default sorting occurs. Why this is not mentioned in the documentation nor example?
But the main question is - inside of SortCommand my RadGrid already has all items loaded. So is there any way to sort them to avoid hitting database? I tried accessing various Items properties of both "object source, GridSortCommandEventArgs e", but all Items are read-only, so I cannot sort them and attach back to the RadGrid.
Thanks for any ideas.
You can set the sortExpression in the OnSelecting event of the objectDatasource and use it in the SelectMethod.
protected void odsGridData_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.InputParameters["filterExpression"] = grdMyTasks.MasterTableView.FilterExpression;
//Set the Sort Expression and use this in the Get method
e.InputParameters["sortExpression"] = grdMyTasks.MasterTableView.SortExpressions.GetSortString();
e.Arguments.StartRowIndex = grdMyTasks.CurrentPageIndex;
e.Arguments.MaximumRows = grdMyTasks.PageSize;
}
This way you can perform custom sort and pass on the data to the RadGrid.
Hope this helps.
Here is an example of some code I use that does not hit the database. I'm using MVC 3 with the Razor view engine. Notice the Ajax binding. Don't forget to add using Telerik.Web.Mvc.UI and annotate the "Post" methods in your controller with [GridResult] and to return GridModel to get the Json resultset.
using Telerik.Web.Mvc;
[GridAction]
public ActionResult AjaxGridSelect()
{
return View(new GridModel(db.lm_m_category));
}
Here is the index.cshtml (razor engine), the key is the Ajax binding.
#model IEnumerable<LinkManagerAdmin.Dal.lm_r_category>
#using Telerik.Web.Mvc.UI
#(Html.Telerik().Grid(Model)
.Name("Grid")
.DataKeys(keys => keys.Add(c => c.category_id ))
.DataBinding(dataBinding => dataBinding.Ajax()
.Select("AjaxGridSelect", "CategoryTree")
.Insert("GridInsert", "CategoryTree", new { GridEditMode.PopUp, GridButtonType.ImageAndText })
.Update("GridUpdate", "CategoryTree", new { GridEditMode.InLine, GridButtonType.ImageAndText })
.Delete("GridDelete", "CategoryTree", new { GridEditMode.InLine, GridButtonType.ImageAndText }))
.Columns(columns =>
{
columns.Bound(p => p.category_name).Width(150);
columns.Bound(p => p.status_cd).Width(100);
columns.Command(commands =>
{
commands.Edit().ButtonType(GridButtonType.ImageAndText);
commands.Delete().ButtonType(GridButtonType.ImageAndText);
}).Width(180).Title("Commands");
})
.Editable(editing => editing.Mode(GridEditMode.InLine))
.Pageable(paging => paging.PageSize(50)
.Style(GridPagerStyles.NextPreviousAndNumeric)
.Position(GridPagerPosition.Bottom))
.Sortable(o => o.OrderBy(sortcol =>
{
sortcol.Add(a => a.category_name);
sortcol.Add(a => a.add_date);
})
.Filterable()
.Groupable()
.Selectable())
Related
I'm working with a Kendo-UI grid for asp.net MVC (version 2022.2.621.545) and I added multi-checkbox filtering to the columns. The grid items are pulled from the server using a configured ajax call to a controller action, and clicking on a filter button triggers another call to retrieve the full set of items in order to build the checkbox list. In some cases there are too many items returned and the grid appears to hang trying to determine the unique items for the checkbox list.
I was wondering if lazy loading can be configured for multi-checkbox filtering such that paging info is sent to the data source controller action. Alternatively, I've read that there may be a way to hold off on retrieving items for the filter until a minimal search string has been entered, with the search string being sent to the data source controller action.
I've looked at Kendo-UI documentation for multi-checkbox filtering options, but nothing has been abundantly clear that what I need to do is possible, especially within the asp.net MVC directives. I'm hoping someone can provide some guidance as to how to modify my grid setup to configure additional control for retrieving filter options. This is my current working code:
<div style="height:690px" id="warehouseGrid">
#(Html.Kendo().Grid<WarehouseModel>()
.Name("inventoryGrid")
.HtmlAttributes(new { style = "height:100%; width: 100%;" })
.Columns(columns =>
{
columns.Bound("InventoryLineItemID").Title("").Width(35).Filterable(false).ClientTemplate(
"<img src='https://cdn.host/show_detail.png' class='k-icon k-delete' height='45' width='45' onclick='ShowInventoryItemDetails(\"#= InventoryLineItemID #\")' onmouseover='' style='cursor: pointer;' title='Show Inventory Item Details' alt='Show Inventory Item Details' />"
);
foreach (WarehouseField col in fields)
{
if (!string.IsNullOrEmpty(col.Template))
{
columns.Bound(col.PropertyName).Title(col.Title).Width(col.Width).Filterable(false).ClientTemplate(col.Template);
}
else
{
columns.Bound(col.PropertyName).Title(col.Title).Width(col.Width).Filterable(ftb => ftb.Multi(true).Search(true));
}
}
})
.Pageable(pager => pager.PageSizes(new[] { 10, 20, 50, 100 }))
.Excel(excel => excel
.AllPages(true)
)
.ToolBar(
toolbar =>
{
toolbar.Template(#<text>
#ToolbarTemplate()
</text>);
}
)
.Events(e => e.DataBinding(#<text>function(e) { onDataBinding(this) }</text>))
.Events(e => e.DataBound(#<text>function(e) { onDataBound(this) }</text>))
.Resizable(r => r.Columns(true))
.ColumnResizeHandleWidth(5)
.Scrollable()
.Sortable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(100)
.Read(read => read.Action("GetInventory", "Warehouse", new { area = "Rest" }).Data("additionalData"))
)
)
</div>
I've recently purchased a Kendo subscription, I'm having trouble getting an AJAX bound grid to operate as expected, hoping someone here can help.
I have followed the Kendo docs tutorial # http://docs.kendoui.com/getting-started/using-kendo-with/aspnet-mvc/helpers/grid/ajax-binding
and could get the AJAX binding working nicely.
I've tried to now implement it into an existing MVC solution, and whenever I click the New or Edit command button, I get a string of JSON returned to the browser. Similiar to issue (JSON data to KENDO UI Grid ASP.NET MVC 4) But the answer in that problem didn't work for me.
Here is my Controller code...
public ActionResult Index()
{
// non-important code removed here //
var viewModel = newReferenceViewModel();
ViewBag.TradeReferences = TradeReferenceWorker.Get(applicationId);
return View(viewModel);
}
public ActionResult TradeReferences_Read([DataSourceRequest]DataSourceRequest request)
{
var applicationId = GetCurrentApplicationId();
DataSourceResult result = TradeReferenceWorker.Get(applicationId).ToDataSourceResult(request);
return Json(result, "text/x-json", JsonRequestBehavior.AllowGet);
}
And the View ....
#(Html.Kendo().Grid((IEnumerable<TradeReference>)ViewBag.TradeReferences)
.Name("gridTradeReference")
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(tradeReference => tradeReference.TradeReferenceId);
model.Field(tradeReference => tradeReference.TradeReferenceId).Editable(false);
})
.Read(read => read.Action("TradeReferences_Read", "References"))
.Create(create => create.Action("TradeReference_Create", "References"))
.Update(update => update.Action("TradeReference_Update", "References"))
.Destroy(destroy => destroy.Action("TradeReference_Destroy", "References"))
)
.Columns(columns =>
{
columns.Bound(tref => tref.TradeReferenceId).Visible(false);
columns.Bound(tref => tref.Name);
columns.Bound(tref => tref.Phone);
columns.Command(commands =>
{
commands.Edit();
commands.Destroy();
}).Title("").Width(200);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Sortable()
)
So to sum up... the Grid will load perfectly the first time. I haven't wired up anything on the Edit / Delete actions, just trying to get Create operational. Clicking Add New, or even Edit for that matter will make the browser simply display Json to the screen.
It is hopefully something simple - thanks in advance
Solved it - the problem was the kendo js files were not being referenced correctly.
In my particular case, the bundling wasn't done 100% correctly so the Kendo javascript files were never getting included in the page.
They must also appear in a certain order, as described in the troubleshooting guide http://docs.kendoui.com/getting-started/using-kendo-with/aspnet-mvc/helpers/grid/troubleshooting
I am using ASP.Net Mvc 4 with Kendo UI grid.
I would like to perform more advanced features on the kendo UI grid (like exporting the sorted data from the grid to excel, adding filters, etc.). I need to configure the DataSource in my View and the "Read" method in the Controller. The grid is populated from a LINQ query and stored in the ViewBag.
Here is the razor code in my view Index.cshtml
#(Html.Kendo().Grid((IEnumerable<Reports.Models.Company>)ViewBag.ActComp)
.Name("grid")
.Columns(columns =>
{
columns.Bound(comp => comp.Name);
columns.Bound(comp => comp.DateCreated);
columns.Bound(comp => comp.Quarter).Sortable(false);
columns.Bound(comp => comp.Code);
columns.Bound(comp => comp.Enabled).Column.Title = "Active";
})
.Sortable()
.Groupable()
.Scrollable(src => src.Height(500))
)
Here is the Controller ActiveCompController.cs
namespace Reports.Controllers
{
public class ActiveCompController : Controller
{
private FSLContext fslData = new FSLContext();
public ActionResult Index()
{
ViewBag.ActComp = from b in fslData.Companies
where b.Enabled == true
orderby b.Name
select b;
return View();
}
I have seen a couple of different examples with .Ajax() like:
.DataSource(dataSource => dataSource // Configure the grid data source
.Ajax() // Specify that ajax binding is used
.Read(read => read.Action("Products_Read", "Home")) // Set the action method which will return the data in JSON format
However, it didn't work as my data is from a LINQ query not formatted in JSON. Also, I don't know what to write in the "Read" method.
Any thoughts on how to configure the Datasource and the controller with my configuration ?
It looks like your code is similar to the example for the Kendo Grid at
http://demos.kendoui.com/web/grid/index.html
I would start by setting up a ViewModel class for Company that would hold all of your columns for the grid similar to how they have a ProductViewModel in their example. For instance, you would have the following in your ViewModel:
Name, DateCreated, Quarter, Code, Enabled
If you navigate to ASP.NET MVC > IndexController.cs you'll see where they've defined their method:
public ActionResult Products_Read([DataSourceRequest] DataSourceRequest request)
From there you'll see that they wrapped their LINQ results into their ViewModels and returned them in JSON format. You're on the right track for setting up the DataSource for your grid. As far as the Controller goes, you would change
.Read(read => read.Action("Products_Read", "Home"))
to
.Read(read => read.Action("<YourMethodHere>", "Home"))
Which will allow you to modify the logic for the read. However, note the Read operation is simply used for populating the table, any other functionality (such as sorting) would be handled differently. For more information on sorting take a look here
http://demos.kendoui.com/web/grid/sorting.html
I am converting an existing app from Telerik MVC extensions to the newer KendoUI product. I am using the grid control. How do I specify the default values for the columns when adding a new row to the grid?
With the old Telerik MVC extensions, I did the following:
.Editable(editing=>editing.Mode(GridEditMode.InCell).DefaultDataItem(Model.defaultItem))
The defaultItem of my model was my default for added rows. So how do I do this with Kendo?
Yo yo yo mate,
You need to specify default value for each of the fields via the dataSource model configuration
Here is an example you can use ;)
#(Html.Kendo()
.Grid<TestModel>()
.Name("SomeOtherGridName")
.DataSource(ds => ds.Ajax().Read("test", "test").Model(
x => {
x.Field(c => c.Val1).DefaultValue(5);
x.Field(c => c.Val2).DefaultValue("cool!");
}
))
.Columns(columns =>
{
columns.Bound(c => c.Val1);
columns.Bound(c => c.Val2);
})
)
DefaultDataItem does not currently exist in the MVC extensions specifically. However, it is still possible without using the MVC extensions as a work-around.
I wrote an extension method that accomplishes the core functionality of DefaultDataItem(). It reads every property of a default item and sets the Field() and DefaultValue() in the data source model definition:
public static class DataSourceModelDescriptorFactoryExtensions
{
public static DataSourceModelDescriptorFactory<TModel> DefaultDataItem<TModel>(
this DataSourceModelDescriptorFactory<TModel> dataSourceModelBuilder,
TModel defaultDataItem) where TModel : class
{
var propertyInfos = typeof(TModel).GetProperties();
foreach (var propertyInfo in propertyInfos)
{
dataSourceModelBuilder
.Field(propertyInfo.Name, propertyInfo.PropertyType)
.DefaultValue(propertyInfo.GetValue(defaultDataItem));
}
return dataSourceModelBuilder;
}
}
Use it like this:
#(Html.Kendo().Grid<MyEntity>()
...
.DataSource(ds => ds
...
.Model(model =>
{
model.Id(n => n.Id);
model.DefaultDataItem(myDefaultEntity);
}
)
)
I have a view with several controls that are used for searching. When a user searches (Ajax.BeginForm) off of these I return the data into a PartialView (Telerik MVC3 Grid) that was generated dynamically.
This all works fine. In the grid are buttons for selecting a row. When I select a row, it posts to my controller, I do some "stuff" etc. When I try to get back to the view all I get is my grid data on a page by itself, it displays like a table with no borders, no other controls etc. My code is below.
My partial grid:
#model Highlander.Areas.Highlander.Models.ViewModels.DeliveriesGridViewModel
#using System.Data;
#(Html.Telerik().Grid<System.Data.DataRow>(Model.Data.Rows.Cast<System.Data.DataRow>())
.Name("Grid")
.DataKeys(dataKeys => dataKeys.Add("DeliveryID"))
.Columns(columns =>
{
columns.Command(commandbutton =>
{
commandbutton.Select().ButtonType(GridButtonType.ImageAndText);
}).Width(80).Title(ViewBag.Title);
columns.LoadSettings(Model.Columns as IEnumerable<GridColumnSettings>);
})
.DataBinding(dataBinding => dataBinding.Server().Select("_MarkSystem", "Deliveries"))
.EnableCustomBinding(true)
.Resizable(resize => resize.Columns(true))
)
My Controller:
[GridAction]
public ActionResult _MarkSystem(GridCommand command, int id)
{
string shipDeliver = DataCache.ShipDeliver;
DataTable fullTable = DataCache.FullTable;
// call to function to get the datatable data based on the id
rHelpers.GetDataTableRow(id, fullTable, shipDeliver);
// get the data for the grid into the model
fullTable = DataCache.FullTable;
model = new DeliveriesGridViewModel();
model.Data = fullTable;
model.Columns = rHelpers.NewColumns(DataCache.FullTable);
return PartialView("_DeliveryGrid", model);
//if (Request.IsAjaxRequest())
//{
// return PartialView("_DeliveryGrid", model);
//}
//return PartialView("_DeliveryGrid", model);
//return PartialView("DeliveryManager", model);
}
As you can see I have tried various things with no success.
Can anyone give me some direction on this.
Thanks for your time.
As far i understand you are using dataBinding.Server() that call a server side binding. Use .Editable(editing => editing.Mode(GridEditMode.InLine) it will work.
Both kind of bindings (Server and Ajax) needs a editing mode. Put an editing mode and try again.Kindly Response if it does not work for you. Here full code of data binding:
**.DataBinding(dataBinding => dataBinding.Ajax()
.Select("myAction", "myController")
.Update("myAction",myController")).
Editable(editing => editing.Mode(GridEditMode.InLine))**