How to obtain jQuery UI Sortable item positions? - jquery-ui-sortable

I have 2 jQuery UI Sortable lists. Codes are as follow:
<div class="chapter_container">
<p>Available Chapters</p>
<ul id="sortable_available">
<li id="t1">Title 1</li>
<li id="t2">Title 2</li>
<li id="t3">Title 3</li>
<li id="t4">Title 4</li>
</ul>
</div>
<div class="chapter_container">
<p>Selected Chapters</p>
<ul id="sortable_selected">
</ul>
</div>
For the JS, I use:
jQuery(function() {
jQuery("#sortable_available, #sortable_selected").sortable({
connectWith: ".chapter_container ul"
});
jQuery("#sortable_selected").on("sortstop", function(event, ui) {
console.log(ui.position);
});
jQuery("#sortable_available, #sortable_selected").disableSelection();
});
I can only obtain the position of item moved via sortstop event. How can I obtain the orders of items in both lists?
Here is the JSFiddle

Have you looked at the refreshPositions method? If you make a call to this method, you can query the children from the returned object.
Updated Fiddle
jQuery(function() {
jQuery("#sortable_available, #sortable_selected").sortable({
connectWith: ".chapter_container ul"
});
jQuery("#sortable_available").on("sortstop", function(event, ui) {
//Clear the existing content.
jQuery('#debug').html('');
//Call refreshPositions and store the children in a local variable.
var items = jQuery(this).sortable("refreshPositions").children();
for (var i = 0; i < items.length; i++) {
//I'm using javascript to get the required values, but you can use jQuery if you so desire.
jQuery('#debug').html(jQuery('#debug').html() + items[i].innerHTML + ', Top: ' + items[i].offsetTop + ', Left: ' + items[i].offsetLeft + '<br/>');
}
});
jQuery("#sortable_available, #sortable_selected").disableSelection();
});
Moving the second item to the first position will output the following:
Title 2, Top: 115 Left: 18
Title 1, Top: 152 Left: 18
Title 3, Top: 189 Left: 18
Title 4, Top: 227 Left: 18
$(".selector").sortable("refreshPositions").children(); will return an array.

Related

How to get marker popup on hover element from list using Leaflet and L.Control.ListMarkers?

Using Leaflet and plugins like ListMarkers, I display a list of visible markers on the map. After hovering over the appropriate <li> element in the List, I want the marker popup to be displayed. The <li> element contains various information about the product, unfortunately after hovering over them, the popup appears and disappears. How to make it that if I hover entire <li> element popup will show and not go crazy of each element separately ?
var list = new L.Control.ListMarkers({ layer: markers, itemIcon: null });
list.addTo(map);
list.on('item-mouseover', function(e) {
e.layer.setIcon(L.icon({
iconUrl: '/marker2.png'
}));
e.layer.openPopup();
}).on('item-mouseout', function(e) {
e.layer.setIcon(L.icon({
iconUrl: '/marker.png'
}))
e.layer.closePopup();
});
listaHTML = list.getContainer();
document.getElementById("lista").appendChild(listaHTML);
Seems to be a CSS problem.
Workaround
li.list-markers-li>a>span,
li.list-markers-li>a>b {
pointer-events: none;
}
var map = new L.Map('map', {
zoom: 10,
minZoom: 10,
center: L.latLng(43.90974, 10.2419)
});
map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png')); //base layer
var markersLayer = new L.LayerGroup(); //layer contain searched elements
map.addLayer(markersLayer);
////////////populate map from cities-italy.js
for (var i in cities) {
let marker = L.marker(L.latLng(cities[i].loc), {
title: cities[i].name
}).addTo(markersLayer);
marker.bindPopup(cities[i].name)
}
var list = new L.Control.ListMarkers({
layer: markersLayer,
itemIcon: null
});
list.on('item-mouseover', function(e) {
e.layer.openPopup();
}).on('item-mouseout', function(e) {
e.layer.closePopup();
});
map.addControl(list);
#map {
position: absolute;
top: 35px;
left: 0;
width: 100%;
height: 80%
}
li.list-markers-li>a>span,
li.list-markers-li>a>b {
pointer-events: none;
}
<script src="https://labs.easyblog.it/maps/leaflet-list-markers/examples/cities-italy.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet.js"></script>
<script src="https://labs.easyblog.it/maps/leaflet-list-markers/src/leaflet-list-markers.js"></script>
<link href="https://labs.easyblog.it/maps/leaflet-list-markers/src/leaflet-list-markers.css" rel="stylesheet" />
<div id="map"></div>

