Synced Carousels - javascript

I'm currently working with the Owl Carousel plugin to create multiple synced carousels as per their demo shown on the address below, though with multiple carousels on one page.
http://owlgraphic.com/owlcarousel/demos/sync.html
I've managed to duplicate the carousels successfully and got them to work independently apart from one specific problem when working with different numbers of small items. When I create more items in the top carousel than the bottom and select a small item outside of the bottom carousel's displayed items both small item carousels will shift to show that item (unselected on the top one)
In other words, with the following code, select "20" from the top carousel and watch the bottom carousel's small items carousel shift to the right to display item 20. Then select item 3 on the top small items carousel to watch the bottom small items carousel shift back again. Oddly, when the items number is increased within the bottom carousel's jQuery parameters it doesn't affect the top one at all.
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.min.js"></script>
<script type="text/javascript" src="http://owlgraphic.com/owlcarousel/owl-carousel/owl.carousel.js"></script>
<script>
$(document).ready(function() {
var sync1 = $("#sync1");
var sync2 = $("#sync2");
sync1.owlCarousel({
singleItem : true,
slideSpeed : 1000,
navigation: true,
pagination:false,
afterAction : syncPosition,
responsiveRefreshRate : 200,
});
sync2.owlCarousel({
items : 20,
itemsDesktop : [1199,10],
itemsDesktopSmall : [979,10],
itemsTablet : [768,8],
itemsMobile : [479,4],
pagination:false,
responsiveRefreshRate : 100,
afterInit : function(el){
el.find(".owl-item").eq(0).addClass("synced");
}
});
function syncPosition(el){
var current = this.currentItem;
$("#sync2")
.find(".owl-item")
.removeClass("synced")
.eq(current)
.addClass("synced")
if($("#sync2").data("owlCarousel") !== undefined){
center(current)
}
}
$("#sync2").on("click", ".owl-item", function(e){
e.preventDefault();
var number = $(this).data("owlItem");
sync1.trigger("owl.goTo",number);
});
function center(number){
var sync2visible = sync2.data("owlCarousel").owl.visibleItems;
var num = number;
var found = false;
for(var i in sync2visible){
if(num === sync2visible[i]){
var found = true;
}
}
if(found===false){
if(num>sync2visible[sync2visible.length-1]){
sync2.trigger("owl.goTo", num - sync2visible.length+2)
}else{
if(num - 1 === -1){
num = 0;
}
sync2.trigger("owl.goTo", num);
}
} else if(num === sync2visible[sync2visible.length-1]){
sync2.trigger("owl.goTo", sync2visible[1])
} else if(num === sync2visible[0]){
sync2.trigger("owl.goTo", num-1)
}
}
/* carousel two */
var sync3 = $("#sync3");
var sync4 = $("#sync4");
sync3.owlCarousel({
singleItem : true,
slideSpeed : 1000,
navigation: true,
pagination:false,
afterAction : syncPosition2,
responsiveRefreshRate : 200,
});
sync4.owlCarousel({
items : 15,
itemsDesktop : [1199,10],
itemsDesktopSmall : [979,10],
itemsTablet : [768,8],
itemsMobile : [479,4],
pagination:false,
responsiveRefreshRate : 100,
afterInit : function(el){
el.find(".owl-item").eq(0).addClass("synced");
}
});
function syncPosition2(el){
var current = this.currentItem;
$("#sync4")
.find(".owl-item")
.removeClass("synced")
.eq(current)
.addClass("synced")
if($("#sync4").data("owlCarousel") !== undefined){
center(current)
}
}
$("#sync4").on("click", ".owl-item", function(e){
e.preventDefault();
var number = $(this).data("owlItem");
sync3.trigger("owl.goTo",number);
});
function center(number){
var sync4visible = sync4.data("owlCarousel").owl.visibleItems;
var num = number;
var found = false;
for(var i in sync4visible){
if(num === sync4visible[i]){
var found = true;
}
}
if(found===false){
if(num>sync4visible[sync4visible.length-1]){
sync4.trigger("owl.goTo", num - sync4visible.length+2)
}else{
if(num - 1 === -1){
num = 0;
}
sync4.trigger("owl.goTo", num);
}
} else if(num === sync4visible[sync4visible.length-1]){
sync4.trigger("owl.goTo", sync4visible[1])
} else if(num === sync4visible[0]){
sync4.trigger("owl.goTo", num-1)
}
}
});
</script>
<link rel="stylesheet" type="text/css" href="http://owlgraphic.com/owlcarousel/owl-carousel/owl.carousel.css">
<style>
#sync1 .item{
background: #0c83e7;
padding: 80px 0px;
margin: 5px;
color: #FFF;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
text-align: center;
}
#sync2 .item{
background: #C9C9C9;
padding: 10px 0px;
margin: 5px;
color: #FFF;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
text-align: center;
cursor: pointer;
}
#sync2 .item h1{
font-size: 18px;
}
#sync2 .synced .item{
background: #0c83e7;
}
/*carousel 2 */
#sync3 .item{
background: #0c83e7;
padding: 80px 0px;
margin: 5px;
color: #FFF;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
text-align: center;
}
#sync4 .item{
background: #C9C9C9;
padding: 10px 0px;
margin: 5px;
color: #FFF;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
text-align: center;
cursor: pointer;
}
#sync4 .item h1{
font-size: 18px;
}
#sync4 .synced .item{
background: #0c83e7;
}
</style>
<div id="sync1" class="owl-carousel">
<div class="item"><h1>1</h1></div>
<div class="item"><h1>2</h1></div>
<div class="item"><h1>3</h1></div>
<div class="item"><h1>4</h1></div>
<div class="item"><h1>5</h1></div>
<div class="item"><h1>6</h1></div>
<div class="item"><h1>7</h1></div>
<div class="item"><h1>8</h1></div>
<div class="item"><h1>9</h1></div>
<div class="item"><h1>10</h1></div>
<div class="item"><h1>11</h1></div>
<div class="item"><h1>12</h1></div>
<div class="item"><h1>13</h1></div>
<div class="item"><h1>14</h1></div>
<div class="item"><h1>15</h1></div>
<div class="item"><h1>16</h1></div>
<div class="item"><h1>17</h1></div>
<div class="item"><h1>18</h1></div>
<div class="item"><h1>19</h1></div>
<div class="item"><h1>20</h1></div>
<div class="item"><h1>21</h1></div>
<div class="item"><h1>22</h1></div>
<div class="item"><h1>23</h1></div>
</div>
<div id="sync2" class="owl-carousel">
<div class="item"><h1>1</h1></div>
<div class="item"><h1>2</h1></div>
<div class="item"><h1>3</h1></div>
<div class="item"><h1>4</h1></div>
<div class="item"><h1>5</h1></div>
<div class="item"><h1>6</h1></div>
<div class="item"><h1>7</h1></div>
<div class="item"><h1>8</h1></div>
<div class="item"><h1>9</h1></div>
<div class="item"><h1>10</h1></div>
<div class="item"><h1>11</h1></div>
<div class="item"><h1>12</h1></div>
<div class="item"><h1>13</h1></div>
<div class="item"><h1>14</h1></div>
<div class="item"><h1>15</h1></div>
<div class="item"><h1>16</h1></div>
<div class="item"><h1>17</h1></div>
<div class="item"><h1>18</h1></div>
<div class="item"><h1>19</h1></div>
<div class="item"><h1>20</h1></div>
<div class="item"><h1>21</h1></div>
<div class="item"><h1>22</h1></div>
<div class="item"><h1>23</h1></div>
</div>
<!-- carousel two -->
<div id="sync3" class="owl-carousel">
<div class="item"><h1>1</h1></div>
<div class="item"><h1>2</h1></div>
<div class="item"><h1>3</h1></div>
<div class="item"><h1>4</h1></div>
<div class="item"><h1>5</h1></div>
<div class="item"><h1>6</h1></div>
<div class="item"><h1>7</h1></div>
<div class="item"><h1>8</h1></div>
<div class="item"><h1>9</h1></div>
<div class="item"><h1>10</h1></div>
<div class="item"><h1>11</h1></div>
<div class="item"><h1>12</h1></div>
<div class="item"><h1>13</h1></div>
<div class="item"><h1>14</h1></div>
<div class="item"><h1>15</h1></div>
<div class="item"><h1>16</h1></div>
<div class="item"><h1>17</h1></div>
<div class="item"><h1>18</h1></div>
<div class="item"><h1>19</h1></div>
<div class="item"><h1>20</h1></div>
<div class="item"><h1>21</h1></div>
<div class="item"><h1>22</h1></div>
<div class="item"><h1>23</h1></div>
</div>
<div id="sync4" class="owl-carousel">
<div class="item"><h1>1</h1></div>
<div class="item"><h1>2</h1></div>
<div class="item"><h1>3</h1></div>
<div class="item"><h1>4</h1></div>
<div class="item"><h1>5</h1></div>
<div class="item"><h1>6</h1></div>
<div class="item"><h1>7</h1></div>
<div class="item"><h1>8</h1></div>
<div class="item"><h1>9</h1></div>
<div class="item"><h1>10</h1></div>
<div class="item"><h1>11</h1></div>
<div class="item"><h1>12</h1></div>
<div class="item"><h1>13</h1></div>
<div class="item"><h1>14</h1></div>
<div class="item"><h1>15</h1></div>
<div class="item"><h1>16</h1></div>
<div class="item"><h1>17</h1></div>
<div class="item"><h1>18</h1></div>
<div class="item"><h1>19</h1></div>
<div class="item"><h1>20</h1></div>
<div class="item"><h1>21</h1></div>
<div class="item"><h1>22</h1></div>
<div class="item"><h1>23</h1></div>
</div>
I'm sure it's a case of a variable that needs a different name assigned to it but I can't for the life of me work out what's wrong. Any thoughts?

