Kendo Grid ClientTemplate conditional column - asp.net-mvc-4

I am working with ASP.NET MVC 4 with Kendo UI(kendo grid).Below is sample code of Kendo Grid -
#(Html.Kendo().Grid(Model.Users).Name("Grid").Columns(columns =>
{
columns.Bound(p => p.FirstName);
columns.Bound(p => p.LastName);
columns.Bound(p => p.UserName);
columns.Bound(p => p.Email);
columns.Bound(o => o.IsActive).ClientTemplate(links).Title("Action");
})
In the above code my IsActive column have some links for Actions like Edit,Update,Delete.And i am adding those links into Kendo grid by links variable.And I want to use links variable on the basis of conditions.Means i want conditional ClientTemplate here.
So anyone suggest how can make a conditional ClientTemplate in kendoGrid ?
2) Also i want to add condition on the basis on the bool field value of my model(Model.Users).
So i want to know how we can get that field from Model.Users model in kendo grid for each row.Like -
.ClientTemplate(if(IsAdmin && ViewBag.IsActive){.....} else{....})

You can try like below code..may be this help you..
columns.Bound(p => p.Active).ClientTemplate("\\#if('#=Active#'=='Y') {\\<input type='button' value='OK' />\\}\\#");
or may be use
"#= (Active) ? ' ' : 'your code here' #"

You can use the following piece of code:
#(Html.Kendo().Grid(Model.Users).Name("Grid").Columns(columns =>
{
columns.Bound(p => p.FirstName);
columns.Bound(p => p.LastName);
columns.Bound(p => p.UserName);
columns.Bound(p => p.Email);
columns.Bound(o => o.IsActive).ClientTemplate("#if(IsActive){#<a href='javascript:void(0)' >Edit</a>#}#").Title("Action");
})

I'm concatenating a name and using a javascript function which made condition testing much easier, plus you can get access to multiple fields:
cshtml:
#(Html.Kendo().Grid<Debtors>()
.Name("Debtors")
.Columns(columns =>
{
columns.Bound(c => c).Title("Name").ClientTemplate("#=showName(data)#");
columns.Bound(c => c.Busname);
...
})
...
)
js:
function showName(data) {
var returnName = "";
if (data.Lname) {
returnName = data.Lname;
if (data.Fname) {
returnName += ", " + data.Fname;
if (data.Mi) {
returnName += " " + data.Mi;
}
}
}
return returnName;
}

Related

kendodropdownlist not binding value to model after post

