Ionic 2 Slides Component - How to Access Swiper API - ionic-framework

Using ion-slides component (4 slides) on app welcome page/slides. I need ability for user to skip to last slide. Docs say ion-slides implementation of Swiper API. I need to access methods like: mySwiper.slideTo(index, speed, runCallbacks);
Tips on how to implement?

You can pass a function within the options property.
Original answer.
#Component({
selector: 'my-component',
template: '<ion-slides [options]="options">
<ion-slide>Slide1</ion-slide>
<ion-slide>Slide2</ion-slide>
</ion-slides>',
directive: [IONIC_DIRECTIVES]
})
export class MyComponent {
public slider: any;
constructor() {
this.options = {
onlyExternal: false,
onInit: (slides: any) =>
this.slider = slides
}
}
click() {
this.slider.sliderNext(true, 250);
}
}
For further options have a look at the swiper api.

If you are looking for a simple solution without custom directives, you can try this
constructor(
private _app: IonicApp
){}
ngAfterViewInit() {
this._slider = this._app.getComponent('my-slider');
}
goToSlide(slideIndex){
this.slider.slider.slideTo(slideIndex);
}

You can make a service with your Swiper
#Injectable()
export class HomeSwiper {
swiper = null;
initSwiper(selector) {
this.swiper = new Swiper(selector, {
pagination: '.home-swiper-pagination',
speed: 400,
spaceBetween: 100,
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev'
});
}
goTo(index) {
this.swiper.slideTo(index);
}
}
And use it into your #Page
#Page({
templateUrl: 'build/pages/home/home.html',
providers: [HomeSwiper]
})
export class Home {
constructor(private swiperService: HomeSwiper) {
this.swiperService.initSwiper('.home-modal-swiper-container');
}
skipSlides() {
this.swiperService.goTo(indexOfTheLastSlide);
}
}

Related

How to customize side menu animation

I´m developing an Ionic 4 aplication and I want to usea a custom side menu animation like this:
but Ionic only have 3 options: push, overlay and reveal.
I already have my 3dmenu.ts file but I don´t no how to inject it to use It with the Ion-menu componet like the other 3 options, could some one give a hint about how to do this?
I finally can do it, Using workaruond than I found here here. The trick is extend the menu controller class to create a new method registerAnimation:
Step 1: Create a new ts file (extended.ts or the name than you want) and put this code inside:
import { DOCUMENT } from '#angular/common';
import { Inject, Injectable } from '#angular/core';
import { MenuController } from '#ionic/angular';
import { AnimationBuilder } from '#ionic/core';
function proxyMethod(ctrlName: string, doc: Document, methodName: string, ...args: any[]) {
const controller = ensureElementInBody(ctrlName, doc);
return controller.componentOnReady()
.then(() => (controller as any)[methodName].apply(controller, args));
}
function ensureElementInBody(elementName: string, doc: Document) {
let element = doc.querySelector(elementName);
if (!element) {
element = doc.createElement(elementName);
doc.body.appendChild(element);
}
return element as HTMLStencilElement;
}
const CTRL = 'ion-menu-controller';
#Injectable({
providedIn: 'root',
})
export class EloMenuController extends MenuController {
constructor(#Inject(DOCUMENT) private document: any) {
super(document)
}
/**
* Registers a new animation that can be used with any `ion-menu` by
* passing the name of the animation in its `type` property.
*
* #param name The name of the animation to register.
* #param animation The animation function to register.
*/
registerAnimation(name: string, animation: AnimationBuilder) {
return proxyMethod(CTRL, this.document, 'registerAnimation', name, animation);
}
}
Step 2: Create a new ts file with the animation, in my case I use this:
import { Animation, MenuI } from '#ionic/core';
export function menu3D (AnimationC: Animation, baseEl: HTMLElement, menu: MenuI):
Promise<Animation> {
let contentOpenedX: string;
let menuClosedX: string;
const width = menu.width;
const baseAnimation = new AnimationC();
if (menu.isEndSide) {
contentOpenedX = -width + 'px';
menuClosedX = width + 'px';
}
else {
contentOpenedX = width + 'px';
menuClosedX = -width + 'px';
}
const menuAnimation = new AnimationC()
.addElement(menu.menuInnerEl)
.fromTo('z-index', '0', '0')
.fromTo('translateX', menuClosedX, '0px');
const contentAnimation = new AnimationC()
.addElement(menu.contentEl)
.fromTo('translateX', '0px', contentOpenedX)
.fromTo('scale', '1', '0.7');
const backdropAnimation = new AnimationC()
.addElement(menu.backdropEl)
.fromTo('opacity', 0.01, 0.32);
return Promise.resolve(baseAnimation
.addElement(baseEl)
.easing('cubic-bezier(0.0, 0.0, 0.2, 1)')
.easingReverse('cubic-bezier(0.4, 0.0, 0.6, 1)')
.duration(300)
.add(contentAnimation)
.add(menuAnimation)
.add(backdropAnimation));
};
Step 3: import in your app.component.ts the extended class and the animation and register your animation to be able to use it:
import { Component, OnInit, Input } from '#angular/core';
import { Extend } from './animations/extend
import { menu3D } from './animations/menu3D';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html',
})
export class AppComponent implements OnInit {
#Input() name: string;
constructor(
private menu: Extend
) {
this.menu.registerAnimation('menu3d', menu3D);
}
ngOnInit() {}
}
Step 4: configure the type to your ion-menu component
<ion-menu side="start" type="menu3d" style="z-index: 10;">
........
</ion-menu>
Step 5: Don't forget to thanks to svallory from github and Enjoy it :-)
I don´t konw if it this the best way to do it but its the only way than I found after 5 days searching, I hope this helps other and if anyone can improve this feel free to comment :-)

