angular ui.bootstrap.carousel call next()/prev() from $scope - angularjs

How do I access the next()/prev() methods of the carousel from the slide? I'm trying to connect to hm-swipe-left/right, but I don't seem to have the right $scope
<carousel interval="1000">
<slide ng-repeat="card in slides" active="card.active">
<div class="card list-unstyled text-center">
<ul class='header list-inline list-unstyled'
hm-swipe-left="swipe('next')"
hm-swipe-right="swipe('prev')">
<li><i class="icon {{card.icon}} fa-3x"></i></li>
<li class="title">{{card.title}}</li>
</ul>
</div>
</slide>
</carousel>

I was looking for a solution to this. I'll post what I finally did:
In the controller where you have the carousel (make sure your html carousel has id="myCarousel"):
$scope.showNext = function(){
var index = ($('#myCarousel .active').index()+1)%(slides.length);
var modIndex = (((index)%(slides.length))+(slides.length))%(slides.length);
$scope.slides[modIndex].active=true;
}
$scope.showPrev = function(){
var index = ($('#myCarousel .active').index()-1)%(slides.length);
var modIndex = (((index)%(slides.length))+(slides.length))%(slides.length);
$scope.slides[modIndex].active=true;
}
Then in your HTML page:
<img ng-src="{{slide.image}}" style="margin:auto;" ng-swipe-right="showPrev()" ng-swipe-left="showNext()">
Hope it helps to anyone!
It works for bootstrap 3.0.2 (my version)
EDIT:
Edited the modulus (since there is a bug in javascript when calculating modulus: Javascript modulo not behaving)
Now it works! :)

In my case I was just able to do this
<div ng-swipe-left="$parent.$parent.prev()" ng-swipe-right="$parent.$parent.next()" uib-slide ng-repeat="product in vm.productList track by $index" index="$index">
I am not sure if doing $parent.$parent is advised but it worked perfectly for me and I did not have put jquery/html code in my controller.
Keep in mind I was inside a ng-repeat, it could also be $parent.next() outside of the ng-repeat.

You can get the scope of directive from DOM element and re-use it
var element = angular.element('.carousel .left');
if (element.length > 0 && element.scope && element.scope().prev) {
element.scope().prev();
}
// or
if (element.length > 0 && element.scope && element.scope().next) {
element.scope().next();
}

Here is a slightly simpler solution:
Javascript Controller
$scope.carouselNext = function() {
$('#carousel-main').carousel('next');
}
$scope.carouselPrev = function() {
$('#carousel-main').carousel('prev');
}
HTML View
<div id="carousel-main" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#carousel-main" data-slide-to="0" class="active"></li>
<li data-target="#carousel-main" data-slide-to="1"></li>
<!-- add indicators for any slides added -->
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div id="slide1" class="item active" ng-swipe-right="carouselPrev()" ng-swipe-left="carouselNext()">
<!-- img or content here -->
</div>
<div id="slide2" class="item" ng-swipe-right="carouselPrev()" ng-swipe-left="carouselNext()">
<!-- img or content here -->
</div>
<!-- add more slides as needed -->
</div>
</div>

Related

Refreshing ng-repeat list after adding an element

