Ionic4 Ion-select style property not working - ionic-framework

I would like to apply css property for my alert Controller but not working.
home.html
<ion-select [(ngModel)]="accountSystem" placeholder="Match Accounting Standard" okText="Done" cancelText="Cancel" class="select-account">
<ion-select-option value="PRC Gaap">PRC Gaap</ion-select-option>
<ion-select-option value="IFRS">IFRS</ion-select-option>
<ion-select-option value="US Gaap">US Gaap</ion-select-option>
</ion-select>
global.scss
.select-account{
.alert-wrapper{
.alert-button-inner{
color:rgb(239,52,52);
}
.alert-button{
color:rgb(52,223,57);
}
}}

this is my working solution in my project.
home.ts
const alert = await this.alertCtrl.create({
header: "Alert",
mode: "ios",
cssClass: "codealert",
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'alertbutton',
handler: () => {
console.log('Confirm Cancel');
}
}, {
text: 'Ok',
cssClass: 'alertbutton',
handler: () => {
console.log('Confirm Ok');
}
}
]
});
await alert.present();
}
global.scss
.codealert {
--background: white;
}
.alertbutton {
color: #600001 !important;
font-weight: bold;
}

Related

How to Manage Session in side menu in Ionic 4?

Ionic app with a side menu
Here my app concept is Blog App
in this I need to log-in, profile, etc
Ionic app with a side menu
if user want to like or comment any blog post he must log-in first
so I want to manage session if the already log-in user so hide log-in ion-item from side menu else logout ion-item vise-Versa
Here is code
home.html
<ion-app>
<ion-split-pane contentId="main-content" >
<ion-menu contentId="main-content" >
<ion-header>
<ion-toolbar color="primary">
<ion-title>Lady Help Lady</ion-title>
</ion-toolbar>
</ion-header>
<ion-content color="primary">
<ion-list >
<ion-menu-toggle auto-hide="false" *ngFor="let p of appPages">
<ion-item color="primary" [routerDirection]="'root'" [routerLink]="[p.url]">
<ion-icon slot="start" [name]="p.icon" color="light"></ion-icon>
<ion-label color="light">
{{p.title}}
</ion-label>
</ion-item>
</ion-menu-toggle>
<ion-menu-toggle auto-hide="false" >
<ion-item color="primary" *ngIf="showBtnLogin">
<ion-icon slot="start" name="log-in" color="light"></ion-icon>
<ion-label color="light" (click)="login()">
Login
</ion-label>
</ion-item>
<ion-item color="primary" *ngIf="!showBtnLogin">
<ion-icon slot="start" name="log-out" color="light"></ion-icon>
<ion-label color="light" (click)="logout()" > Log Out</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>
home.page.ts
import { Component, OnInit } from '#angular/core';
import { Router} from '#angular/router';
import { MenuController } from '#ionic/angular';
import { AuthService } from '../services/auth.service';
import { StorageService } from '../services/storage.service';
#Component({
selector: 'app-home',
templateUrl: './home.page.html',
styleUrls: ['./home.page.scss'],
})
export class HomePage implements OnInit {
public appPages = [
{
title: 'Blog',
url: '/home/blog',
icon: 'home'
},
{
title: 'Profile',
url: '/home/profile',
icon: 'cog'
},
{
title: 'Change Password',
url: '/home/change-password',
icon: 'lock'
},
{
title: 'About Us',
url: '/home/about-us',
icon: 'cog'
},
{
title: 'Privacy Policy',
url: '/home/privacy-policy',
icon: 'settings'
}
,
{
title: 'Terms & Conditions',
url: '/home/terms-conditions',
icon: 'paper'
},
{
title: 'Enable Location',
url: '/home/enable-location',
icon: 'pin'
}
,
{
title: 'Donation',
url: '/home/donation',
icon: 'card'
}
];
public authUser: any;
showBtnLogin = true;
// showBtnLogout: boolean = true;
currentUser: any;
constructor(private router: Router,
private authService: AuthService,
private menu: MenuController,
public storageService: StorageService) { }
ngOnInit() {
this.authService.userData$.subscribe((res: any) => {
this.authUser = res;
if (res === null) {
console.log(res);
this.showBtnLogin = false;
} else {
this.showBtnLogin = true;
}
});
}
logout() {
this.authService.logout();
}
login() {
this.router.navigate(['/home/login']);
}
}
login.page.ts
validateInputs() {
const mobile = this.postData.mobile.trim();
const password = this.postData.password.trim();
return (
this.postData.mobile &&
this.postData.password &&
mobile.length > 0 &&
password.length > 0
);
}
formLogin() {
if (this.validateInputs()) {
this.loader.loadingPresent();
console.log(this.postData);
this.authService.login(this.postData).subscribe(
(res: any) => {
if (res.status === true) {
this.loader.loadingDismiss();
// Storing the User data.
this.storageService.store(AuthConstants.AUTH, res.logindata);
this.router.navigate(['/home/blog']);
} else {
this.loader.loadingDismiss();
this.toastService.presentToast(res.error);
}
},
(error: any) => {
this.loader.loadingDismiss();
this.toastService.presentToast('Network Issue.');
}
);
} else {
this.loader.loadingDismiss();
this.toastService.presentToast('Please enter mobile or password.');
}
}
StorageService.ts
import { Injectable } from '#angular/core';
import { Plugins } from '#capacitor/core';
const { Storage } = Plugins;
#Injectable({
providedIn: 'root'
})
export class StorageService {
constructor() { }
// Store the value
async store(storageKey: string, value: any) {
const encryptedValue = btoa(escape(JSON.stringify(value)));
await Storage.set({
key: storageKey,
value: encryptedValue
});
}
// Get the value
async get(storageKey: string) {
const ret = await Storage.get({ key: storageKey });
return JSON.parse(unescape(atob(ret.value)));
}
async removeStorageItem(storageKey: string) {
await Storage.remove({ key: storageKey });
}
// Clear storage
async clear() {
await Storage.clear();
}
}
You can also do that like this
in your html
<ion-menu-toggle auto-hide="false" >
<ion-item color="primary" *ngIf="showBtnLogin">
<ion-icon slot="start" name="log-in" color="light"></ion-icon>
<ion-label color="light" (click)="login()">
Login
</ion-label>
</ion-item>
<ion-item color="primary" *ngIf="!showBtnLogin">
<ion-icon slot="start" name="log-out" color="light"></ion-icon>
<ion-label color="light" (click)="logout()" > Log Out</ion-label>
</ion-item>
</ion-menu-toggle>
in your .ts
showBtnLogin: boolean = true;
currentUser: any;
ngOnInit() {
this.authService.userData$.subscribe((res: any) => {
this.authUser = res;
// this.postData.user_id = res.id;
console.log(this.authUser.id);
this.currentUser = this.authUser;
if (res === null) {
this.showBtnLogin = true;
} else {
this.showBtnLogin = false;
}
});
}
logout() {
this.authService.logout();
}
login() {
this.router.navigate(['/home/login']);
}
Change some code in your .ts file here it is
showBtnLogin = true;
public appPages = [
{
title: 'Blog',
url: '/home/blog',
icon: 'home'
},
{
title: 'Profile',
url: '/home/profile',
icon: 'cog',
status: true
},
{
title: 'Change Password',
url: '/home/change-password',
icon: 'lock',
status: true
},
{
title: 'About Us',
url: '/home/about-us',
icon: 'cog',
status: true
},
{
title: 'Privacy Policy',
url: '/home/privacy-policy',
icon: 'settings',
status: true
}
,
{
title: 'Terms & Conditions',
url: '/home/terms-conditions',
icon: 'paper',
status: true
},
{
title: 'Enable Location',
url: '/home/enable-location',
icon: 'pin',
status: true
}
,
{
title: 'Donation',
url: '/home/donation',
icon: 'card',
status: true
}
];
In your ngOnInit
ngOnInit() {
this.authService.userData$.subscribe((res: any) => {
this.authUser = res;
if (res === null) {
console.log(res);
this.showBtnLogin = false;
for (let i = 0; i < this.appPages.length; i++) {
if (this.appPages[i].title == 'Profile') {
this.appPages[i].status = false;
}
if (this.appPages[i].title == 'Change Password') {
this.appPages[i].status = false;
}
}
} else {
this.showBtnLogin = true;
}
});
}
if your profile and change password index not change then you can directly change status via index without using for loop
and finally in your logout
logout() {
this.authService.logout();
for (let i = 0; i < this.appPages.length; i++) {
if (this.appPages[i].title == 'Profile') {
this.appPages[i].status = false;
}
if (this.appPages[i].title == 'Change Password') {
this.appPages[i].status = false;
}
}
}
In your .html file
<ion-list>
<ion-menu-toggle auto-hide="false" *ngFor="let p of appPages">
<ion-item [routerDirection]="'root'" [routerLink]="[p.url]" *ngIf="p.status">
<ion-icon slot="start" [name]="p.icon"></ion-icon>
<ion-label>
{{p.title}}
</ion-label>
</ion-item>
</ion-menu-toggle>
<ion-menu-toggle auto-hide="false">
<ion-item color="primary" *ngIf="showBtnLogin">
<ion-icon slot="start" name="log-in" color="light"></ion-icon>
<ion-label color="light" (click)="login()">
Login
</ion-label>
</ion-item>
<ion-item color="primary" *ngIf="!showBtnLogin">
<ion-icon slot="start" name="log-out" color="light"></ion-icon>
<ion-label color="light" (click)="logout()"> Log Out</ion-label>
</ion-item>
</ion-menu-toggle>
</ion-list>

