Capturing ion-tab click on active tab event

To resolve this issue, you need to modify from the source code for now
inside the ionic project at node_modules\ionic-angular\components\tabs\tabs.js (or tabs.ts)

In different rc build, the source code of tabs.js(or tabs.ts) might be different.

Basically, the guideline is in the select tab function

Tabs.prototype.select = function (tabOrIndex, opts)

if (selectedTab.root) //this is the active tab
you will still need to file the event and the code is
this.ionChange.emit(selectedTab);

Hope it is helpful for the people who is looking for the solution.
This is very inconvenience that can’t select the active tab for some scenarios.

You can use

ionSelected(){
    //this.scrollArea.scrollToTop();
    //this.refresh()
}

on the component.

9 Likes

@markhardling. this seems to be the solution everyone is looking for. worked for me! thanks

Would you give an example… how to add ionSelected() to the component??

hi guys, I got a hacked solution, hope help someone:

export class TabsPage {
  tabHome: any = HomePage;   
  selectedIndex: number = 0;
  tabHomeClickEvent: any; //for home tab click event
  constructor(public navCtrl: NavController, public events: Events) {
    let that = this;
    this.tabHomeClickEvent = function(e) {
      if(0 == that.selectedIndex){
        //tab home be clicked!
        //do some thing
      }
    }
  }

  // <ion-tabs (ionChange)="tabChange($event)">
  tabChange(tab: Tab){
    this.selectedIndex = tab.index;
    console.log(this.selectedIndex);
    //index equals 0/other to add/remove tab home click event 
    if(0 == this.selectedIndex){
      this.tabHomeAddClickEvent();
    }
    else{
      this.tabHomeRemoveClickEvent();
    }
  }


  //ion-md-home: <ion-tab home [root]="tabHome" tabTitle="Home" tabIcon="md-home"></ion-tab>
  private tabHomeAddClickEvent(): void {

    let that = this;
    let tabHomeIcon = document.getElementsByClassName('ion-md-home');
    if(tabHomeIcon.length == 1){
      tabHomeIcon[0].addEventListener('click', that.tabHomeClickEvent, true)
    }

  }

  private tabHomeRemoveClickEvent(): void {
 
    let that = this;
    let tabHomeIcon = document.getElementsByClassName('ion-md-home');
    if(tabHomeIcon.length == 1){
      tabHomeIcon[0].removeEventListener('click',that.tabHomeClickEvent , true);
    }
 
  }  


}

3 Likes

I’m using this solution:

tabs.html

<ion-tabs #mainTabs (tap)="tapped()">
  <ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="paper"></ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="About" tabIcon="information-circle"></ion-tab>
  <ion-tab [root]="tab3Root" tabTitle="Contact" tabIcon="contacts"></ion-tab>
</ion-tabs>

tabs.ts

@ViewChild('mainTabs') mainTabs: Tabs;

constructor(public nav:NavController, public events: Events ) {}

// This will be executed before ionChange event
public tapped() {
    this.events.publish('home:scrollToTop', Date.now() );
}

home.ts

[...]
@ViewChild(Content) content: Content;

constructor(public app: App, public nav: NavController, public events: Events, private logic:StpLogicService) {
    // NOTE: This will be executed only when home is already the active/current tab
    events.subscribe('home:scrollToTop', (time) => {
      console.log('home:scrollToTop', 'at', time);
      this.content.scrollToTop();
    });
}

The effect is: Homepage si scrolled to top only when already displayed.

8 Likes

Does anyone have another solution for this issue? When I try to use BLaCkSMiTH77 solution, my content scrolls also when I scroll down to a button and push from there a new View on the Viewstack which should not happen! The other solutions does not work for me but I dont know how to use ionSelected() as markharding replied.

Thanks guys.

ionSelected() must be implemented in the called component. Thanks @markharding.
@okbong here is an example how it works:

tabs.html

    <ion-tabs>
        <ion-tab [root]="tab1"></ion-tab>
        <ion-tab [root]="tab2"></ion-tab>
    </ion-tabs>

tabs.ts (straight forward)

export class TabsPage {
  tab1: any = HomePage;
  tab2: any = OtherPage;

  constructor() {
  }
}

home.ts

export class HomePage {
 
  constructor() {
  }

  ionSelected() {
    console.log("Home Page has been selected");
    // do your stuff here
  }
}}
20 Likes

This solved a slightly different problem for me.

I noticed that when I click an already selected tab, it gets destroyed and recreated again. What’s even worse, the “rootParams” specified in the Tabs are not passed to the page when recreating. Do you think this is a bug?

When I add the ionSelected() method, the tab page won’t be recreated so that solved my problem. Is this method documented somewhere? I couldn’t find it anywhere else than here.

It seems it is best to add an empty ionSelected to every tab page to prevent recreating the page and to avoid unexpected bugs. It’s a bit strange it isn’t documented properly anywhere.

I think you’re refering to the discussion over here: Tab reloading while double click the tab

which resulted in a pull request, which you can track over here:

Right, that’s it. Thanks!

Thanks @psalchow that was exactly I searched for :slight_smile: You helped me a lot.

Thank you for your code.

Is there any documentation on ionSelected()?

Well I would like to know more about this method and about possible similar methods!

Worked fine for me. It will execute if you click on current active page. Nice. Thanks alot

Thanks @psalchow his is the trick I’ve been searching for…

Thanks a lot. It works perfectly

Awesome!! Thanks a lot :kissing_heart:

Thanks, I resolved my issue.

I needed a long press on a tab button. Here is what I came up with, hope it helps someone:

...
<ion-tab #helpTab tabTitle="HELP" tabIcon="help"></ion-tab>
...
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { NavParams, Tab, TabButton } from 'ionic-angular';
import { Observable } from 'rxjs/Observable';

@Component({
  templateUrl: 'tabs.html'
})
export class TabsPage implements AfterViewInit {
  private longpressTimeOut:any;
  private initialTouchX:number;
  private initialTouchY:number;
  @ViewChild("helpTab") helpTab: Tab;

  private initiateTimer() {
    if (this.longpressTimeOut) {
      clearTimeout(this.longpressTimeOut);
    }
    this.longpressTimeOut = setTimeout(() => {
      console.log("Longpress Triggered!")
    }, 5000);
  }

  ngAfterViewInit(): void {
    console.log("helpTab", this.helpTab)

    let tabButton: TabButton = this.helpTab.btn

    Observable.fromEvent(tabButton.getNativeElement(), 'touchstart').subscribe(
      (touchEvent: TouchEvent) => {
        console.log("touchstart")
        this.initialTouchX = touchEvent.changedTouches[0].pageX;
        this.initialTouchY = touchEvent.changedTouches[0].pageY;
        this.initiateTimer();
      }
    )

    Observable.fromEvent(tabButton.getNativeElement(), 'touchmove').subscribe(
      (touchEvent: TouchEvent) => {
        if ((Math.abs(touchEvent.changedTouches[0].pageX - this.initialTouchX) > 20)
          || (Math.abs(touchEvent.changedTouches[0].pageY - this.initialTouchY) > 20)
        ) {
          console.log("touchmove outside of tollerance... canceling longpress");
          if (this.longpressTimeOut) {
            clearTimeout(this.longpressTimeOut);
          }
        }
      }
    )

    Observable.fromEvent(tabButton.getNativeElement(), 'touchend').subscribe(
      (touchEvent: TouchEvent) => {
        console.log("touchend")
        if (this.longpressTimeOut) {
          clearTimeout(this.longpressTimeOut);
        }
      }
    )
  }
}

1 Like