Hover effect on ion-item without routerLink - html

This is a side menu on the Ionic web app.
<ion-content>
<ion-list>
<ion-menu-toggle autoHide="false" *ngFor="let p of appPages; let i = index">
<ion-item (click)="selectedIndex = I"
[class.selected]="selectedIndex == i" tappable (click)="goToPage(p)">
<ion-icon slot="start" [name]="p.ionicIcon? p.ionicIcon: ''"></ion-icon>
<ion-label>
{{p.title}}
</ion-label>
</ion-item>
</ion-menu-toggle>
</ion-list>
</ion-content>
</ion-menu>
Doc: https://ionicframework.com/docs/api/item#css-custom-properties
Here I need to give a Hover effect. But it is not working. Key thing here is you can see that I do not use routerLink here. So how can I do that?
I have tried this. But not working.
ion-item:hover {
--background-hover: gray !important;
}

If you read through the docs, you'll see your "tappable" attribute is no long valid.
All you need to do is set button="true" on the ion-item.
<ion-item button="true">
My Item
</ion-item>
https://codepen.io/mhartington/pen/KKVemNx?editors=1000
Also worth noting...
You do not need to use the :hover selector on the element. It should just be
ion-item {
--background-hover: gray;
}

Related

Ionic Menu Template not showing on mobile

I created my Ionic app with the wizard on their page and chose the template "menu". If I look at my app in the desktop version, it is totally ok as you can see here: Desktop view OK
BUT IF I switch to the "mobile view" in my Browser (Firefox), the menu does not show up??
As you can see here: Mobile view no menu
This is my html code for the menu:
<ion-app>
<ion-split-pane contentId="main-content">
<ion-menu contentId="main-content" type="overlay">
<ion-content>
<ion-list id="inbox-list">
<ion-list-header>Netzwerkverwaltung</ion-list-header>
<ion-note></ion-note>
<ion-menu-toggle auto-hide="false" *ngFor="let p of appPages; let i = index">
<ion-item routerDirection="root" [routerLink]="[p.url]" lines="none" detail="false" routerLinkActive="selected">
<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-menu>
<ion-router-outlet id="main-content"></ion-router-outlet>
</ion-split-pane>
</ion-app>
You put your ion-menu inside of an ion-split-pane.
So the visibility depends on the width of the windows!
U can open your sidemenu from mobile using a swipe from the border of
the side of the menu.
Using menuController.toggle()
Or using ion-menu-button inside the ion-header!
The menu is hidden on smal screens!!
Docs:
IonMenuButton: https://ionicframework.com/docs/api/menu-button
MenuToggle: https://ionicframework.com/docs/api/menu-toggle
MenuController: https://ionicframework.com/docs/v4/api/menu-controller

Change Ionic button color for a specific button not for all of them

I have this code for multi buttons inside Ngfor and I want just the clicked button to change its color not all of them, how can I do it please?
.html:
<ion-col size="6" *ngFor="let data of dataArray" >
<ion-card>
<ion-card-header>
<ion-button class="fav-icon2" ion-button [color]="ionicNamedColor (click)="changecolor()" >
<ion-icon name="heart"></ion-icon>
</ion-button>
</ion-card-header>
</ion-card>
</ion-col>
.ts:
public ionicNamedColor: string = 'warning';
changecolor() {
if(this.ionicNamedColor === 'warning') {
this.ionicNamedColor = 'primary'
} else {
this.ionicNamedColor = 'warning'
}
}
here you are using the array named dataArray for showing the buttons on the screen.
Add one more property called clicked in the object used in the dataArray.
So whenever you call the method for changeColor, you just check the property clicked and decide whether to change the color or not.
So your file should be updated with the following code:
<ion-col size="6" *ngFor="let data of dataArray" >
<ion-card>
<ion-card-header>
<ion-button class="fav-icon2" ion-button [color]="data.isClicked?'warning':'primary" (click)="data.isClicked = !data.isClicked" >
<ion-icon name="heart"></ion-icon>
</ion-button>
</ion-card-header>
Here there is not need to add anything in your typescript file.
You are iterating over an array through an ngFor loop, means many button elements could get created, but you have only one single variable for the color attribute, thats why changing for one button, shall change colors for all.
Having said that, you'll have to devise a mechanism so that each rendered button elements through ngFor should get its own reference of color variable. Seeing your code, you should either have the color variable inside the dataArray array, or maintain a separate array of string equal in length to dataArray. Something like this..
public colorArr:string[]= [];
//initially I've populated dataArray with initial colors.
public ngOnInit(){
this.dataArray.forEach(x=>this.colorArr.push('warning'));
}
Your HTML would get modified, like this
<ion-col size="6" *ngFor="let data of dataArray; let i = index" >
<ion-card>
<ion-card-header>
<ion-button class="fav-icon2" ion-button [color]="colorArr[i]" (click)="changecolor(i)" >
<ion-icon name="heart"></ion-icon>
</ion-button>
</ion-card-header>
</ion-card>
</ion-col>
And your changeColor mehtod would get modified like this
changecolor(index) {
if(this.colorArr[index] === 'warning') {
this.colorArr[index] = 'primary'
} else {
this.colorArr[index] = 'warning'
}
}
So in essence we are maintaing colors in separate array for each single button element, without affecting original dataArray.
Another approach could be you create a separate component only for button elements, and pass its relevant data through #input decorators. In that case your this approach of single variable would work.
Thanks.
Try this using button index..
<ion-col size="6" *ngFor="let data of dataArray; index as i;" >
<ion-card>
<ion-card-header>
<ion-button
class="fav-icon2"
ion-button [color]="activeIndex==i ? 'warning' : 'primary'
(click)="setIndex(i)" >
<ion-icon name="heart"></ion-icon>
</ion-button>
</ion-card-header>
</ion-card>
</ion-col>
activeIndex;
setIndex(index) {
this.activeIndex = index:
}
Note: you can change color as per the condition..

