This is a migrated thread and some comments may be shown as answers.

Toolbar, dynamic buttons & overflow

10 Answers 935 Views
ToolBar
This is a migrated thread and some comments may be shown as answers.
ICT
Top achievements
Rank 1
Iron
ICT asked on 30 Jun 2020, 08:38 AM

Hello,

i'm trying to create a toolbar component wrapper that allows the user to configure the toolbar passing a list of json objects, using overflow feature.

I'm facing 2 problems

  1. when i hide a button using ngIf the button disappears from normal visualization and appears in the overflow popup, despite the available space. The button appears when a resize is fired.
  2. o often get an error "TypeError: Cannot read property 'nativeElement' of undefined" when the overflow popup is opened

Is there a correct way to create buttons dynamically?

Thanks,

My markup

01.<div
02.  class="toolbar-container"
03.  [ngClass]="{ 'toolbar-container-closed': !isExpanded }"
04.>
05.  <div class="toolbar-expander" title="{{ 'CORE.TOGGLE_TOOLBAR' | translate }}">
06.    <i
07.      class="material-icons expander"
08.      *ngIf="!isExpanded && canCollapse"
09.      (click)="toggleExpand()"
10.    >
11.      keyboard_arrow_down
12.    </i>
13.    <i
14.      class="material-icons expander"
15.      *ngIf="isExpanded && canCollapse"
16.      (click)="toggleExpand()"
17.    >
18.      keyboard_arrow_up
19.    </i>
20.  </div>
21.  <div
22.    class="toolbar-toolbar-container"
23.    [ngClass]="{
24.      'toolbar-toolbar-container-hidden': !isExpanded
25.    }"
26.  >
27.    <kendo-toolbar
28.      #toolbar
29.      [ngClass]="{
30.        'toolbar-toolbar-right': right,
31.        'toolbar-toolbar-left': !right
32.      }"
33.      overflow="true"
34.      [style.width.%]="100"
35.      [popupSettings]="{ animate: false }"
36.    >
37.      <div *ngFor="let item of config.items">
38.        <kendo-toolbar-button
39.          *ngIf="item.type === 'button' && !item.hidden"
40.          [disabled]="item.disabled"
41.          [iconClass]="getIconClass(item.icon)"
42.          [text]="item.text"
43.          title="{{ item.tooltipText | translate }}"
44.          (click)="item.onClick(item)"
45.        >
46.        </kendo-toolbar-button>
47.        <kendo-toolbar-dropdownbutton
48.          *ngIf="item.type === 'dropdownbutton' && !item.hidden"
49.          [iconClass]="getIconClass(item.icon)"
50.          [text]="item.text"
51.          [data]="item.data"
52.          title="{{ item.tooltipText | translate }}"
53.          (itemClick)="onItemClick($event, item)"
54.          [textField]="item.textField"
55.        >
56.        </kendo-toolbar-dropdownbutton>
57.        <kendo-toolbar-splitbutton
58.          *ngIf="item.type === 'splitbutton' && !item.hidden"
59.          [disabled]="item.disabled"
60.          [iconClass]="getIconClass(item.icon)"
61.          [text]="item.text"
62.          [data]="item.data"
63.          title="{{ item.tooltipText | translate }}"
64.          (buttonClick)="item.onClick(item)"
65.          (itemClick)="onItemClick($event, item)"
66.          [textField]="item.textField"
67.        >
68.        </kendo-toolbar-splitbutton>
69.        <kendo-toolbar-separator
70.          *ngIf="item.type === 'separator' && !item.hidden"
71.        ></kendo-toolbar-separator>
72.      </div>
73.    </kendo-toolbar>
74.  </div>
75.</div>

10 Answers, 1 is accepted

Sort by
0
Petar
Telerik team
answered on 30 Jun 2020, 01:30 PM

Hello Benedetta,

