Well, i have a problem with design in ionic 4 with Pop Over Component...
Thanks for you time.
I do the following.
App.Module
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule,
IonicModule.forRoot(),
IonicStorageModule.forRoot(),
AppRoutingModule,
PopoverLogoPageModule,
],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
TS
import { PopoverLogoPage } from '../PopOvers/popover-logo/popover-logo.page';
import { PopoverController } from '#ionic/angular';
constructor(public popoverController: PopoverController)
{}
async presentPopover(ev: any) {
const popoverElement = await this.popoverController.create({
component: PopoverLogoPage,
event: ev,
translucent: true
});
return await popoverElement.present();
}
Html
<ion-toolbar>
<ion-title>
Bienvenido
</ion-title>
<ion-buttons slot="end">
<ion-button (click)="presentPopover()">
<ion-icon size="large" name="contact"></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
I want my popover to be show under my button , but this is presented in the middle.
What all you need to do is just pass $event in your presentPopover method like -
<ion-button (click)="presentPopover($event)">
<ion-icon size="large" name="contact"></ion-icon>
</ion-button>
I hope it will solve your problem...
Related
I am new to ionic4. Before that i try ionic3 in that menu is working proper.
But now i migrate to ionic4.
I just create new project with inbuild menu option. It run successfully in web browser But When I run on my Android mobile device , Menu open but after clicking it did not close.
I use:
Ionic version:5.2.3
Node version:v10.16.3
Cordova version:9.0.0
First attempt:
my app.component.html file:
<ion-app>
<ion-menu type="overlay"side="start" contentId="menu-content">
<ion-header>
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-menu-toggle auto-hide="false" *ngFor="let p of appPages">
<ion-item [routerDirection]="'root'" [routerLink]="[p.url]" *ngFor="let p of appPages" (click)="togglemenu()">
<ion-icon slot="start" [name]="p.icon"></ion-icon>
<ion-label>
{{p.title}}
</ion-label>
</ion-item>
</ion-menu-toggle>
</ion-list>
</ion-content>
</ion-menu>
<ion-router-outlet main id="menu-content"></ion-router-outlet>
</ion-app>
my app.component.ts file:
import { Component } from '#angular/core';
import { Platform,MenuController } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent {
public appPages = [
{
title: 'Home',
url: '/home',
icon: 'home'
},
{
title: 'List',
url: '/list',
icon: 'list'
}
];
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
public menu: MenuController,
private statusBar: StatusBar
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
togglemenu(){
this.menu.close();
console.log("clikc");
}
}
Second attempt:
<ion-app>
<ion-split-pane contentId="menu-content" side="start">
<ion-menu type="overlay">
<ion-header>
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-menu-toggle auto-hide="false" *ngFor="let p of appPages">
<ion-item [routerDirection]="'root'" [routerLink]="[p.url]" *ngFor="let p of appPages">
<ion-icon slot="start" [name]="p.icon"></ion-icon>
<ion-label>
{{p.title}}
</ion-label>
</ion-item>
</ion-menu-toggle>
</ion-list>
</ion-content>
</ion-menu>
<ion-router-outlet main></ion-router-outlet>
</ion-split-pane>
</ion-app>
Looking at the ion-menu-toggle documentation it states:
"In case it's desired to keep ion-menu-toggle always visible, the autoHide property can be set to false."
https://ionicframework.com/docs/api/menu-toggle
It looks like you have this set to false. You can remove auto-hide="false" because it defaults to true.
Am new to angular and am starting off with a simple login form. However the form values are always showing up as empty - even if values have been entered before form submission.
I have created a login component which is imported in app module. The page comes up, but the submission does not carry any values. I have removed all Angular validation checks for debugging but the values received in my onsubmit function are still empty.
I have pasted the component code.Below.
login.component.html
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<div class="form-group" >
<div class="form-group">
<input type="email" class="form-control" formcontrolname="username"
placeholder="Email Id" required autofocus/><br/>
</div>
<div class="form-group">
<input type="password" class="form-control" formcontrolname="password" placeholder="Password" required/><br/>
</div>
<div class="form-group">
<button>Login</button>
<a href="/public/register" class="btn" >Register</a>
</div>
app.component
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
#NgModule({
imports: [ BrowserModule, AppRoutingModule, FormsModule,
ReactiveFormsModule ],
declarations: [ AppComponent, HelloComponent, LoginComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
login.component.ts
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
loginForm: FormGroup;
submitted = false;
returnUrl = '';
constructor(
private formBuilder: FormBuilder,
private router: Router
) {
}
ngOnInit() {
this.loginForm = this.formBuilder.group ({
username: ['', Validators.required],
password: ['', Validators.required]
});
}
get user() { return this.loginForm.controls; }
onSubmit() {
// stop if form is invalid
/* if (this.loginForm.invalid) {
console.log("Returning");
return;
} */
this.submitted = true;
console.log('login values:');
console.log(this.user.username.value, this.user.password.value);
this.returnUrl='/home';
// this.router.navigate([this.returnUrl]);
}
}
You can try this:
get user() { return this.loginForm.value; }
Knew it would be something super silly and trivial - turned out to be a case sensitivity problem issue on my end. Changed 'formcontrolname' to 'formControlName' and it started working! Duh!
I am using Ionic 4, I want to do different menu content in different page. I have add menuId inside my code, but I only get the second page menu. My first page menu is missing.
I think you should build 1 menu and then just populate its page list depending on the page being visited.
So your code would look something like this:
import { Component, OnInit } from '#angular/core';
import { Router, RouterEvent } from '#angular/router';
#Component({
selector: 'app-menu',
templateUrl: './menu.page.html',
styleUrls: ['./menu.page.scss'],
})
export class MenuPage implements OnInit {
selectedPath = '';
pages = getPages();
constructor(private router: Router) {
this.router.events.subscribe((event: RouterEvent) => {
if (event && event.url) {
this.selectedPath = event.url;
}
});
}
getPages() : any[] {
if (this.router.url === '/page1') {
return [
{
title: 'First Page with Tabs',
url: '/menu/first'
},
{
title: 'Second Page blank',
url: '/menu/second'
}
];
}
if (this.router.url === '/page2') {
return [
{
title: 'First Page with Tabs',
url: '/menu/first'
},
{
title: 'Second Page blank',
url: '/menu/second'
}
];
}
}
ngOnInit() {
}
}
And then display it like this:
<ion-split-pane>
<ion-menu contentId="content">
<ion-header>
<ion-toolbar color="primary">
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-menu-toggle auto-hide="false" *ngFor="let p of pages">
<ion-item [routerLink]="p.url" routerDirection="root" [class.active-item]="selectedPath.startsWith(p.url)">
<ion-label>
{{ p.title }}
</ion-label>
</ion-item>
</ion-menu-toggle>
<ion-item tappable routerLink="/login" routerDirection="root">
<ion-icon name="log-out" slot="start"></ion-icon>
Logout
</ion-item>
</ion-list>
</ion-content>
</ion-menu>
<ion-router-outlet id="content" main></ion-router-outlet>
</ion-split-pane>
Full tutorial about setting up a menu like this is available here:
How to Combine Ionic 4 Tabs and Side Menu Navigation [v4] - Ionic AcademyIonic Academy
Although the code I used as an example above for get getPages() is the bit you would write yourself.
I tried installing npm i -S #ionic-super-tabs/angular , which doesn’t work in Ionic 4. Please let me know if there any way to do this
Yes, there is a way to achieve this.
page.ts
import { Component, ViewChild } from '#angular/core';
import { IonSlides } from '#ionic/angular';
#Component({
selector: 'app-tab3',
templateUrl: 'tab3.page.html',
styleUrls: ['tab3.page.scss']
})
export class Tab3Page {
#ViewChild('slider') slider: IonSlides;
page = "0";
selectedTab(index) {
this.slider.slideTo(index);
}
async moveButton() {
let index = await this.slider.getActiveIndex();
this.page = index.toString();
// console.log("0")
}
segmentChanged(ev: any) {
// console.log('Segment changed', ev);
}
}
page.html
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-menu-button></ion-menu-button>
</ion-buttons>
<ion-title>Notifications</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-segment (ionChange)="segmentChanged($event)" [(ngModel)]="page">
<ion-segment-button value="0" (click)="selectedTab(0)">
<ion-label>All</ion-label>
</ion-segment-button>
<ion-segment-button value="1" (click)="selectedTab(1)">
<ion-label>Mentions</ion-label>
</ion-segment-button>
</ion-segment>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-slides #slider (ionSlideWillChange)="moveButton()">
<ion-slide>
<ion-label>All</ion-label>
</ion-slide>
<ion-slide>
<ion-label>Mentions</ion-label>
</ion-slide>
</ion-slides>
</ion-content>
Segment work as swipeable tabs, Hope it help you :)
environment
dotnet core 2.1.0
"bootstrap-vue": "^2.0.0-rc.11",
"nuxt": "^1.4.1",
"vue": "^2.5.16",
"vue-axios": "^2.1.1",
"vue-router": "^3.0.1",
"vue-server-renderer": "^2.1.8",
"vue-template-compiler": "^2.5.16",
"vue-toasted": "^1.1.24",
"vuex": "^3.0.1",
"vuex-router-sync": "^4.0.1"
I can't figure out how to get a simple bootstrap-vue modal working. The modal-sample component renders, with the button visible, but when the button is clicked nothing happens (modal doesn't "show").
However, in the vue dev tools, I can see the show event was emitted. Also, if I copy and paste the code in the bootstrap-vue playground it works, so it has to be my set up. Not sure if it matters but it's also running in a dotnet core environment.
webpack.config
const VueLoaderPlugin = require('vue-loader/lib/plugin');
...
resolve: {
extensions: ['.js', '.vue'],
alias: {
'vue$': 'vue/dist/vue',
...
}
...
,
module: {
rules: [
{ test: /\.vue$/, include: /ClientApp/, use: 'vue-loader' },
{ test: /\.js$/,
include: [/ClientApp/,
require.resolve("bootstrap-vue")],
use: 'babel-loader' },
{ test: /\.css$/,
use: isDevBuild ? ['vue-style-loader', 'style-loader', 'css-loader'] : ExtractTextPlugin.extract({ use: 'css-loader' }) },
{ test: /\.(png|jpg|jpeg|gif|svg)$/,
use: 'url-loader?limit=25000' }
]
},
plugins: [
new VueLoaderPlugin(),
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
})
].concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: '[file].map', // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
})
] : [
// Plugins that apply in production builds only
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin({use: 'site.css', fallback: 'vue-style-loader'})
])
}];
app-root.vue
import Swapshift from './modal-sample'
Vue.component('modal-sample', Swapshift);
modal-sample.vue
<template>
<div style="margin-top: 20px; padding: 10px;">
<b-button variant="primary" v-b-modal.newSwapShiftModal>New Swap Shift</b-button>
<b-modal id="newSwapShiftModal" title="New Swap Edit" >
<div class="d-block text-center">
<h3>Hello From My Modal!</h3>
</div>
</b-modal>
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex'
import bModal from 'bootstrap-vue/es/components/modal/modal'
import bModalDirective from 'bootstrap-vue/es/directives/modal/modal'
export default {
components: { bModal },
directives: { bModalDirective },
data() {
return {
swapshift: {
id: 1,
status: {
id: 1,
description: 'Requested'
}
}
}
},
computed: {
},
methods: {
},
async created() {
console.log('...in modal-sample1');
}
}
</script>
HTML attributes all get translated to lowercase. This includes parts of the directive attribute on your button. So what is happening is that when the v-b-modal directive receives the modifiers (ie. .newSwapShiftModal), it receives newswapshiftsodal from the browser (all attributes are always lowercased by the browser).
So you need to set the id on the modal to also be lowercase (as attribute values inside quotes retain their case).
<template>
<div style="margin-top: 20px; padding: 10px;">
<b-button variant="primary" v-b-modal.new-swap-shift-modal>New Swap Shift</b-button>
<b-modal id="new-swap-shift-modal" title="New Swap Edit" >
<div class="d-block text-center">
<h3>Hello From My Modal!</h3>
</div>
</b-modal>
</div>
</template>
Example fiddle showing case sensitivity issues with IDs: https://jsfiddle.net/4cnk28yw/
EDIT: also register the directive with the correct name (as mentioned by #ittus):
import { mapActions, mapState } from 'vuex'
import { BModal, VBModal } from 'bootstrap-vue'
export default {
components: { BModal },
directives: { 'b-modal': VBModal },
// ...
}
Directive name should be b-modal. You should try changing:
directives: {
'b-modal': bModalDirective
}