[Solved] Telerik Grid - Call its update function from button outside grid with Javascript

0 Answers 7 Views
Grid
Joshua
Top achievements
Rank 1
Iron
Iron
Joshua asked on 30 Oct 2026, 05:06 PM

Razor Page cshtml - 

<body>
	<div class="outerDivBlue">
		<div id="AddCertHeader">
			<span id="nameSearch">Certificates</span>
		</div>

		<div id="CertInfo">
			<div style="padding-left:10px; width:800px" id="CertificatesGridDiv">
			@(
						Html.Kendo().Grid<CertificateDTO>().Name("CertificatesGrid").Size(ComponentSize.Medium)
						.Editable(editable => editable.Mode(GridEditMode.InCell))
						.Columns(col =>
						{
							col.Bound(c => c.CertificateTypeDesc).Title("Type").Width(250);
								col.Bound(c => c.NumberOrdered).Title("Ordered").Width(100).EditorTemplateName("QuantityEditor");
								col.Bound(c => c.NumberIssued).Title("Issued").Width(100).EditorTemplateName("QuantityEditor");
						})
						.DataSource(dataSource => dataSource
						.Ajax()
						.Batch(true)//Here so all items are sent over together
						.Read(r => r.Url(Url.Page("/CaseCreate/AddCertificates", "GetCertificateTypes")).Data("forgeryToken"))
						.Update(u => u.Url(Url.Page("/CaseCreate/AddCertificates", "SaveCertificatesToSession")).Data("forgeryToken"))
						//Note above - Update function gets called from pressing create file button outside of grid
						.Model(m =>
						{
							m.Id(a => a.CertificateId);
							m.Field(p => p.CertificateTypeDesc).Editable(false);
							m.Field(p => p.NumberOrdered).Editable(true);
							m.Field(p => p.NumberIssued).Editable(true);
						}))
						)
						</div>
			<form id="certificateForm" method="post" asp-page-handler="SaveCertificateInfoAndFile">
				<div id="processTopRow">
					<label asp-for="ProcessedBy" id="ProcessedByLabel">Processed By:</label>
					<span><input asp-for="ProcessedBy" id="processedBy" name="ProcessedBy" style="width:215px;" /></span>

					<span id="ProcessedDateLabel">Processed Date:</span>
					<span id="processDate">
						@Html.EditorFor(e => e.ProcessedDate)						
					</span>
				</div>

				<div>
					<label asp-for="ProcessedLocation" id="ProcessedLocLabel">Processed Location:</label>
					<span>
						<input asp-for="ProcessedLocation" id="processedLocation" name="ProcessedLocation" style="width:540px;" />
					</span>
				</div>
			</form>
		</div>
	</div>
	<div class="solidLine"></div>
	<div class="PrevNextButtons">
		<span class="cancelbtn"><button id="textButton" data-role-"button" class="k-button k-button-md k-rounded-md k-button-solid k-button-solid-base-cancel" type="button" role="button" aria-disabled="false" onClick="window.location.href='../admin/LandingPage.html'">Cancel</button></span>
		<span class="PrevButtonWNext"><button id="textButton" data-role-"button" class="k-button k-button-md k-rounded-md k-button-solid k-button-solid-base" type="button" role="button" aria-disabled="false" onClick="window.location.href='@Url.Page("/CaseCreate/AddCertificates")'">Previous</button></span>
		<span>
			<button id="CertCreateBtn"
					class="k-button-solid-base-create"
					type="button"
					role="button">
				Create File
			</button>
		</span>
	</div>
</body>

<script>
	function forgeryToken() {
		return kendo.antiForgeryTokens();
	}

	$("#CertCreateBtn").on("click", function () {
	   const grid = $("#CertificatesGrid").data("kendoGrid");

	   grid.closeCell();
	   alert(grid);
		grid.dataSource.sync()
			.done(function () {
				document.getElementById("certificateForm").submit();
			})
			.fail(function (xhr) {
				alert("Grid save failed: " + xhr.status + " " + xhr.responseText);
			});
	});

</script>

cshtml.cs file: 

 public class AddCertificatesModel : PageModel
 {
     private readonly IDocumentService _documentService;
     private readonly IMapper _mapper;

     public DateOnly? ProcessedDate { get; set; }

     public string ProcessedBy { get; set; }

     public string ProcessedLocation { get; set; }

     public CaseCreateSession curSession { get; set; }

     public AddCertificatesModel(IDocumentService documentService, IMapper mapper)
     {
         _documentService = documentService;
         _mapper = mapper;
     }

     public void OnGet()
     {
         curSession = HttpContext.Session.GetObjectFromJson<CaseCreateSession>("CaseCreateSession");
     }

     public async Task<IActionResult> OnPostGetCertificateTypes([DataSourceRequest] DataSourceRequest request)
     {
         var CertificateTypes = await _documentService.GetCertificateTypes();
         return new JsonResult(CertificateTypes.ToDataSourceResult(request));
     }

     public async Task<IActionResult> OnPostSaveCertificatesToSession([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")] IEnumerable<CertificateDTO> CertificateList)
     {
         curSession = HttpContext.Session.GetObjectFromJson<CaseCreateSession>("CaseCreateSession");

         curSession.CertificateGroup = new CertificateGroupDTO();

         foreach(var certificate in CertificateList)
         {
             if (certificate.NumberOrdered > 0 || certificate.NumberIssued > 0)
             {
                 curSession.CertificateGroup.CertificateList.Add(certificate);
             }
         }

         HttpContext.Session.SetObjectAsJson("CaseCreateSession", curSession);

         return new JsonResult(CertificateList.ToDataSourceResult(request, ModelState));


     }

     public async Task<IActionResult> OnPostSaveCertificateInfoAndFile()
     {
         if(!ModelState.IsValid)
         {
             return Page();
         }

         curSession = HttpContext.Session.GetObjectFromJson<CaseCreateSession>("CaseCreateSession");

         foreach(var certificate in curSession.CertificateGroup.CertificateList)
         {
             certificate.ProcessedDate = ProcessedDate;
             certificate.ProcessedLocation = ProcessedLocation;
             certificate.ProcessedBy = ProcessedBy;
         }

         HttpContext.Session.SetObjectAsJson("CaseCreateSession", curSession);

         return RedirectToPage("FileInfo", "SaveFileToDatabase");
     }

 }

I am trying to make the Create File button call the grid's Update function and then submit the form through javascript. This is not working, it is giving me a "Grid Save failed 400 " error. And telling me bad request. Further looking into it its giving me these errors:

Exception thrown: 'Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException' in Microsoft.AspNetCore.Antiforgery.dll Exception thrown: 'Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException' in System.Private.CoreLib.dll

So its something with the antiforgery token. It is failing on the grid submit and never reaches the function on the backend.

I have worked for a long time with Copilot and is unable to provide me an answer and its likely a simple one line, but I do not

kknow what it looks like. Can you please assist?

No answers yet. Maybe you can help?

Tags
Grid
Asked by
Joshua
Top achievements
Rank 1
Iron
Iron
Share this question
or