How to hide ion-label from main select page and show it only on select modal header

Context : I have a list of courses followed by the authenticated user. I want to be able to show all the courses's title in the ion-title header, and show the details relative to the selected course in the page content.
The problem : I want to show only the current course name in ion-title without adding a label, and show the label "Courses List" only on the select modal header.I tried to remove the ion-label,but the select modal displayed without title..
This is what I want :
The header :
The select modal :
This is what I get :
When keeping ion-label
When removing ion-label
My code :
<ion-item lines="none">
<ion-label>Courses List</ion-label>
<ion-select [(ngModel)]="course.id" (ionChange)="selectcourse($event)">
<ion-select-option *ngFor="let course of courses" [value]="course.id">
{{course.title}}
</ion-select-option>
</ion-select>
</ion-item>
A quick workaround is to set display:none to the ion-label and a placeholder with Course List to achieve what you are looking for.
<ion-item lines="none">
<ion-label style="display:none">Courses List</ion-label>
<ion-select placeholder="Courses List" (ionChange)="selectcourse($event)">
<ion-select-option *ngFor="let course of courses" [value]="course.id">
{{course.title}}
</ion-select-option>
</ion-select>
</ion-item>
First Time:
When one item selected:
You can use the default properties provided by ionic.
In your ts file, declare this:
import { Component } from '#angular/core';
#Component({
selector: 'app-CoursesComponent',
templateUrl: 'CoursesComponent.html',
styleUrls: ['./CoursesComponent.scss'],
})
export class CoursesComponent {
customActionSheetOptions: any = {
header: 'Courses List',
};
}
And then, in your html file:
<ion-item>
<ion-select placeholder="Select" [interfaceOptions]="customActionSheetOptions">
<ion-select-option value="Course1">Course 1</ion-select-option>
<ion-select-option value="Course2">Course 2</ion-select-option>
<ion-select-option value="Course3">Course 3</ion-select-option>
</ion-select>
</ion-item>
I have found out if you put the ion-label inside the selector tags and make the label 'fixed' using the position property with ionic labels it will do the job.
<ion-item lines="none">
<ion-select [(ngModel)]="course.id" (ionChange)="selectcourse($event)">
<ion-label position="fixed">Courses List</ion-label>
<ion-select-option *ngFor="let course of courses" [value]="course.id">
{{course.title}}
</ion-select-option>
</ion-select>
</ion-item>

How to show full text for options of ionic select button?

