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();
})
}
Related
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 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
}
}
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 am add animation effect using animate.css i need to time delay of the each child element
for the referral add image
How to add time delay in ionic 2 or Angular2 ?
also referred this to implement in ionic2
<ion-item *ngFor="let transLeaf of transLeafTmp" class="animated zoomIn">
<ion-avatar item-left>
<i class="icon" [style.background-color]="transLeaf.bgColor"><img src="{{transLeaf.categoryIcon}}"></i>
</ion-avatar>
<p>{{transLeaf.narration}}</p>
<h3>heading</h3>
<ion-note item-right class="transValue">
<h2 test111</h2>
</ion-note>
</ion-item>
HeyHey!
I didn't try but I think it should work! Good luck! ;)
HTML
<ion-item *ngFor="let transLeaf of transLeafTmp;" [class.animated]="transLeaf.isAnimated" class="zoomIn">
<ion-avatar item-left>
<i class="icon" [style.background-color]="transLeaf.bgColor"><img src="{{transLeaf.categoryIcon}}"></i>
</ion-avatar>
<p>{{transLeaf.narration}}</p>
<h3>heading</h3>
<ion-note item-right class="transValue">
<h2 test111</h2>
</ion-note>
</ion-item>
TypeScript :
private ngAfterViewInit(){
this.animateTransLeaf();
}
private animateTransLeaf(){
let i = -1;
while (++i < this.transLeafTmp.length) {
setTimeout(() => {
this.transLeafTmp[i].isAnimated = true;
}, 50 * i);
}
}
I need to remove an ionic 2 card when someone clicks on the trash icon. The code I have so far gives a querySelector is null error when I run it.
The view html looks like this:
<ion-card *ngFor="#mediaItem of mediaItems" id="item{{mediaItem.id}}" class="media-item">
<ion-card-header class="title-header">
<div class="title-item">
{{mediaItem.title}}
</div>
<ion-icon name="trash" class="bookmark_trash_icon" (click)="removeItem(mediaItem.id)"></ion-icon>
</ion-card-header>
<ion-card-content class="outer-content" >
<img src='{{mediaItem.url}}'>
</ion-card-content>
<ion-item class="bookmark-media-item">
<!-- <button (click)="topup(mediaItem)" clear item-left> -->
<div style="float:left;">
<ion-icon name="heart"></ion-icon>
{{mediaItem.liked}}
<ion-icon name="close-circle"></ion-icon>
{{mediaItem.disliked}}
</div>
<a (click)="showUserProfile(mediaItem.owner, mediaItem.username)" style="float:left;">
{{mediaItem.username}}
</a>
<div style="float:right;">
<img src="img/tiny-v.png" class="bookmark-v-icon">
{{mediaItem.credits_left}}
</div>
</ion-item>
</ion-card>
My controller javascript code looks like this:
removeItem(theItemID) {
let cardToHide = '#item'+theItemID;
document.querySelector(cardToHide).style.display = 'none';
}
The error I get is
querySelector is null
You can send the object instead of the id by changing that part of the code:
(click)="removeItem(mediaItem)"
And then find that object in you mediaItems array and delete it from there. Then your view will be automatically updated.
First get the index of that object in the array, and then you can use the mediaItems.splice(index, 1) to delete it from the array:
removeItem(theItem) {
let index = this.mediaItems.indexOf(theItem);
this.mediaItems.splice(index,1);
}