(Ionic 2) Keep auto play in slides when the slide is swiped - ionic-framework

i have the slider like this:
<ion-slides #promoSlider [options]="homeOptions" (change)="onPromoSlideChanged()" >
<ion-slide *ngFor="let promo of promos">
<img *ngIf="promo" src="{{promo.image}}" style="width:300px;height:300px;margin:auto;display:block" >
</ion-slide>
</ion-slides>
I have use this options to keep my slide playing using auto play:
homeOptions = {
initialSlide: 0,
loop: true,
autoplay:2000
};
But the problem is when i swipe the slider the auto play is stopped and the slider is not sliding again. How to keep the slider playing even i swipe the slider. I have try this code:
onPromoSlideChanged() {
alert('ABC');
this.promoSlider.options = this.homeOptions;
this.promoSlider.rapidUpdate();
//What should i do in this method?
};
What event i need to keep the slider slide again (keep playing) when i swipe the slider ? Thanks...

You can find your answer here => https://forum.ionicframework.com/t/how-to-keep-slides-auto-play-when-the-slides-is-swiped/54025/6
The official docs reference the component Swiper as the base of the ion-slides component, so the API should be the same as the one described in http://idangero.us/swiper/api/11.
You could use the option autoplayDisableOnInteraction to avoid disabling auto play after the user interaction.
Your options array should be:
homeOptions = {
initialSlide: 0,
loop: true,
autoplay:2000,
autoplayDisableOnInteraction: false
};
Hope it helps.

