Ionic 2 - ion-scroll fire event on scroll bottom - ionic-framework

I have a page where I have a section which is scrollable. However I am not able to implement infinite scroll function inside the ion-scroll section. I know infinite-scroll applies on ion-content but how can I fire an event when the user scroll downs in an ion-scroll section.
<ion-content class="main-view">
<div class="overlay" tappable (click)="dismiss()">
</div>
<div (click)="CloseScreen()">
<ion-icon name="close" tappable class="close-modal"></ion-icon>
</div>
<div>
<div class="modal_content">
<ion-scroll scrollY="true" style="height:300px">
<ion-spinner class="loading-center" *ngIf="loadingCustomers"></ion-spinner>
<div class="customer-items">
<ion-item *ngFor="let customer of customersView.paginatedCustomers" tappable (click)="SelectCustomer(customer)">
<h6>
{{customer.BusinessName}}
</h6>
</ion-item>
</div>
<ion-infinite-scroll (ionInfinite)="LoadMoreCustomers($event)"> // NOT FIRING!
<ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-scroll>
....OTHER STUFF
</div>
</div>
</ion-content>

I will post this in case you or someone else is still looking for an answer.
Like you said ion-infinite-scroll would only applies to the ion-content even when placed inside an ion-scroll. So you could see it firing if you add some margin to your ion-scoll and try to scroll the page itself.
However, for your case, you may want to try something like this:
https://stackoverflow.com/a/42176764/4084776
If you want to check when you reach the bottom of the scroll you could add a dummy element and check if it is near the bottom of the scroll. See the example below.
...
#ViewChild(Scroll) ionScroll: Scroll;
#ViewChild("endOfScroll") endOfScroll: ElementRef;
updating: Boolean = false;
private threshold: number = 0.01; //1% This is similar to ion-infinite-scroll threshold
...
ionViewDidLoad() {
this.ionScroll.addScrollEventListener(this.scrollHandler.bind(this));
}
...
scrollHandler(evenman){
let endOfScroll = this.endOfScroll.nativeElement.getBoundingClientRect();
let ionScroll = this.ionScroll._scrollContent.nativeElement.getBoundingClientRect();
let clearance = 1 - ionScroll.bottom/endOfScroll.bottom;
if(clearance <= this.threshold){
this.updating = true;
// DO your work here
console.log(JSON.stringify({fen: endOfScroll.bottom, lis: ionScroll.bottom}));
this.updating = false;
}
}
...
...
<ion-scroll scrollY="true">
<ion-list>
<ion-item-sliding *ngFor="let machann of lisMachann.lisMachann let endeks = index" [class.active]="endeks == endeksKlik">
<ion-item (click)="ouveFenet(endeks)">
...
</ion-item>
<ion-item-options side="left">
...
</ion-item-options>
</ion-item-sliding>
<ion-item *ngIf="updating">
<ion-spinner class="loading-center"></ion-spinner>
</ion-item>
</ion-list>
<div #endOfScroll></div>
</ion-scroll>
...

Related

Ionic 6 & Vue 3 | Ion-Modal scrollIntoView() Hides Fixed Header Issue

I created scrollTo functionality by clicking on an icon in a sidebar.
The scrolling works but the ion-header is moved out of view when scrolling to the desired location.
Here is a video of the behavior I am describing:
https://drive.google.com/file/d/1XeCr0RKOlas_9PpZZTUx5pEteA8Np42-/view?usp=sharing
Almost identical template works with Ionic 4 & Angular
Any ideas on what is wrong here?
Template
<template>
<ion-modal>
<ion-header>
<ion-toolbar>
// Close modal button
</ion-toolbar>
<ion-searchbar />
<div>
// Vertical column of scroll to anchor tags
<a #click="scrollTo('Math')">
<ion-icon :icon="calculator"/>
</a>
</div>
</ion-header>
<ion-content>
<ion-list>
<ion-list-header id="Math">
<ion-label>
Math
</ion-label>
</ion-list-header>
</ion-list>
</ion-content>
</ion-modal>
</template>
scrollTo Function
function scrollTo (category: string) {
let elementId = category.replace(' ', '')
let subject = document.getElementById(elementId)
if (subject) {
subject.scrollIntoView({ behavior: 'smooth', block: 'start' })
}
}

FAB Button does not have backdrop to close when theuser clicks outside the options

