I want to add row to kendo Grid with inline edit support. I need to do it after grid is initialized and data are loaded.
I tried this:
$(document).ready(function () {
gridAdd(); // no work
});
function gridAdd(){
$(".k-grid-add").click()
}
When I call gridAdd() in DataBound event in Grid, grid freeze and data do not load. What is correct event to perform this function ?
Grid code is before code for gridAdd function:
#(Html.Kendo().Grid<TT.Web.Models.ViewModel.WorkViewModel>()
.Name("gridAdd")
.Events(events => events.Edit("gridEdit").DataBound("databoundinitAdd").Save("gridAddSaveChanges"))
.Columns(columns =>
{
columns.Template(x => x.Id)
.HeaderTemplate("<input id='mastercheckbox' type='checkbox'/>")
.ClientTemplate("#if(Status == 0 || Status == 3) {# <input type='checkbox' name='checkedRecords' value='#= Id #' class='checkboxGroups'/> #} #")
.Width(30)
.HtmlAttributes(new { style = "text-align:center" })
.HeaderHtmlAttributes(new { style = "text-align:center" });
columns.Template(#<text></text>).Title("Status").ClientTemplate("#if(Status == 0) {# <i class='fa fa-bolt icc'></i> #}#" + "#if(Status == 1) {# <i class='fa fa-paper-plane icc'></i> #}#" + "#if(Status == 2) {# <i class='fa fa-check-square-o icc'></i> #}#" + "#if(Status == 3) {# <a class='popoverEl' data-toggle='popover' data-trigger='hover' tabindex='0' title='Důvod zamítnutí' data-content='#=RejectionReason#' ><i class='fa fa-ban icc popoverEl' ></i></a> #}#").HtmlAttributes(new { #class = "icc" });
columns.Bound(work => work.Date).EditorTemplateName("WorkDate").Title(#L("Date"));
columns.Bound(work => work.Project).ClientTemplate("#=Project.Name#").Width(250).Title(#L("ProjectNameP")); // .ClientTemplate("#=Project.Name#")
columns.Bound(work => work.Spp).ClientTemplate("#=Spp.Code#").Width(100);
columns.Bound(work => work.Operation).ClientTemplate("#=Operation.Code#").Width(100).Title(#L("TypeOfOperation"));
columns.Bound(work => work.Hours).Title(#L("Hours"));
//columns.Command(command => { command.Edit(); command.Destroy(); }).Width(172);
columns.Template(#<text></text>).ClientTemplate(
"<div class='btn-group'>" +
"#if(Status == 0 || Status == 3 ) {# <a class='btn btn-success btn-sm k-button-icontext k-grid-edit'><i class='fa fa-pencil'></i></a>#}#" +
"#if(Status == 0 || Status == 3 ) {# <a class='btn btn-sm btn-primary sendToApprove' data-href='" + Url.Action("WorkToApprove", "Home") + "/#=Id#'><i class='fa fa-paper-plane'></i></a>#}#"
+ "#if(Status == 0 ) {# <a data-href='" + Url.Action("WorkDelete", "Home") + "/#=Id#' class='btn btn-sm btn-danger delete-work-item' ><i class='fa fa-times'></i></a>#}#"
+ "</div>"
).Width(130);
})
.ToolBar(toolbar =>
{
toolbar.Create().Text(#L("AddRecord"));
//toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InLine))
.DataSource(dataSource => dataSource
.Ajax()
.Batch(false)
.Events(events => events.RequestEnd("OnRequestEnd_TopLinePriceGrid"))
.PageSize(20)
//.Events(events => events.Error("error_handler"))
.Model(model =>
{
model.Id(p => p.Id);
model.Field(p => p.Operation).DefaultValue(ViewData["defaultOperation"] as TT.Web.Models.ViewModel.OperationViewModel);
model.Field(p => p.Spp).DefaultValue(ViewData["defaultSpp"] as TT.Web.Models.ViewModel.SppViewModel);
model.Field(p => p.Project).DefaultValue(ViewData["defaultProject"] as TT.Web.Models.ViewModel.ProjectViewModel);
})
.Read(read => read.Action("WorkRead", "Home").Data("currentWeekInfo")) // Přidádo HTTP parametr s vybranným týdnem
.Create(update => update.Action("EditingInline_Create", "Home").Data("currentWeekInfo"))
.Update(update => update.Action("EditingInline_Update", "Home").Data("currentWeekInfo"))
.Destroy(update => update.Action("EditingInline_Destroy", "Home").Data("currentWeekInfo"))
)
.Pageable() // Enable paging
.Sortable() // Enable sorting
)
Thanks!
EDIT NOT SOLVED BY: in databound Event, but there is a problem. GridAdd cause databound event, so it is calling repeatedly and brower freeze.
setTimeout(function(){
$(".k-grid-add").click()
})
Basically the best way is to get the Grid client side object and then use the client-side API to add the row. Please check the related docuemntation below:
Grid: Server side wrappers fundamentals
Grid: getting the client-side object
Grid: client side API, addRow
Related
I want to hide/remove one column when the data exported to excel..But that should be visible in grid. I have tried several solutions but not able find out the exact problem.
Currently excel is generating but unable to hide the column... Can anybody please help regarding this ?? Thanks in advance.
Here is my grid code:
#(Html.Kendo().Grid<Database.Model.UserSummaryInfo>()
.Name("Grid")
.Columns(col =>
{
col.Bound(c => c.ApplicationUserId).Hidden();
col.Bound(c => c.MemberId).Title("Member ID");
col.Bound(c => c.Visit).Title("Visit");
col.Bound(c => c.CreatedDate).Title("Visit Start Date");
col.Bound(c => c.LogInCount).Title("LogIn Count");
col.Bound(c => c.SurveyStatus).Title(" Survey Status");
col.Bound(c =>
c.ApplicationUserId).HeaderTemplate(#<text>Action</text>).ClientTemplate("#
if(SurveyStatus == 'Did Not Attempt') { #" + "<a class='btn btn-primary
disabled' style='display: none;' href='" + Url.Action("TestDetails",
"Admin") + "?id=#= TestSummaryId #&Year=#=Year#'" + " >Details</a>" + "#
}else{#" + "<a class='btn btn-primary enabled' style='width:60px' href='"
+ Url.Action("TestDetails", "Admin") + "?id=#= ApplicationUserId
#&Year=#=Year #&testSummaryId=#=TestSummaryId#'" + ">Details</a>" + "#
}#")
.HeaderHtmlAttributes(new { style = "text-align: center;font-size:18px"
});
})
.ToolBar(toolbar => toolbar.Template(#<text>
<div class="pull-left index-header">Test Summary</div>
<button type="button" class="btn btn-primary rounded pull-
right margin-right-10" onclick="clearFiter()"><i class="fa fa-times-
circle-o margin-right-5"></i> Clear Filter</button>
<a style="padding-right:5px;" class="k-button-icontext k-grid-
excel btn btn-primary pull-right margin-right-10" href="#"><span
class="fa fa-file-excel-o"></span>Export to Excel</a>
</text>))
.Excel(excel => excel
.FileName(DateTime.Now.Date.ToShortDateString() + " " +
"GetUserSummary.xlsx")
.AllPages(false)
.ProxyURL(Url.Action("Excel_Export_Save", "Admin")))
.Pageable(paging => paging.PageSizes(new int[] { 100, 500, 1000
}).Refresh(true).ButtonCount(5).Info(true).Input(true))
.Sortable(sortable =>
{
sortable.SortMode(GridSortMode.SingleColumn);
})
.Groupable()
.Scrollable(s => s.Height("auto"))
.Filterable(filterable => filterable.Operators(operators =>
operators.ForNumber(nmbr => nmbr.Clear().IsEqualTo("Is equal
to").IsLessThan("Less than").IsGreaterThan("Greater
than").IsNotEqualTo("Not equal to")).ForString(str =>
str.Clear().Contains("Contains").IsEqualTo("Is equal
to").StartsWith("Starts with").IsNotEqualTo("Is not equal
to")).ForDate(date => date.Clear().IsGreaterThan("Is
after").IsLessThan("Is Before").IsGreaterThanOrEqualTo("Is after or
equal to").IsLessThanOrEqualTo("Is before or equal to"))))
.Resizable(resize => resize.Columns(true))
.Events(e => e.ExcelExport("Hidecolumn"))
.DataSource(datasource =>
datasource
.Ajax()
.Sort(sort => {
sort.Add(c => c.MemberId).Ascending();
sort.Add(c => c.Visit).Ascending();
})
.PageSize(10)
.Read(read => read.Action("GetUserSummaryList", "Admin"))
)
)
</div>
</div>
</div>
<!-- End Content -->
</form>
</div>
<script>
var exportFlag = false;
$("#Grid").data("kendoGrid").bind("excelExport", function (e) {
debugger;
if (!exportFlag) {
e.sender.hideColumn(2);
e.preventDefault();
exportFlag = true;
setTimeout(function () {
e.sender.saveAsExcel();
});
} else {
e.sender.showColumn(2);
exportFlag = false;
}
});
function Hidecolumn(e) {
e.sender.hideColumn(2);
}
</script>
What you would need to do is to bind to the export function and then hide the columns similar to how you have above:
var exportFlag = false;
$("#grid").data("kendoGrid").bind("excelExport", function (e) {
if (!exportFlag) {
e.sender.hideColumn(1);
e.preventDefault();
exportFlag = true;
setTimeout(function () {
e.sender.saveAsExcel();
});
} else {
e.sender.showColumn(1);
exportFlag = false;
}
});
The exportFlag is due to stopping a recursive loop, because the saveAsExcel method fires the excelExport event.
Added this function to the excelExport event. We are knockout / jQuery but the logic should work for you.
It simply goes through all the rows in the sheet and deletes cells based on our excelHidden property.
self.resultsExcelExport = function(e) {
var sheet = e.workbook.sheets[0];
for (var i = this.columns.length - 1; i >= 0; i--) {
if (this.columns[i].excelHidden) {
sheet.columns.splice(i, 1);
sheet.rows.forEach(function(row) {
row.cells.splice(i, 1);
})
}
}
}
In the grid columns object add a property "excelHidden: true" to signal which columns to hide.
{
field: "Id",
title: 'Download',
excelHidden: true,
},
UPDATE:
Well that worked until I tried grouping a column. So had to lookup via title to find the correct column number to remove. Now looks like this.
function(e) {
var hiddenColumnsByTitle = {};
var hiddenColumns = [];
var sheet = e.workbook.sheets[0];
this.columns.forEach(function(column) {
if (column.excelHidden) {
hiddenColumnsByTitle[column.title] = true;
}
})
for (var r = 0; r < sheet.rows.length; r++) {
var row = sheet.rows[r];
if (row.type === "header") {
row.cells.forEach(function(headerCell, index) {
var columnTitle = headerCell.value;
if (hiddenColumnsByTitle[columnTitle]) {
hiddenColumns.push(index);
}
})
break;
}
}
for (var i = hiddenColumns.length - 1; i >= 0; i--) {
var hiddenColumn = hiddenColumns[i];
sheet.columns.splice(hiddenColumn, 1);
sheet.rows.forEach(function(row) {
row.cells.splice(hiddenColumn, 1);
})
}
}
I have a View made up of 3 Partial Views:
Partial View #1 is listing RadioButtons. When I click a button I would like to send the resulting selection to the controller in order to update the Partial View #2 (which is a Telerik grid). Then the selection in PV #2 will update Partial View #3 (another Telerik grid).
I am currently doing a Window.location to send selected values to the Controller which causes the Controller and ViewModel to be reloaded and lose state. Other than losing the state, the flow works as I would like.
Is there a way to do this in Ajax to where I do not have to reload the Controller?
I will spare you the Partial Views #2 & #3 of the Telerik grids. If I can get the answer to how to get the radio button to call the Controller without a postback, I can apply the same to those Partial Views.
View:
#model MyProject.ViewModel.MaterialsListVM
#{
ViewBag.Title = "Materials List";
}
<div>
<div class="row">
<div class="col-sm-2">
#Html.Partial("MaterialTypeFilter")
</div>
<div class="col-lg-10">
#Html.Partial("MaterialsGrid")
</div>
</div>
<div class="row"> </div>
<div class="row">
<div class="col-sm-2"> </div>
<div class="col-lg-10">
#Html.Partial("ProjectMaterialsGrid")
</div>
</div>
</div>
Partial View #1:
#model MyProject.ViewModel.MaterialsListVM
<div class="container">
<h5> #Html.Label("Material Type: ", new { style = "font-weight:bold;" })</h5>
#if (Model != null)
{
for (int i = 0; i < Model.Material_Type.MaterialTypeList.Count; i++)
{
<span class="btn-group-sm">
#Html.RadioButton("MatType", new { Model.Material_Type.MaterialTypeList[i].Name }, Model.Material_Type.MaterialTypeList[i].Selected, new { #onclick = "CallChangefunc(this.value)" })
#Html.Label(Model.Material_Type.MaterialTypeList[i].Name)
</span><br />
}
}
</div>
<script>
function CallChangefunc(value) {
var selected = value.replace("{ Name = ", "");
selected = selected.replace("}", "");
window.location = '#Url.Action("Index", "MaterialsList")' + '?selectedMatType=' + selected;
//alert("val is:" + selected);
}
Update
I changed the JavaScript to this Ajax call and that called my Controller HttpPost Index() function:
$(document).ready(function () {
$(':radio[name="MatType"]').change(function (e) {
$.ajax({
type: 'POST',
url: '/MaterialsList/Index',
data: { selectedMatType: $(':radio[name="MatType"]:checked').val()},
dataType: "json",
success: function (data) {
alert('did it');
}
});
});
})
Unfortunately the Controller is still being reloaded and I'm losing the state of the data selected into the Partial View #3 Telerik grid...
...any help would be much appreciated...
Update #2
This solution sucks but I don't know what else to do...
The goal is to retain the state of the datasource for a Telerik grid in Partial View #3. The datasource is a ViewModel with a List of class objects.
Added Partial View #2 code and ActionResult from Controller. There is no HttpPost Index function. Every radio button change fires the ActionResult Index. Every select event in Telerik grid fires ActionResult Index.
Pertinent Controller code:
public ActionResult Index(string selectedMatType, string selectedMaterials, string projectMaterialsList)
{
if (projectMaterialsList != null)
{
materialsListVM.ProjectMaterialsList = JsonConvert.DeserializeObject<List<ProjectMaterialsListVM.ProjectMaterial>>(projectMaterialsList);
}
if (selectedMatType != null)
{
materialsListVM.SelectMaterialType(selectedMatType);
materialsListVM.GetMaterials();
}
if (selectedMaterials != null)
{
string[] materialIds = selectedMaterials.Split(',');
foreach (string id in materialIds)
{
MoveToProjectMaterialsList(id, selectedMatType);
}
}
ViewBag.ProjectMaterialsList = materialsListVM.ProjectMaterialsList;
ViewBag.SelectedMatType = selectedMatType;
return View(materialsListVM);
}
Partial View #2 code:
#model MyProject.ViewModel.MaterialsListVM
<div>
#if (ViewBag.SelectedMatType == "Cap Weld")
{
#(Html.Kendo().Grid(Model.CapWeld_Materials)
.Name("grid")
.Columns(columns =>
{
columns.Select().Width(40);
columns.Bound(c => c.MaterialId).Hidden();
columns.Bound(c => c.MaterialTypeName);
columns.Bound(c => c.PcsPartNum);
columns.Bound(c => c.ClientPartNum);
columns.Bound(c => c.Type).Filterable(ftb => ftb.Multi(true));
columns.Bound(c => c.OuterDiameter).Filterable(ftb => ftb.Multi(true));
columns.Bound(c => c.WallThickness).Filterable(ftb => ftb.Multi(true));
columns.Bound(c => c.Specification).Filterable(ftb => ftb.Multi(true));
columns.Bound(c => c.Grade).Filterable(ftb => ftb.Multi(true));
})
.Events(ev => ev.Change("onChange"))
.Pageable()
.Sortable()
.Scrollable()
.TableHtmlAttributes(new { width = "100%" })
//.HtmlAttributes(new { style="height:500px"})
.PersistSelection(true)
.Filterable()
.DataSource(datasource => datasource
.Ajax()
.ServerOperation(false)
.Model(m => m.Id(d => d.MaterialId))
)
);
}
</div>
#{
var jss = new System.Web.Script.Serialization.JavaScriptSerializer();
var val = jss.Serialize(ViewBag.ProjectMaterialsList);
}
<script>
function onChange(arg) {
var selectedMatType = '#(ViewBag.SelectedMatType)';
var projectMaterialsList = '#Html.Raw(val)';
//var obj = $.parseJSON(val);
var grid = $('#grid').data('kendoGrid');
var selectedMaterials = grid.selectedKeyNames().join(", ");
// alert(selectedMaterials);
#*$.ajax({
type: "POST",
data: { selectedMatType: selectedMatType, selectedMaterials: selectedMaterials, projectMaterialsList: projectMaterialsList },
dataType: "json",
url: #Url.Action("Index", "MaterialsList")
});*#
window.location = '#Url.Action("Index", "MaterialsList")' + '?selectedMatType=' + selectedMatType + '&selectedMaterials=' + selectedMaterials
+ '&projectMaterialsList=' + projectMaterialsList;
}
</script>
Kendo-grid search box in toolbar in mvc with razor syntax,
I am facing i need toolbar in which searching box , this searching box search into grid data.
Just copy and paste this code bind with mvc model and custom button(CRUD) and search box in toolbar in kendo grid template
<div>
#(Html.Kendo().Grid(Model)
.Name("DiagnosisTestGrid")
.Columns(columns =>
{
columns.Bound(c => c.Description).Title("Description");
columns.Bound(c => c.Cost).Title("Cost");
columns.Bound(c => c.CostingRequired).Title("Cost Req.");
columns.Bound(c => c.DxTestId).ClientTemplate(#"
<a href='/DiagnosisTest/Details/#=DxTestId#' class = 'dialog-window'>Detail</a> |
<a href='/DiagnosisTest/Edit/#=DxTestId#' class = 'dialog-window' >Edit</a> |
<a href='/DiagnosisTest/Delete/#=DxTestId#' class = 'dialog-window'>Delete</a>
").Title("");
})
.ToolBar(toolbar =>
{
toolbar.Template(#<text>
<div class="toolbar">
<div class="row">
<div class="col-md-4">
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></span>
<input type="text" class="form-control" id='FieldFilter' placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-default" type="button"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span></button>
</span>
</div>
</div>
</div>
</div>
</text>);
})
.Resizable(resizing => resizing.Columns(true))
.Sortable(sorting => sorting.Enabled(true))
.Reorderable(reorder => reorder.Columns(true))
.Pageable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.ServerOperation(false)
))
</div>
Script for search box. and filter grid items
<script>
$(document).ready(function () {
$("#FieldFilter").keyup(function () {
var value = $("#FieldFilter").val();
grid = $("#DiagnosisTestGrid").data("kendoGrid");
if (value) {
grid.dataSource.filter({ field: "Description", operator: "contains", value: value });
} else {
grid.dataSource.filter({});
}
});
});
I know this is a bit of an old question now but it seems like the accepted answer is quite limited. This is how I got my searchbox added into the toolbar.
.ToolBar(toolBar => toolBar.Template(#<text><input class='k-textbox' value="Search..." onfocus="if (this.value=='Search...') this.value='';" onblur="this.value = this.value==''?'Search...':this.value;" id='searchbox'/></text>))
Then the script
<script type="text/javascript">
function addSearch() {
return { searchbox: $('#searchbox').val() };
}
$('#searchbox').keyup(function () {
$('#gridWorkflows').data('kendoGrid').dataSource.read();
});
</script>
This seems a bit simpler that what you are using currently.
Hope it helps.
I have a Kendo grid and a Save button on top of the page. When I click on “Add New Record” toolbar, a new row is added in the grid (client side). When I click on save button, I get the updated viewmodel in my controller’s action method which in turns add/update data in the database.
Now, I want to restrict adding a row in the grid if the grid has already 5 rows in it which means user will not be able to add a new row if the grid reaches its limit (which is 5 rows).
Can anyone of you please give me a sample client side script(jquery) that will restrict user to add new row in the grid?
Thank you very much!!!!!!!
Index.cshtml
#using (Html.BeginForm("Save", "UDF", FormMethod.Post))
{
<input class="button" type="submit" name="save" value="Save"/>
#(Html.Kendo().Grid(Model.List1)
.Name("List1")
.HtmlAttributes(new { style = "width:auto;height:100%" })
.ToolBar(toolbar => toolbar.Create().Text("Add New Record"))
.Editable(editable => editable.Mode(GridEditMode.InCell).CreateAt(GridInsertRowPosition.Top))
.Columns(columns =>
{
columns.Bound(p => p.Title)
.ClientTemplate("#= Title #" +
"<input type='hidden' name='DateFields[#= index(data)#].Title' value='#= Title #' />")
.Title("Title").HtmlAttributes(new { style = "width:30%" });
columns.Bound(p => p.MaxPrecision).Title("Decimal Places")
.ClientTemplate("#= MaxPrecision #" +
"<input type='hidden' name='DateFields[#= index(data)#].MaxPrecision' value='#= MaxPrecision #' />");
columns.Bound(p => p.IsObsolete).Title("Obsolete")
.ClientTemplate("#= IsObsolete #" +
"<input type='hidden' name='DateFields[#= index(data)#].IsObsolete' value='#= IsObsolete #' />");
})
.DataSource(datasource => datasource
.Ajax()
.Model(model =>
{
{
model.Id(p => p.Title);
model.Field(p => p.Title).Editable(true);
model.Field(p => p.MaxPrecision).Editable(true);
model.Field(p => p.IsObsolete).Editable(true);
}
}
)
)
)
}
You can use the toolbar template, like the one demonstrated here.
The template can look something like this:
<button class="k-button" id="myAdd">My Custom Add</button>
Once the Grid is initialized you can attach click handler which adds the new row based on your condition.
$('#myAdd).click(function(){
var gr = $('#gridName').data('kendoGrid');
if(gr.dataSource.data().length<5){
gr.addRow();
}
})
The methods used above are all covered in the documentaion.
I am trying to rebind Kendo Grid on a button click after filtering data using the JavaScript below, but it is not working. What should I do?
My HTML code using Kendo.Mvc.Dll:
Html.Kendo().Grid<EquityStreet.Data.ESData.Proc_GetESManagersListAndFilterResult>().Name("GridESManager").BindTo(Model.ESManagersList).Columns(columns =>
{
columns.Bound(m => m.pkESManagerId).Template(#<input type="checkbox" id="#item.pkESManagerId" />).Title("").Width("2%");
columns.Bound(m => m.pkESManagerId).Template(#<text> #item.FirstName #item.LastName</text>).Title("Name");
columns.Bound(m => m.CompanyName).Title("Company");
columns.Bound(m => m.MobileNo).Title("Phone Number");
columns.Bound(m => m.ESManagerStatus).Template(#<text>#(item.ESManagerStatus == 1 ? "Active" : "Inactive")</text>).Title("Status");
columns.Bound(m => m.pkESManagerId).Template(#<text> <a href="../Utilities/NewESManager?EId=#item.pkESManagerId" class="access_btn">
</a><a href="../Utilities/NewESManager?EId=#item.pkESManagerId" class="edit_btn">
</a>
</text>).Title("Actions");
}).ToolBar(tb =>
{
tb.Template("<div class='GridSearchHeader'><div style='float:left'><input type='button' value='Reset Pwd'><input type='button' value='Delete'></div><label>Filter: </label><input type='search' style='width: 230px' id='txtSearch'><select id='Status'><option value=-1>Select</option><option value=1>Active</option><option value=0>Inactive</option></select><input type='button' onclick='FilterList()' value='Go'><input type='button' value='Reset'></div>");
}).Pageable()
)
JavaScript:
$.post('#Url.Action("FilterESManagerList", "../../Utilities")', { Keyword: Search, UserStatus: status }, function (result) {
var grid = $("#GridESManager").data("kendoGrid");
grid.dataSource.data(result);
grid.refresh();
alert(grid);
});
Calling grid.dataSource.data(result) should rebind the grid unless the result is not in the expected format.
It looks that when using ajax-binding, calling grid.dataSource.fetch() will trigger the read method defined in the datasource and rebind automatically.
try this:
$("#gridName").data("kendoGrid").dataSource.sync();