Add loading indicator.

This commit is contained in:
David Molineus
2015-01-08 11:01:22 +01:00
parent 5cd680562d
commit 91674e2f8d
15 changed files with 664 additions and 11 deletions

View File

@@ -16,6 +16,17 @@ L.Contao = L.Class.extend( {
*/
initialize: function() {
L.Icon.Default.imagePath = 'assets/leaflet/libs/leaflet/images';
// Bind triggered data:loading and data:loaded events to the map so that the loading indicator
// is aware of that. Dataloading and dataloaded are the default events which leaflet uses but leaflet.ajax not.
L.Map.addInitHook(function () {
var map = this;
this.on('layeradd', function(e) {
e.layer.on('data:loading', function() { map.fire('dataloading'); });
e.layer.on('data:loaded', function() { map.fire('dataload'); });
});
});
},
/**

View File

@@ -0,0 +1,19 @@
Contributing
============
Your pull requests are very welcome! Please follow these guidelines:
* Keep code compatible with the same browsers Leaflet aims to be [compatible
with](http://leafletjs.com/features.html).
* Use four spaces rather than tabs.
## Contributors
* [Eric Brelsford](https://github.com/ebrelsford)
* [Nick Iaconis](https://github.com/codefox421)
* [Matthias Althaus](https://github.com/althaus)
* [Yohan Boniface](https://github.com/yohanboniface)
* [kermit-the-frog](https://github.com/kermit-the-frog)
* [kcwu](https://github.com/kcwu)
* [Robbie Trencheny](https://github.com/robbiet480)

View File

@@ -0,0 +1,23 @@
.leaflet-control-loading:empty {
/* This is where your loading indicator would go */
background-image: url('loading.gif');
}
.leaflet-control-loading,
.leaflet-control-zoom a.leaflet-control-loading ,
.leaflet-control-zoomslider a.leaflet-control-loading {
display: none;
}
.leaflet-control-loading.is-loading,
.leaflet-control-zoom a.leaflet-control-loading.is-loading,
.leaflet-control-zoomslider a.leaflet-control-loading.is-loading {
display: block;
}
/* Necessary for display consistency in Leaflet >= 0.6 */
.leaflet-bar-part-bottom {
border-bottom: medium none;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}

View File

@@ -0,0 +1,262 @@
/*
* L.Control.Loading is a control that shows a loading indicator when tiles are
* loading or when map-related AJAX requests are taking place.
*/
(function () {
function defineLeafletLoading(L) {
L.Control.Loading = L.Control.extend({
options: {
position: 'topleft',
separate: false,
zoomControl: null,
spinjs: false,
spin: {
lines: 7,
length: 3,
width: 3,
radius: 5,
rotate: 13,
top: "83%"
}
},
initialize: function(options) {
L.setOptions(this, options);
this._dataLoaders = {};
// Try to set the zoom control this control is attached to from the
// options
if (this.options.zoomControl !== null) {
this.zoomControl = this.options.zoomControl;
}
},
onAdd: function(map) {
if (this.options.spinjs && (typeof Spinner !== 'function')) {
return console.error("Leaflet.loading cannot load because you didn't load spin.js (http://fgnass.github.io/spin.js/), even though you set it in options.");
}
this._addLayerListeners(map);
this._addMapListeners(map);
// Try to set the zoom control this control is attached to from the map
// the control is being added to
if (!this.options.separate && !this.zoomControl) {
if (map.zoomControl) {
this.zoomControl = map.zoomControl;
} else if (map.zoomsliderControl) {
this.zoomControl = map.zoomsliderControl;
}
}
// Create the loading indicator
var classes = 'leaflet-control-loading';
var container;
if (this.zoomControl && !this.options.separate) {
// If there is a zoom control, hook into the bottom of it
container = this.zoomControl._container;
// These classes are no longer used as of Leaflet 0.6
classes += ' leaflet-bar-part-bottom leaflet-bar-part last';
}
else {
// Otherwise, create a container for the indicator
container = L.DomUtil.create('div', 'leaflet-control-zoom leaflet-bar');
}
this._indicator = L.DomUtil.create('a', classes, container);
if (this.options.spinjs) {
this._spinner = new Spinner(this.options.spin).spin();
this._indicator.appendChild(this._spinner.el);
}
return container;
},
onRemove: function(map) {
this._removeLayerListeners(map);
this._removeMapListeners(map);
},
removeFrom: function (map) {
if (this.zoomControl && !this.options.separate) {
// Override Control.removeFrom() to avoid clobbering the entire
// _container, which is the same as zoomControl's
this._container.removeChild(this._indicator);
this._map = null;
this.onRemove(map);
return this;
}
else {
// If this control is separate from the zoomControl, call the
// parent method so we don't leave behind an empty container
return L.Control.prototype.removeFrom.call(this, map);
}
},
addLoader: function(id) {
this._dataLoaders[id] = true;
this.updateIndicator();
},
removeLoader: function(id) {
delete this._dataLoaders[id];
this.updateIndicator();
},
updateIndicator: function() {
if (this.isLoading()) {
this._showIndicator();
}
else {
this._hideIndicator();
}
},
isLoading: function() {
return this._countLoaders() > 0;
},
_countLoaders: function() {
var size = 0, key;
for (key in this._dataLoaders) {
if (this._dataLoaders.hasOwnProperty(key)) size++;
}
return size;
},
_showIndicator: function() {
// Show loading indicator
L.DomUtil.addClass(this._indicator, 'is-loading');
// If zoomControl exists, make the zoom-out button not last
if (!this.options.separate) {
if (this.zoomControl instanceof L.Control.Zoom) {
L.DomUtil.removeClass(this.zoomControl._zoomOutButton, 'leaflet-bar-part-bottom');
}
else if (typeof L.Control.Zoomslider === 'function' && this.zoomControl instanceof L.Control.Zoomslider) {
L.DomUtil.removeClass(this.zoomControl._ui.zoomOut, 'leaflet-bar-part-bottom');
}
}
},
_hideIndicator: function() {
// Hide loading indicator
L.DomUtil.removeClass(this._indicator, 'is-loading');
// If zoomControl exists, make the zoom-out button last
if (!this.options.separate) {
if (this.zoomControl instanceof L.Control.Zoom) {
L.DomUtil.addClass(this.zoomControl._zoomOutButton, 'leaflet-bar-part-bottom');
}
else if (typeof L.Control.Zoomslider === 'function' && this.zoomControl instanceof L.Control.Zoomslider) {
L.DomUtil.addClass(this.zoomControl._ui.zoomOut, 'leaflet-bar-part-bottom');
}
}
},
_handleLoading: function(e) {
this.addLoader(this.getEventId(e));
},
_handleLoad: function(e) {
this.removeLoader(this.getEventId(e));
},
getEventId: function(e) {
if (e.id) {
return e.id;
}
else if (e.layer) {
return e.layer._leaflet_id;
}
return e.target._leaflet_id;
},
_layerAdd: function(e) {
if (!e.layer || !e.layer.on) return
try {
e.layer.on({
loading: this._handleLoading,
load: this._handleLoad
}, this);
}
catch (exception) {
console.warn('L.Control.Loading: Tried and failed to add ' +
' event handlers to layer', e.layer);
console.warn('L.Control.Loading: Full details', exception);
}
},
_addLayerListeners: function(map) {
// Add listeners for begin and end of load to any layers already on the
// map
map.eachLayer(function(layer) {
if (!layer.on) return;
layer.on({
loading: this._handleLoading,
load: this._handleLoad
}, this);
}, this);
// When a layer is added to the map, add listeners for begin and end
// of load
map.on('layeradd', this._layerAdd, this);
},
_removeLayerListeners: function(map) {
// Remove listeners for begin and end of load from all layers
map.eachLayer(function(layer) {
if (!layer.off) return;
layer.off({
loading: this._handleLoading,
load: this._handleLoad
}, this);
}, this);
// Remove layeradd listener from map
map.off('layeradd', this._layerAdd, this);
},
_addMapListeners: function(map) {
// Add listeners to the map for (custom) dataloading and dataload
// events, eg, for AJAX calls that affect the map but will not be
// reflected in the above layer events.
map.on({
dataloading: this._handleLoading,
dataload: this._handleLoad,
layerremove: this._handleLoad
}, this);
},
_removeMapListeners: function(map) {
map.off({
dataloading: this._handleLoading,
dataload: this._handleLoad,
layerremove: this._handleLoad
}, this);
}
});
L.Map.addInitHook(function () {
if (this.options.loadingControl) {
this.loadingControl = new L.Control.Loading();
this.addControl(this.loadingControl);
}
});
L.Control.loading = function(options) {
return new L.Control.Loading(options);
};
}
if (typeof define === 'function' && define.amd) {
// Try to add leaflet.loading to Leaflet using AMD
define(['leaflet'], function (L) {
defineLeafletLoading(L);
});
}
else {
// Else use the global L
defineLeafletLoading(L);
}
})();

View File

@@ -0,0 +1,19 @@
Copyright (c) 2013 Eric Brelsford
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,83 @@
Leaflet.loading
===============
Leaflet.loading is a simple loading control for [Leaflet][]. An unobtrusive
loading indicator is added below the zoom control if one exists. The indicator
is visible when tiles are loading or when other data is loading, as indicated by
firing custom events on a map. The indicator can be an image, or a [spin.js][] spinner (image-less).
## Usage
Leaflet.loading is only tested on Leaflet version 0.6 or greater. It will almost
certainly not work with older versions of Leaflet.
Include `Control.Loading.js` and `Control.Loading.css`, then create a map with `loadingControl: true`
in its options.
By default, Leaflet.loading expects an image. `Control.Loading.css` contains a
start in this direction. The simplest case would be adding a 16 x 16 loading gif
in `.leaflet-control-loading`.
You can also set `spinjs: true` in the options, and load [spin.js][]
to use that instead of an image. A spin.js options object can be passed as the spin key
when initializing the control.
Whichever method you use, make sure you only use one.
Once the above is complete you will have a loading indicator that only appears
when tiles are loading.
If you want to show the loading indicator while other AJAX requests or something
else is occurring, simply fire the `dataloading` event on your map when you
begin loading and `dataload` when you are finished loading. The control tracks
the number of concurrent loaders, so it is your responsibility to ensure that
the `dataloading` and `dataload` are called symmetrically.
### Options
- **position**: (string) Where you want the control to show up on the map (standard
Leaflet control option). Optional, defaults to `topleft`
- **separate**: (boolean) Whether the control should be separate from the zoom
control or not, defaults to false.
- **zoomControl**: (L.Control.Zoom) The zoom control that the control should be
added to. This is only necessary when adding a loading control to a zoom
control that you added manually and do not want a separate loading control.
- **spinjs**: (boolean) Enable the use of [spin.js][]. Optional, defaults to `false`
- **spin**: (object) A [spin.js][] options object. Optional, defaults to
```
{
lines: 7,
length: 3,
width: 3,
radius: 5,
rotate: 13,
top: "83%"
}
```
## Demos
See Leaflet.loading in action (zoom or pan to make tiles load):
- Using the [simplest setup][simple], with the loading indicator attached to
the zoom control.
- With the loading indicator [separate][] from the zoom control.
- With the loading indicator and zoom control on the [top right][topright] of
the map.
- The [simplest example using spin.js](http://ebrelsford.github.io/Leaflet.loading/spinjs.html) instead of an image
## License
Leaflet.loading is free software, and may be redistributed under the MIT
License.
[Leaflet]: https://github.com/Leaflet/Leaflet
[spin.js]: https://github.com/fgnass/spin.js/
[simple]: http://ebrelsford.github.io/Leaflet.loading/simple.html
[separate]: http://ebrelsford.github.io/Leaflet.loading/separate.html
[topright]: http://ebrelsford.github.io/Leaflet.loading/topright.html

View File

@@ -0,0 +1,27 @@
{
"name": "leaflet.loading",
"version": "0.1.13",
"homepage": "https://github.com/ebrelsford/leaflet.loading",
"authors": [
"Eric Brelsford <ebrelsford@gmail.com>"
],
"description": "A loading-indicator control for Leaflet",
"main": "src/Control.Loading.js",
"keywords": [
"leaflet",
"map",
"gis",
"loading"
],
"dependencies": {
"leaflet": ">=0.6"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,21 @@
The MIT License
Copyright (c) 2011-2014 Felix Gnass [fgnass at neteye dot de]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

2
assets/libs/spin-js/spin.min.js vendored Normal file
View File

@@ -0,0 +1,2 @@
//fgnass.github.com/spin.js#v2.0.1
!function(a,b){"object"==typeof exports?module.exports=b():"function"==typeof define&&define.amd?define(b):a.Spinner=b()}(this,function(){"use strict";function a(a,b){var c,d=document.createElement(a||"div");for(c in b)d[c]=b[c];return d}function b(a){for(var b=1,c=arguments.length;c>b;b++)a.appendChild(arguments[b]);return a}function c(a,b,c,d){var e=["opacity",b,~~(100*a),c,d].join("-"),f=.01+c/d*100,g=Math.max(1-(1-a)/b*(100-f),a),h=j.substring(0,j.indexOf("Animation")).toLowerCase(),i=h&&"-"+h+"-"||"";return l[e]||(m.insertRule("@"+i+"keyframes "+e+"{0%{opacity:"+g+"}"+f+"%{opacity:"+a+"}"+(f+.01)+"%{opacity:1}"+(f+b)%100+"%{opacity:"+a+"}100%{opacity:"+g+"}}",m.cssRules.length),l[e]=1),e}function d(a,b){var c,d,e=a.style;for(b=b.charAt(0).toUpperCase()+b.slice(1),d=0;d<k.length;d++)if(c=k[d]+b,void 0!==e[c])return c;return void 0!==e[b]?b:void 0}function e(a,b){for(var c in b)a.style[d(a,c)||c]=b[c];return a}function f(a){for(var b=1;b<arguments.length;b++){var c=arguments[b];for(var d in c)void 0===a[d]&&(a[d]=c[d])}return a}function g(a,b){return"string"==typeof a?a:a[b%a.length]}function h(a){this.opts=f(a||{},h.defaults,n)}function i(){function c(b,c){return a("<"+b+' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">',c)}m.addRule(".spin-vml","behavior:url(#default#VML)"),h.prototype.lines=function(a,d){function f(){return e(c("group",{coordsize:k+" "+k,coordorigin:-j+" "+-j}),{width:k,height:k})}function h(a,h,i){b(m,b(e(f(),{rotation:360/d.lines*a+"deg",left:~~h}),b(e(c("roundrect",{arcsize:d.corners}),{width:j,height:d.width,left:d.radius,top:-d.width>>1,filter:i}),c("fill",{color:g(d.color,a),opacity:d.opacity}),c("stroke",{opacity:0}))))}var i,j=d.length+d.width,k=2*j,l=2*-(d.width+d.length)+"px",m=e(f(),{position:"absolute",top:l,left:l});if(d.shadow)for(i=1;i<=d.lines;i++)h(i,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(i=1;i<=d.lines;i++)h(i);return b(a,m)},h.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d<e.childNodes.length&&(e=e.childNodes[b+d],e=e&&e.firstChild,e=e&&e.firstChild,e&&(e.opacity=c))}}var j,k=["webkit","Moz","ms","O"],l={},m=function(){var c=a("style",{type:"text/css"});return b(document.getElementsByTagName("head")[0],c),c.sheet||c.styleSheet}(),n={lines:12,length:7,width:5,radius:10,rotate:0,corners:1,color:"#000",direction:1,speed:1,trail:100,opacity:.25,fps:20,zIndex:2e9,className:"spinner",top:"50%",left:"50%",position:"absolute"};h.defaults={},f(h.prototype,{spin:function(b){this.stop();{var c=this,d=c.opts,f=c.el=e(a(0,{className:d.className}),{position:d.position,width:0,zIndex:d.zIndex});d.radius+d.length+d.width}if(e(f,{left:d.left,top:d.top}),b&&b.insertBefore(f,b.firstChild||null),f.setAttribute("role","progressbar"),c.lines(f,c.opts),!j){var g,h=0,i=(d.lines-1)*(1-d.direction)/2,k=d.fps,l=k/d.speed,m=(1-d.opacity)/(l*d.trail/100),n=l/d.lines;!function o(){h++;for(var a=0;a<d.lines;a++)g=Math.max(1-(h+(d.lines-a)*n)%l*m,d.opacity),c.opacity(f,a*d.direction+i,g,d);c.timeout=c.el&&setTimeout(o,~~(1e3/k))}()}return c},stop:function(){var a=this.el;return a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=void 0),this},lines:function(d,f){function h(b,c){return e(a(),{position:"absolute",width:f.length+f.width+"px",height:f.width+"px",background:b,boxShadow:c,transformOrigin:"left",transform:"rotate("+~~(360/f.lines*k+f.rotate)+"deg) translate("+f.radius+"px,0)",borderRadius:(f.corners*f.width>>1)+"px"})}for(var i,k=0,l=(f.lines-1)*(1-f.direction)/2;k<f.lines;k++)i=e(a(),{position:"absolute",top:1+~(f.width/2)+"px",transform:f.hwaccel?"translate3d(0,0,0)":"",opacity:f.opacity,animation:j&&c(f.opacity,f.trail,l+k*f.direction,f.lines)+" "+1/f.speed+"s linear infinite"}),f.shadow&&b(i,e(h("#000","0 0 4px #000"),{top:"2px"})),b(d,b(i,h(g(f.color,k),"0 0 1px rgba(0,0,0,.1)")));return d},opacity:function(a,b,c){b<a.childNodes.length&&(a.childNodes[b].style.opacity=c)}});var o=e(a("group"),{behavior:"url(#default#VML)"});return!d(o,"transform")&&o.adj?i():j=d(o,"animation"),h});

View File

@@ -48,6 +48,7 @@ $GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\Control\ZoomCon
$GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\Control\ScaleControlMapper';
$GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\Control\LayersControlMapper';
$GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\Control\AttributionControlMapper';
$GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\Control\LoadingControlMapper';
$GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\UI\MarkerMapper';
$GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\Type\ImageIconMapper';
$GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\Vector\PolylineMapper';
@@ -115,7 +116,7 @@ $GLOBALS['LEAFLET_LAYERS'] = array
*
* Supported leaflet control types. Register your type for the database driven definition here.
*/
$GLOBALS['LEAFLET_CONTROLS'] = array('zoom', 'layers', 'scale', 'attribution');
$GLOBALS['LEAFLET_CONTROLS'] = array('zoom', 'layers', 'scale', 'attribution', 'loading');
/*
@@ -181,3 +182,17 @@ $GLOBALS['LEAFLET_ASSETS']['leaflet-ajax'] = array(
)
);
$GLOBALS['LEAFLET_ASSETS']['leaflet-loading'] = array(
'css' => array(
array('assets/leaflet/libs/leaflet-loading/Control.Loading.css', 'file')
),
'javascript' => array(
array('assets/leaflet/libs/leaflet-loading/Control.Loading.js', 'file')
)
);
$GLOBALS['LEAFLET_ASSETS']['spin.js'] = array(
'javascript' => array(
array('assets/leaflet/libs/spin-js/spin.min.js', 'file')
)
);

View File

@@ -102,9 +102,16 @@ $GLOBALS['TL_DCA']['tl_leaflet_control'] = array
),
'attribution extends default' => array(
'config' => array('attributions', 'prefix')
),
'loading extends default' => array(
'config' => array('separate', 'zoomControl', 'spinjs')
)
),
'metasubpalettes' => array(
'spinjs' => array('spin')
),
'fields' => array
(
'id' => array
@@ -311,5 +318,51 @@ $GLOBALS['TL_DCA']['tl_leaflet_control'] = array
'eval' => array('mandatory' => false, 'maxlength' => 255, 'tl_class' => 'clr', 'allowHtml' => true),
'sql' => "mediumblob NULL"
),
'separate' => array
(
'label' => &$GLOBALS['TL_LANG']['tl_leaflet_control']['separate'],
'exclude' => true,
'inputType' => 'checkbox',
'eval' => array('tl_class' => 'w50'),
'sql' => "char(1) NOT NULL default ''"
),
'zoomControl' => array
(
'label' => &$GLOBALS['TL_LANG']['tl_leaflet_control']['zoomControl'],
'exclude' => true,
'inputType' => 'select',
'options_callback' => array('Netzmacht\Contao\Leaflet\Dca\Control', 'getZoomControls'),
'reference' => &$GLOBALS['TL_LANG']['tl_leaflet_control'],
'eval' => array(
'mandatory' => false,
'tl_class' => 'w50',
'chosen' => true,
'includeBlankOption' => true
),
'sql' => "varchar(255) NOT NULL default ''"
),
'spinjs' => array
(
'label' => &$GLOBALS['TL_LANG']['tl_leaflet_control']['spinjs'],
'exclude' => true,
'inputType' => 'checkbox',
'eval' => array('tl_class' => 'w50', 'submitOnChange' => true),
'sql' => "char(1) NOT NULL default ''"
),
'spin' => array
(
'label' => &$GLOBALS['TL_LANG']['tl_leaflet_control']['spin'],
'exclude' => true,
'inputType' => 'textarea',
'eval' => array(
'style' => 'height:60px',
'preserveTags' => true,
'decodeEntities' => true,
'allowHtml' => true,
'rte' => 'ace|json',
'tl_class' => 'clr'
),
'sql' => "mediumtext NULL"
),
),
);

View File

@@ -59,6 +59,16 @@ $GLOBALS['TL_LANG']['tl_leaflet_control']['collapsed'][0] = 'Collapsed';
$GLOBALS['TL_LANG']['tl_leaflet_control']['collapsed'][1] = 'If true, the control will be collapsed into an icon and expanded on mouse hover or touch.';
$GLOBALS['TL_LANG']['tl_leaflet_control']['autoZIndex'][0] = 'Auto zIndex';
$GLOBALS['TL_LANG']['tl_leaflet_control']['autoZIndex'][1] = 'If true, the control will assign zIndexes in increasing order to all of its layers so that the order is preserved when switching them on/off.';
$GLOBALS['TL_LANG']['tl_leaflet_control']['spin'][0] = 'Spin.js configuration';
$GLOBALS['TL_LANG']['tl_leaflet_control']['spin'][1] = 'Use valid json to configure the spin.js plugin. For more details see <a href="http://fgnass.github.io/spin.js/" target="_blank">http://fgnass.github.io/spin.js/</a>.';
$GLOBALS['TL_LANG']['tl_leaflet_control']['spinjs'][0] = 'Use spin.js';
$GLOBALS['TL_LANG']['tl_leaflet_control']['spinjs'][1] = 'Instead of an background image the spin.js plugin is used.';
$GLOBALS['TL_LANG']['tl_leaflet_control']['separate'][0] = 'Separate';
$GLOBALS['TL_LANG']['tl_leaflet_control']['separate'][1] = 'Display control separate from zoom control.';
$GLOBALS['TL_LANG']['tl_leaflet_control']['zoomControl'][0] = 'Zoom control';
$GLOBALS['TL_LANG']['tl_leaflet_control']['zoomControl'][1] = 'Assign loading control to a specific zoom control. If it\'s not used on the map/activated the default one is used.';
$GLOBALS['TL_LANG']['tl_leaflet_control']['layerMode'][0] = 'Mode';
$GLOBALS['TL_LANG']['tl_leaflet_control']['layerMode'][1] = 'Add layer as baselayer or overlay.';
$GLOBALS['TL_LANG']['tl_leaflet_control']['bottomleft'][0] = 'Bottom left';
$GLOBALS['TL_LANG']['tl_leaflet_control']['bottomleft'][1] = 'Bottom left of the map.';

View File

@@ -12,6 +12,8 @@
namespace Netzmacht\Contao\Leaflet\Dca;
use Netzmacht\Contao\DevTools\Dca\Options\OptionsBuilder;
use Netzmacht\Contao\Leaflet\Model\ControlModel;
use Netzmacht\Contao\Leaflet\Model\LayerModel;
class Control
@@ -38,4 +40,11 @@ class Control
return $options;
}
public function getZoomControls()
{
$collection = ControlModel::findBy('type', 'zoom', array('order' => 'title'));
return OptionsBuilder::fromCollection($collection, 'id', 'title')->getOptions();
}
}

View File

@@ -0,0 +1,99 @@
<?php
/**
* @package dev
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2015 netzmacht creative David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Control;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Model\ControlModel;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Control\Zoom;
use Netzmacht\LeafletPHP\Definition\Type\LatLngBounds;
use Netzmacht\LeafletPHP\Plugins\Loading\LoadingControl;
use Netzmacht\LeafletPHP\Plugins\Loading\SpinJsLoadingControl;
class LoadingControlMapper extends AbstractControlMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Plugins\Loading\LoadingControl';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'loading';
/**
* {@inheritdoc}
*/
protected function getClassName(\Model $model, DefinitionMapper $mapper, LatLngBounds $bounds = null)
{
if ($model->spinjs) {
return 'Netzmacht\LeafletPHP\Plugins\Loading\SpinJsLoadingControl';
}
return parent::getClassName($model, $mapper, $bounds);
}
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->addOption('separate');
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
LatLngBounds $bounds = null
) {
parent::build($definition, $model, $mapper, $bounds);
if ($definition instanceof SpinJsLoadingControl && $model->spin) {
$config = json_decode($model->spin, true);
if (is_array($config)) {
$definition->setSpin($config);
}
}
if ($definition instanceof LoadingControl && !$definition->isSeparate() && $model->zoomControl ) {
// Only assign if zoom control is activated and part of the map.
$control = ControlModel::findOneBy(
array('active=1', 'type=?', 'pid=?', 'id=?'),
array('zoom', $model->pid, $model->zoomControl)
);
if ($control) {
$control = $mapper->handle($control);
if ($control instanceof Zoom) {
// By default the loading control overrides the position of the zoom control. Deactivate it by
// overriding the position.
$definition->setPosition($control->getPosition());
$definition->setZoomControl($control);
}
}
}
}
}