Ionic 4 Manual Override of ion-select

Hi I need 'select from list' functionality on a form but with the ability to enter a value manually if needed.  I've been trying ion-select but there doesn't seem to be a way to have a manual override.  Is there a way to do this?
Thanks
For example
<ion-header>
<ion-toolbar>
<ion-title>kitlist testy</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<form [formGroup]="myForm">
<ion-list>
<ion-item>
<ion-label stacked>Lens</ion-label>
<ion-select placeholder="Select One">
<ion-select-option value="f">Female</ion-select-option>
<ion-select-option value="m">Male</ion-select-option>
</ion-select>
<ion-input type="text" formControlName='lens'></ion-input>
</ion-item>
</ion-list>
</form>
</ion-content>
will give
I want the user to be able to add their own value - which I will then store.
Thanks
Following Sergey's very helpful answer I have tried getting this to work and I'm stuck at inputAlert.onDidDismiss which gives me
Expected 0 arguments, but got 1
Here's the code which I have adjusted for my use case:-
import { Component, OnInit } from "#angular/core";
import { FormBuilder, FormGroup } from "#angular/forms";
import { AlertController } from "#ionic/angular";
#Component({
selector: "app-kitlist",
templateUrl: "./kitlist.page.html",
styleUrls: ["./kitlist.page.scss"]
})
export class KitlistPage implements OnInit {
kitlist = ["lens1", "lens2", "Custom"];
currentLens: any;
myForm: FormGroup;
constructor(
private fb: FormBuilder,
private alertController: AlertController
) {
this.myForm = new FormGroup({});
}
ngOnInit() {
this.myForm = this.fb.group({
lens: ""
});
this.myForm.valueChanges.subscribe(console.log);
}
submitForm() {
console.log("submit");
}
selectChanged(selectedLens) {
if (selectedLens === "Custom") {
this.inputCustomLensValue();
} else {
this.currentLens = selectedLens;
}
}
async inputCustomLensValue() {
const inputAlert = await this.alertController.create({
header: "Enter your custom lens:",
inputs: [{ type: "text", placeholder: "type in" }],
buttons: [{ text: "Cancel" }, { text: "Ok" }]
});
inputAlert.onDidDismiss(data => {
let customLensName: string = data.data.values[0];
if (customLensName) {
let indexFound = this.kitlist.findIndex(
lens => lens === customLensName
);
if (indexFound === -1) {
this.kitlist.push(customLensName);
this.currentLens = customLensName;
} else {
this.currentLens = this.kit[indexFound];
}
}
});
await inputAlert.present();
}
}
Since ion-select under the hood uses alert controller, I would leverage it directly and I would have a couple of alerts working together here:
In your template:
<ion-item>
<ion-label>Hair Color</ion-label>
<ion-button slot="end" (click)="selectColors()">{{ currentOptionLabel }}
<ion-icon slot="end" name="arrow-dropdown"></ion-icon>
</ion-button>
</ion-item>
You can style ion-button according to your needs.
Now in your ts file we can import Alert Controller and have 2 of them: one for selecting premade options and one that we will create input type of alert in case our user wants to add custom value.
I am not using button's handler's methods here to make sure Angular can pick up all the data changes:
import { Component } from '#angular/core';
import { AlertController } from '#ionic/angular';
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.css'],
})
export class HomePage {
public colorOptions: Array<{type: string, label: string, value: string}>
public currentColorOptionIndex: number;
public currentOptionLabel: string;
constructor(public alertController: AlertController) {
this.currentColorOptionIndex = 1;
this.colorOptions = [
{
type: "radio",
label: "Custom",
value: "Custom"
},
{
type: "radio",
label: "Brown",
value: "Brown",
},
{
type: "radio",
label: "Dark",
value: "Dark",
}
]
this.currentOptionLabel = this.colorOptions[this.currentColorOptionIndex].label;
}
async selectColors() {
const radioAlert = await this.alertController.create({
header: 'Prompt!',
inputs: this.colorOptions as any,
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary'
}, {
text: 'Ok'
}
]
});
await radioAlert.present();
radioAlert.onDidDismiss().then((data) => {
let selectedValue = data.data.values;
if (selectedValue === 'Custom') {
this.inputCustomColorValue()
};
this.currentColorOptionIndex = this.colorOptions.findIndex(option => option.value == selectedValue)
this.currentOptionLabel = this.colorOptions[this.currentColorOptionIndex].label;
})
}
async inputCustomColorValue() {
const inputAlert = await this.alertController.create({
header: 'Enter your custom color:',
inputs: [
{
type: 'text',
placeholder: 'type in'
}
],
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary'
}, {
text: 'Ok',
}
]
});
await inputAlert.present();
inputAlert.onDidDismiss().then((data) => {
let customValue = data.data.values[0];
let indexFound = this.colorOptions.findIndex(option => option.value == customValue)
if (indexFound !== -1) {
this.currentColorOptionIndex = indexFound
} else {
this.colorOptions.push(
{
type: 'radio',
label: customValue,
value: customValue,
}
)
this.currentColorOptionIndex = this.colorOptions.length - 1;
};
this.currentOptionLabel = this.colorOptions[this.currentColorOptionIndex].label;
})
}
}
Updated: added the fact that now in latest Ionic versions (compared to Stackblitz that uses old 4 beta) onDidDismiss hook returns Promise and requires onDidDismiss.then((data) => {}) syntax vs onDidDismiss((data => {})

Customization in Ionic Bottom Sheet

I am trying to add list in bottom sheet but ionic gave us an array so we can add class there and style it.
What i am trying to ask is how we can make a list or totally our own html code and pass it to bottom sheet function that will just display?
async presentActionSheet() {
const actionSheet = await this.actionSheetController.create({
header: 'Albums',
buttons: [{
text: 'Delete',
role: 'destructive',
icon: 'trash',
handler: () => {
console.log('Delete clicked');
}
}, {
text: 'Share',
icon: 'share',
handler: () => {
console.log('Share clicked');
}
}, {
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
handler: () => {
console.log('Play clicked');
}
}, {
text: 'Favorite',
icon: 'heart',
handler: () => {
console.log('Favorite clicked');
}
}, {
text: 'Cancel',
icon: 'close',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
}]
});
await actionSheet.present();
}
It is by default action sheet, what i want is to make it in DOM. I have found the similar question here with no answer Similar Question URL Please see what i need...!
What i need
Try with Modal Component
home.page.html
<ion-button (click)="OpenModel()">
Open Modal (Bottom)
<ion-icon mode="ios" name="arrow-forward"></ion-icon>
</ion-button>
home.page.ts
import { ModalController } from '#ionic/angular';
import { ModalpagePage } from '../modalpage/modalpage.page';
constructor(private modalCtrl: ModalController) {}
async OpenModel(){
const presentModel = await this.modalCtrl.create({
component: ModalpagePage,
componentProps: {
title: 'Billing Address',
type:'billing',
},
showBackdrop: true,
mode: "ios",
cssClass: 'change-address-shipping-modal'
});
presentModel.onWillDismiss().then((data)=>{
console.log(data);
//custom code
});
return await presentModel.present();
}
modalpage.page.html
<ion-header>
<ion-toolbar text-center>
<ion-title>
Modal title
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<div>
HTML CODE HERE
</div>
</ion-content>
Declare in app.module.ts
declarations: [AppComponent, ModalpagePage],
entryComponents: [ModalpagePage],
Global.scss
.change-address-shipping-modal{
--height:60%;
align-items: flex-end;
}
ScreenShot
Demo
Currently action sheet does not allow you to add html code in it. This feature is however requested you can see here https://github.com/ionic-team/ionic/issues/16718
Try <ion-card>
<ion-header> </ion-header>
<ion-content> </ion-content>
<ion-card> </ion-card>
<ion-footer> </ion-footer>
you can use *ngIf to control ion-card
example:
in page.ts
showCard:Boolean = true;
constructor(){}
ngOnInit() {}
in page.html
<ion-card *ngIf="showCard"> </ion-card>
https://ionicframework.com/docs/api/card

How to add text-area and select to the Alert in Ionic

I am working on Ionic App and I want to show I am showing the input fields in the alert but the problem is that, I am not able to show the textarea and the select box in the alert controller.
This is my popupdetails.ts file:
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, LoadingController, AlertController } from 'ionic-angular';
#IonicPage()
#Component({
selector: 'page-checkout',
templateUrl: 'checkout.html',
})
export class CheckoutPage {
constructor(public navCtrl: NavController, public navParams: NavParams,
public loadingCtrl: LoadingController, private alertCtrl: AlertController) {
}
presentPrompt() {
let alert = this.alertCtrl.create({
title: 'Submit Shipping Details',
inputs: [
{
name: 'name',
placeholder: 'Name'
},
{
name: 'mobilenumber',
placeholder: 'Mobile Number',
type: 'number'
},
{
name: 'pincode',
placeholder: 'Pincode',
type: 'number'
},
{
name: 'state',
placeholder: 'State',
},
{
name: 'city',
placeholder: 'City',
},
{
name: 'address',
placeholder: 'Address',
},
],
buttons: [
{
text: 'Cancel',
role: 'cancel',
handler: data => {
console.log('Cancel clicked');
}
},
{
text: 'Submit',
handler: data => {
console.log('Submit clicked');
}
}
]
});
alert.present();
}
}
In this, I have used the alert controller to the input fields but the problem is that, I am not able to show the textarea and the select box in the alert controller.
This is my output currently coming.
I want this type of output with textarea and the select box.
Any help is much appreciated.
https://stackblitz.com/edit/ionic-x1os3c please check this link may hope it will help you
<ion-content padding style="background:white">
<ion-list no-lines>
<form>
<p style="font-weight:bold">Name</p>
<ion-item>
<ion-label hidden></ion-label>
<ion-input style="border:1px solid black" type='text'></ion-input>
</ion-item>
<p style="font-weight:bold">Mobile</p>
<ion-item>
<ion-label hidden></ion-label>
<ion-input style="border:1px solid black" type='tel'></ion-input>
</ion-item>
<p style="font-weight:bold">Country</p>
<ion-item>
<ion-label hidden></ion-label>
<ion-input style="border:1px solid black" readonly="true" type='text'></ion-input>
</ion-item>
</form>
<ion-grid>
<ion-row>
<ion-col>
<button color="secondary" ion-button float-right>Add</button>
<button color="light" ion-button float-right>Close</button>
</ion-col>
</ion-row>
</ion-grid>
</ion-list>
</ion-content>

