Kendo UI Grid, setting page to 1 without double postback - kendo-grid

I have the following code on a page.
The problem is that when the "MainSearchSubmit" button is clicked the method "RefreshGrid()" is resulting in 2 subsequent ajax calls to the server. I found this is because the call to "datasource.read()" and "datasource.page(1)" are both posting back to the server (they are both running the read() method of the dataSource).
I still need to set the grid page to 1 when the search button is clicked because otherwise someone can be on page 3, then click the search button, get the updated results, but still be on page 3. They need to be reset to page 1 when the click the search button.
Also I still need to run the read() because otherwise the updated parameters are not passed and the data is not refreshed.
I've found similar posts, some with people suggesting using the .query() method. I tried that (code commented out in "RefreshGrid()" method), but that was also resulting in 2 posts to the server.
Any ideas on how I can fix this?
Code:
<script>
$(document).ready(InitializeNDCMapping);
function InitializeMainMapping() {
$("#MainSearchSubmit").click(function (e) {
RefreshGrid();
e.preventDefault();
});
}
function RefreshGrid() {
$("#MainListGrid").data("kendoGrid").dataSource.read();
$("#MainListGrid").data("kendoGrid").dataSource.page(1);
//Defunct code
//var dataSource1 = $("#NDCListGrid").data("kendoGrid").dataSource;
//dataSource.query({
// read: dataSource1.read(),
// page: dataSource1.Page(1),
// pagesize: dataSource1.PageSize(25)
//});
}
</script>
<div class="search-buttons">
<input type="submit" value="Search" id="MainSearchSubmit" />
<input type="button" value="Reset" onclick="ResetMainSearch()" />
</div>
<div>
#(Html.Kendo().Grid<BackOffice.ViewModels.NDCItem>()
.Name("MainListGrid")
.Filterable()
.Pageable(p => p.PageSizes(new int[] { 25, 50, 100 }).Input(true)
.Messages(m=>m.Empty("No Main-Ingredient found")).Numeric(false))
.Sortable()
.Navigatable()
.Selectable(selectable => selectable.Mode(GridSelectionMode.Single))
.Columns(columns =>
{
columns.Bound(l => l.NDCCode).Title("NDC Code").Width("5%")
.ClientTemplate(#Html.DialogFormLink("#=NDCCode#", Url.Action("NDCMappingEdit", new { NDCCode = "#=NDCCode#", mainMultumDrugCode = "#=MainMultumDrugCode#", drugId = "#=DrugId#", isMapped = "#=IsMapped#" }), "NDC Mapping", "", "", "NDCDialogLink", "1100", "600", "").ToHtmlString());
columns.Bound(l => l.Name).Title("Generic Name").Width("15%");
columns.Bound(l => l.MainCode).Hidden();
columns.Bound(l => l.MainId).Hidden();
columns.Bound(l => l.MainDescription).Title("Main Description").Width("15%");
columns.Bound(l => l.MainIngredientCode).Hidden();
columns.Bound(l => l.MainIngredient).Title("Main Ingredient").Width("15%");
columns.Bound(l => l.MainNumAmount).Title("Main Qty").Width("5%");
columns.Bound(l => l.MainNum).Title("Main Unit").Width("5%");
columns.Bound(l => l.MainDenomAmount).Title("Main Denom").Width("5%");
columns.Bound(l => l.MainDenom).Title("Main Denom Unit").Width("5%");
columns.Bound(l => l.IsMapped).Title("Mapped").Width("5%").Filterable(false).Sortable(false)
.ClientTemplate("<input type='checkbox' name='selected_#=MainCode#' class='chkbx select'" + "#= IsMapped ? 'checked' : ''#" + " />")
.HtmlAttributes(new { #class = "center", #onclick = "return false" })
.HeaderHtmlAttributes(new { #class = "center" });
})
.AutoBind(false)
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.Read(read => read.Action("MainList_Read", "Drug").Data("getRouteParams"))
.Model(model =>
{
model.Field(f => f.MainCode).Editable(false);
model.Field(f => f.MainName).Editable(false);
model.Field(f => f.MainDCCode).Editable(false);
model.Field(f => f.MainId).Editable(false);
model.Field(f => f.MainDescription).Editable(false);
model.Field(f => f.MainIngredientCode).Editable(false);
model.Field(f => f.MainIngredient).Editable(false);
model.Field(f => f.MainNumAmount).Editable(false);
model.Field(f => f.MainNum).Editable(false);
model.Field(f => f.MainDenomAmount).Editable(false);
model.Field(f => f.MainDenom).Editable(false);
model.Field(f => f.IsMapped).Editable(false);
})
.PageSize(25)
.Events(events => events.Error("MainRead_Error"))
)
)
</div>

In the past, when I had similar problems, it was almost always because the click handler was registered twice and even though the user clicked the button once, the handler executed twice.
Where do you call InitializeMainMapping()? Also, I am not sure if this is a copy and paste error, but the InitializeMainMapping() is missing a closing }. Are you getting any javascript errors when the user clicks on the button?
Just a few ideas to get you started.

I was able to find the solution. If the page is already set to 1 and you run...
grid.dataSource.page(1);
This results in a read. Otherwise if the page is not yet set to 1 and you run the code above it doesn't result in a read. So the solution to the issue is below.
if (grid.dataSource.page() != 1) {
grid.dataSource.page(1);
}
grid.dataSource.read( {parameter: "value"} );
Found this solution here:
KendoUI: resetting grid data to first page after button click

Related

writing a script/Function for checkboxes and Custom Delete button in Telerik UI for ASP.NET MVC

I need help writing a script/Function for my Telerik UI for asp.net MVC program. I have a delete button in my tool bar and I think my script is correct for it deleting. Now, I'm told that my check boxes haft to have a script also to be deleted when checked. As a C# coder, I'm not entirely knowledgeable about Json coding. So, any help would be appreciated! Here is my code below.
#(Html.Kendo().Grid<MVCSQLDatabase.Models>()
.Name("Grid")
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Batch(true)
.Model(model => model.Id(p => p.Proposal_Uid))
.Read(read => read.Action("Proposals_Read", "Grid"))
.Create(create => create.Action("Proposals_Create", "Grid"))
.Update(update => update.Action("Proposals_Update", "Grid"))
.Destroy(destroy => destroy.Action("Proposals_Destroy", "Grid"))
)
.Resizable(resize => resize.Columns(true))
.Columns(columns =>
{
columns.Select().Width(100); //<-- my check boxes code.
columns.Bound(c => c.Prime).Width(215);
columns.Bound(c => c.Proposal).Width(200);
columns.Bound(c => c.C).Width(190);
columns.Bound(c => c.Cl).Width(185);
columns.Bound(c => c.T).Width(290);
columns.Bound(c => c.M).Width(220);
columns.Bound(c => c.S).Format("{0: dd/MM/yyyy}").Width(170);
columns.Bound(c => c.E).Format("{0: dd/MM/yyyy}").Width(170);
columns.Bound(c => c.P).Width(235);
columns.Bound(c => c.Con).Width(215);
columns.Command(command => { command.Destroy(); }).Width(180);// <--- My delete button in my column
})
.ToolBar(toolbar =>
{
toolbar.Create();
toolbar.Save();
toolbar.Excel();
toolbar.Custom().Text("Delete").Name("batchDestroy").IconClass("k-icon k-i-close"); //<-- my custom made delete button in my toolbar.
})
.ColumnMenu()
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable()
.Selectable(selectable =>
{
selectable.Mode(GridSelectionMode.Multiple);
selectable.Type(GridSelectionType.Row);
})
.PersistSelection()
.Filterable(filterable => filterable.Mode(GridFilterMode.Row))
.Scrollable()
.HtmlAttributes(new { style = "height:835px;" })
)
<script>
$("#grid").on("click", "batchDestroy", function() {
var $tr = $(this).closest("tr"),
grid = $("#grid").data("kendoGrid"),
dataItem = grid.dataItem($tr);
grid.dataSource.remove(dataItem);
});
</script>
Here is the code for anybody else stuck in this situation. The thing that got me the most, was the .done function to end the button click function and then saving the grid AFTER the delete was made. Hopefully, this helps others!
<script>
$(document).ready(function ()
{
$(".k-grid-Destroy").on("click", function (e)
{
e.preventDefault();
var grid = $("#Grid").data("kendoGrid");
var selectedRows = grid.select();
kendo.confirm(kendo.format("Are you sure you wish to delete {0} records?", selectedRows.length))
.done(function ()
{
$.each(selectedRows, function (i, row)
{
grid.removeRow(row);
})
grid.saveChanges();
});
});
});
</script>

