Reputation: 15384
I am using Slick for a carousel implementation and everything works fine when the pages loads.What I am trying to achieve is that when i make an Ajax call to retrieve new data I still want the slick carousel implementation, at the moment i lose it.
I have put the call for slick into a function
function slickCarousel() {
$('.skills_section').slick({
infinite: true,
slidesToShow: 3,
slidesToScroll: 1
});
}
and then I call the function within my success callback
$.ajax({
type: 'get',
url: '/public/index',
dataType: 'script',
data: data_send,
success: function() {
slickCarousel();
}
});
But the function isn't being called. How can I reinitialize this js?
Upvotes: 32
Views: 157060
Reputation: 857
Although, above answers are correct, there is one more problem regarding showing new slides with updated/new data after array has been updated and then need to refresh the slick slider instance.
If we don't do like this, then somehow slick keeps showing older data which was bounded there before updating the array even if the array is already updated.
So the code with newer frameworks available and ES6 approach might look something like this.
Let's say we are showing array of data via loop in modern library like vue, react, angular or alpine js and we have array of shops
to show as a slider.
Each time someone triggers some action, array(and eventually dom) is updated but we have to manually tell slick slider to update the slides data as per the data in the new array. here we have data in the form of shops
array.
{
shops: [],
init() {
let self = this;
// watch for your data and provide callback function after it has been updated
// this $watch is example from alpine js but similar could be available in other framrworks
self.$watch('shops',(currentShops,oldShops) => {
//currentshops holds the new value of shops after update
//oldShops holds older value before update
//first remove all slides that were attached with slick before shops array was updated (sorted for example)
$('#shops-section-slider.slick-initialized').slick('slickRemove', null, null, true);
//After this, add new slides after shops has been updated(sorted)
// via template that accepts shop as an argument
currentShops.forEach(function(shop,index) {
$('#shops-section-slider.slick-initialized').slick('slickAdd', self.getSliderTmpl(shop));
})
//after adding and removing is completed,
//finally just call refresh to prevent reinit entirely.
$('#shops-section-slider.slick-initialized').slick('refresh');
})
//shopsPromise only does slider creation and other things when data has been updated in dom.
shopsPromise.then(function(data) {
//update shops here via data that has been recieved
shops.push(data)
}).then(function() {
//crate slider after promise is resolved
$('#shops-section-slider').not('.slick-initialized').slick({
//your slick settings
})
});
},
getSliderTmpl(shop) {
return `<div class="col-12 col-md-6 col-lg-4 col-xl-4 d-flex flex-column shops-section">
<div class="row flex-grow-1 flex-column flex-xxl-row">
<div class="col-12 col-xxl-6">
<div class="shops-img position-relative">
<strong class="shops-title-card d-block d-xxl-none">${shop.whateveravailable}</strong>
</div>
</div>
</div>
</div>`;
}
}
and inside the html, we even don't need the <template>
element which is used as looping in alpine js as it creates incorrect width and issues due to one more slides there so we can omit that, and thus managing entire slider data and template both from js only.
<div class="row shops-section-wrapper" id="shops-section-slider"></div>
Upvotes: 0
Reputation: 81
Slick Version: 1.8.0
function getSliderSettings() {
return {
slidesToShow: 3,
slidesToScroll: 1,
loop: true,
arrows: true,
dots: false,
}
}
$.ajax({
type: 'get',
url: '/public/index',
dataType: 'html',
data: some_data,
success: function(response) {
$('[data-role="slick-slider"]').slick('unslick');
$('[data-role="slick-slider"]').html($(response).html());
$('[data-role="slick-slider"]').slick(getSliderSettings());
}
});
Upvotes: 0
Reputation: 4926
I was facing an issue where the Slick carousel wasn't refreshing on new data instead it was appending new slides to the previous ones, I found a solution that solved my problem, it's very simple.
TL;DR
Try passing unslick, then assign your new data which is being rendered inside slick carousel, and then initialize slick again. these were the steps for me:jQuery('.class-or-#id').slick('unslick'); myData = my-new-data; jQuery('.class-or-#id').slick({slick-options});
Notes:
Check the slick.js website for syntax just in case. Also, make sure you are not using unslick before slick is even initialized. What that means is, simply initialize like this the very first ajax call
jquery('.my-class').slick({slick-options})
And once it's initialized then follow the above steps. You might wanna use if-else.
Upvotes: 4
Reputation: 41
Try this code, it helped me!
$('.slider-selector').not('.slick-initialized').slick({
dots: true,
arrows: false,
setPosition: true
});
Upvotes: 4
Reputation: 618
Here we go, guys! It helped me
$('.slick-slider').not('.slick-initialized').slick({
infinite: false,
slidesToShow: 1,
slidesToScroll: 1,
dots: true,
arrows: false,
touchThreshold: 9
});
Upvotes: 3
Reputation: 3155
$('#slick-slider').slick('refresh'); //Working for slick 1.8.1
Upvotes: 18
Reputation: 332
After calling an request, set timeout to initialize slick slider.
var options = {
arrows: false,
slidesToShow: 1,
variableWidth: true,
centerPadding: '10px'
}
$.ajax({
type: "GET",
url: review_url+"?page="+page,
success: function(result){
setTimeout(function () {
$(".reviews-page-carousel").slick(options)
}, 500);
}
})
Do not initialize slick slider at start. Just initialize after an AJAX with timeout. That should work for you.
Upvotes: -1
Reputation: 539
The best way is you should destroy the slick slider after reinitializing it.
function slickCarousel() {
$('.skills_section').slick({
infinite: true,
slidesToShow: 3,
slidesToScroll: 1
});
}
function destroyCarousel() {
if ($('.skills_section').hasClass('slick-initialized')) {
$('.skills_section').slick('destroy');
}
}
$.ajax({
type: 'get',
url: '/public/index',
dataType: 'script',
data: data_send,
success: function() {
destroyCarousel()
slickCarousel();
}
});
Upvotes: 20
Reputation: 65
The best way would be to use the unslick
setting or function(depending on your version of slick) as stated in the other answers but that did not work for me. I'm getting some errors from slick that seem to be related to this.
What did work for now, however, is removing the slick-initialized
and slick-slider
classes from the container before reinitializing slick, like so:
function slickCarousel() {
$('.skills_section').removeClass("slick-initialized slick-slider");
$('.skills_section').slick({
infinite: true,
slidesToShow: 3,
slidesToScroll: 1
});
}
Removing the classes doesn't seem to initiate the destroy event(not tested but makes sense) but does cause the later slick()
call to behave properly so as long as you don't have any triggers on destroy, you should be good.
Upvotes: 3
Reputation: 76
I had to unslick the carousel before the ajax call starts, but you can't do that until there is already a slick carousel. So, I set a variable to 0 and only run unslick after it changed
var slide = 0
if(slide>0)
$('#ui-id-1').slick('unslick');
$.ajax({
//do stuff, here
},
success: function( data ) {
$('#ui-id-1').slick();
slide++;
}
Upvotes: 3
Reputation: 281
You should use the unslick method:
function getSliderSettings(){
return {
infinite: true,
slidesToShow: 3,
slidesToScroll: 1
}
}
$.ajax({
type: 'get',
url: '/public/index',
dataType: 'script',
data: data_send,
success: function() {
$('.skills_section').slick('unslick'); /* ONLY remove the classes and handlers added on initialize */
$('.my-slide').remove(); /* Remove current slides elements, in case that you want to show new slides. */
$('.skills_section').slick(getSliderSettings()); /* Initialize the slick again */
}
});
Upvotes: 28
Reputation: 751
This should work.
$.ajax({
type: 'get',
url: '/public/index',
dataType: 'script',
data: data_send,
success: function() {
$('.skills_section').slick('reinit');
}
});
Upvotes: 15
Reputation: 6003
There is a unslick
method which de-initializes the carousel, so you might try using that before re-initializing it.
$.ajax({
type: 'get',
url: '/public/index',
dataType: 'script',
data: data_send,
success: function() {
$('.skills_section').unslick(); // destroy the previous instance
slickCarousel();
}
});
Hope this helps.
Upvotes: 4