Preferred method since it only makes one call to the server. Method uses detailDataBound: onExpand (currently remarked out) Also, selecting single record for clarity.
https://localhost:44307/odata/employers(107)?$expand=opportunities,employertype
{"@odata.context":"https://localhost:44307/odata/$metadata#Employers/$entity","IdEmployer":107,"EmployerName":"OHL USA","StreetAddress":null,"City":null,"State":null,"PostalCode":null,"IdEmployerType":1,"Opportunities":[{"IdOpportunity":15,"Postion":"Desktop Support Technician","EmploymentTypeId":1,"PayRate":17.00,"PeriodTypeId":2,"IdEmployer":107},{"IdOpportunity":39,"Postion":"PROCESS CONTROL TECHNICIAN","EmploymentTypeId":2,"PayRate":37.48,"PeriodTypeId":2,"IdEmployer":107},{"IdOpportunity":42,"Postion":"AWWU SYSTEMS ANALYST","EmploymentTypeId":2,"PayRate":42.32,"PeriodTypeId":2,"IdEmployer":107}],"EmployerType":{"IdEmployerType":1,"Description":"For Profit Business"}}
Using a seperate datasource for the child grid and linking by id to the main grid. This seems to be problematic because it is doing some sort of conversion and not populating the id value.
What the childgrid dataSource/query are generating:
https://localhost:44307/odata/opportunities/?$count=true&$filter=tolower(idEmployer)%20eq%20%27undefined%27
Server response:
{"error":{"code":"","message":"The query specified in the URI is not valid. No function signature for the function with name 'tolower' matches the specified arguments. The function signatures considered are: tolower(Edm.String Nullable=true).","details":[],"innererror":{"message":"No function signature for the function with name 'tolower' matches the specified arguments. The function signatures considered are: tolower(Edm.String Nullable=true).","type":"Microsoft.OData.ODataException","stacktrace":" at Microsoft.OData.UriParser.FunctionCallBinder.MatchSignatureToUriFunction(String functionCallToken, SingleValueNode[] argumentNodes, IList`1 nameSignatures)\r\n at Microsoft.OData.UriParser.FunctionCallBinder.BindAsUriFunction(FunctionCallToken functionCallToken, List`1 argumentNodes)\r\n at Microsoft.OData.UriParser.FunctionCallBinder.BindFunctionCall(FunctionCallToken functionCallToken)\r\n at Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\r\n at Microsoft.OData.UriParser.BinaryOperatorBinder.GetOperandFromToken(BinaryOperatorKind operatorKind, QueryToken queryToken)\r\n at Microsoft.OData.UriParser.BinaryOperatorBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken)\r\n at Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\r\n at Microsoft.OData.UriParser.FilterBinder.BindFilter(QueryToken filter)\r\n at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseFilterImplementation(String filter, ODataUriParserConfiguration configuration, ODataPathInfo odataPathInfo)\r\n at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseFilter()\r\n at Microsoft.AspNet.OData.Query.FilterQueryOption.get_FilterClause()\r\n at Microsoft.AspNet.OData.Query.Validators.FilterQueryValidator.Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings)\r\n at Microsoft.AspNet.OData.Query.Validators.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.ValidateQuery(HttpRequest request, ODataQueryOptions queryOptions)\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.<>c__DisplayClass1_0.<OnActionExecuted>b__3(ODataQueryContext queryContext)\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.ExecuteQuery(Object responseValue, IQueryable singleResultCollection, IWebApiActionDescriptor actionDescriptor, Func`2 modelFunction, IWebApiRequestMessage request, Func`2 createQueryOptionFunction)\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.OnActionExecuted(Object responseValue, IQueryable singleResultCollection, IWebApiActionDescriptor actionDescriptor, IWebApiRequestMessage request, Func`2 modelFunction, Func`2 createQueryOptionFunction, Action`1 createResponseAction, Action`3 createErrorAction)"}}}
What I am expecting to see:
https://localhost:44307/odata/opportunities?$filter=idemployer+eq+107
{"@odata.context":"https://localhost:44307/odata/$metadata#Opportunities","value":[{"IdOpportunity":15,"Postion":"Desktop Support Technician","EmploymentTypeId":1,"PayRate":17.00,"PeriodTypeId":2,"IdEmployer":107},{"IdOpportunity":39,"Postion":"PROCESS CONTROL TECHNICIAN","EmploymentTypeId":2,"PayRate":37.48,"PeriodTypeId":2,"IdEmployer":107},{"IdOpportunity":42,"Postion":"AWWU SYSTEMS ANALYST","EmploymentTypeId":2,"PayRate":42.32,"PeriodTypeId":2,"IdEmployer":107}]}
Source:
<div id="Grid"></div>
<script>
ej.base.enableRipple(true);
var data = new ej.data.DataManager({
url: 'https://localhost:44307/odata/employers?$expand=opportunities,employertype',
adaptor: new ej.data.ODataV4Adaptor(),
crossDomain: true
});
var oppdata = new ej.data.DataManager({
url: 'https://localhost:44307/odata/opportunities',
adaptor: new ej.data.ODataV4Adaptor(),
crossDomain: true
});
@*{"IdOpportunity":39,"Postion":"PROCESS CONTROL TECHNICIAN","EmploymentTypeId":2,"PayRate":37.48,"PeriodTypeId":2,"IdEmployer":107} *@
ej.grids.Grid.Inject(ej.grids.DetailRow);
var grid = new ej.grids.Grid({
dataSource: data,
allowPaging: true,
pageSettings: { pageSizes: false, pageSize: 10 },
columns: [
{ field: 'IdEmployer', headerText: 'Id', textAlign: 'Right', type: 'number' },
{ field: 'EmployerName', headerText: 'Employer Name', type: 'string' },
{ field: 'EmployerType.Description', headerText: 'Employer Type', textAlign: 'Right' },
],
childGrid: {
dataSource: oppdata,
queryString: 'idEmployer',
columns: [
{ field: 'Postion', headerText: 'Postion', textAlign: 'Right' },
{ field: 'EmploymentTypeId', headerText: 'EmploymentTypeId' },
{ field: 'PayRate', headerText: 'PayRate', type: 'number', format: 'C' },
{ field: 'PeriodTypeId', headerText: 'PeriodTypeId' }
]
}
//detailDataBound: onExpand
});
grid.appendTo('#Grid');
function onExpand(args) {
var opps = args.data["Opportunities"];
console.log(opps);
this.childGrid.dataSource = opps; // assign data source for child grid.
}
</script>