Mouseover shows image in ng-repeat - angularjs

HTML:
<ul>
<li ng-repeat="image in files | filter :'image'">
<div class="file-tag-baloon1" ng-mouseover="hoverImg(image.id)" ng-mouseleave="hoverOut()">
<span style="width: 200px;">
<a ng-show="hideHoveredImage==false;" class="hover-title">{{hoverTitle}}
<img class="hover-image" src="{{hoveredImage}}">
</a>
</span>
</div>
</li>
</ul>
JS:
$scope.hoverOut = function () {
$scope.hideHoveredImage = true;
$scope.hoveredImage = "";
}
$scope.hoverImg = function (id) {
$scope.hoveredImage = FileService.getFile(json, id);
}
I wrote a function to hove the image on mouseover. But the problem is If I have 4{{hoverTitle}}, four times the hovering image div appears ,i need the hovering image per index also I wanted it to be exactly at top of the $scope.hiverTitle . Any examples or solution will help me better.

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. Why filter invokes automatically?

I'm new in angular and I reeding A.Freeman's book "Pro Angular JS".
So I stuck in one of examples trying to understand why filter in ng-repeat is triggered.
Here is the code:
<body ng-controller="sportsStoreCtrl">
<div class="navbar navbar-inverse">
<a class="navbar-brand" href="#">SPORTS STORE</a>
</div>
<div class="panel panel-default row" ng-controller="productListCtrl">
<div class="col-xs-3">
<a ng-click="selectCategory()" class="btn btn-block btn-default btn-lg">Home</a>
<a ng-repeat="item in data.products | orderBy:'category' | unique:'category'" ng-click="selectCategory(item)" class=" btn btn-block btn-default btn-lg">
{{item}}
</a>
</div>
<div class="col-xs-8">
<div class="well" ng-repeat="item in data.products | filter:categoryFilterFn">
<h3>
<strong>{{item.name}}</strong>
<span class="pull-right label label-primary">
{{item.price | currency}}
</span>
</h3>
<span class="lead">{{item.description}}</span>
</div>
</div>
</div>
</body>
and
angular.module("sportsStore")
.controller("productListCtrl", function ($scope, $filter) {
var selectedCategory = null;
$scope.selectCategory = function (newCategory) {
selectedCategory = newCategory;
}
$scope.categoryFilterFn = function (product) {
return selectedCategory == null ||
product.category == selectedCategory;
}
});
categoryFilterFn is one that confuses me. Why it's invoking when I press catefory buttons (with selectCategory() method on ng-click) since I never call categoryFilterFn explicitly?
Answering you question - because of $digest. You don't have call categoryFilterFn directly. Your selectedCategory has changed which is used in categoryFilterFn and categoryFilterFn is bound to scope.
Not sure how I can describe it correctly but here my explanation.
There are two "independent" parts :
The repeat iterate over an array of items.
If you select an category via ng-click function you set the new category in the scope.
Here kicks the filter function in, witch ties it up.
It is triggered because a new category is selected ($digest) and "reordering" the array (like map function in plain Javascript) and the angular magic (ng-repeat) displays only items with this category.
And that's the reason why I love angular so much 🤓

AngularJS - Enable and disable button

