Hello Syncfusion team,
I have an issue with the Syncfusion Toolbar. I would like to create a toolbar (especially for a grid) that should be able to have submenus.
After reading the documentation I think that this is not possible, since the Toolbar elements only support ItemModel that does not support items as attribute. I tried to bind a MenuItemModel instead, but it did not create the according submenus.
I thought about using an ejs-menu instead that relies on MenuItemModel, which again is nestable, but then I would lose advantages that are built-in in toolbars e.g. the automatically working operations (Add, Delete, Print, ...) of a grid and especially the column chooser.
It is also not that easy to adapt the ng-template of the toolbar because it should be created dynamically due to a JSON config.
So, my question is: Is there really no other way to make a toolbar nestable and if so, why is that the case?
Thanks in regard,
Jonas Czeslik
Hi Jonas,
We have prepared sample to integrate menu inside toolbar item based on your requirement.
app.component.html:
<div class="control-section"> <div class="toolbar-menu-control"> <div id="shoppingMenu"> <ejs-menu [items]="data"></ejs-menu> </div> <!-- Render the Toolbar Component --> <ejs-toolbar [items]="toolbarItems" #toolbar (created)="onCreated()"> </ejs-toolbar> </div> </div> |
app.component.ts:
public data: MenuItemModel[] = [ { text: 'Appliances', items: [ { text: 'Kitchen', items: [ { text: 'Electric Cookers' }, { text: 'Coffee Makers' }, { text: 'Blenders' }, ], }, ], }, ];
public toolbarItems = [ { text: 'Add', id: 'Add', }, { text: 'Edit', id: 'Edit', }, { text: 'Delete', id: 'Delete', }, { text: 'Update', id: 'Update', }, { template: '#shoppingMenu', }, ]; |
Kindly try the above sample and let us know if this meets your requirement.
Regards,
Satheesh Kumar B
Hello and thanks for the answer! That indeed sounds like it could be the solution, but how can I make that generic? Depending on a config, I want to dynamically add the toolbar and therefore it could be possible that there are no nested submenu at all or there could be 7 in the same toolbar.
I thought of something like that:
And then, in an initializing function, I would iterate through this array and - if !isSubMenu === true, I would push it to the items array for the toolbar and otherwise I would have to use the template property, but I am not sure how to do that generically.
Creating a big number of possible ejs-menus to bind them too does not seem to be a good solution. I tried to use a template string like
but I dont know how to fill the items input in this case?
Hi Jonas,
No, it is not possible to render submenu structure on toolbar which is the default behavior of our toolbar control. As mentioned in the previous update you can use template property to render our menu bar control in toolbar item.
Please let us know for further assistance.
Regards,
Satheesh Kumar B
"As mentioned in the previous update you can use template property to render our menu bar control in toolbar item."
That is what I am trying, but like I said, I dont know how to do that, when I have multiple possible submenus.
The template property can take an HTML ID or an HTML template string.
If I chose to bind the menu to an HTML element and its ID (like you did in your example), I would have to create an amount of ejs-menus according to the amount of submenus I want to support in the toolbar. That is a good solution for a static toolbar, but like I said, I want to create the toolbar generically in each of my components and sometimes it gets no submenu at all, other times it can get a few at the same time.
The other way would be to define an HTML template string, which would look like that:
template: '<ejs-menu [items]="?"></ejs-menu>'
But here I would have to fill in the items input property with the according items I want to render in the ejs-menu and I still dont know how to do that in such an HTML string.
To make the issue a bit clearer, I adapted the Stackblitz example and added some explanations:
https://stackblitz.com/edit/angular-menu-integration-toolbar-using-items-xakx1e?file=app.component.ts
app.componnent.html:
<div class="control-section"> <div class="toolbar-menu-control"> <ng-container *ngFor="let backendItem of toolbarItems"> <div *ngIf="backendItem.isSubMenu" id="{{ backendItem.id }}"> <ejs-menu [items]="backendItem.items"></ejs-menu> </div> </ng-container> <!-- Render the Toolbar Component --> <ejs-toolbar [items]="toolbarItems" #toolbar (created)="onCreated()"> </ejs-toolbar> </div> </div> |
app.componnent.ts:
ngOnInit() { this.toolbarDataFromBackend = [ { text: 'Add', isSubMenu: false, }, { text: 'Edit', isSubMenu: false, }, { text: 'Delete', isSubMenu: false, }, { text: 'Process', isSubMenu: true, id: 'shoppingMenu', items: [ { text: 'Appliances', items: [ { text: 'Kitchen', items: [ { text: 'Electric Cookers' }, { text: 'Coffee Makers' }, { text: 'Blenders' }, ], }, ], }, { text: 'CSV Export', }, ], }, ]; // Here the toolbar items should be inserted accordingly for (let backendItem of this.toolbarDataFromBackend) { if (backendItem.isSubMenu !== true) { // Just push the normal items into the toolbar this.toolbarItems.push(backendItem); } else { this.data = backendItem.items; let toolbarSubMenuItem = { items: backendItem.items, text: backendItem.text, id: backendItem.id, isSubMenu: backendItem.isSubMenu, template: '#' + backendItem.id, // TODO: That is the tricky part! Here I want to create an // ejs-menu based on backendItem and containing backendItem.items }; this.toolbarItems.push(toolbarSubMenuItem); } } } |
That indeed meets the requirements.
As always: Thank you very much for the support!
You are most welcome!!!