Combining Swiper slider and photoswipe

I'm looking for a combination of Swiper slider and Photoswipe (Or other lightbox).
Trying to make a product slider with 3 products in a slide.
Each product has a lightbox/modal with video and a gallery.
The modals are generated within the boundaries of the product div.
When you click an 'open gallery' / 'show video' link. The lightbox opens fullscreen.
The problem I'm having is: the lightbox won't (but has to) exceed the boundary of the slider product boundary.
Looking for a solution.
Something like an empty modal/lightbox containers outside the slider with dynamic content when an 'open modal' link is clicked within the product slide.
You can check it, here is example:
<header>
<h1>
<a title="swiper.js" href="http://idangero.us/swiper/" target="_blank">Swiper.js (5.3.7)</a> &
<a title="photoswipe" href="http://photoswipe.com/" target="_blank">Photoswipe.js (4.1.3)</a> - Mobile Native feel
slider gallery
</h1>
<p>Combine two of the most powerfull JS plugins (Endless options / Great docs / Fast / Modern / Mobile freindly) -
<a title="swiper.js" href="http://idangero.us/swiper/" target="_blank">SWIPER</a> IS PERFECT FOR THIS IDEA BEACUSE OF
ITS unique <code>preventClicks</code> Parameter (Prevent accidental unwanted clicks on links during swiping) -
<strong>Works like magic</strong>. Also its really <b>hard</b> to find - Code example of working photoswipe
combination with any slider out there(slick, flickity, owl etc.) and
in general slider & lightbox - so i hope this example be usefull for you.</p>
</header>
<!-- https://swiperjs.com/get-started/ -->
<!-- Slider main container -->
<div class="swiper-container">
<!-- Additional required wrapper -->
<ul class="swiper-wrapper my-gallery" itemscope itemtype="http://schema.org/ImageGallery">
<!-- Slides -->
<li id="1" class="swiper-slide" itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a id="first" title="click to zoom-in" href="https://picsum.photos/id/1079/1200/600" itemprop="contentUrl" data-size="1200x600">
<img src="https://picsum.photos/id/1079/1200/600" itemprop="thumbnail" alt="Image description" />
</a>
</li>
<li id="2" class="swiper-slide" itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a title="click to zoom-in" href="http://placehold.it/1200x601/AB47BC/ffffff?text=Zoom-image-2"
itemprop="contentUrl" data-size="1200x601">
<img src="http://placehold.it/600x300/AB47BC/ffffff?text=Thumbnail-image-2" itemprop="thumbnail" alt="Image description" />
</a>
</li>
<li id="3" class="swiper-slide" itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a title="click to zoom-in" href="http://placehold.it/1200x600/EF5350/ffffff?text=Zoom-image-3" itemprop="contentUrl" data-size="1200x600">
<img src="http://placehold.it/600x300/EF5350/ffffff?text=Thumbnail-image-3" itemprop="thumbnail" alt="Image description" />
</a>
</li>
<li id="4" class="swiper-slide" itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a title="click to zoom-in" href="http://placehold.it/1200x600/1976D2/ffffff?text=Zoom-image-4" itemprop="contentUrl" data-size="1200x600">
<img src="http://placehold.it/600x300/1976D2/ffffff?text=Thumbnail-image-4" itemprop="thumbnail" alt="Image description" />
</a>
</li>
<li id="5" class="swiper-slide" itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a title="click to zoom-in" href="https://picsum.photos/id/1011/1200/600" itemprop="contentUrl"
data-size="1200x600">
<img src="https://picsum.photos/id/1011/1200/600" itemprop="thumbnail" alt="Image description" />
</a>
</li>
</ul>
<!-- Add Pagination -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons -->
<div title="Prev" class="swiper-button-prev"></div>
<div title="Next" class="swiper-button-next"></div>
</div>
<!-- https://photoswipe.com/documentation/getting-started.html -->
<!-- add PhotoSwipe (.pswp) element to DOM -
Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
<!-- Background of PhotoSwipe.
It's a separate element, as animating opacity is faster than rgba(). -->
<div class="pswp__bg"></div>
<!-- Slides wrapper with overflow:hidden. -->
<div class="pswp__scroll-wrap">
<!-- Container that holds slides. PhotoSwipe keeps only 3 slides in DOM to save memory. -->
<!-- don't modify these 3 pswp__item elements, data is added later on. -->
<div class="pswp__container">
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
<div class="pswp__ui pswp__ui--hidden">
<div class="pswp__top-bar">
<!-- Controls are self-explanatory. Order can be changed. -->
<div class="pswp__counter"></div>
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
<button class="pswp__button pswp__button--share" title="Share"></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
<!-- Preloader demo https://codepen.io/dimsemenov/pen/yyBWoR -->
<!-- element will get class pswp__preloader--active when preloader is running -->
<div class="pswp__preloader">
<div class="pswp__preloader__icn">
<div class="pswp__preloader__cut">
<div class="pswp__preloader__donut"></div>
</div>
</div>
</div>
</div>
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class="pswp__share-tooltip"></div>
</div>
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
</button>
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
</button>
<div class="pswp__caption">
<div class="pswp__caption__center"></div>
</div>
</div>
</div>
</div>
<!-- ////////////////////////
DOCS
////////////////////////////
-->
<!-- Include Tippy -->
<script src="https://unpkg.com/tippy.js#3/dist/tippy.all.min.js"></script>
<!-- OPTIONAL: Set the defaults for the auto-initialized tooltips -->
<script>
tippy('.swiper-button-prev', {
content: "Prev",
theme: "light",
arrow: true,
})
tippy('.swiper-button-next', {
content: "Next",
theme: "light",
arrow: true,
})
</script>
<section id="docs">
<br>
<br>
<br>
<hr>
<h2>Noted / Important</h2>
<ol>
<li>
<h3>
A non-jQuery dependent
</h3>
</li>
<li>
<h3>Cdns</h3>
<h4>Head (CSS)</h4>
<code>
<!-- photoswipe CSS -->
<br>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe.min.css" />
<br>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/default-skin/default-skin.min.css" />
<br>
<!-- swiper CSS -->
<br>
<link rel="stylesheet" href="https://unpkg.com/swiper/css/swiper.min.css" />
</code>
<h4>Before body (JS)</h4>
<code>
<script src="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe.min.js"></script>
<br>
<script src="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe-ui-default.min.js"></script>
<br>
<script src="https://unpkg.com/swiper/js/swiper.min.js"></script>
<br>
<!-- copy-paste the code under codepen js tab her (wrap with script tag) -->
</code>
</li>
<li>
<h3>Loop & Counter</h3>
<p>
<strong> Wont work well </strong> with swiper: <code>loop = true;</code> & photoswipe: <code>counterEl:
true,</code>(What is counter? example: 1/5...2/5) - "loop" duplicate images - the photoswipe counter will be
wrong. *** If you dont want a
loop - you can set photoswipe counter <code>counterEl: true,</code>
</p>
</li>
<li>
<h3><a target="_blank" href="https://schema.org/ImageGallery">Schema.org - ImageGallery</a> Markup (0 ERRORS 0 WARNINGS )</h3>
<p>
Schema.org markup + semantic HTML: use unordered (bulleted) list (If you want a <code>div</code> under photoswipe - change JS -
<strong>"(find) control+f-->"</strong> tagname value) . Copy-paste - this code to check: <a target="_blank"
href="https://search.google.com/structured-data/testing-tool">Structured Data Testing Tool - Google</a>
</p>
</li>
<li>
<h3>Match index - BY API</h3>
<p>
<strong>
Extra CODE "match index"
</strong> - EXAMPLE: When you click(zoom) image1 -- goes to image 2 - close image2 (X) - also the swiper update
is position (<strong>BETTER</strong> User Experience) (find<kbd>(ctr +f)</kbd>-->
<code>mySwiper.slideTo(getCurrentIndex, false);</code>) -
This idea miss
in most slider & lightbox examples/plugins mixed.
<br>
Very simple code idea (100% API solution) - get photoswipe index (for example 2) and swiper slideTo index (2 - in this example).
<ul>
<li >
<a target="_blank" href="https://photoswipe.com/documentation/api.html">Photoswipe API - <strong>pswp.getCurrentIndex()</strong></a>
<li style="border-top-width: 0;"> <a target="_blank" href="https://swiperjs.com/api/#methods">Swiper API - <strong>slideTo(index);</strong></a>
</li>
</li>
</ul>
</p>
</li>
<li>
<h3>Photoswipe options</h3>
<p>
JS - line (find) -ctr +f --> the term:<code>// define options (if needed)</code>. You find endless options for
<strong>photoswipe</strong> - This is the place to add/modify options. Full Options list her
<a href="http://photoswipe.com/documentation/options.html" target="_blank">PhotoSwipe
Options</a>
</p>
</li>
<li>
<h3>SWIPER options</h3>
<h4>slideperview</h4>
<p>
<code>slideperview</code> - option1: Set number (1,2,3 and so on) - example |||||
option2(<b>"Carousel Mode"</b> this example): Set to "<code>auto</code>"
than add CSS <a href="https://www.w3schools.com/cssref/pr_dim_width.asp" target="_blank">width
Property</a></code> <code>.swiper-slide</code> (in thie case eash slide is 88% width) - example.
</p>
<h4>spaceBetween & centeredSlides</h4>
<p>
Space Between slide by js option <code>spaceBetween</code> - and also usefull to change
<code>centeredSlides</code>(true/flase). <br>
Swiper API
</p>
</li>
</ol>
<hr>
<h3>Related Example</h3>
<p>
<a title="FancyBox3 & Flickity" href="https://codepen.io/ezra_siton/pen/OQmjoq" target="_blank">#FancyBox3 -
lightbox & Flickity Slider</a>
</p>
</section>
/* zero custom styles for photoswipe */
/*==================================
SWIPER - minimal styling
===================================*/
/* semantic HTML - remove bullet and space from the list */
ul.swiper-wrapper {
list-style-type: none;
margin: 0;
padding: 0;
}
/* Swiper container */
.swiper-container {
max-width: 100%;
}
/* swiper responive image */
.swiper-container img {
width: 100%;
height: auto;
}
.swiper-slide {
/* Remove this if you want 1 slide perview - than change slidesPerView js-option to 1 -or- 2+ instead of 'auto' */
width: 80%;
}
/* Swiper custom pagination */
.swiper-pagination-bullet {
width: 34px;
height: 34px;
text-align: center;
line-height: 34px;
font-size: 14px;
color: #000;
opacity: 1;
background: rgba(0, 0, 0, 0.3);
transition: background-color 0.5s ease, color 0.5s ease;
}
/* Swiper custom pagination */
.swiper-pagination-bullet:hover {
transition: background-color 0.5s ease;
background: rgba(0, 0, 0, 1);
color: white;
}
/* Swiper custom pagination active state */
.swiper-pagination-bullet-active {
color: #fff;
background: black;
}
/*==================================================================
CODEPEN STYLES -(under codepen gear/setting icon)
==============================================++++++================*/
.tippy-tooltip.light-theme {
color: #26323d;
box-shadow: 0 0 20px 4px rgba(154, 161, 177, 0.15),
0 4px 80px -8px rgba(36, 40, 47, 0.25),
0 4px 4px -2px rgba(91, 94, 105, 0.15);
background-color: white;
}
.tippy-backdrop {
background-color: white;
}
.tippy-roundarrow {
fill: white;
}
/* Default (sharp) arrow */
.tippy-popper[x-placement^='top'] .tippy-tooltip.light-theme .tippy-arrow {
border-top-color: #fff;
}
.tippy-popper[x-placement^='bottom'] .tippy-tooltip.light-theme .tippy-arrow {
border-bottom-color: #fff;
}
.tippy-popper[x-placement^='left'] .tippy-tooltip.light-theme .tippy-arrow {
border-left-color: #fff;
}
.tippy-popper[x-placement^='right'] .tippy-tooltip.light-theme .tippy-arrow {
border-right-color: #fff;
}
/* Round arrow */
.tippy-tooltip.light-theme .tippy-roundarrow {
fill: #fff;
}
/* TOC
part one - Swiper instilaze
part two - photoswipe instilaze
part three - photoswipe define options
part four - extra code (update swiper index when image close and micro changes)
/* 1 of 4 : SWIPER ################################### */
var mySwiper = new Swiper(".swiper-container", {
// If swiper loop is true set photoswipe counterEl: false (line 175 her)
loop: true,
/* slidesPerView || auto - if you want to set width by css like flickity.js layout - in this case width:80% by CSS */
slidesPerView: "auto",
spaceBetween: 10,
centeredSlides: true,
slideToClickedSlide: false,
autoplay: { /* remove/comment to stop autoplay */
delay: 3000,
disableOnInteraction: false /* true by deafult */
},
// If we need pagination
pagination: {
el: ".swiper-pagination",
clickable: true,
renderBullet: function(index, className) {
return '<span class="' + className + '">' + (index + 1) + "</span>";
}
},
// Navigation arrows
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
// keyboard control
keyboard: {
enabled: true,
}
});
// 2 of 4 : PHOTOSWIPE #######################################
// https://photoswipe.com/documentation/getting-started.html //
var initPhotoSwipeFromDOM = function(gallerySelector) {
// parse slide data (url, title, size ...) from DOM elements
// (children of gallerySelector)
var parseThumbnailElements = function(el) {
var thumbElements = el.childNodes,
numNodes = thumbElements.length,
items = [],
figureEl,
linkEl,
size,
item;
for (var i = 0; i < numNodes; i++) {
figureEl = thumbElements[i]; // <figure> element
// include only element nodes
if (figureEl.nodeType !== 1) {
continue;
}
linkEl = figureEl.children[0]; // <a> element
size = linkEl.getAttribute("data-size").split("x");
// create slide object
item = {
src: linkEl.getAttribute("href"),
w: parseInt(size[0], 10),
h: parseInt(size[1], 10)
};
if (figureEl.children.length > 1) {
// <figcaption> content
item.title = figureEl.children[1].innerHTML;
}
if (linkEl.children.length > 0) {
// <img> thumbnail element, retrieving thumbnail url
item.msrc = linkEl.children[0].getAttribute("src");
}
item.el = figureEl; // save link to element for getThumbBoundsFn
items.push(item);
}
return items;
};
// find nearest parent element
var closest = function closest(el, fn) {
return el && (fn(el) ? el : closest(el.parentNode, fn));
};
// triggers when user clicks on thumbnail
var onThumbnailsClick = function(e) {
e = e || window.event;
e.preventDefault ? e.preventDefault() : (e.returnValue = false);
var eTarget = e.target || e.srcElement;
// find root element of slide
var clickedListItem = closest(eTarget, function(el) {
return el.tagName && el.tagName.toUpperCase() === "LI";
});
if (!clickedListItem) {
return;
}
// find index of clicked item by looping through all child nodes
// alternatively, you may define index via data- attribute
var clickedGallery = clickedListItem.parentNode,
childNodes = clickedListItem.parentNode.childNodes,
numChildNodes = childNodes.length,
nodeIndex = 0,
index;
for (var i = 0; i < numChildNodes; i++) {
if (childNodes[i].nodeType !== 1) {
continue;
}
if (childNodes[i] === clickedListItem) {
index = nodeIndex;
break;
}
nodeIndex++;
}
if (index >= 0) {
// open PhotoSwipe if valid index found
openPhotoSwipe(index, clickedGallery);
}
return false;
};
// parse picture index and gallery index from URL (#&pid=1&gid=2)
var photoswipeParseHash = function() {
var hash = window.location.hash.substring(1),
params = {};
if (hash.length < 5) {
return params;
}
var vars = hash.split("&");
for (var i = 0; i < vars.length; i++) {
if (!vars[i]) {
continue;
}
var pair = vars[i].split("=");
if (pair.length < 2) {
continue;
}
params[pair[0]] = pair[1];
}
if (params.gid) {
params.gid = parseInt(params.gid, 10);
}
return params;
};
var openPhotoSwipe = function(
index,
galleryElement,
disableAnimation,
fromURL
) {
var pswpElement = document.querySelectorAll(".pswp")[0],
gallery,
options,
items;
items = parseThumbnailElements(galleryElement);
// #################### 3/4 define photoswipe options (if needed) ####################
// https://photoswipe.com/documentation/options.html //
options = {
/* "showHideOpacity" uncomment this If dimensions of your small thumbnail don't match dimensions of large image */
//showHideOpacity:true,
// Buttons/elements
closeEl: true,
captionEl: true,
fullscreenEl: true,
zoomEl: true,
shareEl: false,
counterEl: false,
arrowEl: true,
preloaderEl: true,
// define gallery index (for URL)
galleryUID: galleryElement.getAttribute("data-pswp-uid"),
getThumbBoundsFn: function(index) {
// See Options -> getThumbBoundsFn section of documentation for more info
var thumbnail = items[index].el.getElementsByTagName("img")[0], // find thumbnail
pageYScroll =
window.pageYOffset || document.documentElement.scrollTop,
rect = thumbnail.getBoundingClientRect();
return { x: rect.left, y: rect.top + pageYScroll, w: rect.width };
}
};
// PhotoSwipe opened from URL
if (fromURL) {
if (options.galleryPIDs) {
// parse real index when custom PIDs are used
// http://photoswipe.com/documentation/faq.html#custom-pid-in-url
for (var j = 0; j < items.length; j++) {
if (items[j].pid == index) {
options.index = j;
break;
}
}
} else {
// in URL indexes start from 1
options.index = parseInt(index, 10) - 1;
}
} else {
options.index = parseInt(index, 10);
}
// exit if index not found
if (isNaN(options.index)) {
return;
}
if (disableAnimation) {
options.showAnimationDuration = 0;
}
// Pass data to PhotoSwipe and initialize it
gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);
gallery.init();
/* ########### PART 4 - EXTRA CODE ########### */
/* EXTRA CODE (NOT FROM photoswipe CORE) -
1/2. UPDATE SWIPER POSITION TO THE CURRENT ZOOM_IN IMAGE (BETTER UI) */
// photoswipe event: Gallery unbinds events
// (triggers before closing animation)
gallery.listen("unbindEvents", function() {
// This is index of current photoswipe slide
var getCurrentIndex = gallery.getCurrentIndex();
// Update position of the slider
mySwiper.slideTo(getCurrentIndex, false);
// 2/2. Start swiper autoplay (on close - if swiper autoplay is true)
mySwiper.autoplay.start();
});
// 2/2. Extra Code (Not from photo) - swiper autoplay stop when image zoom */
gallery.listen('initialZoomIn', function() {
if(mySwiper.autoplay.running){
mySwiper.autoplay.stop();
}
});
};
// loop through all gallery elements and bind events
var galleryElements = document.querySelectorAll(gallerySelector);
for (var i = 0, l = galleryElements.length; i < l; i++) {
galleryElements[i].setAttribute("data-pswp-uid", i + 1);
galleryElements[i].onclick = onThumbnailsClick;
}
// Parse URL and open gallery if it contains #&pid=3&gid=1
var hashData = photoswipeParseHash();
if (hashData.pid && hashData.gid) {
openPhotoSwipe(hashData.pid, galleryElements[hashData.gid - 1], true, true);
}
};
// execute above function
initPhotoSwipeFromDOM(".my-gallery");
https://codepen.io/ezra_siton/pen/XNpJaX/
instead using photoswipe, use only swiper like in this demo I did make:
<-------html------>
<div class="swiper-container horizontal">
<div class="swiper-wrapper">
<div class="swiper-slide"><div class="swiper-container vertical">
<div class="swiper-wrapper vertical">
<div class="swiper-slide vertical">
Slide 1
</div>
<div class="swiper-slide vertical">
Slide 1.1
</div>
<div class="swiper-slide vertical">
Slide 1.2
</div>
<div class="swiper-slide vertical">
Slide 1.3
</div>
</div>
<div class="swiper-pagination vertical"></div>
</div></div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
<div class="swiper-slide">Slide 4</div>
<div class="swiper-slide">Slide 5</div>
<div class="swiper-slide">Slide 6</div>
<div class="swiper-slide">Slide 7</div>
<div class="swiper-slide">Slide 8</div>
<div class="swiper-slide">Slide 9</div>
<div class="swiper-slide">Slide 10</div>
</div>
<!-- Add Pagination -->
<div class="swiper-pagination horizontal"></div>
</div>
<!-- Swiper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.3.1/js/swiper.min.js"></script>
<script>
var swiper = new Swiper('.swiper-container.horizontal', {
pagination: '.swiper-pagination.horizontal',
direction: 'horizontal',
slidesPerView: 1,
paginationClickable: true,
spaceBetween: 30,
mousewheelControl: true
});
</script>
<script>
var swiper = new Swiper('.swiper-container.vertical', {
pagination: '.swiper-pagination',
direction: 'vertical',
slidesPerView: 1,
paginationClickable: true,
spaceBetween: 30,
mousewheelControl: true
});
</script>
<---------html end----------->
<--------css----------->
html, body {
position: relative;
height: 100%;
}
body {
background: #eee;
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
font-size: 14px;
color:#000;
margin: 0;
padding: 0;
}
.swiper-container {
width: 100%;
height: 100%;
margin-left: auto;
margin-right: auto;
}
.swiper-slide {
text-align: center;
font-size: 18px;
background: #fff;
/* Center slide text vertically */
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
<---------css end------------->
https://jsfiddle.net/120ngmoh/

using durandal and knockout but I can't set span text from a drop down change

I'm trying to bind a value to a span tag by changing the position on the drop down.
My JS file code is
define(['plugins/router', 'durandal/app', 'knockout', 'durandal/system'], function (router, app, ko, system) {
var Property = function (ref, title) {
this.ref = ref;
this.title = title;
};
var propertyList = [
new Property("0", "sample"),
new Property("1", "sasasfa"),
new Property("2", "jgpjijo"),
new Property("3", "uifhiuefh")
];
var items = ko.observableArray(propertyList);
var selectedProperty = ko.observable();
return {
router: router,
items: items,
selectedProperty: selectedProperty,
activate: function () {
router.map([
{ route: '', moduleId: 'viewmodels/propertydetails', title: 'Property Details', nav: true } ]).buildNavigationModel();
return router.activate();
}
};
});
My html is:
<div>
<div class="header-nav-items">
<ul class="nav" data-bind="foreach: router.navigationModel">
<li data-bind="css: { 'header-tab-active': isActive }">
<a data-bind="attr: { href: hash }, html: title"></a>
</li>
</ul>
</div>
<div style="background-color: #E05000; padding: 3px; height: 25px;">
<div style="float: left; margin-left: 10px; color: #ffffff;">
<span id="title" data-bind="text: selectedProperty() ? selectedProperty().title : 'Unknown'"></span>
</div>
<div style="float: right; margin-right: 10px;">
<select id="PropertyDDL" data-bind="options: items, optionsText: 'title', optionsValue: 'ref', value: selectedProperty, optionsCaption: 'Please select a property'"></select>
</div>
</div>
I'm completely new to using Durandal and knockount. I'm trying to set the text of the span tag with the value title from PropertyList using selectedProperty().title but the value appears blank when I change the drop down to any position greater than 0. At pos 0 it displays unknown. If I replace selectedProperty().title with selectedProperty() then the ref prints out correctly on the span text. Any ideas?
All is much more simple. optionsValue: 'ref' means that selectedProperty() is 0, 1, 2 or 3.
Therefore selectedProperty().title is undefined and text is empty.
If you want to use selectedProperty().title just remove optionsValue: 'ref' from select.
Try encapsulating the text for your title span in a computed observable. Like this:
var self = this;
self.titleText = ko.computed(function() {
var prop = self.selectedProperty();
return prop ? prop.title : 'Unknown';
});
<span id="title" data-bind="text: titleText"></span>
Knockout can be a bit quirky when you execute the observable in the binding expression itself, it doesn't always register the dependency properly such that the binding is notified when the underlying selectedProperty observable changes (in my experience).

jQuery connectToSortable Nested Lists and Greedy Option

I've been trying to resolve an issue for some time with connectToSortable and nested lists. I've created an example at jsfiddle that shows the basic code:
http://jsfiddle.net/ZYSYM/
What I would like to achieve is the ability for a user to drag a "New Item" from the right list into the sub items list. However, the issue is that it adds the item to both the sub and parent lists.
I've read that perhaps the Greedy option may resolve this, however I'm not sure if it's working correctly or I've misinterpreted how it's meant to work. I've googled and searched around but could not find anyone with the exact same issue.
I've also performed some debugging and the greedy option fires the line parentInstance._out.call(parentInstance, event); in jquery-ui, which I think is for this purpose, but it doesn't seem to have any affect.
I'm not an expert in jQuery so any help is greatly appreciated. Perhaps I've missed something simple or there's a better way of doing this?
Thanks and please let me know if you require any further information.
This is little trickier than simple cases:
The Html:
<div style="float: left;">
<ul id="list_1">
<li>Existing 1</li>
<li>Existing 2</li>
<li>
<ul id = "list_2">
<li><dl> <dt>Existing Sub 1</dt></dl></li>
<li>Existing Sub 2</li>
<li>Existing Sub 3</li>
<li>Existing Sub 4</li>
</ul>
</li>
<li>Existing 3</li>
<li>Existing 4</li>
</ul>
</div>
<div style="float: right; margin-top: 30px;">
<ul id="from_list">
<li class="new_item">New Item 1</li>
<li class="new_item">New Item 2</li>
<li class="new_item">New Item 3</li>
<li class="new_item">New Item 4</li>
</ul>
</div>
The CSS:
#list_1 .dropzone {
background-color: #FFFFFF;
border-bottom: 4px solid #FFFFFF;
height: 6px;
}
The Javascript:
var selector = '#list_1, #list_2';
$('#list_1 li').prepend('<div class="dropzone"></div>');
$('#list_1 li, #from_list li').draggable({
opacity: .8,
handle: ' > dl',
addClasses: false,
helper: 'clone',
zIndex: 100 }
);
$('#list_1 .dropzone').droppable({
accept: '#from_list li',
tolerance: 'pointer',
drop: function(e, ui) {
var li = $(this).parent();
var child = !$(this).hasClass('dropzone');
//If this is our first child, we'll need a ul to drop into.
if (child && li.children('ul').length == 0) {
li.append('<ul/>');
}
//ui.draggable is our reference to the item that's been dragged.
if (child) {
li.children('ul').append(ui.draggable);
}
else {
li.before(ui.draggable);
}
//reset our background colours.
li.find('dl,.dropzone').css({ backgroundColor: '', borderColor: '' });
},
over: function() {
$(this).filter('dl').css({ backgroundColor: '#ccc' });
$(this).filter('.dropzone').css({ borderColor: '#aaa' });
},
out: function() {
$(this).filter('dl').css({ backgroundColor: '' });
$(this).filter('.dropzone').css({ borderColor: '' });
}
});
You can see the result here:
http://jsfiddle.net/F3nck/
Credit due:
I found the solution and adapted to your example from:
http://boagworld.com/technology/creating-a-draggable-sitemap-with-jquery/