I would like to add css backdrop which allows the user to close FAB button options once it's clicked. I tried the following CSS solution from here but covers the options and cannot be seeing.
<button ion-button (click)="toggle!=toggle ">Add</button>
<div [ngClass]="{ 'blur' : toggle }">
your content
</div>
<!-- fab placed to the bottom & center -->
<ion-fab vertical="bottom" horizontal="center" slot="fixed">
<ion-fab-button (click)="toggle!=toggle ">
<ion-icon name="arrow-dropup"></ion-icon>
</ion-fab-button>
<ion-fab-list side="top">
<ion-fab-button><ion-icon name="logo-vimeo"></ion-icon></ion-fab-button>
<ion-fab-button><ion-icon name="logo-facebook"></ion-icon></ion-fab-button>
<ion-fab-button><ion-icon name="logo-twitter"></ion-icon></ion-fab-button>
<ion-fab-button><ion-icon name="restaurant"></ion-icon>
<div class="list-label">Meals</div>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<div [ngClass]="{ 'blur' : toggle }">
<ion-content
<ion-card class="welcome-card">
<ion-img src="/assets/shapes.svg"></ion-img>
<ion-card-header>
<ion-card-subtitle>Get Started</ion-card-subtitle>
<ion-card-title>Welcome to Ionic</ion-card-title>
</ion-card-header>
<ion-card-content>
<p>Now that your app has been created, you'll want to start building out features and components. Check out some of the resources below for next steps.</p>
</ion-card-content>
</ion-card>
</ion-content
</div>
CSS
.blur {
filter: blur(5px);
-webkit-filter: blur(5px);
transition: -webkit-filter 200ms linear;
}
We have a similar thing in our app, but we use the backdrop as a loading screen with animations inside. I used a separate component with a high z-index:50 and if I want to have something on a higher level, I just add a lager number to the z-index of that element. I have ran some tests and it should work with ion-fab.

CheckBox Function calling a button with IONIC 2

I'm simulating something like a shopping cart using ionic 2. Basically you write the item's name and value and it's creating a list with checkbox as in the image below.
But I wanted the option only appear when selecting one of the checkboxes, and did not stay static on the screen as it is now. How can I do this?
grid calling the CheckBox:
<ion-grid>
<ion-row *ngFor="let item of produto">
<ion-item>
<ion-label (click)="clicou(item.desc)">
{{ item.desc }} {{ item.valor }}
</ion-label>
<ion-checkbox checked="false"></ion-checkbox>
</ion-item>
</ion-row>
</ion-grid>
button code part:
<button ion-button block (click)="remove()" color="danger" style="transition: none 0s ease 0s;">
<span class="button-inner">
<ion-icon name="close"></ion-icon>
Remover Selecionados
</span>
<div class="button-effect"></div>
</button>
in ts create a variable that contains the value of the checks, as an example I will use productState which will be boolean type, and create in produto a state.
you can use a ngmodel and the variable already created (productState) to validate the status of the product, and use the event (ionchange) to this
<ion-grid>
<ion-row *ngFor="let item of produto">
<ion-item>
<ion-label (click)="clicou(item.desc)">
{{ item.desc }} {{ item.valor }}
</ion-label>
<ion-checkbox (ionChange)="validState()" [(ngModel)]="productState" ></ion-checkbox>
</ion-item>
</ion-row>
in ts create a function to valid the state of products:
validState(){
let cont = 0;
for (let index = 0; index < this.produto.length; index++) {
if (this.produto[index].State){
cont++;
}
}
if(cont >=1){
this.productState = true;
}else{
this.productState = false;
}
}
and in the button we will use ngIf to validate the product status through productState
<button *ngIf="productState" ion-button block (click)="remove()" color="danger" style="transition: none 0s ease 0s;">
<span class="button-inner">
<ion-icon name="close"></ion-icon>
Remover Selecionados
</span>
<div class="button-effect"></div>
</button>
ngIf docs
ngmodel docs

Unable to use infinite scroll using Ionic 3