Kendo UI Grid SignarlR datasource not firing update event

I'm using asp.net core razor pages with a Kendo Grid that is datasourced using SignalR. It gets the initial read ok, but the update does not fire. I've looked at the Kendo Demo, and other stackover flow pages, but nothing seems to work.
I know the API works fine in sending the update because I see the call when debugging through Chrome that the websocket received an update commmand with the new data in json format. But the Grid doesn't update, or fire any update commands. It's as if it never received it, or doesn't know that it received it.
Index.cshmtl
<script src="~/signalr/signalr.js"></script>
<script>
var url = https://demosite.com/hub/controller;
var hub = new signalR.HubConnectionBuilder()
.configureLogging(signalR.LogLevel.Information)
.withUrl(url,
{
transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.LongPolling
})
.build();
var hubStart = hub.start();
</script>
#(Html.Kendo().Grid<myModel>
()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.Name);
columns.Bound(c => c.Date);
})
.HtmlAttributes(new { style = "width: 98%;" })
.DataSource(dataSource => dataSource
.SignalR()
.AutoSync(true)
.ServerFiltering(true)
.ServerSorting(true)
.PageSize(10)
.Transport(tr => tr
.Promise("hubStart")
.Hub("hub")
.Client(c => c
.Read("read") //Read works, initial data loads
.Create("create")
.Update("update")
.Destroy("destroy")
)
.Server(s => s
.Read("read")
.Create("create")
.Update("update")
.Destroy("destroy")
)
)
.Schema(schema => schema
.Data("Data")
.Total("Total")
.Aggregates("Aggregates")
.Model(model =>
{
model.Id(p => p.ID);
model.Field(p=> p.Name);
model.Field(p => p.Date);
}
)
)
)
.Group(g => g.Add(x => x.Name))
)
.Events(x=>
{
x.DataBound("collapseAllGroups");
}
)
.Groupable(true)
.Sortable()
.Filterable()
.Pageable(pager => pager.AlwaysVisible(true).PageSizes(new int[] { 10, 20, 50, 100 }))
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
.Selectable()
)
Api
[HttpGet]
public async Task<myModel> GetTest()
{
myModel mod= new myModel();
mod.Name = "New Name";
mod.Date = DateTime.UTCNow.ToString();
//Send update command to connected SignalR Clients
await _hub.Clients.All.SendAsync("update", mod);
return mod;
}
Any help would be appreciated.
Ok I got this to work. Turns out that since the Grid is originally expecting a DataSourceResult I had to convert myModel to a DataSourceResult type before doing the update. Example below should be considered Pseudocode as I’m typing this on my phone.
await _hub.Clients.All.SendAsync("update", new DataSourceResult(mod));

