Angular: Using $last to get last element visible using ng-show - javascript

So I have an ng-repeat container div inside which I have a bunch of images.
For each image, there is a div next to it. I want only the div of the final image to be visible and I achieve this using $last. This works like a charm.
Now I have a filter button in the page also, and when this button is clicked some of these images get hidden. This show/hide is done using ng-show on the image tag.
What I want is that when the filter button is clicked and some of the images are hidden, I want the div next to the final visible image to get shown. Seems like $last is not aware of the ng-show/hide value. How can I handle it so that the div next to the last visible image is still shown?
<div class='container' ng-repeat="image in album">
<div class='wrapper' ng-show="getFilterValue(image.imageId)">
<div><img src='{{image.src}}'></div>
<div class='embellish-end' ng-class='{'hidden':!$last}'>The End</div>
</div>
</div>
Any help is greatly appreciated!

Instead of using ng-show you could filter the ng-repeat using angular's built in ng-repeat filter. If your getFilterValue function returns a boolean this should work for you. Then your $last should know what is truly last based on what meets the filter criteria.
<div class='container' ng-repeat="image in album | filter:getFilterValue(image.imageId)">
<div class='wrapper'>
<div><img src='{{image.src}}'></div>
<div class='embellish-end' ng-class='{'hidden':!$last}'>The End</div>
</div>
</div>

Try putting the ng-show on the image rather than the whole div wrapper:
<div class='container' ng-repeat="image in album">
<div class='wrapper'>
<div ng-show="getFilterValue(image.imageId)"><img src='{{image.src}}'></div>
<div class='embellish-end' ng-class='{'hidden':!$last}'>The End</div>
</div>
</div>
Unrelated: use ng-src rather than src when using angularized image sources to avoid browser errors.

Related

how to toggle a specific div in javascript

i have dynamic data in my rails view, all divs have the same name; 'allData', which has alot of info, so i have it not displayed, i want to display that specific div and not all divs when i click show, but it shows all divs, i want to be able to show just that target div i clicked
$('.show'').on('click', (event) =>{
$('.allData').toggle();
$(event.currentTarget).closest('.allData').toggle();
})
<div class='eachData'>
<div class='header'>
<div class='show'> show</div>
<div class='numberOfdata'> 100</div>
</div>
<div class='allData; display:none'>
"foobar all data is here"
</div>
</div>
<div class='eachData'>
.......
</div>
<div class='eachData'>
.......
</div>
Your closest call is on the right track but you're not quite using it right. First you want to find the container (.eachData) that contains your <div class="show">, you use closest for that:
let container = $(event.currentTarget).closest('.eachData');
then you search within that container for the .allData you want to toggle by using find:
container.find('.allData').toggle();
So you use closest to go up the node tree and then find to come back down.
BTW, this:
<div class='allData; display:none'>
should be:
<div class="allData" style="display: none">
The class attribute contains CSS class names delimited by whitespace, raw CSS goes in the style attribute and is delimited by semicolons.
Your inline style on the div should be as follows:
<div class="allData" style="display: none">
Then try the following:
$('.show').on('click', function() {
$(document).find('.eachData .allData:visible').hide('fast');
$(this).parent().closest('.allData').show('fast');
});

ngShow not working with multiElement

I have the following rendered HTML:
<div class="tutorial-dot ng-hide" ng-show-start="currentStep">
<div class="dot"></div>
</div>
<div class="tutorial-modal" ng-show-end="">
As you can see, the ng-show-start element is hidden but the ng-show-end element is not. They should both have the same ngShow directive instance applied to them since it supports multiElement but the ngShow directive is not working properly on the ng-show-end element.
I was able to get this to work by removing the ng-hide class on the first div. I added some text just to see if the show was working. currentStep is not initialized so it will start hiding the the divs. When you click the button it will flip the value of currentStep to true with the ng-click.
<div class="tutorial-dot" ng-show-start="currentStep">
<div class="dot">Hello, this will show when the current step is true.</div>
</div>
<div class="tutorial-modal" ng-show-end>
This is the end
</div>
Here is a link to a codepen that demonstrates this working. If there are more questions about this fork my codepen and show the issue you are having. http://codepen.io/mkl/pen/PpMvzZ?#

Multiple Featherlight galleries on one page without unique classes

