How to make Swipe work in Angular-UI bootstrap Carousel? - angularjs

Swipe is not working in Carousel in ui-bootstrap v2.1.4 whereas it is working fine with v1.3.3
Is it any syntax change in new version that is causing error?
OR is it a bug in UI-Bootstrap?
Carousel docs mention that swipe is supported.
The carousel also offers support for touchscreen devices in the form of swiping. To enable swiping, load the ngTouch module as a dependency.
Plunker: https://plnkr.co/edit/odlDYR?p=preview
(For ease of swiping, plunker can be opened on mobile with QR code.)
var app = angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngTouch', 'ngSanitize', 'ui.bootstrap']);
app.controller('CarouselDemoCtrl', function ($scope) {
$scope.myInterval = 0;
$scope.noWrapSlides = false;
$scope.active = 0;
var slides = $scope.slides = [];
var currIndex = 0;
$scope.addSlide = function() {
var newWidth = 600 + slides.length + 1;
slides.push({
image: '//unsplash.it/' + newWidth + '/300',
text: ['Nice image','Awesome photograph','That is so cool','I love that'][slides.length % 4],
id: currIndex++
});
};
for (var i = 0; i < 4; i++) {
$scope.addSlide();
}
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible"
content="IE=edge" />
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-sanitize.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-touch.js"></script>
<!-- v1.3.3 swipe works; v2.1.4 swipe does not work -->
<!--<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.3.3.js"></script>-->
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.1.4.js"></script>
<script src="carousel.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="CarouselDemoCtrl">
<div style="height: 305px">
<div uib-carousel active="active" interval="myInterval" no-wrap="noWrapSlides">
<div uib-slide ng-repeat="slide in slides track by slide.id" index="slide.id">
<img ng-src="{{slide.image}}" style="margin:auto;">
<div class="carousel-caption">
<h4>Slide {{slide.id}}</h4>
<p>{{slide.text}}</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

Contrary to docs, Swipe is not supported in Carousel from v2.0.0 till v2.1.4 (at least)
It is mentioned is in changelog
carousel: Due to the removal of replace: true, this causes a slight HTML structure change to the carousel and the slide elements - see documentation demos to see how it changes. This also caused removal of the ngTouch built in support - if one is using ng-touch, one needs to add the ng-swipe-left and ng-swipe-right directives to the carousel element with relevant logic.
To enable swipe, specify a custom template using template-url and use ng-swipe-* directives there. E.g.
<div class="carousel-inner"
ng-swipe-left="$parent.vm.next()"
ng-swipe-right="$parent.vm.prev()"
ng-transclude>
</div>
Ref: https://github.com/angular-ui/bootstrap/issues/6277

Try this
Another approach where we change the active slide scope variable.
Using
Angular 1.6.6
ngTouch 1.6.6
UI Bootstrap 2.5.0
Template
<div uib-carousel active="active" class="carousel-inner" role="listbox" interval="myInterval" no-wrap="noWrapSlides"
ng-swipe-left="changeSlide('left')"
ng-swipe-right="changeSlide('right')">
<div uib-slide ng-repeat="slide in slides" class="wrapper">
<div style="position:relative;">
<img class="img-responsive" ng-src="{{slide.url}}"></div>
</div>
</div>
</div>
</div>
Controller
$scope.myInterval = 5000;
$scope.noWrapSlides = false;
$scope.active = 0;
$scope.slides = [{url: 'image1.jpeg'},{url: 'image2.jpg'}];
$scope.changeSlide = function (direction) {
var index = $scope.active;
if (direction === 'right') {
$scope.active = (index <= 0 ? 0 : index - 1);
return;
}
if (direction ==='left') {
$scope.active = (index >= ($scope.slides.length - 1) ? ($scope.slides.length - 1) : index + 1);
return;
}
};

Related

Pagination not changing when clicking on checkbox

I am trying to make a filter function. Filtering is working as expected but pagination is not updating. When I click on "Mobile Phone" checkbox it shows one record in the first page, two records in second page and so on..
Also, page count is not updating according to the search result.
How to solve this?
Index.html
<!DOCTYPE html>
<html >
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Test</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" >
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<body ng-app="ngTest" ng-controller="testCtrl" ng-cloak >
<div class="container">
<div class="row">
<input type="text" ng-model="searchFilter">
<input type="checkbox" ng-click="includeType('Tablet')" >Tablet
<input type="checkbox" ng-click="includeType('Mobile Phone')" >Mobile Phone
<input type="checkbox" ng-click="includeDistrict('Galle')" >Galle
<input type="checkbox" ng-click="includeDistrict('Kandy')" >Kandy
</div>
<div class="row">
<h4>{{ads.length}} total</h4>
<div class="col-lg-12" ng-repeat="ad in filteredAds | filter:searchFilter | filter:typeFilter | filter:districtFilter" style="border:1px solid #d84530; margin-bottom:20px;">
<p >Post Id: {{ad.post_id}}<br/>
User Id: {{ad.user_id}}<br/>
District: {{ad.district}}<br/>
Town: {{ad.town}}<br/>
Brand: {{ad.brand}}<br/>
Model: {{ad.model}}<br/>
Type: {{ad.type}}<br/>
Auth: {{ad.auth}}<br/>
Condition: {{ad.condition}}<br/>
Trade: {{ad.trade}}<br/>
Price: {{ad.price}}</p>
</div>
<uib-pagination ng-model="currentPage" total-items="ads.length" items-per-page="numPerPage" max-size="maxSize" boundary-links="true"></uib-pagination>
<p>{{ads.length}} and {{maxSize}} and {{currentPage}}</p>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.2.4.js"></script>
<script src="app.js"></script>
<script src="script.js"></script>
</body>
</html>
app.js
angular.module("ngTest",['ui.bootstrap'])
script.js
(function(){
"use strict";
angular
.module("ngTest")
.controller("testCtrl",function($scope, $http){
$http.get('test.json').then(function(result){
$scope.filteredAds = [];
$scope.currentPage = 1;
$scope.numPerPage = 2;
$scope.maxSize = 5;
$scope.ads = result.data;
$scope.$watch('currentPage + numPerPage', function() {
var begin = (($scope.currentPage - 1) * $scope.numPerPage)
, end = begin + $scope.numPerPage;
$scope.filteredAds = $scope.ads.slice(begin,end);
});
$scope.typeIncludes = [];
$scope.includeType = function(type) {
var i = $.inArray(type, $scope.typeIncludes);
if (i > -1) {
$scope.typeIncludes.splice(i, 1);
} else {
$scope.typeIncludes.push(type);
}
}
$scope.typeFilter = function(ads) {
if ($scope.typeIncludes.length > 0) {
if ($.inArray(ads.type, $scope.typeIncludes) < 0)
return;
}
return ads;
}
$scope.districtIncludes = [];
$scope.includeDistrict = function(district) {
var i = $.inArray(district, $scope.districtIncludes);
if (i > -1) {
$scope.districtIncludes.splice(i, 1);
} else {
$scope.districtIncludes.push(district);
}
}
$scope.districtFilter = function(ads) {
if ($scope.districtIncludes.length > 0) {
if ($.inArray(ads.district, $scope.districtIncludes) < 0)
return;
}
return ads;
}
});
});
})();
http://plnkr.co/edit/RV6pQYMTzETZGNKdAFGb?p=preview
Perhaps it is a question of style, but I wouldn't use filters for eliminating data from a collection. I tend to process the data in the controller, or in a service, before serving it to the view.
Moreover, in my experience, it is not good to assign a new value to a watched collection: the original reference is lost and AngularJS is confused.
Therefore, I rather manipulate the original array, to insert or remove items from it.

How to update $scope in Ionic slide box?

I've changing a $scope variable dynamically but Ionic doens't detect the change:
In my controller:
$scope.something = "something" ;
And in my ion-box I see $scope.something, but when try to set a new value to $scope.something ionic slide box doesn't detect the change. If I do the new value has been set..
console.log($scope.something) // The new value
A lot of people says that with $ionicBoxDelegate.update() is enough but doesn't work me. I also tyied all options that I've seen on Internet, but there is no way.
My code works because if I move it to a normal view, out of a slide, runs fine. Using the same code with the same controller.
Is a mystery. Any idea?
If the scope isn't updating correctly you can use $scope.$apply() to force angular to re-evaluate the scope.
I just made a codepen. Will this help?
http://codepen.io/nabinkumarn/pen/obVbmN
HTML
<div ng-controller="SlideBoxController as vm">
<div style="height:30px">{{vm.something}}</div>
<ion-slide-box show-pager="true" on-slide-changed="vm.onSlideChanged($index)">
<ion-slide ng-repeat="item in vm.items">
<div class="box">
<h2>{{item.title}}</h2>
<p>{{item.desc}}</p>
</div>
</ion-slide>
</ion-slide-box>
</div>
JS
vm.something=1
vm.onSlideChanged = function(slideIndex) {
vm.something ++;
};
It would be useful to see your code, in particular, how you are updating $scope.something.
I created the snippet below (loosely based on Scott Whittaker's codepen). Is this what you're trying to accomplish:
angular.module('app', ['ionic'])
.controller('SlideBoxController', function($scope) {
$scope.something = "old value";
$scope.items =
[{title: "item 1", desc: "item 1 description"},
{title: "item 2", desc: "item 2 description"}
];
$scope.onSlideChanged = function(slideIndex) {
if (slideIndex === 1) {
$scope.something = "new value";
}
else
{
$scope.something = "old value"
}
};
})
.slider {
height: 300px;
background-color: #eee;
}
.box {
padding: 1em;
}
<html ng-app="app">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Ionic Slide Box</title>
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body>
<ion-header-bar class="bar bar-header bar-calm">
<h2 class="title">Slide Box</h2>
</ion-header-bar>
<ion-content scroll="false">
<div ng-controller="SlideBoxController">
<ion-slide-box show-pager="true" on-slide-changed="onSlideChanged($index)">
<ion-slide ng-repeat="item in items">
<div class="box">
<h3>$scope.something = {{something}}</h3>
<h2>{{item.title}}</h2>
<p>{{item.desc}}</p>
</div>
</ion-slide>
</ion-slide-box>
</div>
</ion-content>
</body>
</html>
The problem was that the model needs a dot. Because I was using it in a filter and and input.

Carousel image transition does not work (ui.bootstrap.carousel)

I am trying to use the angular-ui bootstrap carousel (reference at http://angular-ui.github.io/bootstrap/). My problem is that the transition does not work, the image just appear/disappear instead of moving from right to left as the demo.
I am using Chrome version 43.0
HTML:
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.1.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
Testing
<div ng-controller="CarouselDemoCtrl">
<div style="height: 305px">
<carousel interval="myInterval" no-wrap="noWrapSlides">
<slide ng-repeat="slide in slides" active="slide.active">
<img ng-src="{{slide.image}}" style="margin:auto;">
<div class="carousel-caption">
<h4>Slide {{$index}}</h4>
<p>{{slide.text}}</p>
</div>
</slide>
</carousel>
</div>
<div class="row">
<div class="col-md-6">
<button type="button" class="btn btn-info" ng-click="addSlide()">Add Slide</button>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="noWrapSlides">
Disable Slide Looping
</label>
</div>
</div>
<div class="col-md-6">
Interval, in milliseconds: <input type="number" class="form-control" ng-model="myInterval">
<br />Enter a negative number or 0 to stop the interval.
</div>
</div>
</div>
</body>
</html>
The example.js:
angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('CarouselDemoCtrl', function ($scope) {
$scope.myInterval = 5000;
$scope.noWrapSlides = false;
var slides = $scope.slides = [];
$scope.addSlide = function() {
var newWidth = 600 + slides.length + 1;
slides.push({
image: '//placekitten.com/' + newWidth + '/300',
text: ['More','Extra','Lots of','Surplus'][slides.length % 4] + ' ' +
['Cats', 'Kittys', 'Felines', 'Cutes'][slides.length % 4]
});
};
for (var i=0; i<4; i++) {
$scope.addSlide();
}
});
Many thanks
The solution is to add ng-animate as a dependency. Like this:
angular.module('ui.bootstrap.demo', ['ui.bootstrap', 'ngAnimate']);
You need to link to the script as well of course.
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular-animate.js"></script>
Here is a Plunker where it is working (not from me though).
However, adding ngAnimate as a dependency might also break your slider/carousel - Catch 22!
If that happens, read this thread and try using a different Angular version.
EDIT: using version 1.3.13 of both Angular and ng-Animate works for me - just tried it in a project - whereas using a version mismatch does not work.

Angular js Images slider example

<body ng-app="myApp">
<div ng-controller="slideShowController" class="imageslide" ng-switch='slideshow' ng-animate="'animate'">
<div class="slider-content" ng-switch-when="1">
<img src="../images/ship.png" />
</div>
<div class="slider-content" ng-switch-when="2">
<img src="../images/cargo.png" />
</div>
<div class="slider-content" ng-switch-when="3">
<img src="../images/lake.png" />
</div>
<div class="slider-content" ng-switch-when="4">
<img src="../images/cargo2.png" />
</div>
</div>
<script>
var app = angular.module('myApp', ['angular-responsive']);
app.controller('slideShowController', function($scope, $timeout) {
//function slideShowController($scope, $timeout) {
var slidesInSlideshow = 4;
var slidesTimeIntervalInMs = 3000;
$scope.slideshow = 1;
var slideTimer =
$timeout(function interval() {
$scope.slideshow = ($scope.slideshow % slidesInSlideshow) + 1;
slideTimer = $timeout(interval, slidesTimeIntervalInMs);
}, slidesTimeIntervalInMs);
});
</script>
</body>
<script src="../bower_components/angular/angular.min.js"></script>
<script src="../bower_components/angular-responsive/src/responsive-directive.js"></script>
<script src="../bower_components/script.js"></script>
<link rel="stylesheet" href="../bower_components/style2.css" />
<link href="../bower_components/style3.css" rel='stylesheet' type='text/css'>
I need Images slider plugin in angular js. It must work both desktop and mobile. Can you please send one example for Image slider Angular JS.
This is the code I am using. Here I slide function is working. But no responsive. For mobile view it is working.
You can look into this library.
It's an Angular carousel, which is swipable (for mobile) but can also be used with regular navigation for desktop.
You can try with this: https://github.com/thenikso/angular-flexslider
But please keep in mind you should try something yourself, post your code and then you will (probably) receive an answer. Don't ask for the full code.
You can look this : http://jsfiddle.net/4m8pppyy
<div ng-controller="MyCtrl"> <div class="company-slide-outer"><company-project-directive></company-project-directive></div>

Angular Bootstrap Carousel Slide Transition not working correctly

I am looking to use the Angular Bootstrap Carousel Directive in an application I am building.
I am able to implement it just fine, but the transition isn't working how it shows in the documentation. What should be happening is the old image slides out to the left, with the new image sliding in from the right.
I also noticed that if you hit 'Edit Plunkr' to see the code they used, it is strangely enough doing the same thing I am seeing on my local implementation.
Direct code taken from their documentation below:
angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('CarouselDemoCtrl', function($scope) {
$scope.myInterval = 5000;
var slides = $scope.slides = [];
$scope.addSlide = function() {
var newWidth = 600 + slides.length + 1;
slides.push({
image: 'http://placekitten.com/' + newWidth + '/300',
text: ['More', 'Extra', 'Lots of', 'Surplus'][slides.length % 4] + ' ' + ['Cats', 'Kittys', 'Felines', 'Cutes'][slides.length % 4]
});
};
for (var i = 0; i < 4; i++) {
$scope.addSlide();
}
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.0.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="CarouselDemoCtrl">
<div style="height: 305px">
<carousel interval="myInterval">
<slide ng-repeat="slide in slides" active="slide.active">
<img ng-src="{{slide.image}}" style="margin:auto;">
<div class="carousel-caption">
<h4>Slide {{$index}}</h4>
<p>{{slide.text}}</p>
</div>
</slide>
</carousel>
</div>
</div>
</body>
</html>
What I am seeing is that it just switches to the new image, no slide, no nothing.
What is the missing piece here? Is it a bug, or something else?
You are missing the angular animate module. You need to add it to your scripts list:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular-animate.min.js"></script>
and then into your module like this:
angular.module('ui.bootstrap.demo', ['ui.bootstrap', 'ngAnimate']);
Here is a fork of the plunker with nganimate added in: http://plnkr.co/edit/E7j7KiZmCzIg629vWTnt?p=preview

Resources