How to create nested grid in kendo? - kendo-grid

I am trying to create a nested grid that will fetch data and populate into 2 grid, parent and a child.
Child grid has only 1 parent
Child grid limited to adding 16 rows
Removing the parent row will re-fetch data from server
Child grid is always open
It similar to this http://dojo.telerik.com/UqURE
But finally should look like this https://photos.app.goo.gl/X6fcZ79779bgjrRZ8

You need to have two kendo grid in your view and two javaScript Method to gets your additional data az method parameters :
The parent grid and its child should be something like this :
<div class="row">
<div class="col-md-12">
#(Html.Kendo().Grid<ProjectName.Models.ViewModel.TasksStaticViewModel>()
.Name("grid")
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("ReadActionName", "ControllerName").Data("additionalData"))
)
.Columns(columns =>
{
columns.Bound(c => c.Column1).HtmlAttributes(new { style = "text-align:center; overflow: hidden; white-space: nowrap;" }).HeaderHtmlAttributes(new { style = "text-align:center;" }).Width(130);
columns.Bound(c => c.Column2).HtmlAttributes(new { style = "text-align:center; overflow: hidden; white-space: nowrap;" }).HeaderHtmlAttributes(new { style = "text-align:center;" }).Width(135);
})
.ToolBar(tool => tool.Template(
#"<a id='lnkexportExcel' class='k-button k-button-icontext ' href='/Report/Tasks'><span></span>ExportToExcel</a>))
.Pageable()
.AutoBind(false)
.Sortable()
.Scrollable(s => s.Enabled(true))
.ClientDetailTemplateId("template")
)
</div>
<div class="col-md-12">
<script id="template" type="text/kendo-tmpl">
#(Html.Kendo().Grid<ProjectName.Models.ViewModel.MyViewModel>()
.Name("grid_#=Id#")
.Columns(columns =>
{
columns.Bound(c => c.SubColumn1).HtmlAttributes(new { style = "text-align:center; overflow: hidden; white-space: nowrap;" }).HeaderHtmlAttributes(new { style = "text-align:center;" }).Width(100);
columns.Bound(c => c.SubColumn2).HtmlAttributes(new { style = "text-align:center; overflow: hidden; white-space: nowrap;" }).HeaderHtmlAttributes(new { style = "text-align:center;" }).Width(100);
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("ReadActionName", "ControllerName",
new { AgentSelectedId = "#=AgentId#", TaskHeaderSelectedId = "#=TaskHeaderId#"})
.Data("additionalData2"))
)
.Pageable()
.Sortable()
.ToClientTemplate()
)
</script>
</div>
And the two additional data which js javascript code :
function additionalData() {
return someModel;}
function additionalData2() {
return someModel;}
If it was useful, check it as an answer, please

Related

Kendo MVC Grid - Dropdown with inline editing

