最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Only option in Angular material select component - Stack Overflow

programmeradmin0浏览0评论

I am having a scenario where I need only option in mat multi select. Currently I am adding a button along with the options, and added a functionality to select single item. The issue I am facing is the text Only is getting appended with the option. Here is the code snip:

<mat-select 
  [formControl]="selectionControl" (selectionChange)="selectionChange($event.value)" multiple
>
  <mat-option class="position-relative options-wrapper"
    *ngFor="let version of [1,2,3,4,5,6,7,8,9,10] [value]="version">
    <span>{{version}}</span>
    <button mat-button class="position-absolute only-btn" style="top:5px; right: 0px;"
      >Only</button>
  </mat-option>
</mat-select>

Any help to resolve this is appreciated.

I am having a scenario where I need only option in mat multi select. Currently I am adding a button along with the options, and added a functionality to select single item. The issue I am facing is the text Only is getting appended with the option. Here is the code snip:

<mat-select 
  [formControl]="selectionControl" (selectionChange)="selectionChange($event.value)" multiple
>
  <mat-option class="position-relative options-wrapper"
    *ngFor="let version of [1,2,3,4,5,6,7,8,9,10] [value]="version">
    <span>{{version}}</span>
    <button mat-button class="position-absolute only-btn" style="top:5px; right: 0px;"
      >Only</button>
  </mat-option>
</mat-select>

Any help to resolve this is appreciated.

Share Improve this question edited Feb 4 at 6:56 mat.hudak 3,2434 gold badges29 silver badges49 bronze badges asked Feb 4 at 6:24 Venkatesh PrasadVenkatesh Prasad 912 silver badges9 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 2

I'm not sure if I understand you correctly, but I guess this is what you are looking for

<mat-select 
  [formControl]="selectionControl" (selectionChange)="selectionChange($event.value)" multiple
>
  <mat-option class="options-wrapper"
    *ngFor="let version of [1,2,3,4,5,6,7,8,9,10] [value]="version">
    <span>{{version}}</span>
    <!-- Try without relative and absolute positions -->
    <button mat-button class="only-btn" style="margin-left: 1rem">Only</button>
  </mat-option>
</mat-select>

EDIT: Try removing relative and absolute positions, they don't make much sense there. Try playing with margin values.

A possible solution:

You could use a directive to show the button on hover. It will create and remove the button on mouseover and mouseleave, respectively. It will also listen any clicks on the button and emit true when clicked.

Please note that the directive's selector name and output variable need to be the same for the output to work the way it is given and used in the html.

directive:

@Directive({
    selector: '[hoverButton]'  
})
export class hoverButtonDirective {
  @Output() hoverButton = new EventEmitter<boolean>();

  constructor( private _elemRef: ElementRef, private _renderer: Renderer2 ) {}

  @HostListener('mouseenter')
  onMouseEnter() {
    const onlyButton = this._renderer.createElement('button');
    this._renderer.setProperty(onlyButton, 'textContent', 'Only');
    this._renderer.appendChild(this._elemRef.nativeElement, onlyButton);

    this._renderer.listen( onlyButton, 'click', () => {
      this.hoverButton.emit(true);
    });
  }

  @HostListener('mouseleave') 
  onMouseLeave() {
    const child = this._elemRef.nativeElement.querySelector('button');

    if (child) {
      this._renderer.removeChild(this._elemRef.nativeElement, child);
    }
  }
}

html:

<mat-select [formControl]="toppings" multiple>
    @for (topping of toppingList; track topping) {
        <mat-option [value]="topping" (hoverButton)="buttonAction()">
            {{topping}}
        </mat-option>
    }
</mat-select>

I believe that is what you are looking for. 'buttonAction()' represents the function you want triggered when only is clicked.

Hope it helps.

Update

If you want the only button to appear only on row hover (as presented here:https://stackblitz/edit/lo4s7v7g-x6byneht?file=src%2Fexample%2Fselect-multiple-example.html) you need to update the code as it follows:

<mat-form-field>
  <mat-label>Toppings</mat-label>
  <mat-select [formControl]="toppings" multiple>
    @for (topping of toppingList; track topping) {
    <mat-option [value]="topping">
      <div class="row">
        {{topping}} &nbsp;
        <button class="only-btn" mat-button>Only</button>
      </div>
    </mat-option>
    }
  </mat-select>
</mat-form-field>

<style lang="scss">
  .row {
    display: flex;
    flex-direction: row;
    &:hover {
      .only-btn {
        visibility: visible;
      }
    }
  }
  .only-btn {
    visibility: hidden;
  }
</style>

Please note that this code is using scss to make it more compact. If you want add some fading effect (to make the transition from hidden to visible smoother) take a look on css animations.

Original answer

If this is the wanted result you need to update the content of <mat-option> as it follows:

<mat-form-field>
  <mat-label>Toppings</mat-label>
  <mat-select [formControl]="toppings" multiple>
    @for (topping of toppingList; track topping) {
    <mat-option [value]="topping">
      <div class="row">
        {{topping}} &nbsp;
        <button mat-button>Only</button>
      </div>
    </mat-option>
    }
  </mat-select>
</mat-form-field>

<style>
  .row {
    display: flex;
    flex-direction: row;
  }
</style>

For more infos on flex you could read this extensive and well written guide :
https://css-tricks/snippets/css/a-guide-to-flexbox/

P.S.

Of course using &nbsp; is not elegant nor the best way to space stuff, you can go forward and add padding etc...

发布评论

评论列表(0)

  1. 暂无评论