Posted 7 July 2025, 9:54 am EST - Updated 7 July 2025, 10:01 am EST
Hi team,
I’m working with Wijmo FlexGrid in an Angular application and trying to dynamically bind a nested JSON structure with grouping to the FlexGrid. My JSON data represents a catalog of attributes, where some of the nodes are grouping nodes (isGrouping: true) and others are leaf attributes.
Here’s a simplified structure of my data:
service data
let data = {
"attributes" : [
{
"nodeId" : 737819,
"attributeName" : "About",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/About",
"isGrouping": false,
"en_US" : [{
"nodeId" : 737818,
"isEditable": true,
"attributeName" : "en_US",
"localeIdentifier": "en_US",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/About/en_US",
"value" : "Eye Comfort HUAWEI FullView Display1 | Super Device2 | HUAWEI Metaline Antenna",
"approvalStatus": false
}],
"en_CA": [{
"nodeId" : 740613,
"isEditable": true,
"attributeName" : "en_CA",
"localeIdentifier": "en_CA",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/About/en_CA",
"value" : null,
"approvalStatus": false
}]
},
{
"nodeId" : 737821,
"attributeName" : "About_Prod",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/About_Prod",
"isGrouping": false,
"en_US" : [{
"nodeId" : 737816,
"isEditable": true,
"attributeName" : "en_US",
"localeIdentifier": "en_US",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/About_Prod/en_US#0",
"value" : "HUAWEI MateBook D 14 comes with 11.1% larger view,8 thanks to its 16:10 golden aspect ratio3 to serve as the perfect companion for your work, leisure, and studies.",
"approvalStatus": false
},
{
"nodeId" : 737816,
"isEditable": true,
"attributeName" : "en_US",
"localeIdentifier": "en_US",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/About_Prod/en_US#1",
"value" : "90% screen-to-body ratio4 3.5 mm bezels9 allow each glimpse to reward you with a tapestry of colour, texture, and intrigue.",
"approvalStatus": false
}],
"en_CA": []
},
{
"nodeId" : 737822,
"attributeName" : "Description",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/Description",
"isGrouping": false,
"en_US" : [ {
"nodeId" : 737817,
"isEditable": true,
"attributeName" : "en_US",
"localeIdentifier": "en_US",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/Description/en_US",
"value" : "This laptop comes with an all-new sleek design, with its metallic body12 being applied with a sandblasting and anodized process, to deliver fine textures while becoming resistant to wear and tear, taking your on-the-go life to exciting new places.",
"approvalStatus": false
}],
"en_CA": [{
"nodeId" : 740612,
"isEditable": true,
"attributeName" : "en_CA",
"localeIdentifier": "en_CA",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/Description/en_CA",
"value" : null,
"approvalStatus": false
}]
},
{
"nodeId" : 737821,
"attributeName" : "Localized grp",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/Localized grp",
"isGrouping": true,
"childList": [
{
"nodeId" : 737811,
"attributeName" : "Prod_desc",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/Localized grp/Prod_desc",
"isGrouping": false,
"en_US" : [{
"nodeId" : 737810,
"isEditable": true,
"attributeName" : "en_US",
"localeIdentifier": "en_US",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/Localized grp/Prod_desc/en_US",
"value" : "HUAWEI MateBook D 14 has passed more than 10 thousand times of durability tests, which means that key parts such as the screen and keyboard are durable enough to resist drops and shocks.13",
"approvalStatus": false
}],
"en_CA": [{
"nodeId" : 740610,
"isEditable": true,
"attributeName" : "en_CA",
"localeIdentifier": "en_CA",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/Localized grp/Prod_desc/en_CA",
"value" : null,
"approvalStatus": false
}]
},
{
"nodeId" : 737813,
"attributeName" : "Multi_Prod_desc",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/Localized grp/Multi_Prod_desc",
"isGrouping": false,
"en_US" : [{
"nodeId" : 737807,
"isEditable": true,
"attributeName" : "en_US",
"localeIdentifier": "en_US",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/Localized grp/Multi_Prod_desc/en_US#0",
"value" : "The 13th Gen Intel® Core™ processor gives you more power to play with, and features like Super Turbo16 and maximum 30 W TDP6 allow you to decompress a 1 GB compressed file in an unbelievable 5.4 seconds.17",
"approvalStatus": false
},
{
"nodeId" : 737807,
"isEditable": true,
"attributeName" : "en_US",
"localeIdentifier": "en_US",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/Localized grp/Multi_Prod_desc/en_US#1",
"value" : "HUAWEI MateBook D 14 packs a special antenna that expands the connection range, increases file download speed by 43%,18 and boosts anti-interference and wall penetration performance, so that you can stay online, wherever life takes you.",
"approvalStatus": false
}
],
"en_CA": [{
"nodeId" : 740610,
"isEditable": true,
"attributeName" : "en_CA",
"localeIdentifier": "en_CA",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/Localized grp/Prod_desc/en_CA#0",
"value" : null,
"approvalStatus": false
},
{
"nodeId" : 740610,
"isEditable": true,
"attributeName" : "en_CA",
"localeIdentifier": "en_CA",
"attributeType" : "STRING",
"attributePath" : "KTCatalogSpec/Localized grp/Prod_desc/en_CA#1",
"value" : null,
"approvalStatus": false
}
]
}
]
}
]
}
I am trying to bind this to wj-flex-grid with grouping based on isGrouping, and display source and target locale fields dynamically (en_US and en_CA) along with approval status, etc.
Here’s what I have so far in TypeScript:
public selectedTargetLocale: string = "en_CA";
public selsectedSourceLocale = "en_US"
this.data = new wjcCore.CollectionView(this.dataService.getData(), {
groupDescriptions: ['isGrouping']
});
HTML
[code]<div #gridContainer
class=“static-mdm-grid-ex version-grid-wrapper grid-without-border”>
[/code]<div class="row translation-head"> <div class="col-lg-12"> <div class="col-md-4"> Search </div> <div class="col-md-8 pdr-0"> <div class="col-md-4 pdl-0"> <div class="set-box"> <label class="text-ellipsis-single-line" [title]="'Source Language'" for="specsPerPage"> {{'Source Language'}} </label> </div> <wj-combo-box #pageSize class="filter-dropdown page-size" [isEditable]="false" [itemsSource]="options" [displayMemberPath]="'text'" [selectedValuePath]="'value'" id="srcLanguage" aria-label="Source Language"> <ng-template wjItemTemplate let-item="item" let-itemIndex="itemIndex"> <div class="item" [title]="item.text"> {{item.text}} </div> </ng-template> </wj-combo-box> </div> <div class="col-md-4 pdl-0 pdr-0"> <div class="set-box"> <label class="text-ellipsis-single-line" [title]="'Target Language'" for="specsPerPage"> {{'Target Language'}} </label> </div> <wj-combo-box #pageSize class="filter-dropdown page-size" [isEditable]="false" [itemsSource]="options" [displayMemberPath]="'text'" [selectedValuePath]="'value'" id="srcLanguage" aria-label="Target Language"> <ng-template wjItemTemplate let-item="item" let-itemIndex="itemIndex"> <div class="item" [title]="item.text"> {{item.text}} </div> </ng-template> </wj-combo-box> </div> <div class="col-md-4 button-align"> <button class="btn btn-primary btn-text btn-search text-ellipsis-single-line" (click)="clickApply()"> Translate</button> <!-- </div> <div class="col-md-2 button-align"> --> <button class="btn btn-primary approve-btn btn-text btn-search text-ellipsis-single-line" (click)="clickApply()"> Approve & Apply</button> </div> </div> </div> </div> <wj-flex-grid #grid [itemsSource]="data" [groupHeaderFormat]="'<b>{value}</b>'" (initialized)="initGrid(grid)" [anchorCursor]="true" selectionMode="ListBox" [headersVisibility]="'Column'" [allowResizing]="1" [allowDragging]="'None'"> <wj-flex-grid-filter [filterColumns]="['attributeName', 'value', 'value', 'approvalStatus']"> </wj-flex-grid-filter> <wj-flex-grid-column [binding]="'isGrouping'" [allowDragging]="false" [isReadOnly]="true" [width]="'*'" [header]="'Attribute'" [visible]="false"> <ng-template wjFlexGridCellTemplate [cellType]="'GroupHeader'" let-cell="cell"> <button class="wj-btn wj-btn-glyph wj-elem-collapse" type="button" tabindex="-1" aria-label="Toggle Group" aria-expanded="true"> <span class="wj-glyph-down-right"></span> <!-- <span *ngIf="cell.row.isCollapsed" class="wj-glyph-right"></span> --> </button> <span [title]="cell.item.items[0].grpPath"> {{cell.item.items[0].grpPath}} </span> </ng-template> </wj-flex-grid-column> <wj-flex-grid-column [binding]="'attributeName'" [minWidth]="180" [width]="'6*'" [isReadOnly]="true" [allowSorting]="true"> <ng-template wjFlexGridCellTemplate [cellType]="'ColumnHeader'" let-cell="cell"> <div [title]="'Attribute'"> {{'Attribute'}} </div> </ng-template> <ng-template wjFlexGridCellTemplate [cellType]="'Cell'" let-cell="cell"> <div class="read-mode" [title]="cell.item.attributeName"> {{cell.item.attributeName}} </div> </ng-template> </wj-flex-grid-column> <!-- Start of Source Language Column --> {cell.item} <wj-flex-grid-column [binding]="value" [minWidth]="180" [width]="'9*'" [isReadOnly]="true" [title]="'Type'" [allowSorting]="false"> <ng-template wjFlexGridCellTemplate [cellType]="'ColumnHeader'" let-cell="cell"> <div [title]="'Source language value'"> {{'Source language value'}} </div> </ng-template> <ng-template wjFlexGridCellTemplate [cellType]="'Cell'" let-cell="cell"> <div class="read-mode" [title]="cell.item[selsectedSourceLocale].value"> {{cell.item[selsectedSourceLocale].value}} </div> </ng-template> </wj-flex-grid-column> <!-- End of Source Language Column--> <wj-flex-grid-column [binding]="value" [minWidth]="180" [width]="'9*'" [isReadOnly]="true" [title]="'Type'" [allowSorting]="false"> <ng-template wjFlexGridCellTemplate [cellType]="'ColumnHeader'" let-cell="cell"> <div [title]="'Target language value'"> {{'Target language value'}} </div> </ng-template> <ng-template wjFlexGridCellTemplate [cellType]="'Cell'" let-cell="cell"> <div class="read-mode" [title]="cell.item[selectedTargetLocale].value"> {{cell.item[selectedTargetLocale].value}} </div> </ng-template> </wj-flex-grid-column> <wj-flex-grid-column [binding]="'approvalStatus'" [minWidth]="180" [width]="'4*'" [isReadOnly]="true" [title]="'Approve/Reject'" [allowSorting]="false"> <ng-template wjFlexGridCellTemplate [cellType]="'ColumnHeader'" let-cell="cell"> <div [title]="'Approve/Reject'"> {{'Approve/Reject'}} </div> </ng-template> <ng-template wjFlexGridCellTemplate [cellType]="'Cell'" let-cell="cell"> <div class="read-mode" [title]="cell.item.approvalStatus"> {{cell.item.approvalStatus}} </div> </ng-template> </wj-flex-grid-column> </wj-flex-grid>
Issues I’m Facing:
- The grid doesn’t automatically handle childList under grouped nodes.
- Source/target locale values (en_US, en_CA) are dynamic and stored as arrays inside each attribute, which makes binding tricky.
- Grouping by isGrouping alone does not create expandable/collapsible group headers for childList items.
What I’m Looking For:
-
How can I bind dynamic locales (e.g., en_US, en_CA) that are arrays in a way that grid can render them per row?
-
Ideally want to show group headers (e.g., “Localized grp”) and then under it list its child attributes.
Could you please help us to bind this dynamic data in wijimo grouping grid through stack blitz?
Attaching the screenshot for the reference and if possible, please try to give answer as soon as possible