Kendo Grid Inline Incell Editing Currency Format changes in Editing Field - asp.net-mvc

I'm using a Kendo Grid.
#(Html.Kendo().Grid<Kosten>()
.Name("gridKosten")
.Columns(columns =>
{
columns.Bound(c => c.Costs);
})
.DataSource(dataSource => dataSource
.Ajax()
.Events(events => events.Error("gridError"))
.Model(model => model.Id(c => c.Id))
.Create(create => create.Action("Kosten_Create", "FahnenSettings"))
.Read(read => read.Action("Kosten_RetrieveAll", "FahnenSettings"))
.Update(update => update.Action("Kosten_Update", "FahnenSettings"))
)
.Editable(editable => editable
.Mode(GridEditMode.InLine)
)
.ToolBar(toolbar => toolbar.Create())
)
Also I set the culture to German.
<script src="https://kendo.cdn.telerik.com/2020.1.219/js/cultures/kendo.culture.de-DE.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.219/js/messages/kendo.messages.de-DE.min.js"></script>
<script>
$(function () {
kendo.culture("de-DE");
})
</script>
Everything works fine. In my column "Costs" the displayed value is like "1.245,21 €". But when I'm activating the "Edit" function, the value in the input has changed to "1245.21" (check the separator). Do I change the value now to something like "1245.20", the value will become "124.520,00 €".
So if I want to have the correct value, I always have to change back the separator "." to "," manually. My culture is set to German, it shows the german value and it interprete the german spelling with comma correctly after editing. But in the moment I open the inline editing mode, the separator is changing to us format with a dot.
How can I avoid that? Someone has an idea?
The column property is set in the model like
[DataType(DataType.Currency)]
public decimal Costs { get; set; }

For anyone who has the same problem.
I solved it by including the "~\Views\Shared\EditorTemplates" folder. I removed it at the beginning from my solution because I thought these Views were only examples and didn't thought they were actually used. The grid wanted to use the missing "Currency.cshtml" in it.

Related

kendo grid - dynamic column with cell format from database

I have a SQL Table result.
ProductNumber ProductNumberColorClass OrderNumber OrderNumberColorClass
I am trying to use Kendo to render this information. Basically i need the output as
ProductNumber OrderNumber
Data value and Apply Css class( ProductNumberColorClass )
Basically this is a report with a lot of columns. The user can select only the columns that he wants to see.
I am able to render the grid using the examples from the web site. I am not able to apply.
My application is Asp.net mvc application
Update
I will try your feedback. This is my code. Basically i wanted to avoid coding for each column as the list is big around 50 . the report can be customized so the user can hide some columns. .So i used a loop. however in this scenario, the clienttemplate is not work. I am not very sure, if it is a code issue too.
If you can find what is wrong in my code it will help me learn about the issue too.
meanwhileI am going to manually type the columns and add a attribute as visible
#(Html.Kendo().Grid <DataTransferObjects.ViewModels.UserReportDataModel>()
.Name("Grid")
.HtmlAttributes(new { style = "height: 550px;" })
.Pageable(pageable => pageable
.Input(true)
.Numeric(false)
)
.Sortable()
.Scrollable(
scr => scr.Height(430)
)
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("GetReportData", "ShortTermPlanner").Data("AdditionnalParameters"))
.PageSize(20)
.ServerOperation(false)
)
.Columns(columns =>
{
var colIndex = 0;
foreach (var col in Model.lstHeaderInformation)
{
if (col.SqlColumnName == "ProductNumber")
{
columns.Bound(col.SqlColumnName)
.Title(col.ColumnHeader)
.Filterable(false)
.Visible(col.IsVisible)
.Width(1190)
.ClientTemplate("<div style='background-color:red; text-align:center;width:70px'> #= ProductNumber # </div>");
}
else
{
columns.Bound(col.SqlColumnName)
.Title(col.ColumnHeader)
.Filterable(true)
.Visible(true)
.Width(300)
.Locked(true)
.HtmlAttributes(new { #class = "selectedRow" });
}
}
})
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
)
Update 2 Adding the clienttemplate and specifying the column information worked. Thanks
However i am curious, is there a better way where i can loop through a 3 table which defines the column name, title and class that needed to be displayed and applied to my report.
what i am looking is
MY Report -- Select * from Report
My header table Select colname, title, class from reportcoldefinication
so now for each matching colname from reportcoldefinication
and Report. add a col to the grid with the class applied.
You can use the template functionality for columns in the Kendo grid.
columns.Template(#<div class= '#=ProductNumberColorClass #'> #= ProductNumber#<div/>)
Have implemented one in the example in the below link. Its implemented using JQuery but you can use the razor syntax for kendo for achieving the same.
http://dojo.telerik.com/ukIma/3

Accessing row data from Kendo Grid ClientTemplate

I am trying to embed a chart in a Kendo Grid Cell, following this example: http://docs.telerik.com/kendo-ui/aspnet-mvc/helpers/grid/faq#how-do-i-use-a-kendo-ui-widget-inside-a-grid-client-column-template
I have managed to embed the graph in the grid, but I am unable to find a way to bind to row data.
The ViewModel has properties for each bar value - but how do I bind to those properties (maybe some #= ... # expression?).
I expect something similar to this:
#(Html.Kendo().Grid<ViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.DataID).Filterable(false);
columns.Template(#<text></text>).ClientTemplate(
Html.Kendo().Chart()
.Name("chart#=DataID#")
.Series(series =>
{
series.Bar("\\#= FirstBarValue \\#");
series.Bar("\\#= SecondBarValue \\#");
})
.ToClientTemplate().ToHtmlString()
);
})
.DataSource(dataSource => dataSource.Ajax().PageSize(20).Read(read => read.Action("Read", "Grid"))))
But the FirstBarValue and SecondBarValue are not properly evaluated, although DataID is. Maybe a different scope? I can only make it work with hard coded values.
Any suggestions?

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 mvc grid batch mode dataItem.set clears the dirty flags

