Using Angular $first and $last outside of ng-repeat - angularjs

I have this code:
<main class="gallery">
<nav class="gallery-list-thumbs">
<ul>
<li ng-click="showLarge($event); modalShow()" ng-repeat="photo in photos | filter:{'section': section }">
<img data-ref="ref-{{ photo.id }}" data-orientation="{{ photo.orientation }}" class="photo-small" ng-src="photos/{{ photo.section }}/th/{{ photo.src }}">
</li>
</ul>
</nav>
<section class="gallery-item" ng-hide="modalHidden">
<h1 ng-model="section">{{ section }}</h1>
<div class="photo-container">
<div class="modal-close" ng-click="modalShow()"></div>
<div class="modal-prev"></div>
<div class="modal-next"></div>
<img data-photoref="ref-{{ photo.id }}" ng-repeat="photo in photos | filter:{'section': section }" class="photo-large below orientation-{{ photo.orientation }}" ng-class="{'above':$first}" ng-src="photos/{{ section }}/{{ photo.src }}">
</div>
</section>
</main>
What I hope to achieve, is to hide the modal-prev when the user click on the first li in gallery-list-thumbs and the same thing with modal-next on the last li.
So far, using $index, it's fairly easy since I can target it by a scope change, but how do I get the last element when there's a different amount of images per galleries? It would be easier if the next and prev arrows were inside the ng-repeat since I could use $first and $last, but I don't want to have to include them in.

OK, I was able to find it by myself.
The solution was to change a scope on $first and last and then add a ng-show and ng-hide depending on the scope value.
Here's the code if anyone has this kind of issue:
<main class="gallery">
<nav class="gallery-list-thumbs">
<ul>
<li ng-click="showLarge($event); modalShow();setPosition('inbetween'); $first && setPosition('first') ; $last && setPosition('last')" ng-repeat="photo in photos | filter:{'section': section }">
<img data-ref="ref-{{ photo.id }}" data-orientation="{{ photo.orientation }}" class="photo-small" ng-src="photos/{{ photo.section }}/th/{{ photo.src }}">
</li>
</ul>
</nav>
<section class="gallery-item" ng-hide="modalHidden">
<h1 ng-model="section">{{ section }}</h1>
<div class="photo-container">
<div class="modal-close" ng-click="modalShow()"></div>
<div class="modal-prev" ng-hide="currentOrder == 'first';">{{ currentOrder }}</div>
<div class="modal-next" ng-hide="currentOrder == 'last';">{{ currentOrder }}</div>
<img data-photoref="ref-{{ photo.id }}" ng-repeat="photo in photos | filter:{'section': section }" class="photo-large below orientation-{{ photo.orientation }}" ng-class="{'above':$first}" ng-src="photos/{{ section }}/{{ photo.src }}">
</div>
</section>
</main>

Related

Ng-repeat an array of images