i have searched all over for a solution and tried many of the advises that was given (just saying if you think I'm too lazy)
I'm a bit of a Kendo noob, so not sure what I'm missing?
As the title say, I got a grid of items and want to edit them inline. all works fine, but it seems that my editor template just get ignored and 2 inputs get shown when in edit mode (since the child object that must be selected is a complex object with Id and Name properties)
ps: sorry bout formatting. seems my browser don't show this windows toolbar?
Kendo MVC Grid
Html.Kendo().Grid<MyViewModel>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(o => o.Id).Hidden(true);
columns.Bound(o => o.Product).EditorTemplateName("ProductsListTemplate");
...other columns
columns.Command(command =>
{
command.Edit();
command.Destroy();
}).Width(180);
})
.AutoBind(true)
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.InLine).Enabled(true))
.Filterable(ftb => ftb.Mode(GridFilterMode.Row))
.Resizable(resize => resize.Columns(true))
.Selectable(sel => sel.Mode(GridSelectionMode.Single)
.Enabled(true))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Model(model =>
{
model.Id(c => c.Id);
model.Field(c => c.Product).Editable(true);
...other fields...
})
.Create(update => update.Action("Create", "MyController"))
.Read(read => read.Action("Read", "MyController"))
.Update(update => update.Action("Edit", "MyController"))
.Destroy(update => update.Action("Delete", "MyController"))
))
ProductsListTemplate.cshtml (in Shared/EditorTemplates, product options are present in the viewdata as IEnumerable )
#(Html.Kendo().DropDownList()
.Name("MyChildViewModel")
.DataValueField("Id")
.DataTextField("Name")
.BindTo((IEnumerable) ViewData["ProductOptions"])
)
MyViewModel
public class MyViewModel
{
public int Id { get; set; }
[Display(Name = "Product")]
[UIHint("ProductsListTemplate")]
public MyChildViewModelProduct { get; set; }
... other properties
public class MyChildViewModel
{
public string Id { get; set; }
public string Name { get; set; }
}

How to add class to a kendo grid table header?

Here is my kendo grid,
#(Html.Kendo().Grid<example.Web.Areas.Models.PredictedValues>()
.Name("MyGrid")
.Columns(column =>
{
column.Bound(p => p.Rlno).Title("Roll no").HtmlAttributes(new { #class = "someclass" });
column.Bound(p => p.stdname).Width(60).Title("Std name").HtmlAttributes(new { style = "text-align:right;" });
column.Bound(p => p.school).Width(50).Title("School").HtmlAttributes(new { style = "text-align:right;" });
})
))
I need to apply some stylings through class to the header names. the included #class is not working for the header. Instead, it is bounding to the table rows. How do i do? Any idea?
Did you try:
column.Bound(p => p.Rlno).Title("Roll no").HeaderHtmlAttributes(new { #class = "someclass" });
.HeaderHtmlAttributes adds a class to the header only.
To add a css class to the gridcell - as an example here I am targetting the Status column - you want to style the grid values... you want to do this instead.
columns.Bound(m => m.Status).Title("Status").HtmlAttributes(new { #class = "someclass" });

Kendo DateTimePicker set value from json result

I have a big trouble with pasting a value in Kendo DateTimePicker inside Kendo Grid from json result. So I have two forms on page. In first I'm loading file:
#using (Html.BeginForm("GetImportSalesModelFromFile", "ExportImport", FormMethod.Post, new { id = "GetImportSaleModelFromFileForm", enctype = "multipart/form-data" }))
{
<input id="importFileInput" type="file" accept="text/csv" name="file" class="user-success" required>
<input style="width: 100px;" type="submit" value="Add">
}
On form submit called function
$('#GetImportSaleModelFromFileForm').submit(function(e) {
e.preventDefault();
var url = $(this).attr('action');
var xhr = new XMLHttpRequest();
var fd = new FormData();
fd.append("file", document.getElementById('importFileInput').files[0]);
xhr.open("POST", url, true);
xhr.send(fd);
xhr.addEventListener("load", function(event) {
AppendImportModel(JSON.parse(event.target.response));
}, false);
});
In controller I get needed import model
public ActionResult GetImportSalesModelFromFile(HttpPostedFileBase file)
{
var importModel = _importService.ConstructSaleImportModel(file.InputStream, file.ContentType);
return Json(importModel, JsonRequestBehavior.AllowGet);
}
In function AppendImportModel I parse result and paste it in kendo grid in second form
#(Html.Kendo().Grid<ImportSaleItemModel>().Name("ImportSalesGrid")
.DataSource(dataSource => dataSource.Ajax())
.Events(x => x.DataBound("initMenus"))
.Columns(columns =>
{
columns.Bound(x => x.Goods.PictureId)
.ClientTemplate("<img style='height: 50px;' src='" + Url.Action("Contents", "FileStorage", new { id = "#= Goods.PictureId #" }) + "'/>")
.Title("")
.Sortable(false)
.HtmlAttributes(new Dictionary<string, object> { { "style", "padding: 3px !important; height: 52px !important; width:52px !important;" } });
columns.Bound(x => x.Goods.Title)
.ClientTemplate("<a onclick='ShowInfoGoodWindow(#= Goods.Id #)'>#= Goods.Title #</a><br>" +
"<span><b>#= Goods.Article #</b> <descr>#= Goods.Description #</descr></span><br><input type='hidden' name='ImportedGoodList[#= index(data)#].Id' value='#= Goods.Id #' />")
.Title("Description");
columns.Bound(x => x.Price)
.ClientTemplate("<input class='priceEditor' maxlength='10' style='width:50px; text-align: center;' type='text' name='ImportedGoodList[#= index(data)#].Price' onkeypress='return isPriceKey(event)' oninput='$(this).get(0).setCustomValidity(clearValidation);' value='#=Price.ParsedValue #'>")
.HtmlAttributes(new Dictionary<string, object> { { "style", "text-align: center;" } })
.Title("Price");
columns.Bound(x => x.Discount)
.ClientTemplate("<input class='discountEditor' maxlength='10' style='width:50px; text-align: center;' type='text' name='ImportedGoodList[#= index(data)#].Discount' onkeypress='return isPriceKey(event)' oninput='$(this).get(0).setCustomValidity(clearValidation);' value='#=Discount.ParsedValue #'>")
.HtmlAttributes(new Dictionary<string, object> { { "style", "text-align: center;" } })
.Title("Discount");
columns.Bound(x => x.DepartmentId)
.HtmlAttributes(new { #class = "templateCell" })
.ClientTemplate(Html.Kendo().DropDownList().Name("Department#=LineId#").BindTo(Model.Departments).Value("#= DepartmentId #").ToClientTemplate().ToHtmlString())
.Title("Department");
columns.Bound(x => x.SaleDateTime)
.HtmlAttributes(new { #class = "templateCell" })
.ClientTemplate(Html.Kendo().DateTimePicker().Name("SaleDateTime#=LineId#").Value("#= ConvertedSaleDateTime #").ToClientTemplate().ToHtmlString())
.Title("Sale Date");
columns.Bound(x => x.SellerId)
.HtmlAttributes(new { #class = "templateCell" })
.ClientTemplate(Html.Kendo().DropDownList().Name("Seller#=LineId#").BindTo(Model.Sellers).Value("#= SellerId #").ToClientTemplate().ToHtmlString())
.Title("Seller");
columns.Bound(x => x.IsCashPayment)
.ClientTemplate("<input type='checkbox' id='IsCashPayment#=LineId#' checked='#= IsCashPayment.ParsedValue #' class='regular-checkbox'/><label for='IsCashPayment#=LineId#'></label> Yes")
.Title("Is Cash Payment");
})
)
In all columns using "#= value #" works fine but not in this line
.ClientTemplate(Html.Kendo().DateTimePicker().Name("SaleDateTime#=LineId#").Value("#= ConvertedSaleDateTime #").ToClientTemplate().ToHtmlString())
"#= ConvertedSaleDateTime #" not changed on real value, but if I write
.ClientTemplate("#= ConvertedSaleDateTime #")
I will get right value "10/07/2013 13:15". And if I write
.ClientTemplate(Html.Kendo().DateTimePicker().Name("SaleDateTime#=LineId#").Value("10/07/2013 13:15").ToClientTemplate().ToHtmlString())
I will get Kendo DateTimePicker inside grid with value "10/07/2013 13:15"
How I can set value to this DateTimePicker from ConvertedSaleDateTime?
Please, help me. Thanks in advance.
I solved my problem via jQuery. Maybe someone needs this solution or knows something more beautiful.
In client template of SaleDateTime columnt I wrote:
columns.Bound(x => x.SaleDateTime).ClientTemplate("<input class='saleDateTimeEditor' id='SaleDateTime#=index(data)#' name='ImportedSalesList[#=index(data)#].SaleDateTime' value='#= ConvertedSaleDateTime #'>")
And in DataBound event of my kendo grid I initialized all kendo DateTimePickers:
$('.saleDateTimeEditor').each(function () {
var id = $(this).attr('id');
var value = new Date(Date.parse($(this).val()));
$("#" + id).kendoDateTimePicker({
value: value,
max: new Date(Date.now())
});
$('#'+id).attr('readonly', 'readonly');
});
ConvertedSaleDateTime is in format "yyyy/MM/dd hh:mm:ss"

How to configure Kendo Dropdownlist to work with Grid popup editor template

I've been struggling with the Kendo dropdownlist for 2 days now and just can't seem to get it configured correctly.
How do I get the Kendo Dropdownlist to show the current item of the #Model? This is my code:
#Html.TextBoxFor(model => model.ShortDescription, new { #class="wide200;" })
#(Html.Kendo().DropDownList()
.Name("importance")
.HtmlAttributes(new { style = "width: 250px" })
.DataTextField("Name")
.DataValueField("ID")
.DataSource(source => {
source.Read(read =>
{
read.Action("GetImportanceList", "Home");
})
.ServerFiltering(true);
})
.SelectedIndex(0)
)
And in my controller:
public ActionResult GetImportanceList()
{
GenericRepository<Importance> _repository = new GenericRepository<Importance>(_context);
IEnumerable<ImportanceViewModel> list = _repository.Get().ConvertToViewModelList();
return Json(list, JsonRequestBehavior.AllowGet);
}
Problem is with SelectedIndex(0) which is set to the first item. How can I set it to whatever is in the model? It's very simple to do for the textbox (first line in the code): model => model.ShortDescription. But how does this work for the dropdownlist?
I don't just want to set it upon the showing of the editor, but also want the grid to know what the new selection is after I click the Update button.
Note that this is in a custom template for the grid popup editor.
Try this,
You have to pass DropDownListId in model and ListItems.
#(Html.Kendo().DropDownListFor(m=>m.DropDownListId)
.Name("importance")
.HtmlAttributes(new { style = "width: 250px" })
.DataTextField("Name")
.DataValueField("ID")
.DataSource(source => {
source.Read(read =>
{
read.Action("GetImportanceList", "Home");
})
.ServerFiltering(true);
})
.SelectedIndex(0)
)
I asked this question to Telerik. Apparently the Name mustn't be assigned.

Kendo DropDown filter and show in GridView

I have filter with dropdown cities. I wanna that when I choose city from dropdown lis and click button search to show data in gridview with this city.
First question
1) How to get value from dropdown and pass to button and call controller?
2) I tried without dropdown, when populate value directly in Read method but nothing, my gridview is empty.
This is my code
Partial View "Filter", View with gridview and method in controller that populate gridview.
#{
ViewBag.Title = "Filter";
}
<div class="filter-all">
<div class="filter-dropdown">
<div class="filter-part">
<div class="custom-label-div">
City:</div>
<div class="defaultSize">
#(Html.Kendo().DropDownList()
.Name("City")
.HtmlAttributes(new { style = "width:250px" })
.DataTextField("CityName")
.DataValueField("CityID")
.OptionLabel("...")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetCities", "Filter");
});
})
)
</div>
</div>
</div>
<div class="filter-buttons">
<div class="button-filter-div">
<input type="button" value="Search City" onclick="location.href='#Url.Action("Index", "MFS3")'" class="k-button" style="width: 80px"/>
<input type="button" value="Cancel" onclick="location.href='#Url.Action("Index", "Preview")'" class="k-button" style="width: 80px"/>
</div>
</div>
</div>
#model IEnumerable<MFS_App.Models.MFS3ViewModel>
<div class="right-content shadow">
<div class="preview-header">
Preview Reports</div>
<div class="preview-content">
#Html.Partial("_Filter")
</div>
</div>
<div class="parent-preview-content shadow">
<div class="child-preview-content">
#Html.Partial("_ReportsGridView")
<div class="mfs-title">
<div class="filter-preview-div">
#(Html.Kendo().Grid(Model)
.Name("GridMFS3")
.Columns(columns =>
{
columns.Bound(p => p.FirstName).HtmlAttributes(new { style="width:50px"});
columns.Bound(p => p.LastName).HtmlAttributes(new { style ="width:70px"});
columns.Bound(p => p.Address).HtmlAttributes(new { style = "width:80px"});
columns.Bound(p => p.Mail).HtmlAttributes(new { style = "width:100px" });
columns.Bound(p => p.County).HtmlAttributes(new { style = "width:70px" });
columns.Bound(p => p.City).HtmlAttributes(new { style = "width:50px" }); columns.Command(c => c.Edit());
})
.DataSource(source =>
{
source.Server()
.Model(model => model.Id(m => m.MFS3_ID))
.Read(read => read.Action("GetMFS", "MFS3", new { cityID = 251} ))
.Update(update => update.Action("Update", "MFS3"));
})
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Selectable(selectable => selectable.Mode(GridSelectionMode.Multiple))
.Pageable()
.Resizable(resize => resize.Columns(true))
.HtmlAttributes(new { style = "width: 1850px" })
)
private IEnumerable<MFS3ViewModel> GetMFS3(int cityID)
{
return HelperClass.dbUp.TBL_MFS_MFS3_Input.Select(p => new MFS3ViewModel
{
CITYID = p.CITIYID,
MFS3_ID = p.MFS3_ID,
FirstName = p. FirstName,
LastName = p. LastName,
p.Address = p. p.Address,
.Mail = p. .Mail,
County = p. County,
City = p. City,
}).Where(p => p.CITYID == cityID);
}
I resolved this via jQuery and added parameter in my Index method
$('#btnSearch').click(function () {
var cityID = $("#City").data("kendoDropDownList").value();
document.location = "/MFS3/Index?cityId=" + cityID;
});
public ActionResult Index(int cityId)
{
return View(GetMFS3(cityId));
}