When I change an amount, tick the checkbox etc, it triggers some javascript, which includes some code to set another field on the dataItem, so dataItem.Set ("Amount", 0);
I can set it using dataItem.Amount = 0; , but then I also need to update the contents of the cell. When I do set I obviously don't want the dirty flag clearing from other cells, as I haven't clicked 'Save changes' yet, so they are still 'dirty'.
I can't find any documentation on the .set method.
Any advice would be appreciated.
#(Html.Kendo().Grid<OurViewModel>()
.Name("Grid")
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(a => a.ID);
model.Field(a => a.Reference).Editable(false);
model.Field(a => a.Narrative).Editable(false);
model.Field(a => a.Include).Editable(true);
model.Field(a => a.Amount).Editable(true);
})
.Batch(true)
.Read(read => read.Action("_Read", "Home"))
.Update(update => update.Action("_Update", "Home"))
.ServerOperation(false)
.Events(events =>
{
events.Change("onDataSourceChange");
})
)
.Columns(columns =>
{
columns.Bound(a => a.Reference).Title("Reference");
columns.Bound(a => a.Narrative).Title("Narrative");
columns.Template(#<text></text>).Title("Include?")
.ClientTemplate("<input type='checkbox' #= Include ? checked='checked': '' # onclick='updateAmount(this, \"#= ID#\")' />");
columns.Bound(a => a.Amount).Title("Amount");
})
.Events(events =>
{
events.Save("onSave");
events.SaveChanges("onSaveChanges");
})
.ToolBar(toolbar =>
{
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
)
and the JS.
function updateAmount(cb, ourID) {
var checked = $(cb).is(':checked');
var grid = $('#Grid').data().kendoGrid;
var dataItem = grid.dataSource.get(ourID);
dataItem.set("Include", checked);
if (checked) {
dataItem.set("Amount", dataItem.get("OriginalAmount"));
} else {
dataItem.set("Amount", 0);
}
}
When calling the set method on an observable object (Note: Each dataItem in the dataSource in converted to a kendo ObservableObject when loaded) any widgets that our bound to the dataItem will be updated, in this case your grid is the bound widget.
If you set the value directly (i.e. dataItem.Amount = 0) none of the observable object's binding events will trigger and the grid (or any other widgets bound to the dataItem) will NOT update. You should always use set when modifying fields of an observable object in order to keep the UI up to date.
Within the dataSource, there are no dirty flags for the individual fields in the dataItem. The dataItem itself will have a field named "dirty" which will be set to true whenever ANY of its fields change. Changing more than 1 field will just keep setting dirty = true for the entire dataItem. You don't need to worry about tracking modified fields. Once a row is dirty it will stay dirty until you save the data.
When you save the contents of the grid (a.k.a. sync the dataSource) any (and only) rows with dirty = true will be sent to the server. Once saved, the dirty flags will be removed. On that note, you will want to refrain from using "dirty" as a table property in your database.
The kendo documentation at is pretty complete but I would highly recommend tracing through the kendo javascript code to really learn it. One last note, I started with the Kendo MVC approach hoping to leverage by C# knowledge but soon found it much easier to just code all the client side in JavaScript. All your C# code gets converted to rather verbose JavaScript anyway each time the server it hit. This puts unnecessary load on the server and makes client side debugging harder IMO.

Sorting a Kendo Grid changes its columns widths

I've got a Kendo Grid like this:
<%: Html.Kendo()
...
.Pageable()
.Columns(c => {
c.Bound(x => x.ProductId).Width(80);
c.Bound(x => x.ProductCode).Width(40);
c.Bound(x => x.ProductName).Width(80);
c.Bound(x => x.Created).Format("{0:yyyy-MM-dd}").Width(70);
c.Bound(x => x.CreatedBy).Width(80);
})
.Sortable()
.Selectable()
...
When you click on a column header an up or down arrow appears to indicate sorting. So far so well, but the sort arrow makes the column expand its width which is very annoying. I want to avoid the columns changing their width, how do you do that?
Adding css rule to the grid's table: table-layout:fixed should resolve your problem.

Resources