<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
    <link rel="stylesheet" type="text/css" href="//cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
    <link rel="stylesheet" href="style.css">
  </head>

  <body>
    <div id="map"></div>
    <script src="//cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="//code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
    <script src="SliderControl.js"></script>
    <script src="script.js"></script>
  </body>

</html>
var map = L.map('map').setView([40.7241745, -73.9841674], 11);

L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}', {
  attribution: 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ',
  maxZoom: 16
}).addTo(map);

var myData = {
  "type": "FeatureCollection",
  "features":[{
    "type":"Feature",
    "geometry":{
      "type":"Point",
      "coordinates":[-74.0481651,40.7208714]
    },
    "properties":{
      "endDate":"12/8/14 22:00",
      "startDate":"12/8/14 19:00"
    }
  },{
    "type":"Feature",
    "geometry":{
      "type":"Point",
      "coordinates":[-73.9924459,40.7176705]
    },
    "properties":{
      "endDate":"12/9/14 19:00",
      "startDate":"12/9/14 19:00"}
  },{
    "type":"Feature",
    "geometry":{
      "type":"Point",
      "coordinates":[-73.4557279,40.6790963]
    },
    "properties":{
      "endDate":"12/9/14 22:00",
      "startDate":"12/9/14 20:00"
    }
  }]
};

var mylayer = L.geoJson(myData).addTo(map);

var sliderControl = L.control.sliderControl({
  position: "topright",
  layer: mylayer
});

map.addControl(sliderControl);

sliderControl.startSlider();
div#map {
 height: 600px;
 width: 800px;
 margin-left: auto;
 margin-bottom: auto;
 margin-top: auto;
 margin-right: auto;
 left: 20px;
 border-color: #000000;
 z-index: 0;
}

body {
 padding: 0px;
 background-color: #fff;
}
L.Control.SliderControl = L.Control.extend({
    options: {
        position: 'topright',
        layers: null,
        maxValue: -1,
        minValue: -1,
        markers: null,
        range: false,
        follow: false
    },

    initialize: function (options) {
        L.Util.setOptions(this, options);
        this._layer = this.options.layer;

    },

    setPosition: function (position) {
        var map = this._map;

        if (map) {
            map.removeControl(this);
        }

        this.options.position = position;

        if (map) {
            map.addControl(this);
        }
        this.startSlider();
        return this;
    },

    onAdd: function (map) {
        this.options.map = map;

        // Create a control sliderContainer with a jquery ui slider
        var sliderContainer = L.DomUtil.create('div', 'slider', this._container);
        $(sliderContainer).append('<div id="leaflet-slider" style="width:200px"><div class="ui-slider-handle"></div><div id="slider-timestamp" style="width:200px; margin-top:10px;background-color:#FFFFFF"></div></div>');
        //Prevent map panning/zooming while using the slider
        $(sliderContainer).mousedown(function () {
            map.dragging.disable();
        });
        $(document).mouseup(function () {
            map.dragging.enable();
            //Only show the slider timestamp while using the slider
            $('#slider-timestamp').html('');
        });

        var options = this.options;
        this.options.markers = [];

        //If a layer has been provided: calculate the min and max values for the slider
        if (this._layer) {
            this._layer.eachLayer(function (layer) {
                if (options.minValue === -1) {
                    options.minValue = layer._leaflet_id;
                }
                options.maxValue = layer._leaflet_id;
                options.markers[layer._leaflet_id] = layer;
            });
            this.options = options;
        } else {
            console.log("Error: You have to specify a layer via new SliderControl({layer: your_layer});");
        }
        return sliderContainer;
    },

    onRemove: function (map) {
        //Delete all markers which where added via the slider and remove the slider div
        for (i = this.options.minValue; i < this.options.maxValue; i++) {
            map.removeLayer(this.options.markers[i]);
        }
        $('#leaflet-slider').remove();
    },

    startSlider: function () {
        _options = this.options;
        $("#leaflet-slider").slider({
            range: _options.range,
            value: _options.minValue + 1,
            min: _options.minValue,
            max: _options.maxValue +1,
            step: 1,
            slide: function (e, ui) {
                var map = _options.map;
                if(!!_options.markers[ui.value]) {
                    // If there is no time property, this line has to be removed (or exchanged with a different property)
                    if(_options.markers[ui.value].feature !== undefined) {
                        if(_options.markers[ui.value].feature.properties.startDate){
                            if(_options.markers[ui.value]) $('#slider-timestamp').html(_options.markers[ui.value].feature.properties.startDate);
                        }else {
                            console.error("You have to have a time property");
                        }
                    }else {
                        // set by leaflet Vector Layers
                        if(_options.markers [ui.value].options.time){
                            if(_options.markers[ui.value]) $('#slider-timestamp').html(_options.markers[ui.value].options.startDate.substr(0, 19));
                        }else {
                            console.error("You have to have a time property")
                        }
                    }
                    
                    var i;
                    if(_options.range){
                        // jquery ui using range
                        for (i = ui.values[0]; i <= ui.values[1]; i++){
                           if(_options.markers[i]) map.addLayer(_options.markers[i]);
                        }
                        for (i = _options.maxValue; i > ui.values[1]; i--) {
                            if(_options.markers[i]) map.removeLayer(_options.markers[i]);
                        }
                        for (i = _options.minValue; i < ui.values[0]; i++) {
                            if(_options.markers[i]) map.removeLayer(_options.markers[i]);
                        }
                    }else if(_options.follow){
                        for (i = _options.minValue; i < (ui.value - _options.follow); i++) {
                            if(_options.markers[i]) map.removeLayer(_options.markers[i]);
                        }
                        for (i = (ui.value - _options.follow); i < ui.value ; i++) {
                            if(_options.markers[i]) map.addLayer(_options.markers[i]);
                        }
                        for (i = ui.value; i <= _options.maxValue; i++) {
                            if(_options.markers[i]) map.removeLayer(_options.markers[i]);
                        }
                    }else{
                        // jquery ui for point before
                        for (i = _options.minValue; i <= ui.value ; i++) {
                            if(_options.markers[i]) map.addLayer(_options.markers[i]);
                        }
                        for (i = (ui.value + 1); i <= _options.maxValue; i++) {
                            if(_options.markers[i]) map.removeLayer(_options.markers[i]);
                        }
                    }
                }
            }
        });
        _options.map.addLayer(_options.markers[_options.minValue]);
    }
});

L.control.sliderControl = function (options) {
    return new L.Control.SliderControl(options);
};