0

I have a MatSelectionList, where I must display multiple lines for each option and have a faMap icon displayed. If the user clicks on the map, I should display an actual map elsewhere in the application.

The problem is, the material selection list allows the full line to be clicked in order to mark/unmark the checkbox. This way, If I click on the map icon itself, the checkbox change is triggered too, which is undesired. The map click should be a separate action from the checkbox selection.

Please, follow this link for a StackBlitz demo.

I found this solution, but this does not work for me, as I have multiple mat lines and I do not want them to slide into each other. (Also, it seems like a hack?)

enter image description here

I will also paste the code here:

html:

  <form [formGroup]="demoSelectForm">
    <mat-selection-list (selectionChange)="onSelectionChange($event)" formControlName="selection">
         <mat-list-option value="1"  checkboxPosition="before">

             <mat-icon mat-list-icon>
                  <fa-icon
                      [icon]="['far', 'map']"
                      (click)="onMapClick()"
                  >
                  </fa-icon>
              </mat-icon>

               <h4 mat-line>The option 1</h4>
               <p mat-line>Description line 1.1</p>
                <p mat-line>Description line 1.2</p>
                 <p mat-line>Description line 1.3</p>

         </mat-list-option>

          <mat-list-option value="2"  checkboxPosition="before">

             <mat-icon mat-list-icon>
                  <fa-icon
                      [icon]="['far', 'map']"
                      (click)="onMapClick()"
                  >
                  </fa-icon>
              </mat-icon>

               <h4 mat-line>The option 2</h4>
               <p mat-line>Description line 2.1</p>
                <p mat-line>Description line 2.2</p>
                 <p mat-line>Description line 2.3</p>

         </mat-list-option>


          <mat-list-option value="3"  checkboxPosition="before">

             <mat-icon mat-list-icon >
                  <fa-icon
                      [icon]="['far', 'map']"
                      (click)="onMapClick()"
                  >
                  </fa-icon>
              </mat-icon>

               <h4 mat-line>The option 3</h4>
               <p mat-line>Description line 3.1</p>
                <p mat-line>Description line 3.2</p>
                 <p mat-line>Description line 3.3</p>

         </mat-list-option>

    </mat-selection-list>
  </form>

   {{ demoSelectForm.get('selection').value | json }}

component:

import { Component } from '@angular/core';
import { AbstractControl, FormArray,FormControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  demoSelectForm = new FormGroup({
      selection: new FormControl([])
  });

  onSelectionChange($event) {
    // console.log($event);
  }

  onMapClick(): void {
    console.log('MAP GOT CLICKED');
  }
}
Akber Iqbal
  • 14,487
  • 12
  • 48
  • 70
szab.kel
  • 2,356
  • 5
  • 40
  • 74
  • As per your question, you want the checkbox to be clicked only on checkbox, not anywhere else right? – nitin9nair Jul 03 '19 at 07:33
  • @nitin9nair Never mind, you are right, best approach would be to only check the checkbox, when the user clicks on it directly and not on any of the mat-lines or elsewhere. This way, the text is even selectable and copyable. – szab.kel Jul 03 '19 at 07:38

1 Answers1

1

Even if you visually take the map icons out of the mat-list area (using position:absolute, the map will still make the selection because the icons are children of the mat-list-option;

A (hack-ish) solution would be to have 2 divs, side by side... left div has the checkbox only ... the right div has the text (which is now selectable) and the map; (if you'd like the text to be clickable, move the text to left div and adjust the width;

relevant HTML:

<div class='parentDiv'>
    <div class='leftSide'>
        <form [formGroup]="demoSelectForm">
            <mat-selection-list (selectionChange)="onSelectionChange($event)" formControlName="selection">
                <mat-list-option value="1" checkboxPosition="before">
                </mat-list-option>

                <mat-list-option value="2" checkboxPosition="before">
                </mat-list-option>

                <mat-list-option value="3" checkboxPosition="before">
                </mat-list-option>

            </mat-selection-list>
        </form>
    </div>

    <div class='rightSide'>
        <mat-selection-list>
            <mat-list-option value="1" checkboxPosition="before">
                <mat-icon mat-list-icon>
                    <fa-icon [icon]="['far', 'map']" (click)="onMapClick()">
                    </fa-icon>
                </mat-icon>
          <h4 mat-line>The option 1</h4>
                    <p mat-line>Description line 1.1</p>
                    <p mat-line>Description line 1.2</p>
                    <p mat-line>Description line 1.3</p>
                </mat-list-option>

            <mat-list-option value="3" checkboxPosition="before">
                <mat-icon mat-list-icon>
                    <fa-icon [icon]="['far', 'map']" (click)="onMapClick()">
                    </fa-icon>
                </mat-icon>
                    <h4 mat-line>The option 2</h4>
                    <p mat-line>Description line 2.1</p>
                    <p mat-line>Description line 2.2</p>
                    <p mat-line>Description line 2.3</p>
                </mat-list-option>

            <mat-list-option value="3" checkboxPosition="before">
                <mat-icon mat-list-icon>
                    <fa-icon [icon]="['far', 'map']" (click)="onMapClick()">
                    </fa-icon>
                </mat-icon>
                    <h4 mat-line>The option 3</h4>
                    <p mat-line>Description line 3.1</p>
                    <p mat-line>Description line 3.2</p>
                    <p mat-line>Description line 3.3</p>
            </mat-list-option>
        </mat-selection-list>

    </div>
</div>

{{ demoSelectForm.get('selection').value | json }}

relevant CSS;

.leftSide{width:50px; border-bottom:2px solid blue;float:left;}
.rightSide{width:calc(100% - 50px); border-bottom:2px solid red;float:left;}
::ng-deep .rightSide .mat-pseudo-checkbox{display:none;}
.rightSide .mat-list-item, .leftSide .mat-list-item{height:109px;}
.parentDiv{width:100vw;}

working stackblitz here

Akber Iqbal
  • 14,487
  • 12
  • 48
  • 70