Ionic Scroll in Expandable Header


#1

I am using Ionic 2, and have implemented an Expandable Header based on this tutorial.

It works perfectly, except I have two issues:

  1. As you can see, all the search items are 0.7 opaque. This is correct, however the background of the items should have a 1.0 opacity.

  2. When there are No Results (i.e. no items in the scroll list). The Expandable Header won’t collapse. There are not items to scroll up on, so it won’t resize the header.

  3. After I apply a filter (and even clear it again), the infinite scroll (ionInfinite)="doInfinite($event)" event does not fire when I scroll to the bottom of the page.

enter image description here

Here is my code. Apologies that it’s so much, I don’t want to leave out something relevant.

Any advise appreciated.

html

<ion-header>
  <expandable-header [scrollArea]="mycontent" headerHeight="{{isIOS ? 270 : 247}}">

    <ion-item class="search-item searchtext">
      <ion-row>
        <ion-col class="col-search">
          <ion-searchbar class="ion-searchtext" id="ion-searchtext" [(ngModel)]="searchQueryText" (change)="onChangeText($event)" (ionClear)="onCancelText($event)"
            (ionInput)="onInputText($event)" placeholder="Keyword Search" debounce="1" [showCancelButton]="isIOS"></ion-searchbar>
        </ion-col>
        <ion-col class="col-cancel" *ngIf="!isIOS">
          <button ion-button *ngIf="!isIOS && searchQueryText" (click)="onCancelText($event)" color="primary" clear small>
        <p class="small-text-search search-cancel">Cancel</p>
      </button>
        </ion-col>
      </ion-row>
    </ion-item>

    <ion-item class="search-item">
      <ion-row>
        <ion-col class="col-search">
          <ion-searchbar id="ion-locationbar" [(ngModel)]="searchQueryLocation" (ionClear)="onCancelLocation($event)" (ionInput)="onInputLocation($event)"
            (click)="presentFilterMap()" placeholder="Location" debounce="1" [showCancelButton]="true"></ion-searchbar>
        </ion-col>
        <ion-col class="col-cancel" *ngIf="!isIOS">
          <button ion-button *ngIf="!isIOS && searchQueryLocation" (click)="onCancelLocation($event)" color="primary" clear small>
        <p class="small-text-search search-cancel">Cancel</p>
      </button>
        </ion-col>
      </ion-row>
    </ion-item>

    <ion-item class="search-item">
      <ion-row>
        <ion-col class="col-search">
          <ion-searchbar id="ion-locationbar" [(ngModel)]="searchQuerySectors" (ionClear)="onCancelSectors($event)" (ionInput)="onInputSectors($event)"
            (click)="presentFilterCategories()" placeholder="Sectors" debounce="1" [showCancelButton]="true"></ion-searchbar>
        </ion-col>
        <ion-col class="col-cancel" *ngIf="!isIOS">
          <button ion-button *ngIf="!isIOS && searchQuerySectors" (click)="onCancelSectors($event)" color="primary" clear small>
        <p class="small-text-search search-cancel">Cancel</p>
      </button>
        </ion-col>
      </ion-row>
    </ion-item>

    <ion-item class="search-item">
      <ion-row>
        <ion-col class="col-search">
          <ion-searchbar id="ion-locationbar" [(ngModel)]="searchQueryRating" (ionClear)="onCancelRating($event)" (ionInput)="onInputRating($event)"
            (click)="presentFilterRating()" placeholder="Star Rating" debounce="1" [showCancelButton]="true"></ion-searchbar>
        </ion-col>
        <ion-col class="col-cancel" *ngIf="!isIOS">
          <button ion-button *ngIf="!isIOS && searchQueryRating" (click)="onCancelRating($event)" color="primary" clear small>
        <p class="small-text-search search-cancel">Cancel</p>
      </button>
        </ion-col>
      </ion-row>
    </ion-item>

    <ion-item class="search-item">
      <ion-row>
        <ion-col class="col-search">
          <ion-searchbar id="ion-locationbar" [(ngModel)]="searchQueryTime" (ionClear)="onCancelTime($event)" (ionInput)="onInputTime($event)"
            (click)="presentFilterTime()" placeholder="Last Online" debounce="1" [showCancelButton]="true"></ion-searchbar>
        </ion-col>
        <ion-col class="col-cancel" *ngIf="!isIOS">
          <button ion-button *ngIf="!isIOS && searchQueryTime" (click)="onCancelTime($event)" color="primary" clear small>
        <p class="small-text-search search-cancel">Cancel</p>
      </button>
        </ion-col>
      </ion-row>
    </ion-item>

  </expandable-header>

  <ion-navbar color="primary">

    <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>

    <ion-title class="search-title-text">
      Market
    </ion-title>

    <div class="clear-all" *ngIf="searchQueryText || searchQueryLocation || searchQuerySectors || searchQueryRating || searchQueryTime"
      (click)="clearFilters($event)">
      <p class="clear-all-text {{isIOS ? 'clear-all-text-ios' : ''}}">Clear all</p>
      </div>

  </ion-navbar>