Ionic V4: ion-modal just like ion-alert

The following ion-alert would be exactly what we need if the input was replaced with a textarea; however, ion-alert doesn't support ion-textarea.
How can the exact same look and feel be implemented with an ion-modal?
We are using Ionic without Angular (Ionic core).
ion-alert code
const alert = await alertController.create({
header: 'Would you be willing to leave feedback?',
inputs: [
{
placeholder: 'enter text'
}],
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: _ => {
alert.dismiss();
console.log('cancel');
}
}, {
text: 'Submit',
handler: _ => {
alert.dismiss();
console.log('submit');
}
}
]
});
alert.present();
attempted ion-modal code
const modalController = $('ion-modal-controller')[0];
await modalController.componentOnReady();
const modalElement = await modalController.create({
showBackdrop: true,
component:
$(`<div>
<h2>Would you be willing to provide feedback?</h2>
<div>
<ion-button>Cancel</ion-button>
<ion-button>Submit</ion-button>
</div>
</div>`)[0]
});
await modalElement.present();
In the page where you call the modal:
async book() {
const modal = await this.modalController.create({
component: BookModal,
componentProps: { value: 123 },
showBackdrop: true,
backdropDismiss: true,
cssClass: ['booking-modal']
});
return await modal.present();
}
The key point is the cssClass. Then in theme/variable.scss, add the class at the end of the file like below:
.booking-modal {
--height: 50% !important;
}
** Note: this might not be the correct way to do it, but it works for me at this stage. Looking for a better solution.