I have added a ionic select button in the page. The option will show a long string, I hope to it can show full text string, but the string is truncated with dot-dot-dot as below:
My code is like:
<ion-item *ngIf="select == 'trip'">
<ion-label> Select Trip </ion-label>
<ion-select text-wrap>
<ion-option *ngFor="let subtrip of trips" value = {{subtrip.tripid}}> {{subtrip.startTime}} - {{subtrip.stopTime}} </ion-option>
</ion-select>
</ion-item>
I have tried add text-wrap in the html, but it doesn't work... Can you help?
For Ionic 4, every option inside ion-select needs to be wrapped inside ion-select-option. Trying out interface="action-sheet" will show the full text of options. The default interface is alert.
<ion-item>
<ion-label>Food</ion-label>
<ion-select interface="action-sheet" [(ngModel)]="food">
<ion-select-option [value]="Burger">BurgerBurgerBurgerBurgerBurgerBurgerBurger</ion-select-option>
<ion-select-option [value]="Sandwich">SandwichSandwichSandwichSandwichSandwichSandwich</ion-select-option>
<ion-select-option [value]="Salad">SaladSaladSaladSaladSaladSaladSalad</ion-select-option>
</ion-select>
</ion-item>
Default alert interface
action-sheet interface
So if this is your template (html):
<ion-content>
<ion-item>
<ion-label>Toppings</ion-label>
<ion-select [(ngModel)]="toppings" multiple="true">
<ion-option>BaconBaconBaconBaconBaconBaconBaconBaconBacon</ion-option>
<ion-option>Black OlivesBaconBaconBaconBaconBaconBaconBacon</ion-option>
<ion-option>Extra CheeseBaconBaconBaconBaconBaconBaconBacon</ion-option>
</ion-select>
</ion-item>
</ion-content>
And you want to ensure no-wrap behavior you can not apply text-wrap to ionic components and hope it will support this behavior out of box unfortunately.
Normally you want to go to your Chrome Dev Tools > Elements and see what CSS rules are inherited and applied to your component (ion-select in this case):
Now depending on which platform style you are using (ios or md) you need to apply changes to this class (in case of ios used like in my case):
page-tutorials {
.no-scroll .scroll-content {
overflow: hidden;
}
}
.alert-ios .alert-md .alert-checkbox-label {
white-space: normal !important;
}
Please note you need to add such class overriding outside of your page component's css (as above) to make it work.
<ion-list radio-group [(ngModel)]="radioGroup">
<ion-item>
<ion-label text-wrap>RadioButtonText</ion-label>
<ion-radio checked="false" value="value"></ion-radio>
</ion-item>
This should work fine for you

ion-infinite-scroll not working inside ion-scroll

I'm trying to implement load more functionality in the half portion of the page.
So I put that code inside the ion-scroll but somehow current implementation is not working i.g. the method is
(ionInfinite)="doInfinite($event)"
is not triggered and loader UI is not rendered. However, the same implementation is working if the content placed in ion-content instead of ion-scroll.
<ion-content padding>
<ion-scroll scrollY="true" id="accountList" class="list-box">
<ion-list >
<ion-item *ngFor="let item of [1,2,3,4,5,6,7,8,9]">
<ion-icon ios="ios-add-circle" md="ios-add-circle" item-start color="secondary"></ion-icon>
Item1
<ion-buttons item-end>
<button ion-button clear icon-only color="orange">
<ion-icon ios="md-create" md="md-create" item-end ></ion-icon>
</button>
<button ion-button clear icon-only color="danger">
<ion-icon ios="md-close" md="md-close" item-end></ion-icon>
</button>
</ion-buttons>
</ion-item>
</ion-list>
<ion-infinite-scroll (ionInfinite)="doInfinite($event)">
<ion-infinite-scroll-content
loadingSpinner="bubbles"
loadingText="Loading more data...">
</ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-scroll>
</ion-content>
Sorry for my bad english, but I resolved this problem by using below code:
<ion-scroll #scrollWeb scrollY="true" class="scroll-y">
<ion-grid>
<ion-row>
<ion-col col-4 col-sm-6 col-md-4 col-lg-4 col-xl-4 *ngFor="let item of items">
<item-card [item]="item"></item-card>
</ion-col>
</ion-row>
</ion-grid>
</ion-scroll>
And on my component:
#ViewChild('scrollWeb') scrollWeb: Scroll;
Added listener on DOM Element to discover if the scroll arrived in the end as follows:
ngAfterViewInit() {
if (this.scrollWeb) {
this.scrollWeb.addScrollEventListener((ev) => {
if ((ev.target.offsetHeight + ev.target.scrollTop) >= ev.target.scrollHeight) {
this.doInfinite(null);
}
});
}
}
In doInfinite function you can omit or show a loader as follows:
if (infiniteScroll !== null) {
infiniteScroll.complete();
}
Ionic-version: 3.9.2
I have a similar problem in the component. My solution was:
Replace <ion-scroll> with <ion-content>
Add overflow: auto; style for <ion-content>
Enjoy virtual scrolling
You need call the $event.complete() method. From the Ionic documentation page of InifniteScroll:
"The expression assigned to the infinite event is called when the user
scrolls to the specified distance. When this expression has finished
its tasks, it should call the complete() method on the infinite scroll
instance."
ion-Scroll doesn't fire scroll events right now, thus ion-infinite-scroll subscription to scroll events is not fired.
You can try to find some workarounds like firing similar event yourself. I just desided to emulate visual similarity in regular ion-content using css for now (not perfect solution).
Link to issue on Ionic Github: https://github.com/ionic-team/ionic/issues/13904
Link to issue on forum: https://forum.ionicframework.com/t/ionscroll-event-doesnt-fire-on-ion-scroll/96188/3