Kendo Grid - Not showing certain sub grids

I have a kendo grid within an mvc asp.net core application. When I expand the grid into a sub grid, for the most part, it works as expected, showing the sub grid and then making the call to the controller and returning the json data required.
When I expand the root grid to select a row to expand. On specific rows, when the sub grid is created, the root report is almost collapsed, the columns disappear and all the data rows. Subsequently, the call to the controller is still executed as normal and the data is returned. However, the data is not shown on screen as it appears the sub report is not displayed.
Why would the code that works to generate a sub report for one row, not work for another?
This is repeatable on my setup. i.e - I can refresh and restart my browser/application and the same rows cause this issue.
Clicking the second row causes the report to collapse, as if its datasource and columns were removed.
Please note that the root report I speak of, is in actual fact a sub report.
Root Report:
<script id="SalesByLocDept_DetailTemplate" type="text/x-kendo-tmpl">
<h4>Department Sales Summary For Location: #=LocCode# - #=LocName#</h4>
#(Html.Kendo().TabStrip()
.Name("sales_by_loc_tabstrip_#=ID#")
.Items(items =>
{
items.Add()
.Text("Department Summary")
.Selected(true)
.Content(#<text>
#(Html.Kendo().Grid<SalesSummaryByDepartmentViewModel>()
.Name("sales_by_loc_dept_tabstrip_#=ID#")
.Scrollable()
.Reorderable(r => r.Columns(true))
.Resizable(r => r.Columns(true))
.ColumnMenu()
.Columns(columns =>
{
columns.Bound(f => f.DeptCode).Title("Department Code");
columns.Bound(f => f.DeptDesc).Title("Department Name");
columns.Bound(f => f.TakingsToday).Title("Today's Takings");
columns.Bound(f => f.MarginToday).Title("Today's Margin");
columns.Bound(f => f.TakingsMonth).Title("Month's Takings");
columns.Bound(f => f.MarginMonth).Title("Month's Margin");
columns.Bound(f => f.TakingsYear).Title("Year's Takings");
columns.Bound(f => f.MarginYear).Title("Year's Margin");
columns.Bound(f => f.TakingsToDate).Title("Takings To Date");
columns.Bound(f => f.MarginToDate).Title("Margin To Date");
})
.Pageable(pageable => pageable.Refresh(true).PageSizes(new int[] { 100, 150, 200 }))
.Sortable()
.Selectable()
.Navigatable()
.Filterable()
.ClientDetailTemplateId("SalesByLocDeptGroup_DetailTemplate")
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => { model.Id(detail => detail.ID); })
.Read(read => read.Action("SalesByLocDepartment_Read", "Reporting", new { LocCode = "#=LocCode#" }))
).ToClientTemplate()
)</text>);
}).ToClientTemplate()
)
</script>
Sub Report:
<script id="SalesByLocDeptGroup_DetailTemplate" type="text/x-kendo-tmpl">
<h4>Group Sales Summary For Location: #=LocCode# - #=LocName#, Department: #=DeptCode# - #=DeptDesc#</h4>
#(Html.Kendo().TabStrip()
.Name("sales_by_loc_dept_tabstrip_#=ID#")
.Items(items =>
{
items.Add()
.Text("Group Summary")
.Selected(true)
.Content(#<text>
#(Html.Kendo().Grid<SalesSummaryByGroupViewModel>()
.Name("sales_by_loc_dept_group_tabstrip_#=ID#")
.Scrollable()
.Reorderable(r => r.Columns(true))
.Resizable(r => r.Columns(true))
.ColumnMenu()
.Columns(columns =>
{
columns.Bound(f => f.GroupCode).Title("Group Code");
columns.Bound(f => f.GroupDesc).Title("Group Name");
columns.Bound(f => f.TakingsToday).Title("Today's Takings");
columns.Bound(f => f.MarginToday).Title("Today's Margin");
columns.Bound(f => f.TakingsMonth).Title("Month's Takings");
columns.Bound(f => f.MarginMonth).Title("Month's Margin");
columns.Bound(f => f.TakingsYear).Title("Year's Takings");
columns.Bound(f => f.MarginYear).Title("Year's Margin");
columns.Bound(f => f.TakingsToDate).Title("Takings To Date");
columns.Bound(f => f.MarginToDate).Title("Margin To Date");
})
.Pageable(pageable => pageable.Refresh(true).PageSizes(new int[] { 100, 150, 200 }))
.Sortable()
.Selectable()
.Navigatable()
.Filterable()
.ClientDetailTemplateId("SalesByLocDeptGroupProduct_DetailTemplate")
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => { model.Id(detail => detail.ID); })
.Read(read => read.Action("SalesByLocDeptGroup_Read", "Reporting", new { LocCode = "#=LocCode#", DeptCode = "#=DeptCode#" }))
).ToClientTemplate()
)</text>);
}).ToClientTemplate()
)
</script>
I noticed that the rows which would fail had a pattern.
If I expanded the root report on row 1. The sub report, on expanding it's row 1, would fail.
If I expanded the root report on row 3. The sub report, on expanding it's row 3, would fail.
This made me look into the Name properties of my grids & tabs. I was including an ID on the end as a way of uniquely identifying them. I removed the IDs from the tabs. For the grids I had to further uniquely Identify them, using a combination of model values and Ids.
If anyone understands this behavior further than I do, please comment.

