Clickable ion-icon inside clickable ion-item

I’d like to have a clickable ion-icon inside a clickable ion-item (e.g. as in the Android gmail app).

My first try was this (see on stackblitz):

<button ion-item *ngFor="let i of ['1','2','3']" (click)="clicked = 'item '+ i">
  item {{i}}
  <button ion-button icon-only item-end clear (click)="clicked = 'star ' + i; $event.stopPropagation()">
	<ion-icon name="star-outline"></ion-icon>
  </button>
</button>

This works in Chrome, but not in Firefox or iOS and apparently a button inside a button is invalid html.

Then I tried this:

<ion-item tappable *ngFor="let i of ['1','2','3']" (click)="clicked = 'item '+ i">
  item {{i}}
  <button ion-button icon-only item-end clear (click)="clicked = 'star ' + i; $event.stopPropagation()">
	<ion-icon name="star-outline"></ion-icon>
  </button>
</ion-item>

This works, but now there is no click animation on the ion-item anymore. How can I get the animation back in the second version? Or is there another way to to this?

Related topics:

@pwespi I did a little change in your code:

<ion-item tappable *ngFor="let i of ['1','2','3']">
<p (click)="clicked = 'item '+ i" >  item {{i}}</p>

  <ion-button icon-only item-end clear (click)="clicked = 'star ' + i; $event.stopPropagation()">
	<ion-icon name="star-outline"></ion-icon>
  </ion-button>
</ion-item>

I hope this helps…

by the way what do you mean by the below:

Thank you for your answer. However it still doesn’t give the same animation as in version 1 (test on stackblitz). Additionally it makes the clickable area smaller, which isn’t ideal either.

In the gmail app you can add a star to an email by clicking on the star icon. Clicking anywhere else opens the email. I want to achieve the same behavior.

How about keeping your code as it is and increase z-index of ion-icon.

I also thought about that, but it still doesn’t work in Firefox and possibly iOS (don’t have a device to test right now)…

Have you put one button on top of another and tested stopPropagation?

Yes, this was my first version, but it doesn’t work on all platforms and a button inside a button seems to be invalid html.

Which platforms does Event.stopPropagation() fail on?

Event.stopPropagation() doesn’t fail, but the click event of the inner button is never triggered. No matter where you click, it always fires the click event of the outer button.
This is the case in Firefox (and possibly iOS).

You don’t place outer and inner buttons. You place one button on top of the other, and stop propagation. It doesn’t sound as though you’ve tried the suggestion of @arnoldparge.

I’m not sure I understand what you mean by on top of the other then. Here and on stackblitz is what I’ve tried (version 2 is acceptable, I’d just like to have the click animation as in version 1).

   <ion-list>
    <ion-list-header>
      Version 1: button inside button (doesn't work in Firefox)
    </ion-list-header>
    <button ion-item *ngFor="let i of ['1','2','3']" (click)="clicked = 'item '+ i">
      item {{i}}
      <button ion-button icon-only item-end clear (click)="clicked = 'star ' + i; $event.stopPropagation()">
        <ion-icon name="star-outline"></ion-icon>
      </button>
    </button>
  </ion-list>

  <ion-list>
    <ion-list-header>
      Version 2: button inside ion-item (no click animation on ion-item)
    </ion-list-header>
    <ion-item tappable *ngFor="let i of ['1','2','3']" (click)="clicked = 'item '+ i">
      item {{i}}
      <button ion-button icon-only item-end clear (click)="clicked = 'star ' + i; $event.stopPropagation()">
        <ion-icon name="star-outline"></ion-icon>
      </button>
    </ion-item>
  </ion-list>

  <ion-list>
    <ion-list-header>
      Version 3: add p element (no click animation on ion-item, smaller clickable area)
    </ion-list-header>
    <ion-item tappable *ngFor="let i of ['1','2','3']" >
      <p (click)="clicked = 'item '+ i">item {{i}}</p>
      <button ion-button icon-only item-end clear (click)="clicked = 'star ' + i; $event.stopPropagation()">
        <ion-icon name="star-outline"></ion-icon>
      </button>
    </ion-item>
  </ion-list>

  <ion-list>
    <ion-list-header>
      Version 4: button with z-index inside button (doesn't work in Firefox)
    </ion-list-header>
    <button ion-item *ngFor="let i of ['1','2','3']" (click)="clicked = 'item '+ i">
      item {{i}}
      <button style="z-index: 1000;" ion-button icon-only item-end clear (click)="clicked = 'star ' + i; $event.stopPropagation()">
        <ion-icon name="star-outline"></ion-icon>
      </button>
    </button>
  </ion-list>

Maybe it doesn’t show without scrolling, but the stopPropagation is there: (click)="clicked = 'star ' + i; $event.stopPropagation()" :wink:

They don’t have the same z-index.

Thanks for clarifying and all your answers. Unfortunately it still doesn’t work in Firefox (see list version 4 of my code above)

This should work:

<ion-item (click)="clicked = 'item '+ i" tappable *ngFor="let i of ['1','2','3']">
  <span>Item {{ i }}</span>
  <button ion-button icon-only clear item-right (click)="clicked = 'star ' + i; $event.stopPropagation()">
    <ion-icon name="star-outline" color="danger"></ion-icon>
  </button>
</ion-item>
2 Likes

Thank you for your answer. Yes, this gives the desired click behavior (as version 2 above), but still doesn’t show the same click animation as version 1 above.
I guess I could live with that, I just thought that there might be an easy way to get the button click animation for the ion-item.

For me it’s almost the same ripple effect, where are you checking? Can you explain the difference you are seeing between the two?

The effect on the button is a round ripple effect and localized on the click event. The ion-item “only” has a light-gray effect on its whole background. I’m checking on an Android device and in the browser.

Hm, seems there are changes to the tappable attribute in the latest ionic version. An older project of mine shows the tappable with almost the same button effect but I tried a latest project and it just shows what you’ve described. Perhaps, there are some sass variables you can tweak.

Thanks for the information. I never thought about different versions. What version were you using, so that I can compare?