Here I m getting data I applied the infinite scrolling but the items didn't show on my scroll page below is my code:
.html
<ion-list
*ngFor="let infi of IfoData;" (click)="Item(infi.Id)" >
<ion-infinite-scroll (ionInfinite)="doInfinite($event)">
<ion-infinite-scroll-content>
<ion-item>
<div >
<p>{{infi.Cost}}</p>
</div>
</ion-item>
</ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-list>
.js
doInfinite(infiniteScroll) {
console.log('Begin async operation');
setTimeout(() => {
for (let i = 0; i < 10; i++) {
this.IfoData.push( this.IfoData.length );
}
console.log('Async operation has ended');
infiniteScroll.complete();
}, 500);
}
After implementing this code I am just getting empty screen the data is not showing in the template and without implementing this infinite scroll it is displaying.
Infinite scroll component must comes last element in ion-content. You should try like this
<ion-content>
<ion-list>
<ion-item class="itm" *ngFor="let i of IData;" (click)="goItem(i.Id,i.Name)">
<ion-avatar item-start role="img">
<img [src]="'data:image/png;base64,'+i.Image" style="width: 110px;">
</ion-avatar>
<div class="item-inner">
<h2 class="_nme">{{i.Name}}</h2>
<p class="_price">{{i.Cost}}</p>
<ion-icon name="arrow-dropright"></ion-icon>
</div>
</ion-item>
</ion-list>
<ion-infinite-scroll (ionInfinite)="doInfinite($event)">
<ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-content>
ion-infinite-scroll-content is to change the default spinner and add text in infinite scroll
Refer the docs for details
put infinite scroll at the last in ion-content
<ion-infinite-scroll (ionInfinite)="doInfinite($event)">
<ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
and in your ts file
doInfinite(infiniteScroll) {
console.log('Begin async operation');
setTimeout(() => {
for (let i = 0; i < 10; i++) {
this.iData.push( this.iData.length );
}
console.log('Async operation has ended');
infiniteScroll.complete();
}, 500);

Ionic scroll won't fire on load with $getByHandle()

I'm trying to scroll down to delegate-handle="start" with ionic on load. When i try to run it, i get this message in console.
Delegate for handle "small" could not find a corresponding element with delegate-handle="small"! scrollTop() was not called!
Possible cause: If you are calling scrollTop() immediately, and your element with delegate-handle="small" is a child of your controller, then your element may not be compiled yet. Put a $timeout around your call to scrollTop() and try again.
My code looks like this, can somebody maybe see what is wrong?
$timeout(function() {
$ionicScrollDelegate.$getByHandle('start').scrollTop();
}, 10);
If i use $ionicScrollDelegate.scrollBottom(), it will scroll to the bottom, so it must be a problem with the specific function.
The html code
<ion-view title="Kalender">
<ion-content>
<ion-list ng-repeat="activity in calendar">
<div class="item item-divider" ng-show="activity.date_divider != null" data-year="{{activity.year}}">
<div class="header-divider-small">{{activity.year}}</div>
<div class="header-divider">{{activity.date_divider}}</div>
</div>
<div class="item item-icon-right calendar" ng-show="activity.date_divider == null">
<span class="header">{{activity.name}}</span>
<br />
<span class="text">{{activity.time}} - {{activity.place}}</span>
<a class="button button-icon icon {{activity.icon}} right not-selected"></a>
</div>
</ion-list>
<div delegate-handle="start"></div>
</ion-content>
</ion-view>
Thanks.
Ionic 1.0.0-beta14 has some strange issue with getByHandle() so you can do it this way:
$timeout(function() {
var startHandle = _.find($ionicScrollDelegate._instances, function (s) {
return s.$$delegateHandle === "start";
});
startHandle.scrollTop();
});
Solution source at forum.ionicframework.com
I think there is a misunderstanding about what the delegate handle does here. Delegate handle is a way to name scroll/content containers. Think of it like a way to give your <ion-content> container a unique name that can be later used with the service. It is possible to have multiple <ion-content> containers on a single view, and this is why the naming is necessary. If you only have one scroll area or don't specify the handle, then it just uses the first view it finds.
You want to scroll to a particular place in the application, which is the job of $ionicScrollDelegate.anchorScroll('element-id');. Take a look at your code here with some modifications. I've put the delegate handle in the correct place, and then use the anchorScroll method to automatically scroll to that ID in the page.
Markup
<ion-view title="Kalender">
<ion-content delegate-handle="kalendar">
<ion-list ng-repeat="activity in calendar">
<div class="item item-divider" ng-show="activity.date_divider != null" data-year="{{activity.year}}">
<div class="header-divider-small">{{activity.year}}</div>
<div class="header-divider">{{activity.date_divider}}</div>
</div>
<div class="item item-icon-right calendar" ng-show="activity.date_divider == null">
<span class="header">{{activity.name}}</span>
<br />
<span class="text">{{activity.time}} - {{activity.place}}</span>
<a class="button button-icon icon {{activity.icon}} right not-selected"></a>
</div>
</ion-list>
<div id="start"></div>
</ion-content>
</ion-view>
Controller
$timeout(function() {
$ionicScrollDelegate.$getByHandle('kalendar').anchorScroll('start');
}, 10);
Specify the dalegate-handler in ion-content
<ion-view title="Kalender">
<ion-content delegate-handle="start">
<ion-list ng-repeat="activity in calendar">
<div class="item item-divider" ng-show="activity.date_divider != null" data-year="{{activity.year}}">
<div class="header-divider-small">{{activity.year}}</div>
<div class="header-divider">{{activity.date_divider}}</div>
</div>
<div class="item item-icon-right calendar" ng-show="activity.date_divider == null">
<span class="header">{{activity.name}}</span>
<br />
<span class="text">{{activity.time}} - {{activity.place}}</span>
<a class="button button-icon icon {{activity.icon}} right not-selected"></a>
</div>
</ion-list>
</ion-content>
</ion-view>
Scroll top can be achieved by forgetting the scroll position which can be achieved by using
$scope.$on("$destroy", function() {
var delegate = $ionicScrollDelegate.$getByHandle('start');
delegate. forgetScrollPosition();
});
Use
$ionicScrollDelegate.$getByHandle('start').scrollTop(); //To scroll to Top.
As I noticed delegate-handle won't work if used with overflow-scroll.
I managed to do it this way:
$scope.scrollHandle = some-handle-value-that-you-want-to-use;
$scope.$on('$ionicView.loaded', function () {
$timeout(function () {
scrollView = $ionicScrollDelegate._instances.filter(function (s) {
if (!s.$$delegateHandle) return false;
return $parse(s.$$delegateHandle.slice(2, -2))
(angular.element(s.element).scope()) == $scope.scrollHandle;
})[0];
}).then(function () {
scrollView.scrollTo(0, 0, false);
});
});
In the template:
delegate-handle="{{scrollHandle}}"
EDIT:
This doesn't work anymore, check this answer for new solution: https://stackoverflow.com/a/32123613/1630623