How to achieve searching in grid with WCF/OData service?
This KB showcase the example to achieve the searching operation in grid when WCF/Odata service is used.
Solution
In WCF/Odata service, we don’t have the default searching support. So, to achieve the searching in remote data use customAdaptor to modify the default search query string.
Step 1: Render the Grid control
HTML
<div id="FlatGrid"></div>
JS
$(function () {
$("#FlatGrid").ejGrid({
dataSource: ej.DataManager({
url: "http://js.syncfusion.com/demos/ejservices//Wcf/Northwind.svc/Orders/",
crossDomain:true,
}),
allowPaging: true,
toolbarSettings: { showToolbar: true, toolbarItems: ej.Grid.ToolBarItems.Search] },
load: "load",
columns: [
{ field: "OrderID", isPrimaryKey: true, headerText: "Order ID", width: 90, textAlign: ej.TextAlign.Right },
{ field: "CustomerID", headerText: "CustomerID", width: 90 },
{ field: "EmployeeID", headerText: "Employee ID", width: 90 },
{ field: "ShipCity", headerText: "Ship City", width: 90 },
]
});
});
MVC
@(Html.EJ().Grid<object>("FlatGrid")
.Datasource("http://js.syncfusion.com/demos/ejServices/Wcf/Northwind.svc/Orders")
.AllowPaging() /*Paging Enabled*/
.ToolbarSettings(toolbar =>
{
toolbar.ShowToolbar().ToolbarItems(items =>
{
items.AddTool(ToolBarItems.Search);
});
})
.ClientSideEvents(eve => eve.Load ("load"))
.Columns(col =>
{
col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width(90).Add();
col.Field("CustomerID").HeaderText("Customer ID”).Width(90).Add();
col.Field("EmployeeID").HeaderText("Employee ID”) .Width(90).Add();
col.Field("ShipCity").HeaderText("Ship City”) .Width(90).Add();
}))
ASP
<ej:Grid ID="FlatGrid" runat="server" AllowPaging="True" > <DataManagerURL="http://js.syncfusion.com/demos/ejServices/Wcf/Northwind.svc/Orders/"></DataManager> <ClientSideEvents Load="load " /> <Columns> <ej:Column Field="OrderID" HeaderText="Order ID" IsPrimaryKey="True" Width="90" /> <ej:Column Field="CustomerID" HeaderText="Customer ID" Width="80" /> <ej:Column Field="EmployeeID" HeaderText="Employee ID" Width="80"/> <ej:Column Field="ShipCity" HeaderText="Ship City" Width="80" /> </Columns> <ToolbarSettings ShowToolbar="True" ToolbarItems="search"></ToolbarSettings> </ej:Grid>
.Net core
<ej-grid id="FlatGrid " allow-paging="true" >
<e-toolbar-settings show-toolbar="true" toolbar-items='@new List<string> {“search”}' />
< e-datamanager url="http://js.syncfusion.com/demos/ejServices/Wcf/Northwind.svc/Orders"></ e-datamanager >
<e-columns>
<e-column field="OrderID" is-primary-key="true" header-text="Order ID" width="90"></e-column>
<e-column field="CustomerID" header-text="Customer ID" width="80”></e-column>
<e-column field="EmployeeID" header-text="Employee ID" width="80”></e-column>
<e-column field="ShipCity" header-text="Ship City" width="80”></e-column>
</e-columns>
</ej-grid>
Angular
<ej-grid #grid [allowPaging]="true" [dataSource]="gridData" [toolbarSettings]="toolbarItems" (load)="load($event)" > <e-columns> <e-column field="OrderID" [isPrimaryKey] = "true" headerText="Order ID" width="85" ></e-column> <e-column field="CustomerID" headerText="Customer ID" width="100"></e-column> <e-column field="EmployeeID" headerText="Employee ID " width="90"></e-column> <e-column field="ShipCity" headerText="ShipCity" width="60"></e-column> </e-columns> </ej-grid>
TS
export class GridComponent {
public gridData: any;
public editSettings;
public toolbarItems;
@ViewChild('grid') Grid: EJComponents<any, any>;
constructor() {
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true};
this.toolbarItems = { showToolbar : true, toolbarItems : ["search"]};
this.gridData = [{
…………………
];
}
load(e: any){
this.Grid.model.dataSource.adaptor = new customadaptor(this.Grid.model.columns);//extend the adaptor
}
var customadaptor = function (data) {
var odataSearch = new ej.ODataAdaptor().extend({
onComplexPredicate: function (pred, requiresCast) {
var res = this.base.onComplexPredicate.apply(this, [pred, requiresCast])
res = res.split(" or ");
res = res.filter(function (element) {
return element !== "(undefined)";
});
return res.join(" " + pred.condition + " ");
},
init: function () {
this.column = data;
},
onPredicate: function (pred, query, requiresCast) {
var returnValue = "", operator, guid, val = pred.value, type = typeof val, field = this._p(pred.field);
if (type === "string") { // handling string query
var args = this._typeStringQuery(pred, requiresCast, val, field, guid);
val = args["val"]; field = args["field"]; guid = args["guid"];
}
operator = ej.data.odUniOperator[pred.operator];
var column = this.column.filter(function (e) { return e.field == pred.field })[0];
if (column.type == "number" || column.type == "boolean") {
returnValue += "(" + pred.field + " eq " + pred.value + ")"; // handling number and boolean query
} else {
if (operator === "substringof") {
var t = val;
val = field;
field = t;
}
returnValue += operator + "(" + field + "," + val + ")";
}
if ((!$.isNumeric(pred.value) && column.type == "number") || column.type == "date" || column.type == "datetime") {
return;
} else
return returnValue;
},
});
$.extend(this, new odataSearch());
return this;
}
}
}
Step 2: Modify the search query in the customAdaptor function
var customadaptor = function (data) {
var odataSearch = new ej.ODataAdaptor().extend({
onComplexPredicate: function (pred, requiresCast) {
var res = this.base.onComplexPredicate.apply(this, [pred, requiresCast])
res = res.split(" or ");
res = res.filter(function (element) {
return element !== "(undefined)";
});
return res.join(" " + pred.condition + " ");
},
init: function () {
this.column = data;
},
onPredicate: function (pred, query, requiresCast) {
var returnValue = "", operator, guid, val = pred.value, type = typeof val, field = this._p(pred.field);
if (type === "string") { // handling string query
var args = this._typeStringQuery(pred, requiresCast, val, field, guid);
val = args["val"]; field = args["field"]; guid = args["guid"];
}
operator = ej.data.odUniOperator[pred.operator];
var column = this.column.filter(function (e) { return e.field == pred.field })[0];
if (column.type == "number" || column.type == "boolean") {
returnValue += "(" + pred.field + " eq " + pred.value + ")"; // handling number and boolean query
} else {
if (operator === "substringof") {
var t = val;
val = field;
field = t;
}
returnValue += operator + "(" + field + "," + val + ")";
}
if ((!$.isNumeric(pred.value) && column.type == "number") || column.type == "date" || column.type == "datetime") {
return;
} else
return returnValue;
},
});
$.extend(this, new odataSearch());
return this;
}
}
Step 3: Extend the OData adaptor as custom adaptor in grid load event.
</script>
function load(args) {
this.model.dataSource.adaptor = new customadaptor(this.model.columns);//extend the adaptor
}
</script>
Refer the below link for JS-playground sample
https://jsplayground.syncfusion.com/jb1j4q2w
Also refer the below link for custom adaptor script file.
https://www.syncfusion.com/downloads/support/directtrac/general/ze/customadaptor-1287990129.zip
Please refer the custom Adaptor script file after the ej.web.all.min.js file.

Figure: Remote data Query string.