How to rearrange the items of a list and the DOM with MooTools?

I'm trying to rearrange the items of a list:
<ul>
<li>1 <button><li>
<li>2 <button><li>
<li>3 <button><li>
<li>4 <button><li>
</ul>
using MooTools:
document.getElements('button').addEvent('click', function() {
var toSort = new Fx.Sort(this.getParent(),this.getParent().getNext());
toSort.swap();
toSort = toSort.rearrangeDOM();
}
When I click the button of the first list element y expect:
<ul>
<li>2 <button><li>
<li>1 <button><li>
<li>3 <button><li>
<li>4 <button><li>
</ul>
but I get:
<ul>
<li>2 <button><li>
<li>3 <button><li>
<li>4 <button><li>
<li>1 <button><li>
</ul>
What I'm doing wrong?
Thanks in advance
depends what the effect is that you want to achieve. what is the purpose of 'button'? move up? move to top? move to bottom?
here's an example of a Fx.Sort use that sends a row up (if not first already)
http://jsfiddle.net/dimitar/ZQhgF/
var sort = new Fx.Sort($$("ul li"), {
transition: Fx.Transitions.linear.easeInOut,
link: "chain",
duration: 500,
mode: "vertical",
onComplete: function() {
this.rearrangeDOM();
}
});
document.getElements('button').addEvent('click', function(e) {
e.stop();
var el = this.getParent(), prev = el.getPrevious();
if (!prev)
return;
sort.swap(el, prev);
});
which works on this dom:
<ul id="sorter">
<li>1 <button>up</button></li>
<li>2 <button>up</button></li>
<li>3 <button>up</button></li>
<li>4 <button>up</button></li>
</ul>
it should give you some ideas. what you could also do is a serialize function that can allow you to set any custom order you want and / or save the order after.