I'm using kendo UI for my project. I have a kendo dropdownlist that I'm populating with json. I get the values in my dropdownlist but on post, the model doesn't get the selected value of the dropdownlist. I have been stuck on it for a day with no result. I'm not sure where I'm going. Please review the code
View:
#model IEnumerable<EntityFrameworkClasses.StaggingException>
#foreach (var item in Model)
{
#(Html.Kendo().DropDownListFor(modelItem => item.Level2)
.Name("Level2")
.HtmlAttributes(new { style = "width:10%" })
.OptionLabel("Select level 2...")
.DataTextField("Text")
.DataValueField("Value")
.BindTo((System.Collections.IEnumerable)ViewBag.Level2)
)
}
#(Html.Kendo().Grid(Model)
.Name("CashExceptionsGridTest")
.Columns(columns =>
{
columns.Bound(p => p.Category).Title("Category").Width(130);
columns.Bound(p => p.EnterText1).Title("Comments").Width(130);
columns.Bound(p => p.Dateoftransaction).Title("Date").Width(130);
columns.Bound(p => p.InternalLocalAmount).Title("InternalAmt").Width(130);
columns.Bound(p => p.ExternalLocalAmount).Title("ExternalAmt").Width(130);
})
.ToolBar(toolbar =>
{
//toolbar.Template("<a class='k-button k-button-icontext' onclick='customCommand()' href='#'></span>Cutom Command</a>");
toolbar.Create(); // The "create" command adds new data items.
toolbar.Save();// The "save" command saves the changed data items.
})
.Editable(editable => editable.Mode(GridEditMode.InCell)) // Use in-cell editing mode.
.HtmlAttributes(new { style = "height: 550px;" })
.HtmlAttributes(new { style = "height: 350px;" })
.Pageable(pageable => pageable
.Input(true)
.Numeric(false)
)
.Reorderable(r => r.Columns(true))
.Sortable()
.ColumnMenu()
.Scrollable(scr => scr.Height(430))
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.ServerOperation(false)
.Batch(true) // Enable batch updates.
.Model(model =>
{
model.Id(p => p.RowID); // Specify the property which is the unique identifier of the model.
model.Field(p => p.RowID).Editable(false); // Make the ProductID property not editable.
})
.Update("Editing_Update", "MultiTab")
.Create("Editing_Create", "MultiTab")
)
)
}
I have a kendo grid below which im not including for code brevity.
Controller:
public ActionResult GetLevel()
{
IEnumerable<SelectListItem> Level2 = db2.StaggingInternalCashExceptions.Where(x=>x.LoadID==loadid).Select(c => new SelectListItem
{
Value = c.Level2.ToString(),
Text = c.Level2
}).Distinct();
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Editing_Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<StaggingException> results)
if (results != null && ModelState.IsValid)
{
foreach (var result in results)
var entity = new StaggingException();
entity.RowID = result.RowID;
entity.Category = result.Category; //this is a textbox in the view for which i get the value
entity.Level1 = result.Level1; //gives null
//I'm adding those values to the db. Didn't include all that for the sake of keeping it short.
}
}
The grid has batch editing, once i hit on save changes, the grid's data is posted to the controller where i can see it in results. I cannot get the dropdown value though.
Any ideas or leads please.
Thank you.
Late to this post but I have had a similar issue, for those with the same problem of the value not being posted in the model, if your model value is a nullable int? (can't see from the above post...) then you need to configure the DropDownListFor as below to avoid the default value binding behavior to update the field with the selected item when the initial value is null. Hope this helps someone.
Html.Kendo().DropDownListFor(m => m)
.HtmlAttributes(new { data_value_primitive = "true" })

Display two values foreign key in kendo Grid MVC

I'm so tired to resolve this problem. I just want to display two values, For example in columns.Foreignkey. Showing Name and Id on the same columns. How do I do this?
#(Html.Kendo().Grid<Project_Test.Models.Workcenter>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.WorkcenterCode)
.Width(80)
.Title("Workcentercode")
.ClientTemplate("");
columns.Bound(p => p.WorkCenterSection)
.Width(84)
.Title("WorkcenterSection");
columns.ForeignKey(p => p.WorkcenterCategory,
(System.Collections.IEnumerable)ViewBag.WorkcenterCategory,
"WorkcenterCategoryID",
"WorkcenterCategoryName")
.Title("Category")
.Width(200);
//command.Custom("Details").Click("showDetails").HtmlAttributes(new { #class = "k-font-icon k-i-insert-unordered-list " });
command.Custom(" ")
.Click("showDetails")
.HtmlAttributes(new { #class = "btn btn-default btn-xs glyphicon glyphicon-list-alt" })
.Width(230);
})
//.Events(e => e.DataBound("onDataBound"))
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable
.Mode(GridEditMode.PopUp)
.TemplateName("Workcent")
.DisplayDeleteConfirmation("Are you sure to delete this Workcenter")
)
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.Messages(messages => messages.Refresh("Click to refresh"))
.ButtonCount(8)
)
.Groupable()
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
.Selectable()
.Scrollable()
.HtmlAttributes(new { style = "height:580px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Model(model =>
{
model.Id(p => p.WorkcenterID);
model.Field(p => p.WorkcenterID).Editable(true);
model.Field(p => p.UpdatedBy).DefaultValue(User.Identity.Name);
model.Field(p => p.CreatedBy).DefaultValue(User.Identity.Name);
})
.Create(update => update.Action("Employee_Create", "Home"))
.Read(read => read.Action("List", "Home"))
.Update(update => update.Action("Products_Update", "Home"))
.Destroy(update => update.Action("adress_Destroy", "Home"))
)
)
The ForeignKey column is just displaying the WorkcenterCategoryName associated with the corresponding WorkcenterCategoryID from the bound list(ViewBag.WorkcenterCategory).
Just make the WorkcenterCategoryName of each element in ViewBag.WorkcenterCategory contain the text you actually want to display, i.e.
"IDOfSelectedItem (TextOfSelectedItem)"
instead of just
"TextOfSelectedItem"
Edit to be more specific:
I'm assuming your server action is filling ViewBag.WorkcenterCategory something like:
ViewBag.WorkcenterCategory = GetWorkcenterCategories()
.Select(x => new
{
WorkcenterID = x.ID,
WorkcenterName = x.Name
});
Let's say this returns the list:
{ WorkcenterID = 1, WorkcenterName = "One" },
{ WorkcenterID = 2, WorkcenterName = "Two" }
Then the ForeignKey column maps a particular key to the corresponding item in the list bound to it (ViewBag.WorkcenterCategory) and the text value associated to the key will be displayed, whatever is contained in the WorkcenterName field.
i.e. value of 1 will display "One" in the grid.
If you want to display more than just the name of the Workcenter, then set the WorkcenterName of the objects in the ViewBag.WorkcenterCategory list to the text you want to have displayed, i.e.:
ViewBag.WorkcenterCategory = GetWorkcenterCategories()
.Select(x => new
{
WorkcenterID = x.ID,
WorkcenterName = x.ID + " (" + x.Name + ")"
});
This would return the list:
{ WorkcenterID = 1, WorkcenterName = "1 (One)" },
{ WorkcenterID = 2, WorkcenterName = "2 (Two)" }
And a value of 1 would now display "1 (One)" instead of just "One".