</ion-header>

<ion-content padding class="content-wanted" id="search-content" fullscreen #mycontent>
  <ion-list>
    <ion-item-sliding #slidingItem *ngFor="let item of myModels">
      <ion-item class="item-search-wanted" (click)="itemTapped($event, item, true)" (press)="openSlide(slidingItem, item, $event)">

css

.ios, .md {
    page-home {
        ion-item {
            width: 92%;
            margin: 4%;
            padding-left: 10px !important;
            margin-bottom: 10px;
            background-color: #fff;
            opacity: 0.7;
            font-size: 0.9em;
            transition: 0.2s linear;
        } 
    } 
}

expandable-header .element.style {
    min-height: 6px;
}

expandable-header .label-md {
    margin: -16px 2px -4px -18px;
}

expandable-header .searchtext .label-md {
    margin: -10px 2px -4px -18px;
}

expandable-header .searchtext .label-ios {
    margin: 25px 2px -4px -4px;
}

expandable-header .label-ios {
    margin: -4px 2px -4px -4px;
}

.toolbar-ios ion-title {
    padding: 13px 90px 3px !important;
}

.toolbar-ios {
    padding-top: 15px;
}

expandable-header .search-item {
    opacity: 0.7 !important;
}

expandable-header .item-md.item-block .item-inner {
    padding-right: 8px;
    border-bottom: 0px solid #dedede;
}

expandable-header .searchbar-md {
    width: 213%;
}

expandable-header .button-clear-md {
    float: right;
    padding-top: 18px;
}

expandable-header .searchbar-clear-icon { 
    display: none !important; 
}

.clear-all-text {
    color: #fff;
    font-size: 85%;
    padding-right: 20px;
    white-space: nowrap;
}

.clear-all-text-ios {
    padding-left: 250px;
}

expandable-header.ts

import { Component, Input, ElementRef, Renderer } from '@angular/core';

@Component({
    selector: 'expandable-header',
    templateUrl: 'expandable-header.html'
})
export class ExpandableHeader {
    @Input('scrollArea') scrollArea: any;
    @Input('headerHeight') headerHeight: number;
    newHeaderHeight: any;
    constructor(public element: ElementRef, public renderer: Renderer) {
    }

    ngOnInit() {
        if (!this.scrollArea._scroll.enabled) {
            this.scrollArea.enableScrollListener();
        }
        this.renderer.setElementStyle(this.element.nativeElement, 'height', this.headerHeight + 'px');
        this.scrollArea.ionScroll.subscribe((ev) => {
            this.resizeHeader(ev);
        });
    }

    resizeHeader(ev) {
        ev.domWrite(() => {
            this.newHeaderHeight = this.headerHeight - ev.scrollTop;
            if (this.newHeaderHeight < 0) {
                this.newHeaderHeight = 0;
            }
            this.renderer.setElementStyle(this.element.nativeElement, 'height', this.newHeaderHeight + 'px');
            for (let headerElement of this.element.nativeElement.children) {
                let totalHeight = headerElement.offsetTop + headerElement.clientHeight;
                if (totalHeight > this.newHeaderHeight && !headerElement.isHidden) {
                    headerElement.isHidden = true;
                    this.renderer.setElementStyle(headerElement, 'opacity', '0');
                } else if (totalHeight <= this.newHeaderHeight && headerElement.isHidden) {
                    headerElement.isHidden = false;
                    this.renderer.setElementStyle(headerElement, 'opacity', '0.7');
                }
            }
        });
    }
}

#2

I have solved question 3 by increasing the threshold attribute on infinite-scroll.


#3
  1. you can change in the TS file of the component, in the change method, just search that file for 0.7, and change it to 1.

#4

I have the same issue, Infinite scroll does not fire.

Can you explain me a bit further about how you solved it?