Ionic 4. Alternative to NavParams

I am using ionic 4. It does not accept to receive data using navparams.
Here is my sender page method:
//private route:Router
gotoFinalView(intent) {
this.route.navigateByUrl(`${intent}`, this.destination);
}
Receiver page line;
//private navParams:NavParams
this.destination = navParams.data;
What is the right approach to doing this in ionic 4. I am also uncertain whether gotoFinalView method is valid.
This is how I solved my problem:
I created a Service with a setter and getter methods as;
import { Injectable } from "#angular/core";
#Injectable({
providedIn: "root"
})
export class MasterDetailService {
private destn: any;
constructor() {}
public setDestn(destn) {
this.destn = destn;
}
getDestn() {
return this.destn;
}
}
Injected the Service and NavController in the first page and used it as;
gotoFinalView(destn) {
this.masterDetailService.setDestn(destn);
this.navCtrl.navigateForward("destn-page");
}
Extracted the data at the final page by;
constructor(
private masterDetailService: MasterDetailService
) {
this.destination = this.masterDetailService.getDestn();
}
This is the efficient way to solve your problem
user Angular Routers concepts in your application.
just declare your router like the following
Your app routing module like the following
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import {ViewComponent} from "./crud/view/view.component";
import {CreateComponent} from "./crud/create/create.component";
import {UpdateComponent} from "./crud/update/update.component";
import {ReadComponent} from "./crud/read/read.component";
const routes: Routes = [
{path: '', component: ViewComponent},
{path: 'create', component: CreateComponent},
{path: 'update/:id', component: UpdateComponent},
{path: 'view/:id', component: ReadComponent}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
:id is the parameter what i want to send to that page.
this.router.navigate([link + '/' + id]);
share your parameter like this in your first page.
In your second page inject the activated route using DI(Dependency Injection)
constructor(private actRoute: ActivatedRoute)
Then Get your parameters using the following code
this.productID = this.actRoute.snapshot.params['id'];
This is the simple way. You can send multiple parameter at a time.
{path: 'update/:id/:name/:price', component: UpdateComponent}
and get those parameters like the following
this.productID = this.actRoute.snapshot.params['id'];
this.productName = this.actRoute.snapshot.params['name'];
this.productPrice = this.actRoute.snapshot.params['price'];
While Routing you can write like this:
this.router.navigate(["/payment-details",{
prev_vehicle_type: this.vehicle_type,
prev_amt: this.amt,
prev_journey:this.whichj
}]);
To get this parameters on the next page you can write:
constructor(
public router: Router,
public activateroute: ActivatedRoute){
this.activateroute.params.subscribe((data: any) => {
console.log(data);
this.vehicle_type = data.prev_vehicle_type;
this.amt = data.prev_amt;
this.whichj = data.prev_journey;
});
}
ionic 4 navigation with params
sender page
1. import the following
import {NavController} from '#ionic/angular';
import { NavigationExtras } from '#angular/router';
constructor(private navCtrl:NavController)
sender page
gotonextPage()
gotonextPage()
{
let navigationExtras: NavigationExtras = {
state: {
user: 'name',
parms:Params
}
};
this.navCtrl.navigateForward('pageurl',navigationExtras);
}
4.Receiver Page
import { ActivatedRoute, Router } from '#angular/router';
constructor( private route: ActivatedRoute, private router: Router)
{
this.route.queryParams.subscribe(params => {
if (this.router.getCurrentNavigation().extras.state) {
this.navParams = this.router.getCurrentNavigation().extras.state.parms;
}});
}
Send data with Router service and extract with global variable, history
//sender component
// private router: Router
nextPage() {
this.router.navigate(['history'],
{ state: [{ name: "covid-19", origin: "china" },{ name: "ebola", origin: "us" }] }
)
}
//receiver page
ngOnInit() {
let data = history.state;
console.log("data-->",data);
// ** data**
//0:{name: "covid-19", origin: "china"} 1: {name: "ebola", origin: "us"} navigationId: 2
}
The item, icon and title variables you want to send should be written in the state in this way.
this.nav.navigateForward('/myUrl', {
state: {
'items': this.substances,
'icon': ICONS.substance,
'title': 'Etken Maddeler'
}
});
We take incoming variables this way.
//receive
constructor(
protected route: ActivatedRoute,
protected router: Router,
) {
this.selectedItem = null;
this.route.paramMap.subscribe(params => {
let st = this.router.getCurrentNavigation().extras.state;
if (st) {
this.selectedItem = st.items;
}
});
}
Very very simply, you can do something like this:
In the "calling screen" :
this.router.navigate(['url', {model: JSON.stringify(myCustomObject)}])
In the "called screen" :
this.myvar = JSON.parse(this.activatedRoute.snapshot.paramMap.get('model')
Et voilà !
//in home.ts
import{ Router,ActivatedRoute, NavigationExtras } from '#angular/router';
getProductStatics(productObject : any) {
var object1 = {
id: productObject,
}
const navigationExtras: NavigationExtras = {state : {object:
JSON.stringify(object1)}};
this.router.navigate(["/product-statics"], navigationExtras);
}
//in product-statics.ts
import{ Router,ActivatedRoute,NavigationExtras } from '#angular/router';
if(self.router.getCurrentNavigation().extras.state) {
var object1
= this.router.getCurrentNavigation().extras.state.object;
var object = JSON.parse(object1);
var newObjectData = object.id;
}

Ionic-3 error Cannot read property 'style' of null

Im Used Ionic-3 and Im hide Tabs bar On Specific pages, Its working fine but i have some issue, some time display this error message
TypeError: Cannot read property 'style' of null
how to fix this issue,
this is my code
check.ts
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams} from 'ionic-angular';
#IonicPage()
#Component({
selector: 'page-check',
templateUrl: 'check.html',
})
export class CheckPage {
tabBarElement: any; // hidetab
constructor(public navCtrl: NavController, public navParams: NavParams) {
this.tabBarElement = document.querySelector('.tabbar.show-tabbar');// hidetab
}
ionViewDidLoad() {
console.log('ionViewDidLoad CheckPage');
}
ionViewWillEnter() {
this.tabBarElement.style.display = 'none'; // hidetab
}
ionViewWillLeave() {
this.tabBarElement.style.display = 'flex'; // hidetab
}
takeMeBack() {
this.navCtrl.parent.select(0); // backbutton
}
}
Try this maybe it can fix your issue :
ionViewWillEnter() {
let tabBarElement = document.querySelector('.tabbar.show-tabbar');
if (tabBarElement != null) {
tabBarElement.style.display = 'none'; // or whichever property which you want to access
}
}