I'm trying to use an ng-repeat on an array of different images. Problem is, these images need to be in-line and do a flip transition. Here's what I had before I decided to use ng-repeat:
`<div class="row">
<div class="col-md-3">
<div class="flip-container" ontouchstart="this.classList.toggle('hover');">
<div>
<div class="front">
<img id="firstTrophy" class="trophy locked" src="/img/trophy.png" />
</div>
<div class="back box">
<p class="text">
You're a champion!!!!
</p>
</div>
</div>
</div>
</div>`
And here's the ng-repeat I have now:
(in view.html)
`<div ng-repeat="trophy in trophies track by $index">
<img src="{{ trophy }}" />`
(in controller)
var trophies = [
"img/trophy.png",
"img/trophy.png",
"img/trophy.png",
"img/trophy.png",
"img/trophy.png"];
Thanks for any help you all can provide!
Replace src with ng-src
<div ng-repeat="trophy in trophies track by $index">
<img ng-src="{{ trophy }}" />`
DEMO

check if $index in ng-repeat is null

I have a grid view with two grids per row. This is the code:
<ion-content scroll="true" class="has-header">
<div class="row" style="padding-bottom: 40px;">
</div>
<div ng-repeat="i in products">
<div class="row" ng-if="$even">
<div class="col col-50">
<a class="item item-thumbnail-center" href="#">
<img src="http://{{host}}/{{
products[$index].prod_img
}}" class="img-thumbnail">
<h2>{{products[$index].prod_name}}</h2>
<p>Php {{products[$index].prod_price}}.00</p>
</a>
</div>
<div class="col col-50" ng-if="$index + 1">
<a class="item item-thumbnail-center" href="#">
<img src="http://{{host}}/{{
products[$index + 1].prod_img
}}" class="img-thumbnail">
<h2>{{products[$index + 1].prod_name}}</h2>
<p>Php {{products[$index + 1].prod_price}}.00</p>
</a>
</div>
</div>
</div>
</ion-content>
controller.js
$http.get("http://"+ $scope.host +"/mobile/get_products.php?cat_id=" + $stateParams.cat_id)
.then(function(response) {
$scope.products = response.data;
});
The problem is when the size of the array products is an odd, the second grid in the last row still shows up and certainly no item is displayed in there because the item is specified by the index is null. I've found some other solution on how to make this by configuring the array right from the controller but I want to ask if there is any way to check using an angular directive whether $index is null, and if true, the grid will be hidden.
you can use ng-class directive and put a css class which will get true when products[$index] === null | products[$index+1] === null. it will be like
ng-class={'hide-row': products[$index] === null | products[$index+1] === null}
where css
.hide-row{ display : none;}

AngularJS loop show the same image

In my project I need to show for each element its image.
This is my html:
<div ng-repeat="event in events.events" class="event show-place" data-id="#{{ event.id }}"
ng-mouseenter="selectEvent(event)">
<div class="cover-events">
<img width="100%" height="100%"
ng-src="#{{ selectedEvent.place.image | addFullPathToImage }}"
alt="#{{ selectedEvent.place.name }}"
>
<div class="user-info">
<a href="#{{ event.created_by.profileSlug }}">
<immagine-profilo hashid="#{{ event.created_by.hashid }}"
username="#{{ event.created_by.profile.username }}"
photo="#{{ event.created_by.profile.photo }}"></immagine-profilo>
<div class="user-event" ng-bind="event.created_by.profile.username"></div>
<rating class="user-experience" stars="#{{ event.created_by.level }}"
icon="star"></rating>
</a>
</div>
</div>
<div class="info-event">
<div vertilize class="content-info">
<div class="title-place">
<h2 ng-bind="event.place.name"></h2>
</div>
<div class="date-time">
#{{ event.unix_date | formatDate }} | #{{ event.time_start }}
</div>
<div class="event-feature">
<div class="category pull-left">
<img ng-src="#{{ event.category.icon | addFullPathToIcon }}"
alt="#{{ event.category.name }}">
<span ng-bind="event.category.name"></span>
</div>
<div class="difficulty pull-left">
<rating class="difficulty-bar" stars="#{{ event.difficulty_level }}"
icon="circle"></rating>
<span>
{{ trans('frontend/events/events.strings.difficulty') }}
</span>
</div>
<div class="participants pull-left">
<div class="speech-bubble speech-bubble-bottom">
#{{ event.participants_count }}
</div>
<span>{{ trans('frontend/events/events.strings.participants') }}</span>
</div>
</div>
</div>
<a class="link-with-arrow"
href="{{ localeRoute('events.event', [null, null])}}/#{{ event.slug }}/#{{ event.id }}">
{{ trans('frontend/pages/place.sidebar.links.read_more') }}
</a>
</div>
the image code is this:
<img width="100%" height="100%"
ng-src="#{{ selectedEvent.place.image | addFullPathToImage }}"
alt="#{{ selectedEvent.place.name }}">
and this is the filter:
app.filter('addFullPathToIcon', function () {
return function (text) {
return window.paths.categoriesPath + "/" + text;
}
});
When I run the code, the same image is shown for each event, if I click on one of it, the images will change and show the second image for every event.
Someone can help me to see the error?
It looks to me like there's only one "selectedEvent", and it is defined on ng-mouseenter. Perhaps you want
<img width="100%" height="100%"
ng-src="#{{ event.place.image | addFullPathToImage }}"
alt="#{{ event.place.name }}">
instead inside your ng-repeat if you don't want all the images to change with the event that is selected...

Bind button/links with my carousel images in Angularjs

In my application there is a carousel with images that I get from my service. Under the carousel there are 3 buttons that give more information about the image.
These information buttons should replace the bullet indicators for a standard carousel. The buttons get an active class when the corresponding image is displayed so it stands out from the other 2.
Below is my code, I'm using this carousel
<ul rn-carousel>
<li ng-repeat="promo in promos">
<img ng-src="{{ promo.slider[0].slide }}" alt="{{ promo.name }}">
</li>
</ul>
<div ng-repeat="promo in promos">
<button>
<h2>{{ promo.name }}</h2>
<p>- {{ promo.descr }} <span>{{ promo.disc }}</span></p>
</button>
</div>
I have no problems getting the info out of my service, it's just the linking part that is giving me problems.
I found the solution after searching through the issues page of the carousel I'm using.
<ul rn-carousel rn-carousel-index="currentSlide">
<li ng-repeat="promo in promos">
<img ng-src="{{ promo.slider[0].slide }}" alt="{{ promo.name }}">
</li>
</ul>
<div ng-repeat="promo in promos">
<button ng-class="{activeBtn: $index==$parent.currentSlide}" ng-click="$parent.currentSlide = $index">
<h2>{{ promo.name }}</h2>
<p>- {{ promo.descr }} <span>{{ promo.disc }}</span></p>
</button>
</div>
I had to name my carousel-index and for my indicators I had to refer to the parent element for the binding to work.
Thanks to Capricorn for leading the way.

Can't get angular-masonry to work

I've installed angular-masonry and tried to use it with my single-page Bootstrap view. The images from the ng-repeat directive render but only in a single column. I am not able to figure out why and I am not getting any JS errors.
This is my view:
<div class="container">
<div class="row">
<div class="span12">
<masonry column-width="230">
<div ng-repeat="image in results.images">
<img class="asset_image" ng-src="{{ image.url }}" alt="A masonry brick">
</div>
</masonry>
</div>
</div>
</div>
Official Docs:
You still need to use masonry-brick either as class name or element attribute on sub-elements in order to register it to the directive.
Don't you need the masonry-brick class or attribute?
<div class="masonry-brick" ng-repeat="image in results.images">
<img class="asset_image" ng-src="{{ image.url }}" alt="A masonry brick">
</div>
or
<div masonry-brick ng-repeat="image in results.images">
<img class="asset_image" ng-src="{{ image.url }}" alt="A masonry brick">
</div>
Final sample:
<div class="container">
<div class="row">
<div class="span12">
<masonry column-width="230">
<div class="masonry-brick" ng-repeat="image in results.images">
<img class="asset_image" ng-src="{{ image.url }}" alt="A masonry brick">
</div>
</masonry>
</div>
</div>
</div>

Resources