Thanks for the provided details. We are aware of the reported problems. Here are the relevant GitHub issues:

  1. Kendo Toolbar responsive async: buttons added to popup by default
  2. [ToolBar] Error when [popupSettings]="{ animate: false }"

Fortunately there are workarounds for these problems.

The workaround for the first issue is to change programmatically the width of the toolbar when a tool is added. Here is a sample StackBlitz - https://stackblitz.com/edit/angular-wcbek7-zphx68?file=app/app.component.ts. These are the key steps:

  1. When toggling a button we have to also resize the toolbar:
    public onToggleButton() {
      this.showButton = !this.showButton;
    
      this.setSize(99);
      this.setSize(100);
    }
  2. Resizing the toolbar has to be done after a button has been toggled. To do that setTimeout is used:
    public setSize(percent: number): void {
      // run setTimeout() outside NgZone to avoid unnecessary change detection runs of the whole app
      this.zone.runOutsideAngular(() => {
        setTimeout(() =>
          // after setTimeout() has finished, set the new width of the toolbar in sync with Angular's change detection algorithm
          this.zone.run(
            () => (this.toolbar.nativeElement.style.width = `${percent}%`)
          )
        );
      });
    }

The workaround for the second issue is to set [popupSettings]="{ animate: true }".

I hope this helps. Please let me know if further assistance is needed.

Regards,
Petar
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
ICT
Top achievements
Rank 1
Iron
answered on 30 Jun 2020, 04:12 PM

Thanks Petar,

for the 1st issue i tried and unfortunately does not work always, sometimes the button is not shown. Anyway is not an acceptable workaround for me cos everyone that use my wrapper have to manually perform that trick.

for the 2nd issue "set [popupSettings]="{ animate: true }" for me is not woring. Same error.

When will you release the fixes?

Another question, is it possible in some way to aligh buttons left/center/right?

Thanks

0
Petar
Telerik team
answered on 02 Jul 2020, 03:11 PM

Hello Benedetta,

As the provided snippet seems quite complex and involves significant amount of custom logic, it will be best if I have a small app or ideally a StackBlitz which reproduces the issue.

In the meantime I can only suggest things based on the provided code - since the toolbar is inside two wrappers, each having classes for hiding them, my suggestion is to try removing the wrappers one by one and see if the issues persist.

Regarding button alignment - we do not provide this option out of the box, but it can be achieved using CSS. Here is a sample StackBlitz demonstrating this - https://stackblitz.com/edit/angular-mbxszs?file=styles.css. Upon inspection of the DOM of the toolbar we can see that each toolbar tool is wrapped inside a <kendo-toolbar-renderer> so in order to position the elements to the left or right, we have to apply margin-left:auto or margin-right to the needed <kendo-toolbar-renderer>s.

I hope this helps.

Looking forward to your response.

Regards,
Petar
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
ICT
Top achievements
Rank 1
Iron
answered on 04 Aug 2020, 03:47 PM

Hi Petar,

I'm find another more critical issue.

Updating to Angular 10, the buttons are not rendered anymore. Seems there is an issue with the ngFor construct.

Any ideas?

Benedetta

 

0
Petar
Telerik team
answered on 06 Aug 2020, 01:57 PM

Hi Benedetta,

Based on the provided code up until now, I think that the problem is related to Angular(and there is a fix for it). Let me explain.

Since Angular 9 a breaking change regarding how ContentChildren are handled was introduced. The gist of it is that since Angular 9 when querying for ContentChildren, a component looks only at its direct descendants in the DOM.

I will try to illustrate this with an example. Up until Angular 9 this was valid code:

        <kendo-toolbar>
            <div *ngFor="let item of config">
                <kendo-toolbar-button [text]="item.text"> </kendo-toolbar-button>
                <kendo-toolbar-dropdownbutton [text]="item.text" [data]="item.data"> </kendo-toolbar-dropdownbutton>
                <kendo-toolbar-splitbutton [text]="item.text" [data]="item.data"> </kendo-toolbar-splitbutton>
            </div>
        </kendo-toolbar>