customize Kendo.ui.progress to remove spinner

Hi i am using progress to disable a grid, i am able to achieve this using
kendo.ui.progress($("#grid"), true);
But for my requirement i must not show the spinner image. for that i tried
Method 1
kendo.ui.progress($("#grid"), function(){
removeclass("k-loading-image") ;
return true;
});
Method 2
$('#grid*').prop('disabled', false);
Method 3:
$("#grid").append("<div class='k-loading-mask' style='width:100%;height:100%'><span class='k-loading-text'>Loading...</span><div class='k-loading-color'><br\><br\><br\><a href='www.google.com' >LINK</a></div></div>");
Any help is much appreciated.Thanks
EDIT
#(Html.Kendo().Grid(Model)
.Name("grdAddrMaster")
.Columns(columns =>
{
columns.Bound(m => m.id);
columns.Bound(m => m.name);
})
.AutoBind(false)
.Sortable()
.Scrollable()
.Pageable()
.Selectable()
.Filterable(filterable => filterable
.Extra(false)
.Operators(operators => operators
.ForString(str => str.Clear()
.StartsWith("Starts With"))
.ForNumber(num => num.ToString()
.StartsWith("Starts With"))
))
.DataSource(datasource => datasource.Ajax()
.Model(model =>
{
model.Id(m => m.id);
})
.PageSize(10)
.Read(read => read.Action("ReadData", "Home"))))
If you just want to remove the loading image then you just need to create a css class to override the existing background image of the loading image class as below:
.k-loading-image {
//background-image: url('Default/loading-image.gif'); // Existing code in the css (kendo.default.min.css)
background-image: url('your logo') !important; // path to your logo which you wish to show
}
Edit:
Working Example
You will need to add the below line to disable the Loading image at run time:
kendo.ui.progress($("#grdAddrMaster"), true);
$("#grdAddrMaster").find(".k-loading-image").css("background-image", "url('') !important");

