Ionic 4 navigate to another page inside modal - ionic4

I have a modal and everytime when I have to navigate to other pages I have to close the modal and then go to that page. But I want to navigate to a particular page without dismissing the modal. Means opening page inside modal without really dismissing it and passing back data from that page to modal.
Is it possible to do it?
Thank you in advance
My code :
.ts to create modal
async address_modal(){
// console.log("clicked")
console.log(this.user_id)
const modal = await this.modalController.create({
component: AddressModalPage,
cssClass : 'address-modal',
componentProps : {
user_id : this.user_id
}
});
return await modal.present();
}
html to open modal from button
<ion-button(click)="address_modal()"> </ion-button>
modal.html // open another page
<ion-button routerLink="menu/items/address/add-address" style="text-transform:none" color= "primary" fill ="clear" (click) = "add_address()" >
<ion-icon name="add" ></ion-icon> Add new address
</ion-button>

I think the problem here is the routerLink, but i'm not really sure about this.
When i want to navigate from a modal to another page i use this.
export class test implements OnInit{
constructor(private router: Router) { }
moveNext(){
this.router.navigate([page]);
}
}
You just need to import this: import { Router } from '#angular/router';. And then put it on a button like this:
<ion-button expand="block" (click)="moveNext()">Go to next page </ion-button>

Related

Auto focus on input field in Ionic Angular App, while open search popup

I was getting an issue regarding auto focus in Ionic 4 and Angular 8 App
While I was opening the search modal in app, I wanted to auto focus on search box
For that I found the solution
I have added reference element on Input field
Ionic Code
<ion-input placeholder="Search for Products" #product_id></ion-input>
Search Modal Component Code
import { IonInput } from '#ionic/angular';
export class SearchModalComponent implements OnInit {
#ViewChild('product_id', {static:true}) product_id:IonInput;
ngAfterViewInit() {
setTimeout(() => {
this.product_id.setFocus();
},500);
}
}

How can I get CKEditor 5 "Link" dialog box to pin to custom DOM element instead of 'document.body'

I'm building a Vue.js web application. I'm using CKEditor in a form that is placed inside a modal window. By design, the user's focus is "trapped" in the modal. In CKEditor, when user clicks the "Link" icon in toolbar, the editor opens a dialog box and attaches the new DOM element to 'document.body'. With respect to the DOM, the "Link" dialog is now outside of trapped focus. The user cannot click or tab his way to the "Link" dialog input.
I dug into the ckeditor5-ui source and found relevant code in balloonpanelview.js. I've unsuccessfully tried to configure CKEditor based on https://ckeditor.com/docs/ckeditor5/latest/api/module_utils_dom_position-Options.html
In my Vue.js component, I have:
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
...
data: () => ({
editor: ClassicEditor,
editorConfig: {
toolbar: ['bold', 'italic', 'bulletedList', 'numberedList', 'link'],
},
...
})
...
I want the CKEditor "Link" dialog DOM element to be attached to a DOM element id that I specify.
In Vuetify dialog component is required to disable retain-focus
<v-dialog :retain-focus="false" />
There may be much time since you opened the issue. However... This issue was happening to me too. This is happening because Bootstrap modal trap the focus in the active modal. If you're using bootstrap-vue, do this.
In your <b-modal> add the prop no-enforce-focus.
no-enforce-focus is reactive. To properly apply this workaround you can use this prop with a variable, that detects when your CKeditor have focus. If have focus, disable the enforce focus. If doesn't have, restore it. You can apply it by the following way:
<template>
<b-modal
...
:no-enforce-focus="editorFocus">
<ckeditor
...
#focus="toggleEditorFocus(true)"
#blur="toggleEditorFocus(false)"
/>
</b-modal>
</template>
<script>
export default {
...
data () {
return {
editorFocus: false
}
},
methods: {
toggleEditorFocus (val = !this.editorFocus) {
setTimeout(() => {
this.editorFocus = val
}, 10)
}
}
}
</script>
I know the setTimeout is a tricky method, but at least is working now for me.

Global header - use back button [duplicate]