Having taken a look at it myself it was a simple case of renaming the "current", "num" and "number" variables in the second copy of the script. Now to name them something more meaningful!!
/* carousel two */
var sync3 = $("#sync3");
var sync4 = $("#sync4");
sync3.owlCarousel({
singleItem : true,
slideSpeed : 1000,
navigation: true,
pagination:false,
afterAction : syncPosition2,
responsiveRefreshRate : 200,
});
sync4.owlCarousel({
items : 15,
itemsDesktop : [1199,10],
itemsDesktopSmall : [979,10],
itemsTablet : [768,8],
itemsMobile : [479,4],
pagination:false,
responsiveRefreshRate : 100,
afterInit : function(el){
el.find(".owl-item").eq(0).addClass("synced");
}
});
function syncPosition2(el){
var current2 = this.currentItem;
$("#sync4")
.find(".owl-item")
.removeClass("synced")
.eq(current2)
.addClass("synced")
if($("#sync4").data("owlCarousel") !== undefined){
center2(current2)
}
}
$("#sync4").on("click", ".owl-item", function(e){
e.preventDefault();
var number2 = $(this).data("owlItem");
sync3.trigger("owl.goTo",number2);
});
function center2(number2){
var sync4visible = sync4.data("owlCarousel").owl.visibleItems;
var num2 = number2;
var found = false;
for(var i in sync4visible){
if(num2 === sync4visible[i]){
var found = true;
}
}
if(found===false){
if(num2>sync4visible[sync4visible.length-1]){
sync4.trigger("owl.goTo", num2 - sync4visible.length+2)
}else{
if(num2 - 1 === -1){
num2 = 0;
}
sync4.trigger("owl.goTo", num2);
}
} else if(num2 === sync4visible[sync4visible.length-1]){
sync4.trigger("owl.goTo", sync4visible[1])
} else if(num === sync4visible[0]){
sync4.trigger("owl.goTo", num2-1)
}
}