From Angular 9 on this code does not work. This is because internally the toolbar uses @ContentChildren to get references to the tools inside of it. A simple workaround for this is to use <ng-container> instead <div>.

Here is a modified version of the code above that should work with Angular 9 and up:

        <kendo-toolbar>
            <ng-container *ngFor="let item of config">
                <kendo-toolbar-button [text]="item.text"> </kendo-toolbar-button>
                <kendo-toolbar-dropdownbutton [text]="item.text" [data]="item.data"> </kendo-toolbar-dropdownbutton>
                <kendo-toolbar-splitbutton [text]="item.text" [data]="item.data"> </kendo-toolbar-splitbutton>
            </ng-container>
        </kendo-toolbar>

I hope this sheds some light on the issue.

Regards,
Petar
Progress Telerik

0
ICT
Top achievements
Rank 1
Iron
answered on 11 Aug 2020, 01:23 PM

Thanks Petar! Now toolbar works in A10 in my app.

Anyway i cannot make it work in stackbliz... but doesn't matter.

I modified the stackbliz to show yuu the overflow problem.

https://stackblitz.com/edit/angular-ivy-tzkuwk

Thanks again.

B

 

0
Petar
Telerik team
answered on 12 Aug 2020, 02:07 PM

Hi Benedetta,

I am glad to hear that you have managed to integrate the ToolBar in Angular 10 successfully. Also thank you for the provided example as it helped a lot.

Here is an updated version of it which works around the issue - https://stackblitz.com/edit/angular-ivy-nkg3wn?file=src%2Fapp%2Fapp.component.ts

Previously it wasn't working due to the aforementioned issue about the async buttons combined with the usage of <ng-container> for iteration. 

In the working StackBlitz the toolbar is again being programmatically resized but the difference is that the shrinking to 99% is done when tools are hidden and expanding to 100% is done only after ngAfterViewChecked() has been called by Angular.

I hope this helps. Please let me know if further assistance is needed.

Regards,
Petar
Progress Telerik

0
ICT
Top achievements
Rank 1
Iron
answered on 31 Aug 2020, 07:43 AM

Thanks Petar,

With your workaround i could make it work.

Do you have one more suggestion for me?

How can i make it work together OVERFLOW and align right/center/left of the buttons?

Or at least ALIGN RIGHT of the ENTIRE TOOLBAR with OVERFLOW = true?

Thanks again

B

0
Petar
Telerik team
answered on 02 Sep 2020, 07:23 AM

Hello Benedetta,

If my understanding is correct, the goal is to align the toolbar tools to the right (or in the center) and have the overflow popup button remain on the right.

If my assumptions are correct then I am afraid that the ToolBar component does not have such a built-in option. However, there are several approaches that could be taken in order to accomplish (at least partly) the desired layout:

Enabling RTL mode:

https://www.telerik.com/kendo-angular-ui/components/toolbar/globalization/#toc-right-to-left-support

Or using custom CSS code. Here is an example:

https://stackblitz.com/edit/angular-mbxszs-pgpmuk?file=styles.css

Please keep in mind that the second option does not work as expected when [overflow]="true".

In case having a built-in option for tool, alignment is important for you, please consider submitting a feature request through our Feedback portal. We keep a close eye on it as this is one of our main indicators on what is really needed.

I hope this helps.

Regards,
Petar
Progress Telerik

Five days of Blazor, Angular, React, and Xamarin experts live-coding on twitch.tv/CodeItLive , special prizes and more, for FREE?! Register now for DevReach 2.0(20).

0
ICT
Top achievements
Rank 1
Iron
answered on 10 Sep 2020, 06:57 AM

Thank Petar,

Unfortunately those workarounds does not fit my requirement.

I opened a feature request.

B

Tags
ToolBar
Asked by
ICT
Top achievements
Rank 1
Iron
Answers by
Petar
Telerik team
ICT
Top achievements
Rank 1
Iron
Share this question
or