How to Refresh single column in Kendo UI Grid asp.net mvc?

Here is my code for loading data into Kendo Grid:
#(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.CountryName);
columns.Bound(p => p.CountryCode);
columns.Bound(p => p.CountryCodeLength);
columns.Bound(p => p.CurrencyString);
columns.Bound(p => p.CountryISOName);
})
.Pageable(p =>
{
p.Enabled(true);
p.PageSizes(new int[] { 10, 20, 30, 40, 50 });
})
.Sortable()
.Selectable()
.Groupable()
.Scrollable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.ID))
.Read(read => read.Action("Country_Read", "Country")).PageSize(10)
)
.Events(events => events.Change("GridChange"))
.ToolBar(toolbar =>
{
toolbar.Template(
#<text>
<div id="Toolbar">
<a id="Add" href="#Url.Action("Create", "Country")" title="Add New Record"></a>
<a id="Edit" title="Edit Selected Record"></a>
<a id="Delete" title="Delete Selected Record"></a>
</div>
</text>);
})
)
How do I refresh the column CountryCodeLength on 10-15 seconds regularly? I tried refreshing the complete Grid, but I have some popup to be open inside the same grid. So while refreshing complete grid on working with popup, the popup will be lost. Please tell me how I can refresh a single column?
Here is the code that I used to refresh the whole grid:
$(document).ready(function()
{
var refreshId = setInterval( function() {
//GET YOUR GRID REFERENCE
var grid = $("#Grid").data("kendoGrid");
grid.dataSource.read();
}, 5000);
});
var gridData = $("#Grid").data("kendoGrid").dataSource;
var data = gridData.at(0);//data at 0 Location
data.set("CountryCodeLength", 20);//set the value here
you can use a polling script to refresh the value
var MyGrid = $("#MyGrid").data("kendoGrid");
var selectedItem = MyGrid.dataItem(MyGrid.select());
selectedItem.set("CountryCodeLength", 10);
MyGrid.tbody.find("tr[data-uid=\"" + selectedItem.uid + "\"]").addClass("k-state-selected");