In Ionic 1, we have the ability to define an <ion-nav-bar> above an <ion-nav-view>, which serves as a generic nav bar for the entire app and we could turn it off on a per-view basis (using ionNavView's hideNavBar=true|false.
It appears in Ionic 2 we have to insert an <ion-nav-bar> per page - and cannot have a global nav bar for the entire app. Is that correct, or am I missing a trick?
If so - it seems like a lot of duplicated code?
Also, it appears you do not have the ability for the NavBar to build its own back button, and you have to write the own mark-up for the back button yourself (per page) which, again, seems like a lot of code duplicate.
UPDATE:
Just like #mhartington says:
There is no way to create a global ion-navbar, as this is done on
purpose. The point of having a navbar defined for each component is so
that we can properly animate the titles, navbar background color (if
you change them) and animate other properties needed.
And about creating a custom directive to avoid duplicating ion-navbar html code:
That will still creat errors with how angular2 content projection
works. We have several issues that have been open when people try this
and the best answer is to not do it.
NOT recommended solution:
In order to avoid duplicating so much code, you can create your own custom component for the navbar.
Create a navbar.html with this code:
<ion-navbar *navbar>
<ion-title>MyApp</ion-title>
<button menuToggle="right" end>
<ion-icon name="menu"></ion-icon>
</button>
<ion-buttons *ngIf="!hideCreateButton" end>
<button (click)="createNew()"><ion-icon name="add"></ion-icon></button>
</ion-buttons>
</ion-navbar>
And then in the navbar.ts:
import {Component, Input} from '#angular/core';
import {NavController} from 'ionic-angular';
import {CreateNewPage} from '../../pages/create-new/create-new';
#Component({
selector: 'navbar',
templateUrl: 'build/components/navbar/navbar.html',
inputs: ['hideCreateButton']
})
export class CustomNavbar {
public hideCreateButton: string;
constructor(private nav: NavController) {
}
createNew(): void {
this.nav.setRoot(CreateNewPage, {}, { animate: true, direction: 'forward' });
}
}
By declaring the hideCreateButton as an input of the Component, you can decide in which pages show that button and in which ones should not be visible. So in this way, you can send information to tell the component how it should be, and customize it for each page.
So if you want to add the navbar in a page (without modifying the default template, so showing the create button) you just have to add the navbar element (binded to our custom component by us in the selector property):
<navbar></navbar>
<ion-content>
...
</ion-content>
And if you want to hide the create button (or modify you navbar like you want to) your page will look like this one:
<navbar [hideCreateButton]="hidebutton()"></navbar>
<ion-content>
...
</ion-content>
And remember that the hideButton() should be defined in your customPage.ts like this:
import {Component} from '#angular/core';
import {NavController} from 'ionic-angular';
import {FORM_DIRECTIVES, FormBuilder, ControlGroup, Validators, AbstractControl } from '#angular/common';
#Component({
templateUrl: 'build/pages/create-new/create-new.html',
directives: [FORM_DIRECTIVES]
})
export class CreateNewPage{
private hideCreateButton: boolean = true;
public hidebutton(): boolean {
return this.hideCreateButton;
}
}
For ionic 3+
What I did to solve this was simply use a custom component.
ionic generate component navbar
Add the relevant navbar html to your component template
Add any other functionality to your component .ts file
Modify your selector to something relevant, (if used command above it
should just default to 'navbar'.
Also add the component to your app.module.ts declarations
Then in any of your page templates, simply use it as a custom element
e.g
<navbar></navbar>
<ion-content padding>
...
</ion-content/>
I had a similar issue creating an Ionic 4+ app (#ionic/angular 4.6.2), I wanted to add a login button and some other global stuffs in the header.
You can achieve that in a quite simple way.
Just add a ion-header containing a ion-toolbar in your app.component.html as a global header, like this:
<ion-header class="page-header">
<ion-toolbar id="main-toolbar">
<ion-title>
<ion-label>{{ pageTitle }}</ion-label>
</ion-title>
<!-- add here all the things you need in your header -->
</ion-toolbar>
</ion-header>
<ion-router-outlet id="content" main></ion-router-outlet>
The problem here is that the "global header" will overlay the content of any page if you do only that. So has a workaround just add an empty ion-header containing an empty ion-toolbar on top of all your pages before the content tag, as follow:
<ion-header>
<ion-toolbar></ion-toolbar>
</ion-header>
<ion-content>
<!-- your content here -->
</ion-content>
Doing that the "global header" will overlay the page header and the content will begin just after it.
Then you can manage all the code for your global header controls in your app.component.ts file.
I guess there could be some strange behaviour if the main header has a height greater than the "standard" toolbar height but with some nice CSS you should be able to fix it.
Furthermore, this workaround works fine with a side menu.
Hope it helps!
I have since found out this is not possible. The only way to achieve this is by providing an <ion-navbar> and that will handle the back button automatically.
E.g.:
<ion-navbar *navbar>
<button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Settings</ion-title>
</ion-navbar>
<ion-content padding class="hub-settings">
<!-- content here -->
</ion-content>

Bootstrap Modal disappears when used with Navigation Wizard

I have an issue with Bootstrap Modal. I am using Bootstrap3.x for Modal and BootstrapWizard for custom navigation wizard. So both the libraries are necessary. When I click on Modal it disappears automatically. Can anyone help me on this?
I found the solution to this problem. My initial HTML code looks like this
<button class="btn-default" data-toggle="modal" data-target="#addPostModal" data-backdrop="static" data-keyboard="false">Add Posts</button>
But I modified this to
<button class="btn-default" id="myButton">Add Posts</button>
and wrote a jQuery function to handle onclick action
$(document).ready(function()
{
$("#myButton").click(function()
{
$("#addPostModal").modal("toggle");
});
});
In brief, I removed the toggle functionality from HTML and added toggle method. We can also remove "toggle" from onclick() function, it doesn't make any difference.
$(document).ready(function()
{
$("#myButton").click(function()
{
$("#addPostModal").modal();
});
});

Data binding does not work after simple modal popup

Please consider the following code (also in this fiddle):
var viewModel = {
count:ko.observable(0),
add:function (){
this.count(this.count()+1);
},
popup:function (){
$.modal($("#divPopup"));
}
}
ko.applyBindings(viewModel);
And this corresponding View:
<button id="btnAdd" data-bind="click:add">Add</button>
<button id="btnPopup" data-bind="click:popup">Popup</button>
<div id="divPopup">
<span data-bind="text:count"></span>
</div>
Now:
click Add button
click Popup button
click top right corner of modal window (sorry I can't have "x" image)
Add button don't work
I can't use:
$.modal($("#divPopup").html());
Because in my app html does not render when $.modal().
Or to put it as another question: how I can know when html render was completed when my viewModel changed?
Try passing persist: true in for the options to modal() like:
$("#divPopup").modal({ persist: true });
http://jsfiddle.net/rniemeyer/BxVF9/