I have a list of orders that I sort based on status key. Then I display it using ng-repeat in bars. I can click Accept button to move one order from submitted to accepted. The question is: How do I refresh the bar displaying accepted orders?
HTML
<div class="bar" ng-controller="AdminCtrl">
<li ng-repeat="order in submitted">
<div >
<p >{{order.name}} </p>
<p>{{order.total}}</p>
<button class="btn" ng-click="acceptOrder(order)">Akceptuj</button>
</div>
</li>
</div>
<div class="bar" ng-controller="AdminCtrl" >
<li ng-repeat="order in delivery">
<div >
<p >{{order.name}} </p>
<p>{{order.total}}</p>
<button class="btn" ng-click="addOrderToDeliveryQueue(order)">Dodaj do kolejki dostawy</button>
</div>
</li>
</div>
</div>
JS
$scope.submitted = [];
$scope.accepted = [];
$scope.delivery = [];
angular.forEach($scope.orders, function(value, key) {
if (value.status == 'submitted')
$scope.submitted.push(value);
if (value.status == 'accepted')
$scope.accepted.push(value);
if (value.status == 'delivery')
$scope.delivery.push(value);
});
$scope.acceptOrder = function(order) {
var index = $scope.submitted.indexOf(order);
order.status = 'accepted';
$scope.accepted.push(order);
$scope.submitted.splice(index, 1);
AngularJS handles refreshing ng-repeat directives automatically when it sees a change in the collection. You are not seeing this behavior because you are actually creating multiple independent instances of your AdminCtrl controller. Each of your divs has this: ng-controller="AdminCtrl". This creates a new instance of the AdminCtrl scoped to that div. What you really want is one instance of that AdminCtrl. You can achieve this by moving the ng-controller directive to the outermost container element.
<div ng-controller="AdminCtrl">
<div class="bar">
<li ng-repeat="order in submitted">
// your markup
</li>
</div>
<div class="bar">
<li ng-repeat="order in accepted">
// your markup
</li>
</div>
</div>
// etc.

Angular.js - ng-repeat not working

Angular.js is pretty new to me. I have learned before the $scope method for the controller and now trying the "this" method. For some reason I can not get my ng-repeat to work. here's my code:
HTML:
<ul class="nav nav-pills">
<li><a ng-click="myCtrl.tab=1" href>one</a></li>
<li><a ng-click="myCtrl.tab=2" href>two</a></li>
<li><a ng-click="myCtrl.tab=3" href>three</a></li>
</ul>
<div ng-controller="imageContr as imageCtrl">
<div ng-show="myCtrl.tab === 1" class="tab">
<h3>ONE title</h3>
<p>hello</p>
<li ng-repeat="item in gallery">
<img alt="imagealt" ng-src="{{item.photo}}">
</li>
</div>
<div ng-show="myCtrl.tab === 2" class="tab">
<h3>TWO title</h3>
<p>how are</p>
</div>
<div ng-show="myCtrl.tab === 3" class="tab">
<h3>THREE title</h3>
<p>you?</p>
</div>
</div>
</section>
</body>
</html>
APP.JS:
(function() {
var app = angular.module('myApp', []);
app.controller('myController', function() {
this.tab = 1;
});
app.controller('imageContr', function() {
this.gallery = images;
var images = {
photo: 'image1.jpg'
};
});
})();
Declare images before you assign it, and make it an array
var images = [{ photo: 'image1.jpg' }];
this.gallery = images;
Then in your view:
<li ng-repeat="item in imageCtrl.gallery">
<img alt="imagealt" ng-src="{{item.photo}}">
</li>
You are storing the gallery on this of the controller (which is basically the $scope), hence you need to access it in the template via imageContr as well:
<li ng-repeat="item in imageCtrl.gallery">
<img alt="imagealt" ng-src="{{item.photo}}">
</li>
You could also consider making gallery an array, so can easily iterate over it. Or you need to use the "iterate over object properties"-syntax:
<div ng-repeat="(key, value) in myObj"> ... </div>

Angularjs Div Show, Hide Toggle with adding class to active button

I'm new to this please bear with me
I'm trying to achieve div toggle and button class added when button clicked (active), i looked every where i been trying to do this for over 6 hours now :(.
here is my NAV div
<div id="sidebar-wrapper-button" ng-controller="Main">
<ul class="nav nav-pills">
<li ng-click="isInfo = !isInfo" ng-class="{'active':isInfo}"></li>
<li ng-click="isSetting = !isSetting" ng-class="{'active':isSetting}"></li>
</ul>
</div>
Content Div
<div ng-class="{'ng-show':isSetting,'ng-hide':!isSetting,'ng-hide':isInfo,}">
<h1>Setting</h1>
</div>
<div ng-class="{'ng-show':isInfo,'ng-hide':!isInfo,'ng-hide':isSetting}">
<h1>Info</h1>
</div>
app.js
//toggle Setting
app.controller('Main', function($scope) {
$scope.isSetting = false;
});
//toggle Info
app.controller('Main', function($scope) {
$scope.isInfo = false;
});
Thank you.
If I understood your request right, here's what I would do:
var app = angular.module('myApp', []);
app.controller('Main', function($scope) {
$scope.tabActive = null; // here insert 1, 2 or null depending on what the initial selection should be
});
li a{text-decoration: none;}
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="container" ng-app="myApp">
<div ng-controller="Main">
<ul class="nav nav-pills">
<li ng-click="tabActive = 1" ng-class="{'active':tabActive == 1}">
</li>
<li ng-click="tabActive = 2" ng-class="{'active':tabActive == 2}">
</li>
</ul>
<div ng-show="tabActive == 1">
<h1>Info</h1>
</div>
<div ng-show="tabActive == 2">
<h1>Setting</h1>
</div>
</div>
</div>
Simpler way is to use angular expression {{}} to output appropriate string:
<h1>{{isSetting ? 'Setting' : 'Info'}}</h1>
Requires less markup and less class change logic code and ultimately less scope watches

how to show exact content of ng-repeat using ng-click in angularjs

I am trying to show exact content when I click on data from ng-repeat.
<div ng-repeat="trailSpot in trail.wayPoints">
<a ng-click="viewState.showSpotDetails = !viewState.showSpotDetails">
<p>Spot {{$index + 1}}. {{trailSpot.wpName}}</p>
</a>
<p >{{trailSpot.wpDescription}}</p>
</div>
When I click the first wpName, I want to show wpDescription only about the first wpName on another div. What should I put in that div.
<div class="panel-body" ng-show="viewState.showSpotDetails">
<div>
???
</div>
</div>
Anybody has any tips on what I am trying to do?Thank you!
Just pass the object to assign the property like this:
http://jsfiddle.net/wLs8axLj/
JS
var app = angular.module('itemsApp',[]);
app.controller('ItemsCtrl',function($scope) {
$scope.items = [
{name:'Test 1',details:'Test 1 Details'},
{name:'Test 2',details:'Test 2 Details'}
];
$scope.showDetails = function(i) {
$scope.item_details = i.details;
};
});
HTML
<div ng-app="itemsApp" ng-controller="ItemsCtrl">
<ul>
<li ng-repeat="i in items" ng-click="showDetails(i)">{{i.name}}</li>
</ul>
<hr>
{{item_details}}
</div>

ng-repeat next and previous navigation

I am looking for a way to implement ng-repeat next-prevous navigation. Navigation is inside repeating area, so the navigation arrows are shown if next or previous items exists.
But I need a way to add an active class to repeater on ng-click, so if I navigate to next item, it receives active class (and same with previous), so i can make that item visible and all other hidden.
<li ng-class="{active: ?}" ng-repeat="page in pages">
<p ng-bind-html-unsafe="page.content"></p>
<a ng-show="pages[$index - 1]" ng-click="?" class="previous" href="#">Previous</a>
<a ng-show="pages[$index + 1]" ng-click="?" class="next" href="#">Next</a>
</li>
Also if there is another way around this, please advise.
HTML:
<div ng-controller="MyCtrl">
<li ng-class="{active: activePage.page == $index,
inactive: activePage.page != $index}" ng-repeat="page in pages">
<p ng-bind-html-unsafe="page.content"></p>
<a ng-show="pages[$index - 1]" ng-click="activePage.page = $index-1"
class="previous" href="#">Previous</a>
<a ng-show="pages[$index + 1]" ng-click="activePage.page = $index+1"
class="next" href="#">Next</a>
</li>
</div>
CSS:
.active{
display:block;
}
.inactive{
display:none;
}
JS:
function MyCtrl($scope, $rootScope) {
/* Dont use a primitive but an object as ng-repeat creates
a scope of its own */
$scope.activePage = {
page:0
};
$scope.pages = [{content:"a"},{content:"b"},{content:"c"}];
}

Resources