Angular2 dynamic form with remote metadata

I created a dynamic form following the instructions in the angular cookbook and then I've tried to create the form with metadata that I have in my database.
I made an HTTP request to the get field types, names, ids, etc. but when I try to build the form as in the angular example, nothing happens or I get errors on console.
Here's the code from the tutorial:
export class AppComponent {
questions: any[];
constructor(service: QuestionService) {
this.questions = service.getQuestions();
}
}
And this is what I did:
export class AppComponent implements OnInit {
campos: any[] = [];
constructor(private servico: FormDadosService) {}
ngOnInit() {
this.servico.getCampos().subscribe(this.processaCampos);
}
processaCampos(dados) {
for (let i = 0; i < dados.length; i++) {
this.campos.push(new CampoBase({
nome: dados[i].ZI2_NOME,
label: dados[i].ZI2_DESC,
ordem: dados[i].ZI2_ORDEM,
obrigatorio: dados[i].ZI2_OBRIGAT,
tamanho: dados[i].ZI2_TAM,
valor: '',
tipoCampo: dados[i].ZI2_TIPO
}))
}
}
}
I am getting this error:
error_handler.js:50EXCEPTION: Cannot read property 'push' of undefined
I think I need to know a way to render the form after all data about it has arrived from my HTTP request.
I made it work this way:
export class AppComponent implements OnInit {
campos: any[] = [];
constructor(private servico: FormDadosService) { }
ngOnInit() {
this.servico.getCampos().subscribe((data) => {
data.forEach(campo => {
this.campos.push(new CampoBase({
valor: '',
nome: campo.ZI2_CAMPO,
label: campo.ZI2_DESC,
tipoCampo: campo.ZI2_TIPO,
tamanho: campo.ZI2_TAM
}))
});
});
}
}
This question can be marked as solved.
Thanks everyone.