$scope.images = {"status":true,"msg":"2 record(s) found","sliders":[{"title":"slider 1","content":"test
value","weblink":null,"image":"http:\/\/192.168.8.54\/test\/media\/mbimages\/a\/m\/test.jpg"},{"title":"Slider
2","content":null,"weblink":null,"image":"http:\/\/192.168.8.54\/test\/media\/mbimages\/
a\/m\/test.png"}]}
<ion-slide-box delegate-handle="img-viewer" options="options" does-continue="true" loop="true" auto-play="true" slide-interval="5000" >
<ion-slide ng-repeat="nt in images" ng-if="nt.slider_position == '1'" >
<div class="box"><img ng-src="{{nt.image}}" style="width:400px;height:200px;margin:auto;display:block"/></div>
</ion-slide>
</ion-slide-box>
**Controller**
$scope.counter = 0;
$interval(function ()
{
if($scope.counter == $ionicSlideBoxDelegate.$getByHandle('img-viewer').currentIndex() + 1)
{
$ionicSlideBoxDelegate.$getByHandle('img-viewer').slide(0);
}
else{
$ionicSlideBoxDelegate.$getByHandle('img-viewer').update();
}
}, 2000);
angular.forEach($scope.images, function(value, key){
if(value.slider_position == "1")
{
$scope.counter++;
}

Using Observable works for your scenario. You can use it as -
import {Observable} from 'Rxjs/rx';
// in class -
#ViewChild(Slides) slides: Slides;
ionViewDidEnter() {
//you get slider data from any web service
this.sliderObservable = Observable.interval(3000).subscribe(x => {
this.autoPlaySlider();
// or you can do this, it will start autoplay at every 3 seconds
// this.slides.startAutoplay();
});
}
autoPlaySlider(){
var slider_index = this.slides.getActiveIndex();
if(slider_index < this.sliderData.length){
this.slides.slideTo(slider_index+1);
}
else{
this.slides.slideTo(0);
}
}
ionViewDidLeave(){
this.sliderObservable.unsubscribe();
}
You can find more reference Here

Related

How to use autocomplete on search bar on Ionic 4?

I'm looking for some example but cannot see anyone googling it, just what i want is to hardcode 2 or 3 words, thank you so much. Do i have to look for on ionic 3? or in angular2 better?
In your html file:
<ion-searchbar type="text" debounce="500" (ionChange)="getItems($event)"></ion-searchbar>
<ion-list *ngIf="isItemAvailable">
<ion-item *ngFor="let item of items">{{ item }}</ion-item>
</ion-list>
in your ts file:
// Declare the variable (in this case and initialize it with false)
isItemAvailable = false;
items = [];
initializeItems(){
this.items = ["Ram","gopi", "dravid"];
}
getItems(ev: any) {
// Reset items back to all of the items
this.initializeItems();
// set val to the value of the searchbar
const val = ev.target.value;
// if the value is an empty string don't filter the items
if (val && val.trim() !== '') {
this.isItemAvailable = true;
this.items = this.items.filter((item) => {
return (item.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
} else {
this.isItemAvailable = false;
}
}
Mohan Gopi's answer is complete, but in order to make use of the debounce attribute, you have to use the ionChange event instead of the ionInput event.
<ion-searchbar type="text" debounce="500" (ionChange)="getItems($event)"></ion-searchbar>
...
...
That way the event will trigger after the user stops typing (after 500 milliseconds have passed since his last key press), instead of whenever a key is pressed.
Just wanted to share something I tried myself. I have implemented the autocomplete from Angulars material design (https://material.angular.io/components/autocomplete/overview)
But it did not look exactly as the rest of the ionic input components. I also tried the ion-searchbar but I did not like the search input, I wanted a normal ion-input So I did this:
html:
<ion-list>
<ion-item>
<ion-label position="floating">Supplier*</ion-label>
<ion-input (ionChange)="onSearchChange($event)" [(ngModel)]="supplier"></ion-input>
</ion-item>
<ion-item *ngIf="resultsAvailable">
<ion-list style="width: 100%; max-height: 200px; overflow-y: scroll;">
<ion-item *ngFor="let result of results" (click)="supplierSelected(result)" button>
<ion-label>{{result}}</ion-label>
</ion-item>
</ion-list>
</ion-item>
</ion-list>
in component.ts:
resultsAvailable: boolean = false;
results: string[] = [];
ignoreNextChange: boolean = false;
onSearchChange(event: any) {
const substring = event.target.value;
if (this.ignoreNextChange) {
this.ignoreNextChange = false;
return;
}
this.dataService.getStrings(substring).subscribe((result) => {
this.results = result;
if (this.results.length > 0) {
this.resultsAvailable = true;
} else {
this.resultsAvailable = false;
}
});
}
supplierSelected(selected: string) :void {
this.supplier = selected;
this.results = [];
this.resultsAvailable = false;
this.ignoreNextChange = true;
}
Granted the question was about ion-searchbar but maybe somebody out there also wants to use a normal ion-input like me. There is no clear icon but I can live with that, or just add one next to the ion-input. Could be that there is a way to turn the ion-searchbar into a normal ion-input style? Can't find it though in the docs.

Ionic change navbar color dynamically

I have to change the color of the navbar of one page when scrolling a bit.
Here we have part of my xml file:
<ion-header no-border>
<ion-navbar color="{{ toolbar_color }}">
<ion-title (click)="change()">{{userdata.Name}}</ion-title>
</ion-navbar>
</ion-header>
<ion-content fullscreen class="container" (ionScrollEnd)="scrollHandler($event)">
I tryed first by changing it using a click event and it worked fine.
change() {
if ( this.toolbar_color == "danger" ) {
this.toolbar_color = "light"
} else {
this.toolbar_color = "danger"
}
}
And this is the ionScrollEnd listener, that does not work. The event is fired correctly, but the changes on toolbar_color are not taking any effect on the navbar.
scrollHandler(event) {
if ( event.scrollTop > 100 ) {
console.log("ScrollEvent --> "+JSON.stringify(event));
this.toolbar_color = "light"
// this.toolbar_change = true;
} else {
this.toolbar_color = "danger"
// this.toolbar_change = false;
}
}
How the hell can I do this?
Thank you :)
Add #ViewChild(Content) content: Content in the TS file and subscribe to scroll end event. refer this link for working version. Also see the ionic forum discussion on this issue
import { Component, ViewChild, ChangeDetectorRef } from '#angular/core';
import { NavController, Content } from 'ionic-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
#ViewChild(Content) content: Content;
Arr = Array; //Array type captured in a variable
num:number = 1000;
toolbar_color: string;
constructor(public navCtrl: NavController, public ref : ChangeDetectorRef) {
this.toolbar_color="secondary";
}
changeColor(){
this.toolbar_color="primary";
this.ref.detectChanges();
}
ionViewDidLoad() {
//this.content.enableJsScroll();
this.content.ionScrollEnd.subscribe(() => {
this.changeColor();
});
}
}
HTML file
<ion-header>
<ion-navbar [color]="toolbar_color">
<ion-title>Home</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<h2>Welcome to Ionic!</h2>
<p>
This starter project comes with simple tabs-based layout for apps
that are going to primarily use a Tabbed UI.
</p>
<p>
Take a look at the <code>pages/</code> directory to add or change tabs,
update any existing page or create new pages.
</p>
<div *ngFor="let i of Arr(num).fill(1)">{{i}}</div>
</ion-content>
Update-1
Added code to change color on scrolling
Sometimes angular will not run changeDetector automatically. we can manually trigger it by using ChangeDetectorRef. it's added to detect the changes while scrolling.
Working version is also updated. Please check the above link

Infinite loop and dynamic content on slides [duplicate]

Hi I'm using ngFor to create an set of 3 slides while starting in the middle so I'm guaranteed to be able to slide to left or right on start.
When I slide right I can simple listen to the reachedEnd and push another slide to the array i'm looping.
but I have a problem with adding a slide to the beginning. If I do the same as above and use e.g. array.unshift() or spread to add an item to the beginning, the view think it's on position 0 and snaps the view to the new slide.
The code below would work but it animates the slide change back to index 1.
slide = [0,1,2] //example to loop
slideChanged(event) {
if(this.slides.isBeginning()){
this.slide = [this.slide[0]-1, ...this.slide];
this.slides.update();
this.slides.slideTo(1)
}
}
<ion-slides [initialSlide]="1" (ionSlideDidChange)="slideChanged($event)">
<ion-slide *ngFor="let item of slide">
<h1>Slide {{item}}</h1>
</ion-slide>
</ion-slides>
Any help is appreciated!
You can do that by using the ionSlideNextEnd and ionSlidePrevEnd events from the Slides. Please take a look at this working plunker
The view
<ion-header>
<ion-navbar>
<ion-title>Dynamic slides Demo</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-slides #slider (ionSlideNextEnd)="loadNext()" (ionSlidePrevEnd)="loadPrev()" [initialSlide]="1">
<ion-slide *ngFor="let n of numbers">
<h2>Current slide: {{n}}</h2>
</ion-slide>
</ion-slides>
</ion-content>
The component
#Component({...})
export class HomePage {
#ViewChild('slider') private slider: Slides;
numbers = [0,1,2];
firstLoad = true;
constructor() {}
loadPrev() {
console.log('Prev');
let newIndex = this.slider.getActiveIndex();
newIndex++;
this.numbers.unshift(this.numbers[0] - 1);
this.numbers.pop();
// Workaround to make it work: breaks the animation
this.slider.slideTo(newIndex, 0, false);
console.log(`New status: ${this.numbers}`);
}
loadNext() {
if(this.firstLoad) {
// Since the initial slide is 1, prevent the first
// movement to modify the slides
this.firstLoad = false;
return;
}
console.log('Next');
let newIndex = this.slider.getActiveIndex();
newIndex--;
this.numbers.push(this.numbers[this.numbers.length - 1] + 1);
this.numbers.shift();
// Workaround to make it work: breaks the animation
this.slider.slideTo(newIndex, 0, false);
console.log(`New status: ${this.numbers}`);
}
}
For you who wonder why this not works on Ionic 4, just add little bit changes on typescript component
This code below works on IONIC 4 :
ionSlideNextEnd(){
if(this.firstLoad) {
// Since the initial slide is 1, prevent the first
// movement to modify the slides
this.firstLoad = false;
return;
}
console.log('Next');
this.daySlider.getActiveIndex().then(idx=>{
let newIndex=idx
console.log(newIndex)
newIndex--;
this.numbers.push(this.numbers[this.numbers.length - 1] + 1);
this.numbers.shift();
// Workaround to make it work: breaks the animation
this.daySlider.slideTo(newIndex, 0, false);
console.log(`New status: ${this.numbers}`);
});
}
ionSlidePrevEnd(){
console.log('Prev');
this.daySlider.getActiveIndex().then(idx=>{
let newIndex=idx
console.log(newIndex)
newIndex++;
this.numbers.unshift(this.numbers[0] - 1);
this.numbers.pop();
// Workaround to make it work: breaks the animation
this.daySlider.slideTo(newIndex, 0, false);
console.log(`New status: ${this.numbers}`);
});
}
Or Much more simpler you can remove getter for Active Index, use below code for Ionic 4:
ionSlideNextEnd(){
if(this.firstLoad) {
this.firstLoad = false;
return;
}else{
this.numbers.push(this.numbers[this.numbers.length - 1] + 1);
this.numbers.shift();
// Workaround to make it work: breaks the animation
this.daySlider.slideTo(1,0,false);
this.monthViewData.selectedTime=new Date(this.monthViewData.selectedTime.setDate(this.monthViewData.selectedTime.getDate()+1));
this.eventSource = this.tmp_events.filter((item)=>{
if(item.startTime >= this.monthViewData.selectedTime.setHours(0,0,0,0) && item.endTime < this.monthViewData.selectedTime.getTime()){
return item;
}
});
}
}
ionSlidePrevEnd(){
this.numbers.unshift(this.numbers[0] - 1);
this.numbers.pop();
this.daySlider.slideTo(1,0,false);
this.monthViewData.selectedTime=new Date(this.monthViewData.selectedTime.setDate(this.monthViewData.selectedTime.getDate()-1));
this.eventSource = this.tmp_events.filter((item)=>{
if(item.startTime >= this.monthViewData.selectedTime.setHours(0,0,0,0) && item.endTime <= this.monthViewData.selectedTime.getTime()){
return item;
}
});
}

How to add multiple event handlers to same event in React.js

All:
I wonder if it is possible that binding multiple event handlers to same event?
For example:
var LikeToggleButton = React.createClass({
render: function(){
(function toggle(){
this.setState({liked:!like});
}).bind(this);
return (
<div onClick={toggle}>TOGGLE LIKE</div>
);
}
});
Until this point everything seems normal, but I want to add another feature to that button, which is decide by other option:
For example, I have another switch component(could be anything like checkbox or radio button etc.) called "count toggle", which when enabled, the LikeToggleButton's button will be added another onClick handler which is start counting times of button clicked, I know it could be predesignd into the toggle function, but I just wonder if there is a way to append this part to onClick handler?
Thanks
If you want to have multiple callbacks executed when onClick is triggered, you can have them passed from outside, so you'll have access to them in the props object. Then execute them all (note: code not tested):
var LikeToggleButton = React.createClass({
toggle: function() {
this.setState({liked:!like});
},
handleClick: function(e) {
e.preventDefault();
this.toggle();
for (var i=0, l<this.props.callbacks.length; i<l; i++) {
this.props.callbacks[i].call();
}
},
render: function() {
return (
<div onClick={this.handleClick}>TOGGLE LIKE</div>
);
}
});
BUT, if you want to have components connected between them, you should not do that by calling methods inside handlers. Instead you should use an architectural pattern, where Flux is the obvious choice (but there are lots more).
Take a look to Flux, and here you have more choices.
For an extensible way that does't require the component to know about components that use it - save the onClick event before changing it.
This is highlights extracted from the actual working code:
button.jsx
class Button extends React.Component {
constructor(props) {
super(props);
this.state= { callback: false};
}
click(){
//do stuff here
if(this.state.callback) { this.state.callback.call(); }
}
render () {
this.state.callback = this.props.onClick; // save the onClick of previous handler
return (
<button { ...this.props } type={ this.props.type || "button" } onClick={ this.click.bind(this) } className = this.props.className } >
{ this.props.children }
</button>
);
}
}
export default Button;
Then in another component you can use the button and it can have it's own onClick handler:
class ItemButtons extends React.Component {
itemClick () {
//do something here;
}
render () {
const buttons = [
(
<Button onClick={ this.itemClick.bind(this) } className="item-button">
<span>Item-Button</span>
</Button>
)
];
return (<section>{ buttons }</section>);
}
export default ItemButtons;
To group multiple actions on an event
onMouseDown={(e) => { e.stopPropagation(); alert('hello'); }}
Maybe you can set multiple click event handlers on the same one target as described here: https://gist.github.com/xgqfrms-GitHub/a36b56ac3c0b4a7fe948f2defccf95ea#gistcomment-2136607
Code (copied from linke above):
<div style={{ display: 'flex' }}>
<div style={{
width: '270px',
background: '#f0f0f0',
borderRight: "30px solid red",
minHeight: ' 500px',
maxHeight: '700px',
overflowX: 'hidden',
overflowY: 'scroll',
}}
onClick={this.state.ClickHandler}
onClick={this.stateHandleClick}
className="sidebar-btn"
>
<button onClick={this.props.ClickHandler}>props</button>
<button onClick={(e) => this.props.ClickHandler}>props</button>
<button onClick={this.props.ClickHandler}>props</button>
<button onClick={this.state.ClickHandler}>state</button>
//...
</div>

Programmatically switch themes in Ionic Framework

I posted this on the Ionic forum, but I never seem to have luck on their forums, so I thought I'd try here.
I'd like to have options for a "dark" and "light" theme that a user can choose in their settings. What's the best way to go about that? Can I programmatically switch between ionic themes, like dark and stable?
Thanks in advance.
You can you ng-style to pass a css options object to an element. This will toggle font color on the element. Following this pattern you would have dark and light theme objects that you toggle between.
<div ng-style="style" class="item">
This is a basic Card.
<button ng-click="toggle()">Toggle</button>
</div>
And in your controller
.controller('AppCtrl', function($scope) {
$scope.style = {
color: '#000'
};
$scope.toggle = function() {
$scope.style.color = ($scope.style.color === '#000' ? '#fff' : '#000');
};
});
Demo
Here is a simple example where you want to change the color of your header dynamically:
<ion-header-bar ng-class="'bar-' + appTheme">
<h1 class="title">Ionic - Switch Themes</h1>
</ion-header-bar>
In your controller:
var selectedTheme = $window.localStorage.appTheme;
if (selectedTheme) {
$scope.appTheme = selectedTheme;
} else {
$scope.appTheme = 'positive';
}
$scope.themeChange = function (theme) {
// save theme locally
$window.localStorage.appTheme = theme;
// reload
$window.location = '';
}
Live demo and full example #: http://techiedreams.com/ionic-custom-and-dynamic-theming/