I have a condition and it is only on selecting an image among the optional images the next button needs to get enabled and also next should not get enabled on last outer select.
The problem here is on selecting the first image, the button is getting enabled and the scope is assigning the value to false and it is not getting true for the second iteration of images. How can I fix this issue?
<div class="col-xs-6 col-md-10 col-lg-7">
<div ng-repeat="outer in outers track by $index">
<div ng-if="outer_index== $index">
<div ng-bind="::outer.label"></div>
<ul class="list-group">
<li class="cursorPointer" ng-repeat="inner in outer.inners | orderBy: 'id'" ng-class="{'selected': getSelectedClass($parent.$index, $index)}" class="deselected">
<div class="col-xs-6">
<div class="img">
<img ng-src="data:image/png;base64,{{inner.base64Icon}}" alt="{{inner.description}}" title="{{inner.description}}"
ng-click="process()">
<div class="desc" ng-bind="inner.description"></div></div>
</div>
</li>
</ul>
</div>
</div>
</div>
<div><button type="button" class="btn btn-info" ng-disabled="outer_index == outers.length -1 || disableNext" ng-click="getNext()">Next</button></div>
In JS code, to activate the button only if,
$scope.disableNext=true;
$scope.process = function() {
$scope.disableNext=false;
}
$scope.getNext = function (){
$scope.outer_index = $scope.outer_index + 1;
$scope.datas = $scope.outers[$scope.outer_index];
}
NOTE: I tried
ng-click="process();disableNext=false;" for this condition won't work within ng-repeat.
Just set the disableNext to true after selecting next and it works!
$scope.getNext = function() {
$scope.disableNext=true;
$scope.outer_index = $scope.outer_index + 1;
$scope.datas = $scope.outers[$scope.outer_index];
}

Bootstrap UI Modal - Injecting and initializing $index for ng-repeat

Currently I have a image gallery like this:
<div class="slider">
<img ng-repeat="image in gallery" class="img-responsive" ng-swipe-right="showPrev()" ng-swipe-left="showNext()" ng-show="isActive($index)" ng-src="{{image}}" ng-click="open($index)"/>
<a class="arrow prev" ng-click="showPrev()"></a>
<a class="arrow next" ng-click="showNext()"></a>
<ul class="navigator">
<li ng-repeat="image in gallery" ng-class="{'active':isActive($index)}">
<img src="{{image}}" ng-click="showPhoto($index);" class="img-responsive" />
</li>
</ul>
</div>
My image gallery functions look like this:
// initial image index
$scope._Index = 0;
// if a current image is the same as requested image
$scope.isActive = function (index) {
return $scope._Index === index;
};
// show prev image
$scope.showPrev = function () {
$scope._Index = ($scope._Index > 0) ? --$scope._Index : $scope.gallery.length - 1;
};
// show next image
$scope.showNext = function () {
$scope._Index = ($scope._Index < $scope.gallery.length - 1) ? ++$scope._Index : 0;
};
// show a certain image
$scope.showPhoto = function (index) {
$scope._Index = index;
};
When I click on a image my 'open' function will run:
$scope.open = function (index) {
$scope.modalInstance = $modal.open({
templateUrl: 'templates/hotelmodal.html',
controller: 'HotelCtrl',
size: 'lg',
scope:$scope
});
};
And a modal will pop-up:
<div class="modal-header">
<h3 class="modal-title">Billedfremviser</h3>
</div>
<div class="modal-body">
<div ng-cloak class="slider">
<img ng-init="$index = 1" ng-repeat="image in gallery" class="img-responsive" ng-swipe-right="showPrev()" ng-swipe-left="showNext()" ng-show="isActive($index)" ng-src="{{image}}"/>
<a class="arrow prev" ng-click="showPrev()"></a>
<a class="arrow next" ng-click="showNext()"></a>
<ul class="navigator">
<li ng-repeat="image in gallery" ng-class="{'active':isActive($index)}">
<img src="{{image}}" ng-click="showPhoto($index);" class="img-responsive" />
</li>
</ul>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="close()">Luk billedfremviser</button>
</div>
As you can see my main gallery site and the content of the modal is almost the same.
The only purpose of the modal is to show the image in a larger size - which is working perfectly.
My only problem is, that I want the modal to show the same image as the main gallery site when it opens.
I've tried to use the following on the modal ng-repeat - just for test purpose:
ng-init="$index = 1"
But it just mess up ng-repeat.
As you can see I inject $index in my open function - but again.. I don't know how to use the number in the in the modal ng-repeat.
Your help will be greatly appreciated!
The only thing i needed to do was:
// initial image index
if (!$scope._Index) {
$scope._Index = 0;
}
Hereafter the $scope._Index im using to determine the active picture, will not be set to 0 when the modal opens with the same controller. The picture will then be the same in the modal as on the main page.
I don't think this is the best way to do it, but it's working great.

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>

Resources