I'm doing a web app with Angular and Angular Material. I have to do a carousel and I found a nice jquery's component. So I made a directive with that. It works, but the problem is that for 1 or 2 seconds I see the elements of the carousel displayed like a <ul> list, so vertically. Then, when the directive is build, I see correctly the carousel.
Is there a way to insert a loader (maybe with angular material) that shows while the directive is not build?
This is the code
angular.module('app').directive("slick", function($timeout) {
return function(scope: any, el: any, attrs: any) {
$timeout((function() {
el.slick({
arrows: true,
autoplay: false,
dots: true,
infinite: false,
speed: 300,
slidesToShow: 4,
slidesToScroll: 4,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
infinite: true,
dots: true
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 2,
slidesToScroll: 2
}
},
{
breakpoint: 480,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
// You can unslick at a given breakpoint now by adding:
// settings: "unslick"
// instead of a settings object
]
})
}), 100)
}
});
I would use a boolean scope variable that tracks when slick is initialized. Start it at false, and use slick's init event to know when to set to true.
Basically:
angular.module('app').directive("slick", function($timeout) {
return {
restrict: 'E',
replace: true,
scope: true,
templateUrl: 'slick.tpl.html',
link: function(scope: any, el: any, attrs: any) {
scope.slickReady = false;
// use a child element (defined in template) so we can toggle between carousel and spinner
var slickEl = el.children('.slick').first();
if(slickEl){
// listen for slick's init event
slickEl.on('init', function(){
scope.slickReady = true;
});
// initialize slick (not sure why you had it wrapped in $timeout in OP)
slickEl.slick({
...
});
}
};
}
});
slick.tpl.html
<div ng-switch on="slickReady">
<div class="slick" ng-switch-when="true"></div>
<div class="spinner" ng-switch-when="false">
<!-- use whatever kind of spinner you want -->
</div>
</div>
Related
Let's suppose slick slider pagination has 25 pages (it might be possible on mobile devices)
Is it possible to set up a slick slider to show pagination like shown below?
Pagination block: < 1 ... 2 3 4 ... 25 >
Update: what I mean is to hide some pages and show these dots instead
try this
<section class="slider">
<div>slide1</div>
<div>slide2</div>
<div>slide3</div>
<div>slide4</div>
<div>slide5</div>
</section>
<span class="pagingInfo"></span>
$(".slider").slick({
autoplay: true,
dots: true,
customPaging: function (slider, i) {
var thumb = $(slider.$slides[i]).data();
return `<a>${i}</a>`;
},
responsive: [
{
breakpoint: 500,
settings: {
dots: false,
arrows: false,
infinite: false,
slidesToShow: 2,
slidesToScroll: 2,
},
},
],
});
_high.html.erb:
<div class="col-xl-12">
<div class="default-slick-carousel freelancers-container freelancers-grid-layout">
<%= render partial: '/pages/top_trainers' %>
</div>
</div>
##To reinitialize the carousel when coming back to the carousel page, I have added this:
<script type="text/javascript">
$(document).ready(function(){
$('.default-slick-carousel').not('.slick-initialized').slick({
infinite: false,
slidesToShow: 3,
slidesToScroll: 1,
dots: false,
arrows: true,
adaptiveHeight: true,
responsive: [
{
breakpoint: 1292,
settings: {
dots: true,
arrows: false
}
},
{
breakpoint: 993,
settings: {
slidesToShow: 2,
slidesToScroll: 2,
dots: true,
arrows: false
}
},
{
breakpoint: 769,
settings: {
slidesToShow: 1,
slidesToScroll: 1,
dots: true,
arrows: false
}
}
]
});
})
</script>
So, when I am on this page, carousel is working fine.But when i am moving to some other page and coming back to the carousel page, carousel sliding is not working
I am using slick carousel in one of my projects & have added the configuration to display the next and prev button.
I am trying to tweak the default behavior of the next and prev button in such a way that clicking them just scrolls from left to right but the currently selected slide will remain the same. I am not able to tweak this default behavior and clicking the next and prev button is changing the selected slide as well. Has anyone tried the same?
$('.product-slider').slick({
dots: true,
infinite: false,
speed: 700,
slidesToShow: 4,
slidesToScroll: 4,
responsive: [{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
infinite: false,
dots: true
}
}, {
breakpoint: 768,
settings: {
slidesToShow: 2,
slidesToScroll: 2,
infinite: false,
dots: true
}
}, {
breakpoint: 480,
settings: {
slidesToShow: 1,
slidesToScroll: 1,
infinite: false,
dots: true
}
}
]
});
I am using a Slick slider/carousal and displaying six items currently. Now what I want to do is I want the script to detect if the browser has been resized or viewed from a smaller screen (say below 768px) then the number of items displayed should change to 3. This is a perfect replica of the media query function in CSS which detects the screen size for making the website responsive. Just the same thing I want to be performed in my jQuery function but I have never done so. Here is my script:
<script src="https://code.jquery.com/jquery-2.2.0.min.js" type="text/javascript"></script>
<script src="http://kenwheeler.github.io/slick/slick/slick.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
jQuery.noConflict();
jQuery(document).on('ready', function() {
jQuery(".center").slick({
dots: true,
infinite: true,
centerMode: true,
slidesToShow: 6,
slidesToScroll: 6
});
});
</script>
The plugin has already way to update the options on different view ports. Please have a look at this. Hope this will help you.
$('.responsive').slick({
dots: true,
infinite: false,
speed: 300,
slidesToShow: 4,
slidesToScroll: 4,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
infinite: true,
dots: true
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 2,
slidesToScroll: 2
}
},
{
breakpoint: 480,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
// You can unslick at a given breakpoint now by adding:
// settings: "unslick"
// instead of a settings object
]
});
I want to hide a directive at the beginning, when it is still creating. In this directive I'm integrating a jquery carousel.
This is the directive:
return {
restrict: 'E',
replace: true,
scope: true,
templateUrl: 'slick.html',
link: function(scope: any, element: any, attrs: any) {
scope.slickReady = false;
var slickEl = element.querySelector('.slick');
if(slickEl){
slickEl.on('init', function(){
scope.slickReady = true;
});
slickEl.slick({
arrows: true,
autoplay: false,
dots: true,
infinite: false,
speed: 300,
slidesToShow: 4,
slidesToScroll: 4,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
infinite: true,
dots: true
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 2,
slidesToScroll: 2
}
},
{
breakpoint: 480,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
]
})
}
}
}
This is the main html:
<slick></slick>
This is the slick.html:
<div ng-switch on="slickReady">
<div class="slick" ng-switch-when="true"></div>
<div class="spinner" ng-switch-when="false">
<div ng-repeat="item in todos">
<img ng-src="{{item.face}}" class="md-avatar img-center">
<p class="truncate">{{item.who}}</p>
</div>
</div>
</div>
The problem is that I have this error in console:
TypeError: element.querySelector is not a function
at Object.link (http://localhost/js/directives/slick.js:9:35)
EDIT
I tried to do this:
var slickEl = element[0]querySelector('.slick');
if(slickEl.length > 0)
because, looking at the debugging, the 'element' is so structured:
0:div length:1
In this way, I have not the error but the carousel doesn't build.
If You are using Jquery Carousel then it must be tipical jquery. So try:
slickEl=$(element).find(".slick");