Skip to content

Commit 6d3b57d

Browse files
Merge branch 'hotfix/hotfix-v29.1.33' into 945055-radio-hf
2 parents c0029e5 + c4fce2b commit 6d3b57d

File tree

6 files changed

+546
-32
lines changed

6 files changed

+546
-32
lines changed

ej2-asp-core-mvc/grid/EJ2_ASP.MVC/data-binding/remote-data.md

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,4 +698,61 @@ On remote data binding, all grid actions such as paging, sorting, editing, group
698698
{% highlight c# tabtitle="Offline.cs" %}
699699
{% include code-snippet/grid/data-binding/offline/offline.cs %}
700700
{% endhighlight %}
701-
{% endtabs %}
701+
{% endtabs %}
702+
703+
## Fetch result from the DataManager query using external button
704+
705+
By default, Syncfusion ASP.NET MVC Grid automatically binds a remote data source using the `DataManager`. However, in some scenarios, you may need to fetch data dynamically from the server using a query triggered by an external button. This approach allows greater control over when and how data is loaded into the Grid.
706+
707+
To achieve this, you can use the `executeQuery` method of `DataManager` with a `Query` object. This method allows you to run a custom query and retrieve results dynamically.
708+
709+
The following example demonstrates how to fetch data from the server when an external button is clicked and display a status message indicating the data fetch status:
710+
711+
{% tabs %}
712+
{% highlight razor tabtitle="CSHTML" %}
713+
714+
@using Syncfusion.EJ2
715+
716+
<div id='container'>
717+
@Html.EJS().Button("fetchButton").Content("Execute Query").CssClass("e-primary").Render()
718+
<p id="statusMessage" style="text-align:center;color:blue"></p>
719+
@Html.EJS().Grid("Grid").Columns(col =>
720+
{
721+
col.Field("OrderID").HeaderText("Order ID").Width("120").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Type("number").Add();
722+
col.Field("CustomerID").HeaderText("Customer ID").Width("160").Type("string").Add();
723+
col.Field("EmployeeID").HeaderText("Employee ID").Width("120").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Type("number").Add();
724+
col.Field("Freight").HeaderText("Freight").Width("150").Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Type("number").Add();
725+
col.Field("ShipCountry").HeaderText("Ship Country").Width("150").Type("string").Add();
726+
}).Render()
727+
</div>
728+
729+
<script>
730+
document.addEventListener("DOMContentLoaded", function () {
731+
let SERVICE_URL = 'https://ej2services.syncfusion.com/production/web-services/api/Orders';
732+
let statusMessage = document.getElementById("statusMessage");
733+
734+
fetchButton.addEventListener("click", function () {
735+
statusMessage.textContent = "Fetching data...";
736+
var grid = document.getElementById("Grid")?.ej2_instances?.[0];
737+
738+
let getData = new ej.data.DataManager({
739+
url: SERVICE_URL,
740+
adaptor: new ej.data.WebApiAdaptor()
741+
});
742+
743+
getData.executeQuery(new ej.data.Query()).then(function (e) {
744+
grid.dataSource = e.result;
745+
statusMessage.textContent = "Data fetched successfully! Total Records: " + e.result.length;
746+
statusMessage.style.color = "green";
747+
}).catch(function () {
748+
statusMessage.textContent = "Error fetching data!";
749+
statusMessage.style.color = "red";
750+
});
751+
});
752+
});
753+
</script>
754+
755+
{% endhighlight %}
756+
{% endtabs %}
757+
758+
![Fetch result from DataManager Query](../images/databinding/fetch-data.png)

ej2-asp-core-mvc/grid/EJ2_ASP.MVC/editing/validation.md

Lines changed: 216 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
---
22
layout: post
3-
title: Validation in ##Platform_Name## Grid Component
3+
title: Validation in ##Platform_Name## Grid Control | Syncfusion
44
description: Learn here all about Validation in Syncfusion ##Platform_Name## Grid component of Syncfusion Essential JS 2 and more.
55
platform: ej2-asp-core-mvc
66
control: Validation
77
publishingplatform: ##Platform_Name##
88
documentation: ug
99
---
1010

11-
# Validation in ASP.NET MVC Grid component
11+
# Validation in ASP.NET MVC Syncfusion Grid component
1212

1313
Validation is a crucial aspect of data integrity in any application. The ASP.NET MVC Grid component in Syncfusion<sup style="font-size:70%">&reg;</sup> provides built-in support for easy and effective data validation. This feature ensures that the data entered or modified adheres to predefined rules, preventing errors and guaranteeing the accuracy of the displayed information.
1414

@@ -120,3 +120,217 @@ Here's an example that demonstrates how to change the position of the validation
120120

121121
![Change the position of validation error message](../images/editing/validation-position.png)
122122

123+
## Show custom error message while performing CRUD actions
124+
125+
While performing CRUD actions in the Syncfusion ASP.NET MVC Grid, errors may occur due to various reasons such as validation failures, network issues, or server-side exceptions. Handling these errors effectively is essential for providing meaningful error messages when an operation fails.
126+
127+
To achieve this, you can use the [ActionFailure](https://help.syncfusion.com/cr/aspnetmvc-js2/Syncfusion.EJ2.Grids.Grid.html#Syncfusion_EJ2_Grids_Grid_ActionFailure) event, which is triggered when an action (such as update, delete, or insert) fails. This event allows you to retrieve the error message from the server response and display it in the UI.
128+
129+
The following sample demonstrates how to retrieve and display error messages in the Syncfusion ASP.NET MVC Grid:
130+
131+
{% tabs %}
132+
{% highlight razor tabtitle="CSHTML" %}
133+
<div id="errorMessage" class="error-message" style="display:none; color: red; text-align: center"></div>
134+
@*Replace xxxx with your actual port number*@
135+
@Html.EJS().Grid("grid").DataSource(ds => ds.Url("https://localhost:xxxx/Grid/UrlDatasource")
136+
.InsertUrl("https://localhost:xxxx/Grid/Insert")
137+
.UpdateUrl("https://localhost:xxxx/Grid/Update")
138+
.RemoveUrl("https://localhost:xxxx/Grid/Remove")
139+
.Adaptor("UrlAdaptor")).Columns(col =>
140+
{
141+
col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width("150")
142+
.TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
143+
col.Field("CustomerID").HeaderText("Customer Name").Width("150").Add();
144+
col.Field("Freight").HeaderText("Freight").Width("150").Format("C2")
145+
.TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
146+
col.Field("ShipCity").HeaderText("Ship City").Width("150").Add();
147+
}).EditSettings(edit => edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true)).Toolbar(new List<string>
148+
{ "Add", "Edit", "Delete", "Update", "Cancel" }).Height(320).ActionFailure("actionFailure").AllowPaging(true).Render()
149+
150+
<script>
151+
function actionFailure(args) {
152+
let errorDiv = document.getElementById("errorMessage");
153+
if (args.error && args.error[0] && args.error[0].error) {
154+
let response = args.error[0].error;
155+
response.text().then(errorMessage => {
156+
// Extract meaningful error message.
157+
let match = errorMessage.match(/<h3>HTTP Error 400.*? - (.*?)<\/h3>/);
158+
if (match && match[1]) {
159+
errorDiv.innerText = match[1]; // Display only the relevant error message.
160+
} else {
161+
errorDiv.innerText = "An unexpected error occurred.";
162+
}
163+
}).catch(() => {
164+
errorDiv.innerText = "An unexpected error occurred.";
165+
});
166+
} else {
167+
errorDiv.innerText = "An unexpected error occurred.";
168+
}
169+
}
170+
</script>
171+
172+
{% endhighlight %}
173+
174+
{% highlight c# tabtitle="GridController.cs" %}
175+
176+
using System.Collections.Generic;
177+
using System.Linq;
178+
using System.Net;
179+
using System.Web.Mvc;
180+
using Syncfusion.EJ2.Base;
181+
using UrlAdaptor.Models;
182+
183+
namespace UrlAdaptor.Controllers
184+
{
185+
public class GridController : Controller
186+
{
187+
private static List<OrdersDetails> order = OrdersDetails.GetAllRecords();
188+
/// <summary>
189+
/// Handles the HTTP POST request to retrieve data from the data source based on the DataManagerRequest.
190+
/// Supports filtering,searching, sorting, and paging operations (skip and take).
191+
/// </summary>
192+
/// <param name="dataManager">Contains the filtering, sorting, and paging options requested by the client.</param>
193+
/// <returns>Returns the filtered,searched, sorted, and paginated data along with the total record count.</returns>
194+
[HttpPost]
195+
public ActionResult UrlDatasource(DataManagerRequest dataManager)
196+
{
197+
// Retrieve data source and convert to queryable.
198+
IEnumerable<OrdersDetails> DataSource = order;
199+
200+
// Initialize DataOperations instance.
201+
DataOperations queryableOperation = new DataOperations();
202+
203+
// Handling searching operation.
204+
if (dataManager.Search != null && dataManager.Search.Count > 0)
205+
{
206+
DataSource = queryableOperation.PerformSearching(DataSource, dataManager.Search);
207+
}
208+
209+
// Handling filtering operation.
210+
if (dataManager.Where != null && dataManager.Where.Count > 0)
211+
{
212+
foreach (var condition in dataManager.Where)
213+
{
214+
foreach (var predicate in condition.predicates)
215+
{
216+
DataSource = queryableOperation.PerformFiltering(DataSource, dataManager.Where, predicate.Operator);
217+
}
218+
}
219+
}
220+
221+
// Handling sorting operation.
222+
if (dataManager.Sorted != null && dataManager.Sorted.Count > 0)
223+
{
224+
DataSource = queryableOperation.PerformSorting(DataSource, dataManager.Sorted);
225+
}
226+
227+
// Get the total count of records.
228+
int totalRecordsCount = DataSource.Count();
229+
230+
// Handling paging operation.
231+
if (dataManager.Skip != 0)
232+
{
233+
DataSource = queryableOperation.PerformSkip(DataSource, dataManager.Skip);
234+
}
235+
if (dataManager.Take != 0)
236+
{
237+
DataSource = queryableOperation.PerformTake(DataSource, dataManager.Take);
238+
}
239+
240+
// Return result and total record count.
241+
return dataManager.RequiresCounts ? Json(new { result = DataSource, count = totalRecordsCount }) : Json(DataSource);
242+
}
243+
244+
/// <summary>
245+
/// Inserts a new data item into the data collection.
246+
/// </summary>
247+
/// <param name="newRecord">It contains the new record detail which is need to be inserted.</param>
248+
/// <returns>Returns void.</returns>
249+
[HttpPost]
250+
[Route("Grid/Insert")]
251+
public ActionResult Insert(CRUDModel<OrdersDetails> newRecord)
252+
{
253+
if (newRecord != null)
254+
{
255+
var existingOrder = order.FirstOrDefault(or => or.OrderID == newRecord.value.OrderID);
256+
if (existingOrder == null)
257+
{
258+
order.Insert(0, newRecord.value);
259+
return Json(new { success = true, message = "Order added successfully.", data = newRecord });
260+
}
261+
else
262+
{
263+
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Duplicate values cannot be inserted.");
264+
}
265+
}
266+
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Invalid data received.");
267+
}
268+
269+
/// <summary>
270+
/// Update a existing data item from the data collection.
271+
/// </summary>
272+
/// <param name="updateRecord">It contains the updated record detail which is need to be updated.</param>
273+
/// <returns>Returns void.</returns>
274+
[HttpPost]
275+
[Route("Grid/Update")]
276+
public ActionResult Update(CRUDModel<OrdersDetails> updateRecord)
277+
{
278+
if (updateRecord.value == null)
279+
{
280+
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Invalid data received.");
281+
}
282+
283+
// Corrected condition to validate OrderID range.
284+
if (updateRecord.value.OrderID < 10010 || updateRecord.value.OrderID > 10030)
285+
{
286+
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "OrderID must be between 10010 and 10030 to update.");
287+
}
288+
var data = OrdersDetails.GetAllRecords().FirstOrDefault(or => or.OrderID == updateRecord.value.OrderID);
289+
if (data == null)
290+
{
291+
return new HttpStatusCodeResult(HttpStatusCode.NotFound, "Order not found.");
292+
}
293+
294+
// Update the existing record.
295+
data.CustomerID = updateRecord.value.CustomerID;
296+
data.Freight = updateRecord.value.Freight;
297+
data.ShipCity = updateRecord.value.ShipCity;
298+
data.ShipCountry = updateRecord.value.ShipCountry;
299+
return Json(new { success = true, message = "Order updated successfully.", data = updateRecord });
300+
}
301+
/// <summary>
302+
/// Remove a specific data item from the data collection.
303+
/// </summary>
304+
/// <param name="value">It contains the specific record detail which is need to be removed.</param>
305+
/// <return>Returns void.</return>
306+
[HttpPost]
307+
[Route("Grid/Remove")]
308+
public ActionResult Remove(CRUDModel<OrdersDetails> value)
309+
{
310+
int orderId = int.Parse(value.key.ToString());
311+
if (orderId < 10031 || orderId > 10045)
312+
{
313+
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "OrderID must be between 10031 and 10045 to delete.");
314+
}
315+
var data = OrdersDetails.GetAllRecords().FirstOrDefault(orderData => orderData.OrderID == orderId);
316+
OrdersDetails.GetAllRecords().Remove(data);
317+
return Json(new { success = true, message = "Order deleted successfully." });
318+
}
319+
}
320+
public class CRUDModel<T>
321+
{
322+
public string action { get; set; }
323+
public string keyColumn { get; set; }
324+
public object key { get; set; }
325+
public T value { get; set; }
326+
public List<T> Added { get; set; }
327+
public List<T> Changed { get; set; }
328+
public List<T> Deleted { get; set; }
329+
public IDictionary<string, object> @params { get; set; }
330+
}
331+
}
332+
333+
{% endhighlight %}
334+
{% endtabs %}
335+
336+
![Show custom error message](../images/editing/custom-message.png)

0 commit comments

Comments
 (0)