How can I call multiple galleries using Featherlight Gallery without having to use unique classes?
I tried
if($('.image-gallery').length) {
$('.image-gallery').featherlightGallery({
variant: 'gal',
filter: $(this).find('.featured-image')
});
}
but I don't think filter works the way I think it does.
Currently - it loads each item on the page in the same gallery lightbox. I want a unique lightbox gallery for each parent .image-gallery. In otherwords, clicking the arrows in the first lightbox gallery should not show me photos from the second one.
<div class="image-gallery">
<div class="featured-image" data-featherlight="http://imgurl"><img /></div>
<div class="featured-image" data-featherlight="http://imgurl"><img /></div>
</div>
<div class="image-gallery">
<div class="featured-image" data-featherlight="http://imgurl"><img /></div>
<div class="featured-image" data-featherlight="http://imgurl"><img /></div>
</div>
Here is a Fiddle.
You're pretty close. Problem is that by using data-featherlight, you are using the auto binding, which is not what you want. Turn the auto binding off, or change your markup, like this
Best way is to bind them individually. I didn't test (since you didn't provide a working example), but this should work:
$('.image-gallery).each(function(_i, gallery)) {
$(gallery).featherlightGallery({
variant: 'gal',
filter: '.featured-image'
});
})
Note: filter is a jQuery selector (string).

Can't use custom width with Angular-Slick

Has anybody worked with Angular-Slick? I'm trying to use this directive so I can get a carousel that displays multiple images/cards. Everything works fine but I can't get to customize the CSS width of the images. I set the variableWidth to true, but nothing. I also removed the slides-to-show option so variableWidth can work, but no results — I still get the default width by Slick. Here is the code below:
<slick infinite="true" slides-to-show="4" slides-to-scroll="4"
init-onload="true" data="popularCourses" variableWidth="true" arrows="true">
<div class="homepage-course-box" ui-sref="courses.show({id: popCourse.id})" ng-repeat="popCourse in popularCourses">
<div class="row" style="margin:0;">
<div class="course-img"
ui-sref="courses.show({id: popCourse.id})"
ng-style="{'background-image':'url({{popCourse.banner_url}})'}"></div>
<div class="author-avatar" ng-style="{'background-image':'url({{popCourse.author.avatar}})'}"></div>
</div>
<div class="row" style="margin:0;">
<a ui-sref="courses.show({id: popCourse.id})" class="homepage-course-title">{{popCourse.title}}</a>
</div>
<div class="row homepage-course-last-row">
<p class="author-name">{{popCourse.author.full_name}}</p>
<p class="course-duration">{{popCourse.duration | secondsToHHMM | date: "H'H' mm'M'"}}</p>
</div>
</div>
</div>
</slick>
From the code, I'm using ng-repeat so it displays all the images, I'm suspecting is interfering with the width, I may be wrong.
So far I like this angular directive, but it will be awesome if I can set my own custom CSS width. Please can anybody help with this! Your help will be appreciated!
Html is not case sensitive so angular requires dashes in attribute names on directives. So instead of variableWidth put variable-width.

Possible to sort rendered images based on class of parent div?

I have some images that are wrapped within containers like this:
<div id="swatchcontainer">
<div class="swatchimgouter">
<div class="swatchimginner">
<img src="whatever1.jpg" alt="some text" title="some text too"/>
</div>
</div>
<div class="swatchimgouter">
<div class="swatchimginner swatchdisabled">
<img src="whatever2.jpg" alt="some text" title="some text too"/>
</div>
</div>
<div class="swatchimgouter">
<div class="swatchimginner">
<img src="whatever3.jpg" alt="some text" title="some text too"/>
</div>
</div>
etc., etc.
</div>
It's not mission critical, but I got to thinking that it's probably possible to sort these images fairly easy using JQuery. I would like to place all images that are wrapped in the "swatchdisabled" class at the end.
There could be a couple of dozen of these images. They're all styled with float:left and so they display horizontally in rows. Even if there are a couple of dozen, there are only 2 rows. Each of these images is 30 pixels by 30 pixels.
It's just a UI consideration. Makes it a lot easier to keep track of which items are disabled and which are enabled by placing all disabled images at the end.
If it's fairly simple to do this, I'll also need to keep their inner div classes with them.
Try like this:
$('.swatchdisabled').each(function(){
$(this).parent().parent().append( $(this).parent() );
});
this will move all .swatchimgouter divs,which have .swatchdisabled class on .swatchimginner div, to the end of their parent.
Demo is here.
$('.swatchdisabled').each(function() {
$(this).closest('.swatchimgouter').appendTo($('#parentdiv'));
});
or
$('.swatchdisabled').each(function() {
$(this).parent().appendTo($('#parentdiv'));
});
where #parentid is the common parent of all your wrapping div
A version that does not rely on the container div that you mention in the comments, it will just work with the given divs in your question:
$(".swatchimgouter").last().after("<div id='wall'></div>")
$(".swatchdisabled").each(function(){
$("#wall").after($(this).parent());
});
$("#wall").remove();
You could squeeze more juice out but you get the idea.

Categories

Resources