I'm having trouble getting a custom popup editor bound to a model using tag helpers, razor pages, and entity framework.
Index.cshtml.cs
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using MyApp.Data.Models;
using MyApp.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace MyApp.Pages
{
public class IndexModel : PageModel
{
private readonly IDataService _dataService = null!;
public List<Item> Items { get; set; }
public IndexModel(IDataService dataService)
{
_dataService = dataService;
Items = new();
}
public async Task<JsonResult> OnPostCreate([DataSourceRequest] DataSourceRequest request, Item item)
{
await _dataService.CreateItemAsync(item);
return new JsonResult(new[] { item }.ToDataSourceResult(request, ModelState));
}
public async Task<JsonResult> OnPostRead([DataSourceRequest] DataSourceRequest request, bool isFound)
{
Items = await _dataService.GetActiveItemsAsync(isFound);
var result = await Items.ToDataSourceResultAsync(request);
return new JsonResult(result);
}
public async Task<JsonResult> OnPostUpdate([DataSourceRequest] DataSourceRequest request, Item item)
{
var updatedItem = await _dataService.UpdateItemAsync(item);
return new JsonResult(new[] { updatedItem }.ToDataSourceResult(request, ModelState));
}
public async Task<JsonResult> OnPostDestroy([DataSourceRequest] DataSourceRequest request, Item item)
{
await _dataService.DeleteItem(item.Id);
return new JsonResult(new[] { item }.ToDataSourceResult(request, ModelState));
}
}
}
Index.cshtml
@page
@model IndexModel
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@Html.AntiForgeryToken()
<kendo-grid name="grid" height="700">
<filterable enabled="true" />
<groupable enabled="true" />
<sortable enabled="true" />
<editable enabled="true" mode="popup" template-id="popup-editor" />
<scrollable enabled="true" />
<pageable enabled="true" page-sizes="new int[] { 10, 20, 50}" />
<toolbar>
<toolbar-button template="toolbarTemplate"></toolbar-button>
<toolbar-button name="create"></toolbar-button>
</toolbar>
<columns>
<foreign-key-column field="ItemTypeId" />
<column field="ReportDate" title="Date Reported" format="{0:yyyy-MM-dd}" width="160" />
<column field="ItemDescription" title="Description" />
<column field="Unit" title="Unit" width="200" />
<column field="ContactName" title="Contact Name" width="250" />
<column field="ReceivedBy" title="Received By" hidden="true" />
<column field="ContactPhone" title="Contact Phone" hidden="true" />
<column field="ContactAddress" title="Contact Address" hidden="true" />
<column field="ContactDetails" title="Contact Details" hidden="true" />
<column field="Qty" title="Item Quantity" hidden="true" format="{0:0}" />
<column width="180">
<commands>
<column-command name="edit"></column-command>
<column-command name="destroy"></column-command>
</commands>
</column>
</columns>
<datasource type="DataSourceTagHelperType.Ajax" page-size="10">
<transport>
<read url="/Index?handler=Read" data="getDataParameters" />
<create url="/Index?handler=Create" data="getDataParameters" />
<update url="/Index?handler=Update" data="getDataParameters" />
<destroy url="/Index?handler=Destroy" data="getDataParameters" />
</transport>
<sorts>
<sort field="ReportDate" direction="desc" />
</sorts>
<schema data="Data" total="Total" errors="Errors">
<model id="Id">
<fields>
<field name="Id" type="number" editable="false" />
<field name="ItemTypeId" type="object" />
<field name="ReportDate" type="date" />
<field name="ItemDescription" type="string" />
<field name="Unit" type="string" />
<field name="ContactName" type="string" />
<field name="ReceivedBy" type="string" />
<field name="ContactPhone" type="string" />
<field name="ContactAddress" type="string" />
<field name="ContactDetails" type="string" />
<field name="Qty" type="number" default-value="1" />
</fields>
</model>
</schema>
</datasource>
</kendo-grid>
<script id="popup-editor" type="text/x-kendo-template">
@await Html.PartialAsync("_ItemPartial")
</script>
_ItemPartial.cshtml
<!--
the following @model throws:
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'MyApp.Pages.IndexModel', but this ViewDataDictionary instance requires a model item of type 'MyApp.Data.Models.Item'.
-->
@model MyApp.Data.Models.Item
<!-- the following @model shows an empty grid: -->
@model IndexModel
<h6>magical mystery template</h6>
The questions I have are:
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
Hello,
I have a kendo grid with the FundAge column with a dropdown list editor template. When I select the value from the dropdown and click update the value is showing as undefined. Can someone help with this?
///Editor template
@model Models.FedAge
@(Html.Kendo().DropDownListFor(x => x)
.DataValueField("FedId")
.DataTextField("FedDesc")
.BindTo((System.Collections.IEnumerable)ViewData["FedAge"]))
//////// Grid column
@(Html.Kendo().Grid<AgencyInformation>()
.Name("AgencyInformationGrid")
.Columns(columns =>
{
columns.Bound(p => p.FundAge).ClientTemplate("#=FundAge.FedDesc#").Sortable(false).Width(175).HtmlAttributes(new { @class = "FundAgeClass" });
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Pageable()
.Sortable()
.Scrollable()
.HtmlAttributes(new { style = "height:500px;" })
.DataSource(dataSource => dataSource
.Ajax()
.AutoSync(false)
.Batch(false)
.PageSize(20)
.ServerOperation(false)
.Events(events => events.Error("errorHandler"))
.Events(events => events.RequestEnd("onAgeInfoRequestEnd"))
.Model(model => {
model.Id(p => p.AgeInfoId);
model.Field(p => p.AgeInfoId).Editable(false);
model.Field(p => p.FedAge.FedAgeDesc).Editable(false).DefaultValue(ViewData["FedAge"]);
})
.Create(update => update.Action("AddAgeInfo", "Cove").Type(HttpVerbs.Post))
.Read(read => read.Action("GetAgeInfo", "Cove").Type(HttpVerbs.Get))
.Update(update => update.Action("EditAgeInfo", "Cove").Type(HttpVerbs.Post))
.Destroy(update => update.Action("DeleteAgeInfo", "Cove").Type(HttpVerbs.Post))
)
//////Entity
public class AgeInfo
{
public string AgenfoId { get; set; }
[UIHint("FedlAgeEditor")]
[Required(ErrorMessage = "Required")]
public string FundAge{ get; set; }
public FedAge FedAge{ get; set; }
}
public class FedAge
{
public int FedAgeId { get; set; }
public string FedAgeDesc { get; set; }
}
}
///controller
[HttpGet]
public IActionResult AgeInfo()
{
//if (coveDetails!= null && coveDetails.AgeInfo!= null)
//{
// return View("AgeInfo", coveDetails.AgeInfo);
//}
ViewData["FedAge"] = lookupsDetails.FedAge;
ViewBag.FedAge= lookupsDetails.FedAge;
return View();
}
Can some one please help??
For as long as I've been using Visual Studio, IntelliSense has always defaulted to this first menu labeled "All". It contains HTML, ASP.Net, and Telerik control autocomplete options, among others. For some reason today it started to default to the "TelerikCore" menu in the second screenshot.
Before:
After:
I have no use for anything in this new menu, and would like IntelliSense to go back to defaulting to the first menu.
I couldn't find any IntelliSense options related to this, and we have multiple users with this same problem.
Thank you in advance.
hi, I have a simple grid set up for batch mode data entry . Two of the columns need to allow multiline entry (with line breaks) and I thought I had solved this problem by using a textarea. However, it turns out that the textarea is extremely buggy and the errors seem to be completely random and impossible to reliably duplicate. Sometimes it happens when you click into the cell, sometimes when you tab into a cell. After editing the cell contents, the black triangle to indicate an update does not appear in the upper left-hand corner of the column. Upon saving the changes, the data in the column reverts back to the unedited text (the edit is not saved).
I can't find any pattern to this behavior and it usually works fine on the second try.
Is there a better method for allowing multi-line text area in a column?
This is how I have the column set up:
columns.Bound(c => c.PODescription).ClientTemplate("<textarea rows='2' style='border: none; width:100%;'>#=PODescription#</textarea>").Title("*PO Description").EditorTemplateName("TextAreaTemplate").Width("200px");
The editor template:
@model string
Right now, I have a ListBox on a ASP.NET Core MVC application that has some "clonky" behavior. When I press the "Up/Down" arrows to reorder the contents of the ListBox, it redirects over to the controller then loads an "Edit" view then when I save the Edit result (item index) and it directs back to the view with the ListBox. This is not a good user experience.
Instead, I want to push the up/down arrow and have it perform the update without it redirecting over to the Controller/Edit page. How do I accomplish this?
<div class="container">
@(Html.Kendo().ListBox()
.Name("listBox")
.DataTextField("Name")
.DataValueField("Id")
.DataSource(source =>
source.Read(read =>
read.Action("IndexJson", "SessionOptionItems").Data("gridGetData"))
)
.TemplateId("item-template")
.Toolbar(toolbar =>
{
toolbar.Position(ListBoxToolbarPosition.Right);
toolbar.Tools(tools => tools
.MoveUp()
.MoveDown()
.Remove()
);
})
.Events(events => events
.Reorder("onReorder")
.Remove("onRemove"))
.HtmlAttributes(new { style = "height:550px;width:530px" })
.BindTo(new List<SessionOptionTemplate>()))
</div>
function onReorder(e) {
//alert("onReorder");
$("#isbusy").show();
var dataSource = e.sender.dataSource;
var element = e.sender.select();
var dataItem = e.sender.dataItem(element[0]);
//alert("id: " + dataItem.Id);
//alert("name: " + dataItem.Name);
var index = dataSource.indexOf(dataItem) + e.offset;
//alert("index: " + index);
var url = '@Url.Action("Edit", "SessionOptionItems")?id=' + dataItem.Id + '&order=' + index + '@Model.GetUrlParameters("&")';
// Replace & with & as the above encoding step changes & to &.
window.location.href = url.replace(/&/g, "&");
}
I've got an EF Core model that represents a one-to-many relationship. There's a navigation property on the parent that holds a collection of child items. What I'd like to do is bind this to a hierarchical grid and have the child items display underneath the parent items.
The example for a hierarchical grid shows separate data sources for the parent and child tables. Since I've already retrieved this data, why not just display it in that form?
I have a datasource defined which has an include statement. I tried to adapt the example code and have the same datasource for both grids, using syntax like "Client.Order" in the child table, but it doesn't like that.
Many thanks for any suggestions.
Hi there,
i have a window with a form. in these form there are three fields bound to my model.
One of the fields shouldn't be visible when the window was opened.
Here is the html helper code:
@{Html.Kendo().Window()
.Name("MeterData" + Model.Plan["Number"])
.Title("Vertragskontonummer: " + Model.PlanAccount.PlanAccount.Number + " Vertrags-Nr.: " + Model.Plan["Number"])
.Content(@<text>
<div class="window-plan-content">
<partial name="_PlanDetailData" />
<div style="padding-top: 20px; width: 100%;">
<div class="row window-form-content" style="border-radius: 13px 13px;">
<span class="accordeon-text-header" style="padding: 20px 0px 0px 20px;">Neuen Zählerstand angeben:</span>
</div>
<div class="row window-form-content">
<span class="accordeon-text" style="padding-top: 10px; padding-bottom: 20px; padding-left: 20px;">
Hier können Sie Ihren aktuellen Zählestand eingeben. Um sicher zu sein, dass Sie den richtigen Zähler<br />
abgelesen haben, sehen Sie hier Ihre zuletzt angegebene Zählernummer, die mit der Nummer auf Ihrem zähler<br />
übereinstimmen sollte.
</span>
</div>
<div class="row window-form-content" style="border-radius: 0px 0px 13px 13px;">
@(Html.Kendo().Form<Wsw.MeineWsw.Dks.Models.LastMeterReading>()
.Name("MeterDataDetailsForm")
.HtmlAttributes(new { action = "SaveMeterData", method = "PUT", style = "width: 100%;"})
.Layout("grid")
.ButtonsTemplate("<button id=\"closeMeterDetails" + Model.Plan["Number"] + "\" class=\"k-button open-modal-box\">Zurück</button><button id=\"submit-meter\" class=\"k-button k-primary k-form-submit open-modal-box\" type=\"submit\" planAccount=\"" + Model.PlanAccount.PlanAccount.Number + "\" plan=\"" + Model.Plan["Number"] + "\" meterNumber=\"" + Model.PlanAccount.Meters.Where(m => m.PlanAccountNumber == Model.PlanAccount.PlanAccount.Number).FirstOrDefault().Number + "\" registerKind=\"" + Model.PlanAccount.Meters.Where(m => m.PlanAccountNumber == Model.PlanAccount.PlanAccount.Number).FirstOrDefault().RegisterKind + "\" disabled=\"true\">Zählerstand übernehmen</button>")
.Grid(g => g.Cols(1).Gutter(20))
.Validatable(v =>
{
v.ValidateOnBlur(true);
v.ValidationSummary(vs => vs.Enable(false));
})
.Items(items =>
{
items.AddGroup()
.Layout("grid")
.Grid(g => g.Cols(2).Gutter(10))
.Items(i =>
{
i.Add()
.Field(f => f.Value)
.Label("Neuen Zählerstand angeben:")
.Editor(e => e.NumericTextBox().Spinners(false).Format("n0"))
.InputHtmlAttributes(new { style = "border-radius: 8px;" });
i.Add()
.Field(f => f.Date)
.Label("Ablesedatum")
.InputHtmlAttributes(new { style = "border-radius: 8px;" })
.Editor(e => e.DateInput().Format("dd.MM.yyyy").Messages(m => m.Day("tt").Month("mm").Year("jjjj")).Max(DateTime.Now).Min(DateTime.Now.AddDays(-14)));
i.Add()
.Field(f => f.Comment)
.Label("Kommentar")
.Id("ReadingComment")
.InputHtmlAttributes(new { style = "border-radius: 8px;" });
});
})
.Events(ev => ev.Submit("onFormSubmitMeter").Change("validateMeterForm")))
</div>
</div>
</div>
</text>
)
.Visible(false)
.Modal(true)
.Draggable(true)
.Scrollable(false)
.Width(1085)
.Height(746)
.Events(e => e.Activate("toogleMeterReadingCommentVisibility"))
.Render();
}
And here is the way I tried to toogle the visibility of the field:
function toogleMeterReadingCommentVisibility(e) {
var parentEle = document.getElementById('ReadingComment-form-label').parentNode;
parentEle.style.display = 'none';
console.log(parentEle);
}
After setting display = 'none' the DOM-Element has changed as expected, but only in the console. The field is still visibile.
Thanks for help.
Timo
Hi
I have a grid with checkbox columns, I like to place a checkbox on the header and select /deselect rows.
here is my grid, columns AttendTraining and ExamPassed are checkbox columns
<div>
@(Html.Kendo().Grid<ViewStudents>()
.Name("StudentGrid")
.Columns(columns =>
{
;
columns.Bound(c => c.StId).Width(80);
columns.Bound(c => c.EmailPersonal).Width(230);
columns.Bound(c => c.FirstName).Width(200);
columns.Bound(c => c.Surname).Width(200);
columns.Bound(c => c.AttendTraining).Width(120).ClientTemplate("#= AttendTraining ? 'Yes' : 'No' #").HeaderTemplate("<label><input type='checkbox' id='chkAttTrn' onclick='ChangeCheckStatus(this.checked,this);'> <span> Attend Training </span></label>");
columns.Bound(c => c.ExamPassed).Width(120).ClientTemplate("#= ExamPassed ? 'Yes' : 'No' #").HeaderTemplate("<label><input type='checkbox' id='chkExam' onclick='ChangeCheckStatus(this.checked,this);'> <span> Exam Passed </span></label>");
columns.Bound(c => c.MobilePhoneNumber).Width(120).Title("Mobile/Cell Number");
})
.Editable(e => e.Mode(GridEditMode.InCell).DisplayDeleteConfirmation(false))
.Resizable(resize => resize.Columns(true))
.Scrollable(s => s.Enabled(true))
.Selectable(selectable =>
{
selectable.Mode(GridSelectionMode.Single);
selectable.Type(GridSelectionType.Row);
selectable.Mode(GridSelectionMode.Multiple);
})
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(25)
.PageSizes(new int[] { 25, 50, 100 })
)
.Sortable(sortable =>
{
sortable.SortMode(GridSortMode.SingleColumn);
})
.Events(events => events.Edit("disableEdit"))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(x =>x.EmailWork))
.PageSize(20)
.ServerOperation(false))
)
</div>
I can update each column
function ChangeCheckStatus(flag, e) {
var grid = $('#StudentGrid').data('kendoGrid');
var check = 0;
if (flag)
check = 1;
$.each(grid.dataSource.data(), function (index, row) {
console.log("row...")
if (e.id == "chkAttTrn")
row.set('AttendTraining', check);
else if (e.id == "chkTakeExam")
row.set('ExamPassed', check);
});
}
When I click on the header checkboxes (Attend Training & Exam Passed) it does change the column values, but the checkbox itself does not retain it's value.
what i need is, for it to hold it's value like below so i can toggle.
Thanks
Faz
Scenario:
I've used grid component before,
and I'm aware that it has excel export function,
but what it exports is all the data from the grid.
However, in my scenario,
data in each row of my grid is only the maximum value of a list of data,
and I would like to press the button and export the list of data,
where the button is at the last column of the row.
Its hard to describe with words,
So I'll leave a picture hoping it will clarify my question