Skip to content

Instantly share code, notes, and snippets.

@odoe
Last active January 21, 2023 20:04
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save odoe/f8eae50bd51ba0e17e6e to your computer and use it in GitHub Desktop.
Save odoe/f8eae50bd51ba0e17e6e to your computer and use it in GitHub Desktop.
A custom popup pager for multiple features for use with Leaflet.js.
/*jshint laxcomma:true*/
/**
* The following uses RxJS to handle the
* next/prev click event stream
* https://github.com/Reactive-Extensions/RxJS
* Could substitute with regular addEventListener
* if desired.
*
* It also uses font-awesome for next/prev icons
* http://fortawesome.github.io/Font-Awesome/
*
* It still needs some work to allow using aliases,
* hide certain fields and highlight current item on map.
* */
/**
* CSS for popup
* ----------------
.paged-popup {
min-width: 250px;
width: 100%;
padding: 15px;
}
.table-container {
font-size: 0.8em;
max-height: 300px;
overflow-y: auto;
}
.pager-icon {
float: right;
cursor: pointer;
margin: 2px;
}
* ----------------
* */
var Rx = require('rx');
var nextIcon
, prevIcon
, container
, info
, table_container
, table
, pagedPopup
, addElement
, makeBody;
nextIcon = document.createElement('span');
nextIcon.className = 'fa fa-play pager-icon';
prevIcon = document.createElement('span');
prevIcon.className = 'fa fa-play fa-flip-horizontal pager-icon';
container = document.createElement('div');
container.className = 'paged-popup';
container.appendChild(nextIcon);
container.appendChild(prevIcon);
info = document.createElement('div');
info.className = 'paged-info';
container.appendChild(info);
table_container = document.createElement('div');
table_container.className = 'table-container';
table = document.createElement('table');
table_container.appendChild(table);
// adds tbody element to table
addElement = function addElement(elem) {
table.innerHTML = '';
table.appendChild(elem);
};
// creates the tbody
makeBody = function(elems, idx) {
var elem = document.createElement('tbody');
if (elems[idx]) {
elems[idx].map(function(el) {
elem.appendChild(el);
});
}
return elem;
};
pagedPopup = function pagedPopup(features) {
var data;
info.innerHTML = '<strong>' + features.length + ' items</strong>';
data = features.map(function(feature) {
var props
, keys
, rows;
props = feature.properties;
keys = Object.keys(props);
rows = keys.sort().map(function(k) {
var row
, field
, value;
row = document.createElement('tr');
field = document.createElement('td');
value = document.createElement('td');
field.innerHTML = k;
value.innerHTML = props[k];
row.appendChild(field);
row.appendChild(value);
return row;
});
return rows;
});
info.appendChild(table_container);
// ** helper functions **
// curry
var elemGen = makeBody.bind(undefined, data);
var next = Rx.Observable.fromEvent(nextIcon, 'click').map(function() { return 1; });
var prev = Rx.Observable.fromEvent(prevIcon, 'click').map(function() { return -1; });
// merge the streams
var pages = Rx.Observable.merge(next, prev);
pages
.startWith(0)
.scan(0, function(sum, value) {
var a = sum + value;
var b = a < data.length - 1 ? a : data.length - 1;
return b > -1 ? b : 0;
})
.map(elemGen)
.filter(function(el) {
return el.children.length;
})
.subscribe(addElement);
return container;
};
module.exports = pagedPopup;
@munkh-altai
Copy link

Hello this is very use full plugin.
Can you provide example code with leaflet ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment