I am trying to show popover when the user click on a button. However, when I position the button to right of the screen, the popover does not show up.
This works, file: basket.page.html
<ion-button slot="icon-only" shape="round" fill="outline" (click)="presentPopover($event)" >
<ion-icon button size="large" name="more"></ion-icon>
</ion-button>
<ion-card-title>
{{ basket.name }}
</ion-card-title>
but this does not work, when I click on the button, the popover does not show up. I just added class="float-right" to ion-button tag.
<ion-button class="float-right" slot="icon-only" shape="round" fill="outline" (click)="presentPopover($event)" >
<ion-icon button size="large" name="more"></ion-icon>
</ion-button>
<ion-card-title>
{{ basket.name }}
</ion-card-title>
I have this in basket.page.ts
async presentPopover(ev: any) {
this.popover = await this.popoverController.create({
component: PopoverComponent,
event: ev,
translucent: true,
componentProps: { basketId: this.basketId }
});
return await this.popover.present();
}
Related
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' })
}
}
I want to achieve below two functionalities :
toggle button ON/OFF. (Not want new details page to be open here)
clicking on CardView new details page should open.
On clicking cardView new details page opens, this working as expected.
but, currently on hitting toggle button new page opens. I need help to avoid it.
Html Code for cardview:
<ion-list *ngFor="let individual_room of data?.rooms">
<ion-list-header>
<ion-label>{{ individual_room.name}}</ion-label>
</ion-list-header>
<ion-grid>
<ion-row>
<ion-col *ngFor="let device of individual_room.devices">
<ion-card (click)="openDetailsWithState(device)">
<ion-col><img src="assets/icon/favicon.png" /></ion-col>
<ion-card-content>
<ion-card-title> {{ device.name }} <ion-badge item-end>{{ device.company }} </ion-badge> </ion-card-title>
<ion-toggle (ionChange)="deviceStatusChange(device)" [checked]="device.state =='ON'"></ion-toggle>
</ion-card-content>
</ion-card>
</ion-col>
</ion-row>
</ion-grid>
</ion-list>
home.page.ts :
deviceStatusChange(device: any) {
device.state = device.state === 'ON' ? 'OFF' : 'ON'
console.log('device toggle switch : ' + device.state)
}
openDetailsWithState(device: any) {
let navigationExtras: NavigationExtras = {
state: {
device: device,
},
}
this.router.navigate(['details'], navigationExtras)
}
Folks:
I have an ionic app that has a page where user can post comments on a story. If a user posts new comment, the comment is displayed in the page. Comments are fetched from a REST API using the "let comment of postComments" fragment with *ngFor.
<ion-content *ngIf="!searchUser" #myContent padding [scrollEvents]="true">
<ion-refresher slot="fixed" (ionRefresh)="reloadPage($event)">
<ion-refresher-content pullingIcon="arrow-dropdown" refreshingSpinner="circles" refreshingText="Refreshing..." >
</ion-refresher-content>
</ion-refresher>
<div class="post-content">
<ion-item lines="none" no-padding>
<ion-avatar slot="start">
<img [src]=" (profileUrl == null) ? 'assets/img/emptyperson.jpg' : profileUrl">
</ion-avatar>
<p class="user-post-text">
<strong>{{
username
}}</strong><span>
{{ description }}
</span>
</p>
</ion-item>
<div class="border"></div>
<ion-item-sliding class="comments-container" *ngFor="let comment of postComments; let i = index; let c = count;" [id]="'slidingItem' + i">
<ion-item no-padding lines="none">
<ion-avatar slot="start">
<img [src]=" (comment.profileUrl == null) ? 'assets/img/emptyperson.jpg' : comment.profileUrl">
</ion-avatar>
<p>
<strong>{{
comment.username
}}</strong>
{{ comment.comment }}
</p>
<ion-button
slot="end"
fill="clear"
(click)="likeButton(comment.id, comment.currentUserLike)"
[disabled]="disableLikeButton"
>
<ion-icon
*ngIf="!comment.currentUserLike"
slot="icon-only"
name="heart-outline"
color="black"
></ion-icon>
<ion-icon
*ngIf="comment.currentUserLike"
slot="icon-only"
name="heart"
color="danger"
></ion-icon>
</ion-button>
<br/>
</ion-item>
<ion-item-options *ngIf="isPostMine && (comment.userId != userdetails.id)">
<ion-item-option color="danger" >
<button color="danger" [disabled]="disableDeleteButton" (click)="removeComment(comment.id,i)"><ion-icon class="inside-icon" name="trash"></ion-icon></button>
</ion-item-option>
<ion-item-option color="primary" >
<button color="primary" (click)="reportOffensive(comment.id,i)"><ion-icon class="inside-icon" name="remove-circle"></ion-icon> </button>
</ion-item-option>
</ion-item-options>
<ion-item-options *ngIf="isPostMine && (comment.userId == userdetails.id)">
<ion-item-option color="danger" >
<button color="danger" [disabled]="disableDeleteButton" (click)="removeComment(comment.id,i)"><ion-icon class="inside-icon" name="trash"></ion-icon></button>
</ion-item-option>
</ion-item-options>
<ion-item-options *ngIf="!isPostMine && (comment.userId != userdetails.id)">
<ion-item-option color="primary" >
<button color="primary" (click)="reportOffensive(comment.id,i)"><ion-icon class="inside-icon" name="remove-circle"></ion-icon> </button>
</ion-item-option>
</ion-item-options>
<ion-item-options *ngIf="!isPostMine && (comment.userId == userdetails.id)">
<ion-item-option color="danger" >
<button color="danger" [disabled]="disableDeleteButton" (click)="removeComment(comment.id,i)"><ion-icon class="inside-icon" name="trash"></ion-icon></button>
</ion-item-option>
</ion-item-options>
<p class="all-comments">
<span class="grey-text"> {{ comment.createdAt | timeAgo }}</span>
<span *ngIf="comment.numLikes > 0" class="grey-text tab" (click)="userList(comment.id,'CommentLikes')">{{comment.numLikes}} likes</span>
</p>
</ion-item-sliding>
</div>
</ion-content>
<ion-footer>
<ion-item lines="none">
<ion-avatar slot="start">
<img src="{{ userProfileUrl }}" />
</ion-avatar>
<ion-textarea autocapitalize="sentences" maxLength="255" type="text"
[(ngModel)]="commentContent" (ionChange)="getUsers($event)"
rows="1"
placeholder="Add a comment"
></ion-textarea>
<ion-icon class="blueicon" slot="end" name="send" (click)="addComment()"></ion-icon>
</ion-item>
</ion-footer>
In my typescript, I have a function addComment() which refreshes the value of postComments so that the page automatically reloads.
addComment() {
if (this.commentContent.trim()) {
this.showLoader("Posting Comment ...");
this.userPostComment.comment = this.commentContent;
this.userPostCommentJSON = JSON.stringify(this.userPostComment);
//console.log("Comment JSON is "+this.userPostCommentJSON);
this.https.post(this.serviceUrl+'comments',this.userPostCommentJSON,this.httpOptions)
.subscribe(
(res: any)=>{
this.commentContent = "";
this.refresh();
setTimeout(() => {
console.log("In Timeout");
this.refreshPostComments("");
this.events.publish('postComment:created', {
id: res.id,
time: new Date()
});
this.hideLoader();
this.commentContent = "";
},2000)
},
err => {
this.hideLoader();
this.showAlert(err);
}
);
}
}
This is working like charm, when I get to the Comments page from the story.
Here is my problem. If I navigate to the Comments page from a oneSignal push notification, everything works fine up to the point where I enter a new comment. When I enter a new Comment, the comment is created in the database using the RESTAPI (works fine), the refreshPostComments method is called in typescript (works fine), but my view does not get updated till I physically click the comment box again.
I don't know what I am doing wrong. But in my app.component.ts, I check for oneSignal notification clicked and if clicked, I do this
if (localStorage.getItem('auth-user') != undefined || null) {
if (additionalData.type == "comment") {
await console.log("Going to Comments");
this.router1.navigateForward(['/comments', {
userId: parseInt(additionalData.userId),
username: additionalData.username,
userPostId: parseInt(additionalData.userPostId),
description: additionalData.description,
profileNameKey: additionalData.profileNameKey
}]);
}
That works. Takes me to the Comments Page. But once I am in the page, I can do virtually everything else like peach, except if I add a comment, then it does not reflect in real time.
Any pointers on what I am missing?
JR
Found my solution. I think Angular’s Change detection is triggered by certain events, and when I was navigating to the page from OneSignal's notification - whatever OneSignal was using, it was not getting on Angular's radar. So I had to import ChangeDetectorRef and do a manual detectChanges() to make sure ngFor would detect the changes as soon as they occur.
Phew. Spent almost a half a day on this. So much for OneSignal and Angular's quirks with OneSignal. And Ionic had nothing to do with it.
Regards,
JR
I have used ion-tabs and side-menu for change route the app, both uses routerLink. And when i press Home tab in ion-tab to go back to home page inside other pages, route changed to home but home page constructor method and onInit methods does not invoke.
side-menu.component.ts
<ion-app>
<ion-split-pane contentId="main-content">
<ion-menu *ngIf="isAuthenticated$ | async" contentId="main-content" type="overlay">
<ion-content>
<ion-list id="inbox-list">
<div class="menu-header">
<ion-list-header>
<img src="assets/wa-logo.ico">
</ion-list-header>
<ion-note></ion-note>
</div>
<ion-menu-toggle auto-hide="false" *ngFor="let p of appPages; let i = index">
<ion-item (click)="selectedIndex = i" routerDirection="root" [routerLink]="[p.url]" lines="none" detail="false" [class.selected]="selectedIndex == i">
<ion-icon slot="start" [ios]="p.icon + '-outline'" [md]="p.icon + '-sharp'"></ion-icon>
<ion-label>{{ p.title }}</ion-label>
</ion-item>
</ion-menu-toggle>
</ion-list>
</ion-content>
<ion-footer>
<ion-menu-toggle auto-hide="false">
<ion-item
(click)="logout()"
routerDirection="root"
lines="none"
detail="true"
>
<ion-icon
slot="start"
ios='log-out-outline'
md="log-out-sharp"
></ion-icon>
<ion-label> Logout </ion-label>
</ion-item>
</ion-menu-toggle>
</ion-footer>
</ion-menu>
<ion-router-outlet id="main-content"></ion-router-outlet>
<ion-tabs *ngIf="isAuthenticated$ | async">
<ion-tab-bar [translucent]="true" slot="fixed">
<ion-tab-button (click)="onClick()">
<ion-icon name="home"></ion-icon>
<ion-label> Home </ion-label>
</ion-tab-button>
<ion-tab-button [routerLink]="['/features/new-request']">
<ion-icon name="document-text"></ion-icon>
<ion-label> New Request </ion-label>
</ion-tab-button>
<ion-tab-button [routerLink]="['/features/prev-requests']">
<ion-icon name="reader"></ion-icon>
<ion-label> All Requests </ion-label>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
</ion-split-pane>
</ion-app>
So if i go inside prev-request page using ion-tab and once using hardware back button or ion-toolbar back button to changes route back to home page constructor and ngOnInit does not invoke, but if i route using side menu and go back with hardware back button or ion-toolbar back button constructor and ngOnInit methods are invoked.
prev-req.page
constructor(private _preReqService: PrevReqService,private platform: Platform,
private _modal: ModalService,
private _router: Router) {
this.platform.backButton.subscribeWithPriority(10, () => {
this._router.navigate(['/features/home'])
});
}
Still i don't have any clue why this happens.
Any idea why this happens ?
If you want to execute a function every time you go to a page Use Ionic Page Life Cycle.
ionViewWillEnter: Fired when the component routing to is about to animate into view.
ionViewDidEnter: Fired when the component routing to has finished animating.
ionViewWillLeave: Fired when the component routing from is about to animate.
ionViewDidLeave: Fired when the component routing to has finished animating.
export class ExamplePage implements OnInit {
constructor(){
}
ionViewWillEnter(){
console.log('Will Enter Fired') // will fire every time to go to a page.
}
}
Ionic Life Cycle Docs
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.