Related

Have dragula show drop position on hover over element

I have got a drag and drop functionality working with dragula so that it creates elements to drop the element into as a child. The idea is that you can make any element become a container to hold child items.
The problem I am having is that I don't want the drop locations to be visible until I have hovered my draggable element over. When dragging an element around the page, it renders all the parent containers - but i only really want that to appear when hovering over a spot where it can be created. Not so much of a problem with a small amount of items but when you got 100+ items its causes the page to grow and is quite jarring.
Below is what I have got so far. Any help is greatly appreciated!
var drake;
function setupDragula() {
var containers = Array.prototype.slice.call(document.querySelectorAll(".js-structure-parent"));
var item = Array.prototype.slice.call(document.querySelectorAll(".js-structure-item"));
var opts = {
allowNestedContainers: true
};
opts = {
accepts: function(el, target, source, sibling) {
// prevent dragged containers from trying to drop inside itself
return !contains(el, target);
}
};
drake = dragula(
containers,
opts
).on('drag', function(el) {
prepareEmptyDropZones();
el.classList.remove('ex-moved');
}).on('drop', function(el, container, source) {
el.classList.add('ex-moved');
removeEmptyDropZones();
}).on('cancel', function(el, container, source) {
removeEmptyDropZones();
}).on('over', function(el, container) {
container.classList.add('editing');
el.classList.add('el-over');
}).on('out', function(el, container) {
container.classList.remove('editing');
el.classList.remove('el-over');
});
}
function contains(a, b) {
return a.contains ?
a != b && a.contains(b) :
!!(a.compareDocumentPosition(b) & 16);
}
function prepareEmptyDropZones() {
var item = querySelectorAllArray(".js-structure-item");
item.forEach(function(el) {
var firstParent = el.querySelector('.js-structure-parent');
if (firstParent === null) {
//el.classList.add('empty');
var emptyParent = document.createElement('div');
emptyParent.className = "js-structure-parent";
//emptyParent.classList.add('empty-drop-zone');
el.appendChild(emptyParent);
} else {
el.classList.remove('empty');
}
});
resetContainers();
}
function removeEmptyDropZones() {
var dropZones = querySelectorAllArray(".js-structure-parent");
dropZones.forEach(function(dropZone) {
if (dropZone.children.length == 0) {
dropZone.remove();
}
});
}
function resetContainers() {
drake.containers = Array.prototype.slice.call(document.querySelectorAll(".js-structure-parent"));
}
function querySelectorAllArray(selector) {
return Array.prototype.slice.call(document.querySelectorAll(selector))
}
document.addEventListener("DOMContentLoaded", function(event) {
setupDragula();
});
.js-structure-item {
cursor: move;
}
.js-structure-item .container {
margin-bottom: 10px;
}
/*parent*/
.js-structure-parent {
padding: 0px 0px 0px 30px;
/*border: 1px solid red;
position: relative;*/
}
.js-structure-parent:empty,
.empty-drop-zone {
min-height: 20px;
border: 1px dashed #ccc;
}
.el-over {
background-color: green;
}
.js-structure-item.empty {
color: #666;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dragula/3.7.2/dragula.min.js"></script>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
File Folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
File 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 4
</div>
</div>
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image Folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
Image file 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 4
</div>
</div>
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
Document file 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 4
</div>
</div>
</div>
</div>
</div>
var drake;
function setupDragula() {
var containers = Array.prototype.slice.call(document.querySelectorAll(".js-structure-parent"));
var item = Array.prototype.slice.call(document.querySelectorAll(".js-structure-item"));
var opts = {
allowNestedContainers: true
};
opts = {
accepts: function(el, target, source, sibling) {
// prevent dragged containers from trying to drop inside itself
return !contains(el, target);
}
};
drake = dragula(
containers,
opts
).on('drag', function(el) {
prepareEmptyDropZones();
el.classList.remove('ex-moved');
}).on('drop', function(el, container, source) {
el.classList.add('ex-moved');
removeEmptyDropZones();
}).on('cancel', function(el, container, source) {
removeEmptyDropZones();
}).on('over', function(el, container) {
container.classList.add('editing');
el.classList.add('el-over');
}).on('out', function(el, container) {
container.classList.remove('editing');
el.classList.remove('el-over');
});
}
function contains(a, b) {
return a.contains ?
a != b && a.contains(b) :
!!(a.compareDocumentPosition(b) & 16);
}
function prepareEmptyDropZones() {
var item = querySelectorAllArray(".js-structure-item");
item.forEach(function(el) {
var firstParent = el.querySelector('.js-structure-parent');
if (firstParent === null) {
//el.classList.add('empty');
var emptyParent = document.createElement('div');
emptyParent.className = "js-structure-parent";
//emptyParent.classList.add('empty-drop-zone');
el.appendChild(emptyParent);
} else {
el.classList.remove('empty');
}
});
resetContainers();
}
function removeEmptyDropZones() {
var dropZones = querySelectorAllArray(".js-structure-parent");
dropZones.forEach(function(dropZone) {
if (dropZone.children.length == 0) {
dropZone.remove();
}
});
}
function resetContainers() {
drake.containers = Array.prototype.slice.call(document.querySelectorAll(".js-structure-parent"));
}
function querySelectorAllArray(selector) {
return Array.prototype.slice.call(document.querySelectorAll(selector))
}
document.addEventListener("DOMContentLoaded", function(event) {
setupDragula();
});
.js-structure-item {
cursor: move;
}
.js-structure-item .container {
margin-bottom: 10px;
}
/*parent*/
.js-structure-parent {
padding: 0px 0px 0px 30px;
/*border: 1px solid red;
position: relative;*/
}
.el-over {
background-color: green;
}
.js-structure-item.empty {
color: #666;
}
.gu-mirror {
position: fixed !important;
margin: 0 !important;
z-index: 9999 !important;
opacity: 0.8;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
filter: alpha(opacity=80);
}
.gu-hide {
display: none !important;
}
.gu-unselectable {
-webkit-user-select: none !important;
-moz-user-select: none !important;
-ms-user-select: none !important;
user-select: none !important;
}
.js-structure-parent:empty,
.empty-drop-zone {
min-height: 6px;
}
.gu-transit {
opacity: 0.2;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
filter: alpha(opacity=20);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dragula/3.7.2/dragula.min.js"></script>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
File Folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
File 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 4
</div>
</div>
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image Folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
Image file 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 4
</div>
</div>
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
Document file 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 4
</div>
</div>
</div>
</div>
</div>
Try this :::
var drake;
function setupDragula() {
var containers = Array.prototype.slice.call(document.querySelectorAll(".js-structure-parent"));
var item = Array.prototype.slice.call(document.querySelectorAll(".js-structure-item"));
var opts = {
allowNestedContainers: true
};
opts = {
accepts: function(el, target, source, sibling) {
// prevent dragged containers from trying to drop inside itself
return !contains(el, target);
}
};
drake = dragula(
containers,
opts
).on('drag', function(el) {
prepareEmptyDropZones();
el.classList.remove('ex-moved');
}).on('drop', function(el, container, source) {
el.classList.add('ex-moved');
removeEmptyDropZones();
}).on('cancel', function(el, container, source) {
removeEmptyDropZones();
}).on('over', function(el, container) {
container.classList.add('editing');
el.classList.add('el-over');
}).on('out', function(el, container) {
container.classList.remove('editing');
el.classList.remove('el-over');
});
}
function contains(a, b) {
return a.contains ?
a != b && a.contains(b) :
!!(a.compareDocumentPosition(b) & 16);
}
function prepareEmptyDropZones() {
var item = querySelectorAllArray(".js-structure-item");
item.forEach(function(el) {
var firstParent = el.querySelector('.js-structure-parent');
if (firstParent === null) {
//el.classList.add('empty');
var emptyParent = document.createElement('div');
emptyParent.className = "js-structure-parent";
//emptyParent.classList.add('empty-drop-zone');
el.appendChild(emptyParent);
} else {
el.classList.remove('empty');
}
});
resetContainers();
}
function removeEmptyDropZones() {
var dropZones = querySelectorAllArray(".js-structure-parent");
dropZones.forEach(function(dropZone) {
if (dropZone.children.length == 0) {
dropZone.remove();
}
});
}
function resetContainers() {
drake.containers = Array.prototype.slice.call(document.querySelectorAll(".js-structure-parent"));
}
function querySelectorAllArray(selector) {
return Array.prototype.slice.call(document.querySelectorAll(selector))
}
document.addEventListener("DOMContentLoaded", function(event) {
setupDragula();
});
.js-structure-item {
cursor: move;
}
.js-structure-item .container {
margin-bottom: 10px;
}
/*parent*/
.js-structure-parent {
padding: 0px 0px 0px 30px;
/*border: 1px solid red;
position: relative;*/
}
.el-over {
background-color: green;
}
.js-structure-item.empty {
color: #666;
}
.gu-mirror {
position: fixed !important;
margin: 0 !important;
z-index: 9999 !important;
opacity: 0.8;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
filter: alpha(opacity=80);
}
.gu-hide {
display: none !important;
}
.gu-unselectable {
-webkit-user-select: none !important;
-moz-user-select: none !important;
-ms-user-select: none !important;
user-select: none !important;
}
.gu-transit {
opacity: 0.2;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
filter: alpha(opacity=20);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dragula/3.7.2/dragula.min.js"></script>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
File Folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
File 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 4
</div>
</div>
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image Folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
Image file 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 4
</div>
</div>
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
Document file 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 4
</div>
</div>
</div>
</div>
</div>

Iterate matching elements to control custom slick carousels

I am using slick carousel with some custom code to provide pagination. It's working great but now I want to have multiple carousels per page and although I've found solutions, I'm having trouble getting them to work with the customisations in my code.
There is an example [here] (Multiple Slick Sliders Issue) that iterates over all elements with a particular class and assigns an ID, but I just can't get it working with the custom pagination code I have.
$('.carousel').on('init afterChange', function(event, slick, currentSlide){
let total = $('.carousel .item').length;
var first = $('.slick-active:first > div:first').get(0);
var last = $('.slick-active:last > div:last').get(0);
if($(last).html() == '')
last = $('.slick-active:last > div:not(:empty)').get(0);
let start,end;
$('.slick-slide > div').each(function(i,v){
if(first === $(v).get(0)) {
start = i+1;
}
if(last === $(v).get(0)) {
end = i+1;
}
});
$('.results').html(`Showing ${start} to ${end} of ${total} results`)
})
$('.carousel').slick({
rows: 2,
slidesToShow: 3,
slidesToScroll: 3,
autoplay: false,
arrows: true,
infinite: false,
draggable: false,
prevArrow: $('.prev'),
nextArrow: $('.next')
})
.item {
background: silver;
color: black;
text-align: center;
font-size: 30px;
display: inline;
border: 5px solid white;
}
.nav {
width: 100%;
}
.nav p{
width: 50%;
float: left;
display: block;
text-align: center;
}
.results {
text-align: center;
width: 100%;
padding-top: 10px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick-theme.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.js"></script>
<div class="carousel">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
<div class="item">13</div>
<div class="item">14</div>
<div class="item">15</div>
<div class="item">16</div>
<div class="item">17</div>
<div class="item">18</div>
</div>
<div class="nav">
<p class="prev">prev</p>
<p class="next">next</p>
</div>
<div class="results">
Showing 1 to 9 of [total] results
</div>
You could create a wrapper container to isolate instances
<div class="slider">
<div class="carousel">
<div class="item">1</div>
<div class="item">2</div>
</div>
<div class="nav">
<p class="prev">prev</p>
<p class="next">next</p>
</div>
<div class="results">
Showing 1 to 9 of [total] results
</div>
</div>
Then to initialize use an each loop for isolation
$('.slider').each(function() {
var $slider = $(this),
// arrows within this instance
$nArrow = $slider.find('.next'),
$pArrow = $slider.find('.prev');
// initialize this carousel instance with appropriate arrows
$slider.find('.carousel').slick({
rows: 2,
slidesToShow: 3,
slidesToScroll: 3,
autoplay: false,
arrows: true,
infinite: false,
draggable: false,
prevArrow: $pArrow,
nextArrow: $nArrow
});
})
For the events , look up to the container class and use find() for the elements within that instance
$('.carousel').on('init afterChange', function(event, slick, currentSlide){
var $slider = $(this).parent();
// examples finding elements within this instance
let total = $slider.find('.carousel .item').length;
var first = $slider.find('.slick-active:first > div:first').get(0);
var last = $slider.find('.slick-active:last > div:last').get(0);
// use find for other elements also
......
})

Searching for the same div

I need to compare which div in an orderd list is the one clicked.
Because I then need to show another div which has the index in a different list.
Everything's properly written, but the comparison is failing (if (ten == $(this))). (Now is chenged for: if (ten.is(this)) {. Works fine)
$(document).ready(function() {
$(".divs2 .os").each(function(e) {
if (e != 0)
$(this).hide();
});
var wybrany;
$(".bt-o").click(function() {
$(".divs2 .os").each(function() { $(this).hide(); });
var ten = $(this);
$(".divs .bt-o").each(function(e) {
if (ten.is(this)) {
$(this).css('background-image', 'url(themes/o2.png)');
wybrany = e;
} else {
$(this).css('background-image', 'url(themes/o1.png)');
}
});
$(".divs2 .os").each(function(e) {
if (e == wybrany)
$(this).show();
});
});
});
// EXTRA ADD FOR YOUR HELP (script for next & prev
$(document).ready(function(){
$(".divs div").each(function(e) {
if (e != 0)
$(this).hide();
});
$("#next").click(function(){
if ($(".divs div:visible").next().length != 0)
$(".divs div:visible").next().fadeIn("slow").prev().fadeOut("slow");
else {
$(".divs div:visible").fadeOut("slow");
$(".divs div:first").fadeIn("slow");
}
return false;
});
$("#prev").click(function(){
if ($(".divs div:visible").prev().length != 0)
$(".divs div:visible").prev().fadeIn("slow").next().fadeOut("slow");
else {
$(".divs div:visible").fadeOut("slow");
$(".divs div:last").fadeIn("slow");
}
return false;
});
});
.bt {
position:absolute;
left: 60px;
}
.bt-o {
padding:35px 50px;
width:54px;
height:29px;
display:inline-block;
font-size: 24px;
color: black;
cursor:pointer;
}
.last {
position:absolute;
left: 1000px;
background-image:url('themes/o22.png');
}
.os {
position:relative;
left: 30px;
top: 75px;
z-index:2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="linia">
<a id="prev">PREV</a>
<div class="divs">
<div class="bt"><a class="bt-o">2007</a><a class="bt-o">2008</a><a class="bt-o">2009</a><a class="bt-o">2010</a></div>
<div class="bt"><a class="bt-o">2011</a><a class="bt-o">2012</a><a class="bt-o">2016</a></div>
<div class="bt"><a class="bt-o">2000</a><a class="bt-o">2001</a></div>
</div>
<a id="next">NEXT</a>
</div>
<div class="divs2">
<div class="os"><div class="rok">2007</div>sample</div>
<div class="os"><div class="rok">2008</div>sample</div>
<div class="os"><div class="rok">2009</div>sample</div>
<div class="os"><div class="rok">2010</div>sample</div>
<div class="os"><div class="rok">2011</div>sample</div>
<div class="os"><div class="rok">2012</div>sample</div>
<div class="os"><div class="rok">2016</div>sample</div>
<div class="os"><div class="rok">2000</div>sample</div>
<div class="os"><div class="rok">2001</div>sample</div>
</div>
For Your help I added full working scripts if someone need to use feel free.
Use .is() instead of == to test the equality of two elements.
If you simply try to compare ten to a newly-constructed jQuery object around this, the comparison will fail -- they are distinct objects, created at different times.
is() does a logical comparison of two objects -- do they represent the same DOM element? That's why you don't need to wrap this in $() before comparing.
$(document).ready(function() {
$(".divs2 .os").each(function(e) {
if (e != 0)
$(this).hide();
});
var wybrany;
$(".bt-o").click(function() {
var ten = $(this);
$(".divs .bt-o").each(function(e) {
// test for DOM equality with is()
//
if (ten.is(this)) {
$(this).css('background-color', 'red');
wybrany = e;
} else {
$(this).css('background-color', 'transparent');
}
});
$(".divs2 .os").each(function(e) {
if (e == wybrany)
$(this).show();
});
});
});
.bt-o {
margin: .25em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="linia">
<a id="prev"></a>
<div class="divs">
<div class="bt"><a class="bt-o">2007</a><a class="bt-o">2008</a><a class="bt-o">2009</a><a class="bt-o">2010</a><a class="bt-o">2011</a><a class="bt-o">2012</a><a class="bt-o">2016</a></div>
<div class="bt"><a class="bt-o">2000</a><a class="bt-o">2001</a></div>
</div>
<a id="next"></a>
</div>
<div class="divs2">
<div class="os"><div class="rok">2007</div>sample</div>
<div class="os"><div class="rok">2008</div>sample</div>
<div class="os"><div class="rok">2009</div>sample</div>
<div class="os"><div class="rok">2010</div>sample</div>
<div class="os"><div class="rok">2011</div>sample</div>
<div class="os"><div class="rok">2012</div>sample</div>
<div class="os"><div class="rok">2016</div>sample</div>
<div class="os"><div class="rok">2000</div>sample</div>
<div class="os"><div class="rok">2001</div>sample</div>
</div>
You should add an id or any attribute for each div and adjust a little bit your code like this:
//id could be repleace by attribute what you set
if (ten.attr('id') == $(this).attr('id'){
........
}
If you can change the structure of div.divs so that all div.bts are in the same div.bt then this would be really easy :)
$(function() {
$(".bt").on("click", "a", function(e) { // add a click handler on div.bt which only executes the function if the clicked element has the class "bt-o"
// https://learn.jquery.com/events/event-delegation/
var os = $(".os"); // get all elements with class "os"
os.hide(); // hide all of them
var clickedElementIndex = $(this).index(); // get the position of the clicked element relative to its sibling elements
// https://api.jquery.com/index/
os.eq(clickedElementIndex) // get the "os" element at the same position as the clicked "bt-o" element
// https://api.jquery.com/eq/
.show(); // and show it
});
});
/* this rules are only for visual effects :) */
.bt-o {
border: solid 1px black;
cursor: pointer;
}
.os {
display: none;
color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="linia">
<a id="prev"></a>
<div class="divs">
<div class="bt"> <!-- only one div.bt for all the a.bt-o -->
<a class="bt-o">2007</a>
<a class="bt-o">2008</a>
<a class="bt-o">2009</a>
<a class="bt-o">2010</a>
<a class="bt-o">2011</a>
<a class="bt-o">2012</a>
<a class="bt-o">2016</a>
<a class="bt-o">2000</a>
<a class="bt-o">2001</a>
</div>
</div>
<a id="next"></a>
</div>
<div class="divs2">
<div class="os"><div class="rok">2007</div>sample</div>
<div class="os"><div class="rok">2008</div>sample</div>
<div class="os"><div class="rok">2009</div>sample</div>
<div class="os"><div class="rok">2010</div>sample</div>
<div class="os"><div class="rok">2011</div>sample</div>
<div class="os"><div class="rok">2012</div>sample</div>
<div class="os"><div class="rok">2016</div>sample</div>
<div class="os"><div class="rok">2000</div>sample</div>
<div class="os"><div class="rok">2001</div>sample</div>
</div>
Slightly simpler method with a little less code, you don't need the event handler e, :
$(".bt-o").on('click', function() {
$(".bt-o").css({ background: 'transparent' }); // clear all backgrounds
$(this).css({ background: '#f90' }); // colour this one
var info = $(this).text(); // get the click text
$('.os').hide(); // hide everything
$('.os').each(function() { // cycle through everything
if ($('.rok', this).text() === info) { // check each targets text
$(this).css({
background: '#bbb'
}).fadeIn('fast'); // colour and reveal
}
});
});
.bt {
position: relative;
width: 80%;
margin-bottom: 10px;
}
.bt-o {
border: 1px solid #f90;
margin-right: 5px;
}
.os {
display: none;
position: relative;
width: 80%;
border: 1px solid #09f;
margin-bottom: 10px;
}
.os div {
display: inline-block;
margin-right: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="divs">
<div class="bt"><a class="bt-o">2007</a><a class="bt-o">2008</a><a class="bt-o">2009</a><a class="bt-o">2010</a><a class="bt-o">2011</a><a class="bt-o">2012</a><a class="bt-o">2016</a>
</div>
<div class="bt"><a class="bt-o">2000</a><a class="bt-o">2001</a>
</div>
</div>
<div class="divs2">
<div class="os">
<div class="rok">2007</div>sample</div>
<div class="os">
<div class="rok">2008</div>sample</div>
<div class="os">
<div class="rok">2009</div>sample</div>
<div class="os">
<div class="rok">2010</div>sample</div>
<div class="os">
<div class="rok">2011</div>sample</div>
<div class="os">
<div class="rok">2012</div>sample</div>
<div class="os">
<div class="rok">2016</div>sample</div>
<div class="os">
<div class="rok">2000</div>sample</div>
<div class="os">
<div class="rok">2001</div>sample</div>
</div>

How to splice variable value in AngularJS?

How to splice variable value in AngularJS
HTML:
<div ng-repeat="steps in data" class="card" style="padding:10px 5px 10px 5px; margin-bottom:10px; margin-top:20px; background: url(#routes.Assets.at("images/Assets/icon_move.png")) no-repeat right #FAFBFC; background-position : calc(100% - 10px) 50%;">
{{steps.title}}
<div class="pull-right" ng-click="deleteStep(steps);" style="color:#F26063; padding-right: 40px;">Delete</div>
<a class="pull-right" ng-click="openAddStep('lg');" style="color:#43C944; padding-right: 20px;">Edit</a>
</div>
JavaScript:
$scope.deleteStep = function(steps){
alert('h');
for (var i = $scope.steps.length - 1; i >= 0; i--) {
if (!$scope.steps[i].value) {
$scope.steps.splice(i, 1);
}
}
}
You can pass the current index to the delete method and then splice it as below, another option is to find the index of the data object by using the indexOf method and splice it
<div class="pull-right" ng-click="deleteStep($index);" style="color:#F26063; padding-right: 40px;">Delete</div>
js
$scope.deleteStep = function(index){
$scope.data.splice(index, 1);
}
var app = angular.module('my-app', [], function() {})
app.controller('AppController', function($scope) {
$scope.data = [];
for (var i = 0; i < 10; i++) {
$scope.data.push({
title: 'Title: ' + i
});
}
$scope.deleteStep = function(index) {
$scope.data.splice(index, 1);
}
$scope.deleteStep2 = function(steps) {
$scope.data.splice($scope.data.indexOf(steps), 1);
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="my-app">
<div ng-controller="AppController">
<div ng-repeat="steps in data" class="card" style="padding:10px 5px 10px 5px; margin-bottom:10px; margin-top:20px;">
{{steps.title}}
<div class="pull-right" ng-click="deleteStep($index);" style="color:#F26063; padding-right: 40px;">Delete</div>
<div class="pull-right" ng-click="deleteStep2(steps);" style="color:#F26063; padding-right: 40px;">Delete 2</div>
<a class="pull-right" ng-click="openAddStep('lg');" style="color:#43C944; padding-right: 20px;">Edit</a>
</div>
</div>
</div>

Complex continuous scroll loop

I have a code similar to:
<div id='right-column'>
<div id='results'>
<div id='result1>
<div class='main'></div>
<div class='details'></div>
</div>
<!-- ... -->
<div id='result50>
<div class='main'></div>
<div class='details'></div>
</div>
</div>
</div>
the total number of results depends of the ajax query, I insert all the results dynamically in one go.
div.main is always visible (fixed height) and div.details "unfolds/folds" below div.main when the user clicks on a result div.
the details div height can vary.
If #results scrollHeight is bigger than #right-column height, I would like to create a continuous scroll loop.
In this case, scrolling past #result50 would show #result1, scrolling before #result1 would show #result50.
I can't .append() the first child to the bottom as in some cases a portion of a result can be seen on top and at the bottom of the column.
I can't duplicate a result unless I detect if .details is unfolded/folded.
The fact that the height of a result can change when a user unfolds the .details div, makes it even more complicated...
Here is an example of continuous scroll loop (2 columns):
$(document).ready(function() {
var num_children = $('#up-left').children().length;
var child_height = $('#up-left').height() / num_children;
var half_way = num_children * child_height / 2;
$(window).scrollTop(half_way);
function crisscross() {
$('#up-left').css('bottom', '-' + window.scrollY + 'px');
$('#down-right').css('bottom', '-' + window.scrollY + 'px');
var firstLeft = $('#up-left').children().first();
var lastLeft = $('#up-left').children().last();
var lastRight = $('#down-right').children().last();
var firstRight = $('#down-right').children().first();
if (window.scrollY > half_way ) {
$(window).scrollTop(half_way - child_height);
lastRight.appendTo('#up-left');
firstLeft.prependTo('#down-right');
} else if (window.scrollY < half_way - child_height) {
$(window).scrollTop(half_way);
lastLeft.appendTo('#down-right');
firstRight.prependTo('#up-left');
}
}
$(window).scroll(crisscross);
});
div#content {
width: 100%;
height: 100%;
position: absolute;
top:0;
right:0;
bottom:0;
left:0;
}
#box {
position: relative;
vertical-align:top;
width: 100%;
height: 200px;
margin: 0;
padding: 0;
}
#up-left {
position:absolute;
z-index:4px;
left: 0;
top: 0px;
width: 50%;
margin: 0;
padding: 0;
}
#down-right {
position:fixed;
bottom: 0px;
z-index: 5px;
left: 50%;
width: 50%;
margin: 0;
padding: 0;
}
h1 {margin: 0;padding: 0;color:#fff}
.black {background: black;}
.white {background: grey;}
.green {background: green;}
.brown {background: brown;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div id="content">
<div id="up-left">
<div id="box" class="brown">
<h1>ONE</h1>
</div>
<div id="box" class="black">
<h1>TWO</h1>
</div>
<div id="box" class="white">
<h1>THREE</h1>
</div>
<div id="box" class="black">
<h1>FOUR</h1>
</div>
<div id="box" class="white">
<h1>FIVE</h1>
</div>
<div id="box" class="black">
<h1>SIX</h1>
</div>
</div><!-- #up-left -->
<div id="down-right">
<div id="box" class="white">
<h1>SIX</h1>
</div>
<div id="box" class="black">
<h1>FIVE</h1>
</div>
<div id="box" class="white">
<h1>FOUR</h1>
</div>
<div id="box" class="black">
<h1>THREE</h1>
</div>
<div id="box" class="white">
<h1>TWO</h1>
</div>
<div id="box" class="green">
<h1>ONE</h1>
</div>
</div><!-- #down-right -->
</div><!-- .content -->
(fiddle: http://jsfiddle.net/franckl/wszg1d6c/)
Any hint/ideas on how I could do it ?
Move items to top or bottom based on scroll direction
You can use jQuery's .append() and .prepend() to move items without cloning them.
You'll use similar techniques to infinite scrolling with lazy loading (AJAX), but in this scenario you want to handle scrolling up as well as down, and instead of loading new content from the server, you're just recycling existing DOM elements in the list.
Below I demonstrate one technique. I store the scroll position in the element's .data cache for easy retrieval when detecting scrolling direction. I chose to detect scrolling direction to avoid making unnecessary variable assignments upfront to improve performance. Otherwise, you'd be getting elements and doing math for a scroll event that isn't going to happen in that direction.
The scroll handler:
$('#right-column').on('scroll', function (e) {
var $this = $(this),
$results = $("#results"),
scrollPosition = $this.scrollTop();
if (scrollPosition > ($this.data('scroll-position') || 0)) {
// Scrolling down
var threshold = $results.height() - $this.height() - $('.result:last-child').height();
if (scrollPosition > threshold) {
var $firstResult = $('.result:first-child');
$results.append($firstResult);
scrollPosition -= $firstResult.height();
$this.scrollTop(scrollPosition);
}
} else {
// Scrolling up
var threshold = $('.result:first-child').height();
if (scrollPosition < threshold) {
var $lastResult = $('.result:last-child');
$results.prepend($lastResult);
scrollPosition += $lastResult.height();
$this.scrollTop(scrollPosition);
}
}
$this.data('scroll-position', scrollPosition)
});
A complete working example:
$('#right-column').on('scroll', function (e) {
var $this = $(this),
$results = $("#results"),
scrollPosition = $this.scrollTop();
if (scrollPosition > ($this.data('scroll-position') || 0)) {
// Scrolling down
var threshold = $results.height() - $this.height() - $('.result:last-child').height();
if (scrollPosition > threshold) {
var $firstResult = $('.result:first-child');
$results.append($firstResult);
scrollPosition -= $firstResult.height();
$this.scrollTop(scrollPosition);
}
} else {
// Scrolling up
var threshold = $('.result:first-child').height();
if (scrollPosition < threshold) {
var $lastResult = $('.result:last-child');
$results.prepend($lastResult);
scrollPosition += $lastResult.height();
$this.scrollTop(scrollPosition);
}
}
$this.data('scroll-position', scrollPosition)
});
$('#results').on('click', '.result', function (e) {
$(this).find('.details').toggle();
});
$('#newNumber').on('input', function (e) {
var results = '';
for (var n = 1; n <= $(this).val(); n++) {
results +=
'<div class="result" id="result' + n + '">' +
' <div class="main">Result ' + n + '</div>' +
' <div class="details">Details for result ' + n + '</div>' +
'</div>';
}
$('#results').html(results);
});
body {
font-family: sans-serif;
}
h1 {
font: bold 2rem/1 Georgia, serif;
}
p {
line-height: 1.5;
margin-bottom: 1em;
}
label {
font-weight: bold;
margin-bottom: 1em;
}
.column {
box-sizing: border-box;
float: left;
width: 50%;
height: 100vh;
padding: 1em;
overflow: auto;
}
#right-column {
background-color: LemonChiffon;
}
.result {
padding: 1em;
cursor: pointer;
}
.result .main {
height: 2em;
font-weight: bold;
line-height: 2;
}
.result .details {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class=
"column" id="left-column">
<p>Existing DOM elements are moved to the top or bottom of the list depending on your scroll direction.</p>
<label>Change the number of results to display
<input id="newNumber" type="number" value="10" />
</div>
<div class=
"column" id="right-column">
<div id="results">
<div id="result1" class="result">
<div class="main">Result 1</div>
<div class="details">Details for result 1</div>
</div>
<div id="result2" class="result">
<div class="main">Result 2</div>
<div class="details">Details for result 2</div>
</div>
<div id="result3" class="result">
<div class="main">Result 3</div>
<div class="details">Details for result 3</div>
</div>
<div id="result4" class="result">
<div class="main">Result 4</div>
<div class="details">Details for result 4</div>
</div>
<div id="result5" class="result">
<div class="main">Result 5</div>
<div class="details">Details for result 5</div>
</div>
<div id="result6" class="result">
<div class="main">Result 6</div>
<div class="details">Details for result 6</div>
</div>
<div id="result7" class="result">
<div class="main">Result 7</div>
<div class="details">Details for result 7</div>
</div>
<div id="result8" class="result">
<div class="main">Result 8</div>
<div class="details">Details for result 8</div>
</div>
<div id="result9" class="result">
<div class="main">Result 9</div>
<div class="details">Details for result 9</div>
</div>
<div id="result10" class="result">
<div class="main">Result 10</div>
<div class="details">Details for result 10</div>
</div>
</div>
</div>
A complete working example on CodePen, if you prefer.

Categories