Kendo UI Grid CRUD firing multiple times

I have a kendo UI grid in my page. Below is the code of kendo UI grid with CRUD datasource actions.
#(Html.Kendo().Grid<Gts.GlaspacLX.Web.ViewModel.ProductViewModel>()
.Name("xyzGrid")
.Columns(columns =>
{
columns.Bound(p => p.SelectedProductCategory).EditorTemplateName("_ProductDropDownList").Title("Product Category").HtmlAttributes(new { #tabindex = "8" });
columns.Bound(p => p.Name).Width(130).Title("% Off").HtmlAttributes(new { #tabindex ="9" });
columns.Bound(p => p.Rate).Width(130).HtmlAttributes(new { #class = "prodDiscRtAlign",#tabindex= "10" });
columns.Bound(p => p.Hours).Width(130).HtmlAttributes(new { #class = "prodDiscRtAlign",#tabindex= "11" });
if (SiteContext.CurrentUser.HasPrivilege(PrivilegeNames.Maintenance, PermissionNames.DELETE))
{
columns.Command(command => { command.Destroy(); }).Width(110).Title("Delete").HtmlAttributes(new { #tabindex = "12" });
}
})
.ToolBar(commands =>
{
commands.Create();
commands.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell).CreateAt(GridInsertRowPosition.Bottom))
.Sortable()
.Navigatable()
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.Model(model =>
{
model.Id(p => p.ProductID);
model.Field(p => p.SelectedProductCategory).DefaultValue(ViewBag.DefaultProductCategory);
})
.Read(read => read.Action("Product_Read", "ProductController"))
.Update(update => update.Action("Product_Update", " ProductController "))
.Create(create => create.Action("Product_Create", " ProductController "))
.Destroy(update => update.Action("Product_Destroy", " ProductController ")
))
.Events(e => e.Edit("proField").DataBound("boundProductChange"))
)
Below is the screen shot of "Save" button just after the kendo grid. It's responsible for any create/update operation of the page.
My problem is once I clicked on Save button for any create or update operation its posting the action method twice. You can see the console of above screen shot.
Below is the piece of the code of my controller's action method:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Product_Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<ProductViewModel> product){
return Json(results.ToDataSourceResult(request, ModelState));
}
Below is proField function code :-
function proField(e) {
var defaultproduct = $("#DefaultProductCategory").val();
defaultproduct = "\n" + defaultproduct + "select ";
if (e.model.SelectedProductCategory == "Default" && (e.sender._editContainer[0].textContent == defaultproduct || e.sender._editContainer[0].textContent == "\n select ")) {
e.sender._editContainer[0].disabled = true;
e.sender._editContainer[0].children[0].textContent = "Default";
e.sender.table[0].rows[1].cells[1].click();
e.sender.table[0].rows[1].cells[4].disabled = true;
}
}
after insert any record you should return primary(Id) key to view.
see kendo demo.

Kendo Grid Aggregation for Footer

I'm trying to achieve showing the sum of a column as a footer. Following official Kendo UI demos, my code is as follows :
#(Html.Kendo().Grid<ORMIModel.Content.ContentPurchase.CheckoutListModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.ContentId).ClientTemplate("<a href='javascript:void(0);' onclick='RemoveFromCart(#=ContentId#)'>#=CategoryName#</a>").Width(50).Sortable(true);
columns.Bound(p => p.CategoryName).Width(140).Sortable(true);
columns.Bound(p => p.ModelYear).Width(100).Sortable(true);
columns.Bound(p => p.PurchasePeriod).Width(100).Sortable(true);
columns.Bound(p => p.PurchasePeriodCount).Width(50).Sortable(true);
columns.Bound(p => p.FeeFormatted).Width(50).Sortable(true).ClientFooterTemplate("#=sum#");
})
.Sortable()
.ClientDetailTemplateId("detailTemplate")
.Events(v => v.DetailExpand("detailExpand"))
.DataSource(dataSource => dataSource
.Ajax()
.Aggregates(v => { v.Add(p => p.Fee).Sum(); })
.Read(read => read.Action("ListContentForCheckout", "Content"))
)
As it can be seen above, I'm properly defining the aggregate field, and applying it as #=sum# to my last column's clientFooterTemplate.
However, I'm getting an error as "Uncaught ReferenceError: sum is not defined "
My datasource has the Fee attribute aswell. Any idea about what I'm doing wrong?
I believe this is caused by your column:
columns.Bound(p => p.FeeFormatted).Width(50).Sortable(true).ClientFooterTemplate("#=sum#");
is targeting the FeeFormatted property but the sum aggregate is processed against the p.Fee property.
try changing the column
columns.Bound(p => p.FeeFormatted).Width(50).Sortable(true).ClientFooterTemplate("#=sum#");
to
columns.Bound(p => p.Fee).Width(50).Sortable(true).ClientFooterTemplate("#=sum#");
to see if it works. then use the grid column .Format property to bring in the desired formatting of the Fee value
.Aggregates(aggregates =>
{
aggregates.Add(c => c.MrcPerUnit).Sum();
})
// it works with my own application

How the pop up works in the KendoUI grid and how to bring the controls in the pop up in KendoUI ajax grid for MVC4

How the popup window works when the edit button is click and how to bring the three Combobox in the popup. I am really confused with the below code
Client side Code
//show server errors if any
function error_handler(e) {
if (e.errors) {
var message = "Errors:\n\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n\n";
});
}
});
alert(message);
}
}
#(Html.Kendo().Grid(Model)
.Name("SchoolGrid")
.Columns(columns =>
{
columns.Bound(p => p.SchoolID).Width("80px");
columns.Bound(p => p.Name);
columns.Bound(p => p.Campus).Width("90px");
columns.Bound(p => p.StateCode).Width("90px");
columns.Bound(p => p.SectorCode).Width("95px");
columns.Bound(p => p.MDISurveyStartDate).ClientTemplate("#= (MDISurveyStartDate == null) ? 'Not Set' : kendo.toString(MDISurveyStartDate, 'dd/MM/yyyy') #").Width("90px");
columns.Bound(p => p.MDISurveyEndDate).ClientTemplate("#= (MDISurveyEndDate == null) ? 'Not Set' : kendo.toString(MDISurveyEndDate, 'dd/MM/yyyy') #").Width("90px");
columns.Command(command => { command.Edit(); command.Destroy(); }).Width("190px").HtmlAttributes(new { style = "text-align:center" });
})
.ToolBar(tb => tb.Create().Text("Add New School"))
.Editable(ed => ed.Mode(GridEditMode.PopUp).TemplateName("EditSchool").Window(w => w.Title("Add/Edit School Details").Name("editWindow").Width(600)))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.ClientID))
.Events(e => e.Error("error_handler"))
.Read("Read_Schools", "School")
.Update("Update", "School")
.Create("Create", "School")
.Destroy("Destroy", "School")
)
)
Server Side Code:-
[HttpPost]
public ActionResult Update([DataSourceRequest] DataSourceRequest request, School school)
{
try
{
if (ModelState.IsValid)
{
string errMsg = "";
if (!_Service.UpdateSchool(school, out errMsg))
ModelState.AddModelError("UpdateSchool", errMsg);
}
}
catch (Exception ex)
{
ModelState.AddModelError("UpdateSchool", ex.Message);
}
return Json(ModelState.ToDataSourceResult());
}
There is code library which shows how to manipulate the content of the Window. Rest of the editing is possible through the edit event of the Grid (check documentation).