Assigning an import to a variable within a constructor

I am building an app in Ionic2. I want to implement Facebook within the app and so I am trying to use the ionic-native Facebook api. I imported it and then attempted to assign it to a variable so I could use the functions associated with it.
Here is my code.
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Facebook } from 'ionic-native';
#Component({
selector: 'page-news-feed',
templateUrl: 'news-feed.html',
})
export class NewsFeed {
fb: any;
constructor(public navCtrl: NavController, facebook: Facebook) {
this.fb = facebook;
}
doRefresh(refresher) {
console.log('Begin async operation', refresher);
setTimeout(() => {
console.log('Async operation has ended');
refresher.complete();
}, 2000);
}
this.fb.login([]);
ionViewDidLoad() {
console.log('Hello NewsFeed Page');
}
}
I thought an import works much like a class in that you can import it and assign it to a variable and then have access to its methods. Does it not work like that? How does it work?
You just have to import Facebook class like it is said in Ionic native docs :
https://ionicframework.com/docs/v2/native/
You don't need to inject it through the constructor. As method are static this will print an error.
Be sure to also call Facebook after platform.ready event. And don't forget to add the plugin. See your example modified accordingly.
import { Component } from '#angular/core';
import { NavController, Platform } from 'ionic-angular';
import { Facebook } from 'ionic-native';
#Component({
selector: 'page-news-feed',
templateUrl: 'news-feed.html',
})
export class NewsFeed {
constructor(public navCtrl: NavController, platform: Platform) {
platform.ready().then(() => {
console.log('Faceboook');
Facebook.login([]).then((response) => {
console.log(response);
}).catch((error) => {
console.error(error);
});
})
}
doRefresh(refresher) {
console.log('Begin async operation', refresher);
setTimeout(() => {
console.log('Async operation has ended');
refresher.complete();
}, 2000);
}
ionViewDidLoad() {
console.log('Hello NewsFeed Page');
}
}