Hello!
I am trying to add a <kendo-upload> tag onto the toolbar of a kendo grid using TagHelper and ASP.NET Core
Though I am struggling with figuring out how to do this, I have followed this template: https://demos.telerik.com/aspnet-core/grid/toolbar-template to not much success.
My goal is to simply add a file upload option to upload an excel file to populate the fields of a grid!
Any ideas on how to progress?
Thank you!
But I am still struggling
I have a grid with a Create button and Search field in the toolbar. I would like to add a count of the number of items in the grid. I am aware that it's possible to add paging to display the count and then disable it with:
PreviousNext(false).Numeric(false)
However, that results in wasted space because there's a row for the pager and count, and another row with the Create button and Search field.
Is it possible to add the item count to the custom toolbar so that everything is in in one row?
Thanks
Hello,
I want to add and clear menuButtons with javascript on the client but there is no Api for that. To add items with append like this shows the items but on click nothing happens (no close and no Event)
$(
"#Berichte_optionlist"
).append(
"<li><a href='' tabindex='0' title='test' class='k-button k-button-icontext' id="
test" data-overflow=
'auto'
>test</a></li>
How to add menuButtons the Right way so that the click Event works?
robert
I posted this query as a support ticket but I'm hoping to get an answer before the weekend is over.
I have a Grid with batch editing enabled. It also features a custom toolbar with an additional button: 'Archive'.
Users will be able to check multiple rows and click the 'Archive' button in the toolbar.
The button should submit all the selected rows (models) and POST them to a server side method for processing.
I have used this post as a basis for my work:
https://www.telerik.com/forums/how-to-pass-a-grid%27s-selected-row-values-to-controller
In the post, the custom button simply gets the selected items and posts them to the appropriate Controller method.
I need to POST an IEnumerable<T> to the Controller. Not just properties of an object.
I keep getting this error message:
"Javascript error: 'Uncaught TypeError: Cannot read properties of undefined (reading 'field')'
or the Controller gets NULL.
markup:
<div class="container-fluid"><div class="fc-day-grid-container">
@(Html.Kendo().Grid<Core.Resources.EmPowerReconciliationDto>
()
.Name("EmpFSRollGrid")
.Columns(columns =>
{
columns.Select().Width(50)
.ClientHeaderTemplate("<input type='checkbox' id='selectAll' class='k-checkbox' onClick='selectAll(this)'/>" +
"<label for='selectAll'> All</label>").HeaderHtmlAttributes(new { @class = "k-header" });
columns.Bound(c => c.ProjMessage).Width(100);
columns.Bound(c => c.ProjectId).Width(150);
columns.Bound(c => c.ElectricUtilityUtilityName).Width(150);
columns.Bound(c => c.GasUtilityUtilityName).Width(150);
columns.Bound(c => c.PrimaryHeatingFuel).Width(100);
columns.Bound(c => c.ReferralSF).Width(100);
columns.Bound(c => c.MeasureType).Width(100);
columns.Bound(c => c.ProgramName).Width(100);
columns.Bound(c => c.MeasureId).Width(100);
columns.Bound(c => c.FundedAmount).Width(100).Format("{0:n}").HtmlAttributes(new { @class = "k-text-right" });
columns.Bound(c => c.Adj).Width(100).Format("{0:n}").HtmlAttributes(new { @class = "k-text-right" });
columns.ForeignKey(c => c.XFundingSourceId, (System.Collections.IEnumerable)ViewData["fundingsource"], "FundingSourceId", "FundingSourceDesc").Width(160).Title("Funding Source");
columns.Bound(c => c.MeasureCategoryMeasureCategoryDesc).Width(100);
columns.Bound(c => c.ProjectStage).Width(100);
})
.ToolBar(toolbar =>
{
toolbar.ClientTemplateId("GridToolbarTemplate");
})
.Excel(excel => excel
.FileName($"EmPowerReconciliationReport{System.DateTime.Now.ToString("yyyyMMMMdd")}.xlsx")
.Filterable(true)
.AllPages(true)
)
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable(pageable =>
{
pageable.Refresh(true);
pageable.PageSizes(new[] { 10, 20, 50 });
})
.Sortable()
.Filterable(ftb => ftb.Mode(GridFilterMode.Row))
.Scrollable(s => s.Enabled(true))
.Resizable(resize => resize.Columns(true))
.PersistSelection()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(emp => emp.MeasureId);
model.Field(emp => emp.ProjMessage).Editable(false);
model.Field(emp => emp.ProjectId).Editable(false);
model.Field(emp => emp.ElectricUtilityUtilityName).Editable(false);
model.Field(emp => emp.GasUtilityUtilityName).Editable(false);
model.Field(emp => emp.PrimaryHeatingFuel).Editable(false);
model.Field(emp => emp.ReferralSF).Editable(false);
model.Field(emp => emp.MeasureType).Editable(false);
model.Field(emp => emp.ProgramName).Editable(false);
model.Field(emp => emp.MeasureId).Editable(false);
model.Field(emp => emp.FundedAmount).Editable(false);
model.Field(emp => emp.Adj).Editable(true);
model.Field(emp => emp.XFundingSourceId).Editable(true);
model.Field(emp => emp.MeasureCategoryMeasureCategoryDesc).Editable(false);
model.Field(emp => emp.ProjectStage).Editable(false);
})
.ServerOperation(false)
.Batch(true)
.Events(events => events.Error("error_handler"))
.Events(events => events.RequestEnd("request_end"))
.Read(read => read.Action("GetAllFsRollup", "EmPowerReconciliation"))
.Update(update => update.Action("UpdateCompositeInvoice", "EmPowerReconciliation"))
//.Create(create => create.Action("AddInvoice", "EmPowerInvoiceReport"))
//.Destroy(destroy => destroy.Action("DeleteInvoice", "EmPowerInvoiceReport"))
)
)
</div></div><script id="GridToolbarTemplate" type="text/x-kendo-template">
<div class="toolbar">
<a role="button" class="k-button k-button-icontext k-grid-excel" href="\\#"><span class="k-icon k-i-file-excel"></span>Export to Excel</a>
<a role="button" class="k-button k-button-icontext k-grid-save-changes" href="\\#"><span class="k-icon k-i-check"></span>Save changes</a>
<a role="button" id="cancelmeasureChanges" class="k-button k-button-icontext k-grid-cancel-changes" href="\\#"><span class="k-icon k-i-cancel"></span>Cancel changes</a>
<a role="button" id="ArchiveChanges" class="k-button" href="\\#" onClick="Archive()"><span class="k-icon"></span>Archive</a>
@*@(Html.Kendo().DropDownList()
.Name("InvoicedList")
.OptionLabel("All")
.DataTextField("InvoiceSatusName")
.DataValueField("InvoiceStatusId")
.AutoBind(true)
.Events(e => e.Change("invoicedStatusChange"))
.DataSource(ds =>
{
ds.Read("InvoiceStatuses", "EmPowerInvoiceReport");
})
.ToClientTemplate()
)*@
</div>
</script><script type="text/javascript">
function Archive() {
var items = {};
//var items = [];
var grid = $('#EmpFSRollGrid').data('kendoGrid');
var selectedElements = grid.select();
for (var j = 0; j < selectedElements.length; j++) {
var item = grid.dataItem(selectedElements[j]);
//items.push(item);
items['archiveItems[' + j + ']'] = item;
//items[j] = item;
}
$.ajax({
type: "POST",
data: items,
url: '@Url.Action("Archive", "EmPowerReconciliation")',
success: function (result) {
console.log(result);
}
})
}
// ******* Select/deSelect All
function selectAll(mainCheck) {
var grid = $("#EmpFSRollGrid").data("kendoGrid");
var items = grid.items();
items.each(function (index, td) {
var chckbx = $(td).find("input").get(0);
$(chckbx).prop("checked", mainCheck.checked);
var dataItem = grid.dataItem(this);
dataItem.IsSubmitted = mainCheck.checked;
if (mainCheck.checked) {
//$(chckbx).closest("td").addClass("k-dirty-cell").prepend("<span class='k-dirty'></span>");
$(chckbx).closest("tr").addClass("k-state-selected");
dataItem.dirty = true;
dataItem.dirtyFields = { IsSubmitted: true }
}
else {
//$(chckbx).closest("td").removeClass("k-dirty-cell").remove("span.k-dirty");
$(chckbx).closest("tr").removeClass("k-state-selected");
dataItem.dirty = false;
dataItem.dirtyFields = { IsSubmitted: false }
}
})
if (mainCheck.checked == false) {
dataSource = $("#EmpFSRollGrid").data("kendoGrid").dataSource
grid._selectedIds = {};
grid.clearSelection();
}
}
// ***************** Grid Textbox edited
$("#EmpFSRollGrid").on("change", "input.text-box.single-line.k-valid", function (e) {
var grid = $("#EmpFSRollGrid").data("kendoGrid"),
dataItem = grid.dataItem($(e.target).closest("tr"));
if (dataItem.dirty) {
grid.dataItem($(e.target).closest("tr").addClass("k-state-selected"));
var chk = $(e.target).closest("tr").find(".k-checkbox");
chk.prop("checked", true);
}
});
// *************** Grid checkbox checked/unchecked
$("#EmpFSRollGrid").on("change", "input.k-checkbox", function (e) {
var grid = $("#EmpFSRollGrid").data("kendoGrid"),
dataItem = grid.dataItem($(e.target).closest("tr"));
dataItem.IsSubmitted = this.checked;
if (this.checked) {
//$(e.target).closest("td").addClass("k-dirty-cell").prepend("<span class='k-dirty'></span>");
dataItem.dirty = true;
dataItem.dirtyFields = { IsSubmitted: true }
}
else {
// $(e.target).closest("td").removeClass("k-dirty-cell").remove("span.k-dirty");
dataItem.dirty = false;
dataItem.dirtyFields = { IsSubmitted: false }
var row = e.target.closest('tr')
var uid = $(row).data(uid)
dataSource = $("#EmpFSRollGrid").data("kendoGrid").dataSource
var item = dataSource.getByUid(uid.uid);
dataSource.cancelChanges(item);
grid.refresh();
}
if (!this.checked) {
$("#selectAll").prop('checked', false);
}
});
// ************** Clear the grid after an Update
function request_end(e) {
var grid = $("#EmpFSRollGrid").data("kendoGrid");
var items = grid.items();
items.each(function (index, td) {
var chckbx = $(td).find("input").get(0);
$(chckbx).prop("checked", false);
$(chckbx).closest("tr").removeClass("k-state-selected");
});
grid._selectedIds = {};
grid.clearSelection();
}
function error_handler(e) {
if (e.errors) {
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
alert(message);
}
}
</script>
The important part is here.
<a role="button" id="ArchiveChanges" class="k-button" href="\\#" onClick="Archive()"><span class="k-icon"></span>Archive</a>
Here:
function Archive() {
var items = {};
//var items = [];
var grid = $('#EmpFSRollGrid').data('kendoGrid');
var selectedElements = grid.select();
for (var j = 0; j < selectedElements.length; j++) {
var item = grid.dataItem(selectedElements[j]);
//items.push(item);
items['archiveItems[' + j + ']'] = item;
//items[j] = item;
}
$.ajax({
type: "POST",
data: items,
url: '@Url.Action("Archive", "EmPowerReconciliation")',
success: function (result) {
console.log(result);
}
})
}
Controller
[AcceptVerbs("Post")]
public async Task<ActionResult> Archive([DataSourceRequest] DataSourceRequest request
,IEnumerable<EmPowerReconciliationDto> archiveItems)
{
return Json(archiveItems);
}
Hi,
I'm using the Editor with a lot of options/buttons and that works fine on a 'large' screen.
On a mobile it will split over 4 lines.
(Hardly no room for editing text left)
Is it possible to reduce the number of options/buttons in the toolbar when showing it on a mobile phone?
(I only want to keep the Bold/Italic/Underline buttons)
Thanks....
Hi,
I have a partial example in Fluent for a Grid with a toolbar that has a (partially funcitoning) "Create" button.
I would like to duplicate this in taghelpers. Here is a Figma rendering using the Telerik Figma controls with some slight customizations:
Can you please provide the taghelpers for a toolbar such as this (with a "Create" button with custom CSS)? I don't need the CSS or anything, I just need the taghelpers to achieve this?
This is what I have so far:
<div>
<kendo-datasource name="dataSource2" type="DataSourceTagHelperType.Ajax" server-operation="false" page-size="10">
<transport>
<read url="@Url.Action("List_Employees", "Company1", new {clinicID = @Model?.ClinicID })" />
<create url="@Url.Action("Add_Employee", "Company1")" />
</transport>
</kendo-datasource>
<toolbar-items>
<create/>
</toolbar-items>
<kendo-grid name="ClinicUsersGrid" datasource-id="dataSource2">
<columns>
<column field="EmployeeName" title="Name"/>
<column field="EmployeePhone" title="Phone Number"/>
<column field="Role" title="Role"/>
<column field="EmployeeEmail" title="Email"/>
</columns>
<editable mode="@GridEditMode.PopUp"/>
</kendo-grid>
</div>
My toolbar isn't showing up. I tried inserting toolbar tags but it just complained? Any insight would be really helpful.
It's interesting to note that in the "Tags" for this Question, I cannot add TagHelpers as a subject.
Thanks!
I have the below example:
As you can see, I check and pre Save Changes, everything works ok. I check, hit Cancel Changes and we get back to its original state.
After I save/commit to the db and then hit cancel changes, the grid updates some check boxes (incorrectly) and also updates the items.
What's going on here?!
Here's my grid code
@(Html.Kendo().Grid<BinWithType>
()
.Name("gridBins")
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => {
model.Id(p => p.Bin_ID);
model.Field(p => p.SiteHasBin).Editable(true);
model.Field(p => p.Bin_Type_Name).Editable(false);
model.Field(p => p.Bin_Type_Group).Editable(false);
})
.Batch(true)
.ServerOperation(false)
.Read("Bins_Read", "MySites", new { site_Id = Model.Site_Id })
.Update("Bins_Update", "MySites", new { site_Id = Model.Site_Id })
)
.Columns(columns =>
{
columns.Bound(site => site.SiteHasBin).Filterable(false);
columns.Bound(site => site.Bin_Type_Name).Filterable(false);
columns.Bound(site => site.Bin_Type_Group).Filterable(filterable => filterable.UI("groupFilter"));
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Filterable(filterable => filterable
.Extra(false)
.Operators(operators => operators
.ForString(str => str.Clear()))
)
.Sortable()
.ToolBar(toolbar =>
{
toolbar.Save();
})
)
Further strange behaviour:
When I do a 'standard' batch update this works as expected see first half of gif above. However, when I do one by one, I appear to just replicate the first.
Here is my my Read & Update code:
public ActionResult Bins_Read(int site_Id, [DataSourceRequest]DataSourceRequest request)
{
return Json(Read(site_Id).ToDataSourceResult(request));
}
public IEnumerable<BinWithType> Read(int siteId)
{
return GetAllAsync(siteId).Result.ToList();
}
public async Task<IList<BinWithType>> GetAllAsync(int siteId)
{
if (Session.GetObjectFromJson<IList<BinWithType>>("BinWithType") != null)
{
Session.Remove("BinWithType");
_session.Clear();
}
var result = Session.GetObjectFromJson<IList<BinWithType>>("BinWithType");
var client = new BinsClient(new HttpClient());
var bins = await client.GetBinsWithTypeBySiteIdAsync(siteId);
result = bins.ToList();
Session.SetObjectAsJson("BinWithType", result);
return result;
}
public ActionResult Bins_Update([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")] IEnumerable<BinWithType> bins)
{
var client = new BinsClient(new HttpClient());
foreach (var bin in bins)
{
if (bin.Bin_ID > 300)
{
DeleteBin(bin, client);
}
if (bin.Bin_ID < 300)
{
PostNewBin(bin, client);
}
}
return Json(Read(bins.FirstOrDefault().Site_ID).ToDataSourceResult(request));
}
private static Task<Bin> DeleteBin(BinWithType bin, BinsClient client)
{
return client.DeleteBinByIdAsync(bin.Bin_ID);
}
[HttpPost]
private static Task<Bin> PostNewBin(BinWithType bin, BinsClient client)
{
var thisBin = new Bin
{
Site_ID = bin.Site_ID,
Bin_Type_ID = bin.Bin_Type_ID,
Comments = $"Added { DateTime.Now.ToShortDateString() }"
};
return client.PostBinAsync(thisBin);
}
having a grid, with a search panel, the text in the search panel "Search..." is not translated, but another toolbars are translated
.ToolBar(
toolbar => {
toolbar.Create(); // translated to french
toolbar.Save(); // translated to french
toolbar.Excel(); // translated to french
toolbar.Search().Text("Recherche..."); // NOT translated to french
}
)
I should hardcode translation, but shouldn't it be already translated in JS localization files?
Please add this to translation files :
$(function () {
/* Grid messages */
if (kendo.ui.Grid) {
kendo.ui.Grid.prototype.options.messages =
$.extend(true, kendo.ui.Grid.prototype.options.messages, {
commands: { search: "Rechercher..." }
});
};
});