I'm having a hard time finding out how I can sort columns in a grid thar are set up with the Template property, like below:
#(Html.Kendo().Grid(Model.UnitDetails)
.Name("unitGrid")
.DataSource(ds => ds
.Ajax()
.Read(read => read.Action("Units_Read", "Fleet"))
.AutoSync(true)
.ServerOperation(true)
)
.Columns(columns =>
{
columns.Bound(p => p.ViewUnitContract.CurrentRun.Operation.WellContract.Location).Title("Well Site").Sortable(true);
columns.Bound(p => p.ViewUnitContract.Name).Title("Unit Name").Width(200);
columns.Template(p => { }).ClientTemplate(" ").Title("Well");
columns.Template(p => { }).ClientTemplate(" ").Title("Run").Width(75);
columns.Template(p => { }).ClientTemplate(" ").Title("Task").Width(365);
columns.Template(p => { }).ClientTemplate(" ").Title("Activity").Width(200); ;
columns.Template(p => { }).ClientTemplate(" ").Title("Depth (m)").Width(115);
columns.Template(p => { }).ClientTemplate(" ").Title("Speed (m/min)").Width(90);
columns.Template(p => { }).ClientTemplate(" ").Title("Weight (kg)").Width(90);
})
.ClientRowTemplate(Html.Partial("_ClientRowTemplate", Model).ToHtmlString())
.Sortable())
Sorting the two first columns works just fine, but is it possible to sort the ones bound with ClientTemplates?
To sort a column, it must be a Bound column. You could still set the ClientTemplate on the Bound column, but the Template alone will not be sortable.
One workaround is to update your view model to have whatever "calculated" value (using that term loosely) calculated on the controller and then returned through to the view. In that case, you could use Bound columns.
Related
I have a kendo data grid grouped default by a column and I want to edit the grid inline. I don't want the user to group by any other column. While the default grouping works fine, the update event is not fired and the control doesn't go the controller's inline update method. Can you please check where I'm going wrong. Below is the code:
#(Html.Kendo().Grid(Model)
.Name("grdTimesheets")
.Columns(columns =>
{
columns.Bound(p => p.EmployeeId).Hidden(true);
columns.Bound(p => p.FirstName);
columns.Bound(p => p.Monday.Hour).Title("Monday")
.EditorTemplateName("TimesheetMonday");
columns.Command(command =>
{
command.Edit();
command.Destroy();
command.Custom("Add").Text(" ").Click("AddNewTimesheet");
});
})
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Pageable()
.Sortable()
.Groupable(false)
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(p => p.EmployeeId);
model.Field(p => p.FirstName).Editable(false);
})
.PageSize(20)
.Update(update => update.Action("EditingInline_Update", "Timesheet"))
.Destroy(destroy => destroy.Action("EditingInline_Destroy", "Timesheet"))
.Group(d=>d.Add(f=>f.FirstName))
)
If I comment out the last line ".Group(d=>d.Add(f=>f.FirstName))", everything works fine but the default grouping goes off.
I know that its a bit late for an answer but I will just leave this here in case that anybody else is having the same problem. Once you group by any column the grid will not fire ".Update(update => update.Action("EditingInline_Update", "Timesheet"))". In order to fix this you would need to add OnEditEvent for the grid and in the javascript function to attach an event to the textbox/dropdown or whatever control you have there. Sample below:
.Events(events => events.Edit("grid_edit")) this is in the view
javascript:
function grid_edit(e) {
var grid = $('#grid').data('kendoGrid');
var cell = e.container;
var area = cell.find("textarea")
area.on("blur", function() {
// update ur entries here
var areaVal = cell.find("textarea").val(); // this is the new value
// call some ajax to update the value and in the success call grid.dataSource.sync(); to refresh the grid
});}
Also you would need to remove your .Update() for the DataSource because its no longer needed.
I'm trying to set a min and max values for datetime picker control inside a grid. The value needs to be set dynamically, based on the value of another datepicker on the form.
I had try handling the onEdit event and trying to find the datetime picker control inside the row been edited to set those values without looking.
Whats is the proper way of restricting date ranges in Kendo Grid MVC inline editing?
This is how the grid is created:
<div>
#(Html.Kendo().Grid<CpcPrevisionUnidadesDto>()
.Name("gridListado")
.HtmlAttributes(new { #class = "kendo-grid-" })
.AutoBind(false)
.Columns(columns =>
{
columns.Bound(c => c.IdCpcPrevisionParadasUnidadesDto).Hidden();
columns.Bound(c => c.IdCpcUnidadesProceso).Hidden();
columns.Bound(c => c.CodigoUnidadProceso).Title(Html.Resource("CPC_CU_DP003_Unidad").ToString());
columns.Bound(c => c.DescripcionUnidadProceso).Title(Html.Resource("CPC_CU_DP003_Nombre").ToString());
columns.Bound(c => c.FechaParada).Title(Html.Resource("CPC_CU_DP003_FechaParada").ToString()).Format("{0:dd/MM/yyyy}").EditorTemplateName("Date"); // Need to set MAX and MIN values
columns.Bound(c => c.FechaArranque).Title(Html.Resource("CPC_CU_DP003_FechaArranque").ToString()).Format("{0:dd/MM/yyyy}").EditorTemplateName("Date"); // Need to set MAX and MIN values
columns.Bound(c => c.Observaciones).Title(Html.Resource("CPC_CU_DP003_Observaciones").ToString());
columns.Template(c => { }).Title(" ").Width(40).ClientTemplate("#=menuRuedaTemplate([uid])#").HtmlAttributes(new { style = "overflow: visible;" });
})
.DataSource(datasource => datasource
.Ajax()
.PageSize(20)
.Read(read => read.Action("BuscarPrevisionParadasPrevistasUnidades", "PrevisionParadasPrevistasUnidades").Data("setParametrosListado"))
.Create(create => create.Action("CreatePrevisionParadasPrevistasUnidades", "PrevisionParadasPrevistasUnidades").Type(HttpVerbs.Post).Data("sendAntiForgery"))
.Update(update => update.Action("UpdatePrevisionParadasPrevistasUnidades", "PrevisionParadasPrevistasUnidades").Type(HttpVerbs.Post).Data("sendAntiForgery"))
.Sort(sort => sort.Add("CodigoUnidadProceso").Ascending())
.Events(e => e.Error("screenErrorHandling"))
.Model(model => model.Id(p => p.IdCpcPrevisionParadasUnidadesDto))
)
.Sortable()
.Navigatable()
.Pageable(pager => pager.Messages(messages => messages.Display(Html.Resource("Mensaje_Grid_Datos").ToString()))
.Messages(m => m.Empty(Html.Resource("Mensaje_Grid_SinDatos").ToString())))
.Resizable(r => r.Columns(true))
.Events(e => e.DataBound("dataBoundGrid").Edit("onEdit"))
.Editable(editable => editable.Mode(GridEditMode.InCell))
.ToolBar(toolbar => toolbar.Save().SaveText(Html.Resource("MAIN_Guardar").ToString()).CancelText(Html.Resource("MAIN_Cancelar").ToString())))
</div>
This is the date editor template:
#model DateTime?
#(Html.Kendo().DatePickerFor(m => m))
You need to edit the HTML for your DatePicker and specify values for Min and Max. In this example, you will only be able to choose past values from this year.
#(Html.Kendo().DatePickerFor(m => m)
.Min("01/01/2016")
.Max(DateTime.Now)
)
If you need to set the value dynamically, you can try this, just get the value you need:
$("#Date").data("kendoDatePicker").min(new Date(2015, 0, 1))
same for .max()
Try that on your "onEdit" event, when the datepicker is created, and let me know if you need more help
I've got a hierarchical Kendo UI Grid (MVC Server Helpers) where one of the columns is a FK lookup that is backed with an Editor Template that does an AJAX lookup for the values. All of that works perfectly. What's not working is the column is showing the ID (Data Value Field from the drop down) and not the text (Data Text Field from the drop down).
Here's the Grid
#(Html.Kendo().Grid<ReceivingLogItemResponse>()
.Name("grid_#=GID#")
.Editable(e => e.Mode(GridEditMode.InCell))
.Sortable()
.Columns( c=>
{
c.Bound(i => i.GID).Hidden();
c.Bound(i => i.SerialNumber);
c.Bound(i => i.PartNumber);
c.Bound(i => i.Description);
c.Bound(i => i.Quantity);
c.Bound(i => i.ItemLotNumber).Title("Lot");
c.Bound(i => i.StatusId).Title("Status");
c.Bound(i => i.CategoryId).EditorTemplateName("ClientCategory");
c.Bound(i => i.LocationCode).Title("Location");
c.Bound(i => i.Comments);
c.Command(e => e.Custom("Add").Click("doItemAdd"));
})
.ToolBar(t => t.Save())
.Selectable(s => s.Type(GridSelectionType.Row))
.DataSource(dataSource => dataSource
.WebApi()
.Model(m =>
{
m.Id(i => i.GID);
m.Field(i => i.GID).Editable(false);
})
.Batch(true)
.ServerOperation(false)
.Read(read => read.Url(apiWrapper.receivingLogItemUrl() + "&receivingLogId=#=GID#").Type(HttpVerbs.Get))
.Update(u => u.Url(apiWrapper.receivingLogItemUpdateUrl()).Type(HttpVerbs.Post))
)
.Events(e => e.DataBound("itemDataBound"))
.ToClientTemplate()
)
And here's the EditorTemplate (ClientCategory)
#(Html.Kendo().DropDownList()
.Name("CategoryId")
.DataTextField("Code")
.DataValueField("CID")
.AutoBind(true)
.DataSource(ds => ds.Read(a => a.Url(apiWrapper.clientCategoryUrl()).Data("getClientCategoryID()"))))
The column displays the CID field until you enter it for editing, when the drop-down shows up it's populated with the correct values. When you go to another field it goes back to the CID.
What am I missing?
I have an MVC razor form with a Kendo grid. The grid has an asynch image uploader.
#(Html.Kendo().Grid<CraftStore.Models.Catalog>()
.Name("CatalogGrid")
.Columns(columns =>
{
columns.Bound(p => p.CatalogName).Filterable(true).Width(240);
columns.Bound(p => p.CatalogDescription).Filterable(true).Width(340);
columns.Bound(p => p.ModelNumber).Filterable(true).Width(110);
columns.Bound(p => p.SerialNumber).Filterable(true).Width(110);
columns.Bound(p => p.InventoryCount).Filterable(true).Width(110);
columns.Bound(p => p.WebPrice).Title("Price").Format("{0:C}").EditorTemplateName("Currency").Width(110);
columns.Bound(p => p.ImagePath).ClientTemplate("<img height='80' src='" + Url.Content("~/Content/Images/catalog/Products/") + "#=data.ImagePath#' title='#=data.ImagePath#' alt='#=data.CatalogName#' />").EditorTemplateName("Image").Title("Picture").Width(300);
columns.Command(command => command.Destroy()).Width(110);
})
.ToolBar(toolbar =>
{
toolbar.Create();
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Filterable(filterable => filterable
.Extra(false)
.Operators(operators => operators
.ForString(str => str.Clear()
.Contains("Contains")
.StartsWith("Starts with")
.IsEqualTo("Is equal to")
.IsNotEqualTo("Is not equal to"))
.ForNumber(num => num.Clear()
.IsEqualTo("Is equal to")
.IsNotEqualTo("Is not equal to")
.IsGreaterThan("Greater than")
.IsLessThan("Greater than"))
))
.Navigatable()
.Selectable(selectable => selectable.Type(GridSelectionType.Row))
.Scrollable(scrollable =>
{
scrollable.Virtual(true);
scrollable.Height(400);
})
.Events(events =>
{
events.Change("change");
})
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.PageSize(20)
.Model(model =>
{
model.Id(p => p.Id);
}
)
.Events(events =>
{
events.Error("error_handler");
})
.Create("CatalogEditing_Create", "WebCatalog")
.Read("CatalogEditing_Read", "WebCatalog")
.Update("CatalogEditing_Update", "WebCatalog")
.Destroy("CatalogEditing_Destroy", "WebCatalog")
)
)
All work fine! - the image has a tooltip of the filename...
The upload and remove work great...
I have an edit template for image (image.cshtml in Views/Shared/EditorTemplates)
The template is:
#model string
<div style="width:100%">
<div class="section">
#Html.TextBoxFor(model => model, new {#class="k-textbox result-box" })
#(Html.Kendo().Upload()
.Name("files")
.Events(events=>events.Success("OnUploadSuccess"))
.Multiple(false)
.Async(a => a
.Save("Save", "Upload")
.Remove("Remove", "Upload")
.AutoUpload(true)
)
)
</div>
</div>
The OnUploadSuccess js function (which is defined on the razor view) has the success function
<script type="text/javascript">
//file upload scripts
function getFileInfo(e) {
return $.map(e.files, function (file) {
var info = file.name;
// File size is not available in all browsers
if (file.size > 0) {
info += " (" + Math.ceil(file.size / 1024) + " KB)";
}
return info;
}).join(", ");
}
function OnUploadSuccess(e) {
$(".result-box").value = getFileInfo(e);
Model = getFileInfo(e);
}
all works fine - the variable 'Model' does get the correct filename.
Now...
How do I get that filename value returned by getFileInfo(e) to be the current value for the grid column???
I thought 'Model' would work, but it does not.
Model = getFileInfo(e);
//since this is in a template, I thought it would bind 'Model' to the column
Then, you can see above, in OnUploadSuccess, I also thought it could be done by using jQuery :
$(".result-box").value = getFileInfo(e);
The jQuery does find and set the value, but the row's member named ImagePath never gets the resulting value.
Neither work, and I'm not sure how to get the returned filename to be the column value.
Any help appreciated.
UPDATE:
Well, I've updated the OnUpdateSuccess js function:
var fn = getFileName(e);
$("#ImagePath").val(fn)
And this now updates the field - but this is not saving when you tab out of the field or immediately hit save. In either care, the old value is restored.
How do I get it to stay? I imagine this is where the MVVM binding will help?
After working with the amazing support from Telerik, I was right - it's a binding issue because the MVVM doesn't know about my change. To get it to know about my change I need to add a line after the script change above:
$("#ImagePath").trigger("change");
Now, it works perfectly!
I wrote the code to display the information in Kendo UI grid.
It's using the inline grid mode to update and insert the record.
Here the code:
Timesheet.cshtml
#model HalsionTimesheetWebApp.Models.TimesheetIndexData
#(Html.Kendo().Grid(Model.TimesheetPrinting)
.Name("InlineGrid")
.Columns(columns =>
{
columns.Bound(trans => trans.TimesheetId).Title("ID").Hidden(true)
.EditorTemplateName("TimesheetIdEditor");
columns.Bound(trans => trans.StartDate).Title("Date")
.Format("{0:dd MMM yyyy}").EditorTemplateName("DateEditor").Width(100));
columns.Bound(trans => trans.StartTime).Title("Start Time")
.Format("{0:hh:mm tt}").EditorTemplateName("TimeEditor").Width(85);
columns.Bound(trans => trans.FinishTime).Title("Finish Time")
.Format("{0:hh:mm tt}").EditorTemplateName("TimeEditor").Width(85); columns.Bound(trans => trans.TimeTaken).Title("Taken")
.Format("{0:n2}")
.EditorTemplateName("TimeTakenEditor").Width(70);
columns.Command(command =>
{
command.Edit();
command.Destroy();
}).Width(250).Title("Action");
})
.ToolBar(toolbar => toolbar.Create().Text("New entry"))
.Editable(editable => editable.Mode(GridEditMode.InLine)
.Sortable()
.Pageable(pager => pager
.PageSizes(new int[] { 5, 10, 20, 50, 100 }).Info(true).Messages(messages => messages.Empty("No entry")
.Display("Showing entries from {0} to {1}. Total entries: {2}").ItemsPerPage("entries per page"))
)// Enable paging
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.ServerOperation(true)
.Events(events => events.Error("datasource_error_handler")
.Model(model =>
{
model.Id(p => p.TimesheetId);
})
.Read(read => read.Action("Read", "Timesheet))
.Create(update => update.Action("Create", "Timesheet"))
.Update(update => update.Action("Update", "Timesheet"))
.Destroy(update => update.Action("Destroy", "Timesheet"))
))
EditorTemplates/DateEditor.cshtml
#model DateTime
#(Html.Kendo().DatePickerFor(m => m)
.Format("{0:yyyy-MM-dd}").Max(DateTime.Now.Date.AddDays(1).AddTicks(-1)))
EditorTemplates/TimeEditor.cshtml
#model DateTime?
#(Html.Kendo().TimePickerFor(m => m))
EditorTemplates/TimeTakenEditor.cshtml
#model int
#(Html.Kendo().NumericTextBoxFor(m => m)).Min(0).Max(int.MaxValue)
.Format("# min"))
In this code, each column has its own editor template.
What I need here is to combine some fields into a single cell in inline editing mode.
For example :
Start date and time into a single cell,finish time and time taken into another single cell.
EditorTemplates/StartDateTimeEditor.cshtml
#model DateTime?
#(Html.Kendo().DatePickerFor(m => m) // It's for Start Date
.Format("{0:yyyy-MM-dd}").Max(DateTime.Now.Date.AddDays(1).AddTicks(-1)))
#(Html.Kendo().TimePickerFor(m => m)) // It's for Start Time
EditorTemplates/FinishTimeAndTimeTakenEditor.cshtml
#model object
#(Html.Kendo().TimePickerFor(m => m)) // It's for Finish Time
#(Html.Kendo().NumericTextBoxFor(m => m)).Min(0).Max(int.MaxValue)
.Format("# min")) // It's for Time Taken
Is it possible in Kendo UI Grid ?
I don't find any documentation to support this features in Telerik Kendo UI.
Any help is appreciated.
Thank you.
You are so close! Just put two or more of your fields in the same editor template. So maybe start and finish date in the same editor, then that column uses that editor template but only one cell, if you seen what I mean? Imagine the below in a single editor template:
#model DateTime?
#model object
#(Html.Kendo().DatePickerFor(m => m) // It's for Start Date
.Format("{0:yyyy-MM-dd}").Max(DateTime.Now.Date.AddDays(1).AddTicks(-1)))
#(Html.Kendo().TimePickerFor(m => m)) // It's for Start Time
EditorTemplates/FinishTimeAndTimeTakenEditor.cshtml
#(Html.Kendo().TimePickerFor(m => m)) // It's for Finish Time
#(Html.Kendo().NumericTextBoxFor(m => m)).Min(0).Max(int.MaxValue)
.Format("# min")) // It's for Time Taken