I want to catch scrolling event of list component in ionic3 as in this example:
<ion-content on-scroll = "scrolling()" on-scroll-complete = "scrollComplete()">
<ion-list>
<ion-item ng-repeat="item in items"
item="item"
href="#/item/{{item.id}}">
Item {{ item.id }}
</ion-item>
</ion-list>
</ion-content>
https://codepen.io/etipirev/pen/aNYNpy?editors=1111
as it is seemed it is working in ionic 1, but not in ionic 3? i havent found any event description in ionic docs. is it possible to catch scrolling of list items in ionic 3?
The syntax is different in Ionic2/3. Here's how it should be:
<ion-content (ionScroll)="scrolling($event)" (ionScrollEnd)="scrollComplete($event)">
<ion-list>
...
</ion-list>
</ion-content>
then in your ts file
constructor(){}
scrolling(event) {
// your content here for scrolling
}
scrollComplete(event) {
// your content here of scroll is finished
}
}
Related
I am trying to implement an ion-list with ion-items that are swipable but don't have to be clicked on the side to trigger an event.
It should work like like the default contacts app on Samsung phones, where you can either swipe left to call or right to send a SMS.
The list in the parent page looks like this:
<ion-list *ngFor="let person of persons | filter:searchTerm">
<app-person-entry [person]="person" (click)="openModal(person)"></app-person-entry>
</ion-list>
The person-entry component looks like this:
<ion-item>
<ion-avatar slot="start">
<img src={{person.icon}}>
</ion-avatar>
<div>
<div class="container">
<ion-label>{{person.lastname}}</ion-label>
<ion-label>{{person.firstname}}</ion-label>
</div>
<div class="container">
<ion-label>{{person.postalCode}}</ion-label>
<ion-label>{{person.city}}</ion-label>
<ion-label>{{person.address}}</ion-label>
</div>
</div>
</ion-item>
you can use ion-item-sliding.
e.g:
<ion-list>
<ion-item-group #myItemsId>
<ion-item-sliding (ionSwipe)="swipeEvent($event, myItemsId)">
<ion-item-options side="start">
<ion-item-option>CALL</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Item Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option>SMS</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-item-group>
</ion-list>
.ts:
swipeEvent($event, item) {
console.log($event)
if ($event.detail.side == 'start') {
console.log('call now');
this.closeAllItems(item)
} else {
console.log('SMS now');
this.closeAllItems(item)
}
}
closeAllItems(item) {
let a = Array.prototype.slice.call(item.el.children)
a.map((val) => {
val.close();
})
}
I am making an internal live chat system using Firebase. I make this call to get a list of all chat messages:
firebase.database().ref('chatrooms/'+this.roomkey+'/chats').on('value', resp => {
this.chats = [];
this.chats = snapshotToArray(resp);
setTimeout(() => {
if(this.content._scroll) { this.content.scrollToBottom(0); }
}, 1000);
});
In my view I have this HTML to loop through the chats:
<ion-content>
<ion-list>
<ion-item *ngFor="let chat of chats" no-lines>
<div class="chat-status" text-center *ngIf="chat.type==='join'||chat.type==='exit';else message">
<span class="chat-date">{{chat.sendDate | date:'short'}}</span>
<span class="chat-content-center">{{chat.message}}</span>
</div>
<ng-template #message>
<div class="chat-message" text-right *ngIf="chat.user === nickname">
<div class="right-bubble">
<span class="msg-name">Me</span>
<span class="msg-date">{{chat.sendDate | date:'short'}}</span>
<p text-wrap>{{chat.message}}</p>
</div>
</div>
<div class="chat-message" text-left *ngIf="chat.user !== nickname">
<div class="left-bubble">
<span class="msg-name">{{chat.user}}</span>
<span class="msg-date">{{chat.sendDate | date:'short'}}</span>
<p text-wrap>{{chat.message}}</p>
</div>
</div>
</ng-template>
</ion-item>
</ion-list>
</ion-content>
And here is my relevant CSS:
ion-content {
height: 100%;
overflow: hidden;
.item-md, .item-ios {
background: none;
}
}
There are currently 30 chat messages. They are loaded from Firebase and then after a second, when the setTimeout finishes, the user is automatically scrolled to the bottom of the page so they can see the most recent message. This makes the page load a bit odd with the jump down to the bottom of the page after a second.
Is there any way to replace the timeout with something that will achieve the goal of the user initially seeing the most recent messages? Maybe there is some trigger that can be made that detects that chats has changed in the view and then does the scroll? This would seem better than a fixed 1 second pause?
You could scroll to the bottom of the list when changes to the list of chats are detected:
Associate a template reference variable to the ion-item elements (e.g. #chatItems)
Use ViewChildren to get the QueryList of ion-item elements
In ngAfterViewInit, subscribe to the QueryList.changes event
Scroll to the bottom of the list when the list changes
<ion-content>
<ion-list>
<ion-item #chatItems *ngFor="let chat of chats" no-lines>
...
</ion-item>
</ion-list>
</ion-content>
export class MyComponent {
#ViewChildren("chatItems") chatItems: QueryList<any>;
ngAfterViewInit() {
this.scrollContentToBottom();
this.chatItems.changes.subscribe(() => {
this.scrollContentToBottom();
});
}
scrollContentToBottom() {
if(this.content._scroll) {
this.content.scrollToBottom(0);
}
}
...
}
Note: I used QueryList<any> because I don't know the ion-item component type. You can put the appropriate type if you know what it is.
I have a side project in Ionic 3. In this project I have view with array of users, this works perfectly. These users have a button with id, when we click we move to other view to show more data of this user. All backend is Lumen and tested with Postman, response is correct.
The problem that I have is that the second page doesn´t show any data, but I check in network tab and receive the json correctly. When I go back to first page and go again to the second page, data see in the view. ¿Why the first time that I go to the second page the data doesn´t appear? I think that is a strange error.
data2: any
verDetalles(id:any){
this.visitantes.verVisitante(id)
.then(data2 => {
this.data2 = Array(data2);
});
this.navCtrl.push(DatosPreVisitasPage, {
animate: true,
data:this.data2
});
}
//CALL TO ENDPOINT
verVisitante(id:any) {
return this.http.get('http://visitas.api.app:8000/visitantes/'+id)
.map(res => res.json())
.toPromise();
}
And this code in view
<ion-header >
<ion-navbar>
<ion-title text-center>
Datos Prevista
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding class="background">
<ion-grid >
<ion-card padding>
<ion-list *ngFor="let user of datos" >
<ion-item>
<ion-label floating>Nombre</ion-label>
<ion-input type="text" [(ngModel)]="user.nombre" name="nombre"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Apellido</ion-label>
<ion-input type="text" [(ngModel)]="user.apellidos" name="apellido"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Empresa</ion-label>
<ion-input type="text" [(ngModel)]="user.empresa" name="empresa"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>DNI</ion-label>
<ion-input type="text" [(ngModel)]="user.dni" name="dni"></ion-input>
</ion-item>
</ion-list>
</ion-card>
</ion-grid>
</ion-content>
Maybe is a error on the promise or something like that, but not sure, i'm new in ionic.
You should call the second page inside .then so that it is called only when data has aarrived:
data2: any
verDetalles(id:any) {
this.visitantes.verVisitante(id)
.then(data2 => {
this.data2 = Array(data2);
this.navCtrl.push(DatosPreVisitasPage, {
animate: true,
data:this.data2
});
});
}
I need a static value from list tag when click or touch in mobile individually. how to get it in angularjs
<ion-list ng-controller="MyCtrl">
<ion-item menu-close ng-value="apple">
Apple
</ion-item>
<ion-item menu-close ng-value="orange">
Orange
</ion-item>
<ion-item menu-close ng-value="pineapple">
PineApple
</ion-item>
<ion-item menu-close ng-value="mango">
Mango
</ion-item>
</ion-list>
angularjs
.controller('MyCtrl', function($scope) {
})
Here's a working example using href: http://plnkr.co/edit/35wTi7?p=info
Here's a working example using ng-click: http://plnkr.co/edit/NN4cWr?p=preview
These examples are dynamic, but you'll get the point.The second example is much better in your case.
This is what you want to do:
HTML:
<ion-item menu-close ng-click="someFunction('apple')">
Apple
</ion-item>
<ion-item menu-close ng-click="someFunction('orange')">
Apple
</ion-item>
JavaScript
// We must use .dot notation with Ionic
$scope.fruit = {
selected : ''
};
$scope.someFunction= function(id) {
console.log(id); // Will print apple
$scope.fruit.selected = id;
}
My examples are also called a Master-Detail pattern, click here to find out more.
It's still unclear to me what you need, but to bind a value to the HTML just populate the scope and use it:
HTML:
<ion-list ng-controller="MyCtrl">
<ion-item menu-close>{{apple}}</ion-item>
<ion-list>
JS:
.controller('MyCtrl', function($scope) {
$scope.apple = "This is an apple";
})
Take a look to this example from Angular documentation:
https://docs.angularjs.org/api/ng/directive/ngValue#example
This is the controller for the particular view with which I'm having an issue.
.controller('MenuCtrl', ['$rootScope','$scope','$state','$timeout','$ionicSlideBoxDelegate',
function($rootScope, $scope, $state, $timeout, $ionicSlideBoxDelegate) {
$scope.state = { detail: false, selected: 0 };
$scope.stateSwitch = function() {
$scope.state.detail = !$scope.state.detail;
$timeout( function() { $ionicSlideBoxDelegate.update(); }, 50);
}
$scope.activateSlide = function($index) {
$ionicSlideBoxDelegate.slide($index);
}
Here is the view.
<ion-view left-buttons="leftButtons">
<ion-content class="has-header" has-tabs="true" ng-show="!state.detail">
<div class="list menu-list">
<a class="item" ng-repeat="item in items" ng-click="stateSwitch();activateSlide($index)">
...
</a>
</div>
</ion-content>
<ion-content class="has-header padding" has-tabs="true" ng-show="state.detail">
<div class="menu-detail">
<ion-slide-box does-continue="true" show-pager="false">
<ion-slide ng-repeat="item in items">
...
</ion-slide>
</ion-slide-box>
</div>
</ion-content>
</ion-view>
Upon clicking the list item, it triggers the state.detail flag which switches the view to a menu item detail page. From the menu item detail page, I'm using ion-slide-box so that users can paginate through the items as well.
This works great when I don't specify which slide index to start on. Even when I do pick a static number to start the slider on, it works. However, when I use the $index of the menu list as an argument to change the active slide on the slide box, the slide box just smashes all the slides together and their is no swipe functionality.
This happens even after I update the slide box.
Is there something wrong with how I am using $index? Or perhaps this was not the intended way to dynamically set the active slide? Any advice would be appreciated!
on your controller in your function $scope.activateSlide use without $ on index
here code that worked for me:
on html:
<h4 ng-repeat="type in view.menu.itens" ng-click="changeSlide($index)"></h4>
on my controller
$scope.changeSlide = function funChangeSlide(index) {
$ionicSlideBoxDelegate.slide(index);
}