1

Bootstrap has the following example of an action group. The result is that the buttons inside the group are merged together.

Inside my Angular project I already have a toolbar and wanted to apply these styles on them. Basically I have a ToolbarComponent and an ActionComponent.

concept

The idea works fine as long as I put everything in 1 component without the sublevel of an ActionComponent. But when I seperate them (as shown in the picture above), then things don't work any more.

The buttons are not merged (look at the corners of the buttons).

defect

When I open the runtime html code in google chrome, it shows the following:

source

As you can see, there's a level in-between the <div class="btn-group"> and <div class="btn">. (i.e. the tag of the ActionComponent itself: <objt-action>). My best guess, is that this tag messes things up.

My best guess, is that this additional tag breaks the bootstrap logic.

So, now I'm wondering about the best strategy to solve my problem.

VIEW CODE OF ToolbarComponent

<div class="d-flex flex-wrap justify-content-start" role="toolbar" aria-label="toolbar">

<!-- iterate action-groups -->
<div *ngFor="let actionGroup of actionGroups" class="btn-group p-1" role="group">

  <!-- for each action-group, iterate thru the actions of the group -->
  <ng-template ngFor let-action [ngForOf]="actionGroup.actions">
    <objt-action [action]="action" (actionClicked)="actionClicked($event)"></objt-action>
  </ng-template>

</div>

</div>

EDIT

In mean time, I also tried it by changing the directive of the component, from objt-action to [objt-action]. By doing so, I can define the ActionComponent as follows inside the ToolbarComponent's view:

  <div objt-action> </div>

But the resulting xml is still invalid, there still remains a disturbing intermediate level, i.e. the <div objt-action> itself.

Community
  • 1
  • 1
bvdb
  • 22,839
  • 10
  • 110
  • 123
  • I don't get what the problem is. What's the code that results in this DOM? – Günter Zöchbauer Aug 29 '17 at 16:24
  • @GünterZöchbauer I added the code of the `ToolbarComponent`'s view. I left out the typescript code because it's quiet long and irrelevant I think. Thanks for having a look. – bvdb Aug 29 '17 at 16:31

1 Answers1

1

With the approach mentioned in How to remove/replace the angular2 component's selector tag from HTML you need to make this element <div class="action-group" aria-label="Basic example"> the component.

What you tried is to have a component that doesn't add a tag at all, that is not possible. You could use a structural directive and use it like

<div class="action-group" aria-label="Basic example">
  <ng-container *myDirective></ng-container>
</div>

and then let *myDirective generate the buttons.

See also https://angular.io/guide/structural-directives

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • looks promising, I'll give it a go. :) – bvdb Aug 29 '17 at 16:46
  • I did find examples of directives creating attributes, and 1 example of a structural directive creating an embedded view `this.viewContainer.createEmbeddedView(this.templateRef);` to show/hide its body. But I didn't find any example of a directive that actually creates html tags. (e.g. buttons) - I checked the source of "Bootstrap powered Angular" for their code for tabs. Because it's a similar problem: Found a `TabSet` component with Tab directives. But still the `TabSet` component that contains the html. So, I'm starting to have doubts if this is possible. - An example would be appreciated. – bvdb Aug 30 '17 at 10:16
  • If you use ``, then `templateRef` will refer to ``, so your code will actually add `` – Günter Zöchbauer Aug 30 '17 at 10:28
  • You can add the same template multiple times. – Günter Zöchbauer Aug 30 '17 at 10:30
  • I guess that summarizes your answer to: "move most html to the root component". ... which is a reasonable solution. – bvdb Aug 30 '17 at 12:19
  • I mentioned several approaches. One of them might turn out this way, yes :D – Günter Zöchbauer Aug 30 '17 at 12:20