7

I've seen some nice examples of jQuery sliders that select date ranges: http://ghusse.github.com/jQRangeSlider/stable/demo/

And time ranges: http://marcneuwirth.com/blog/2011/05/22/revisiting-the-jquery-ui-time-slider/

But I'm looking for something that will be able to select date ranges down to the month, day, minute. It would be great to be able to have it as both a date range selector and a plain slider.

Has anyone seen an implementation like that? Would the normal jQuery UI slider using Unix time as my values make sense?

Shawn31313
  • 5,978
  • 4
  • 38
  • 80
mhkeller
  • 713
  • 1
  • 8
  • 19
  • 1
    Welcome to Stack Overflow! Unfortunately for the life expectancy of this question, [Stack Overflow is not a Recommendation Engine.](http://meta.stackexchange.com/a/128562/133242) – Matt Ball May 05 '12 at 23:37
  • http://trentrichardson.com/examples/timepicker/ ? – Christian May 06 '12 at 00:50
  • 1
    @MattBall: He's not asking for recommendations. **He's looking for a solution.** He's asking if anyone has seen a similar control that he needs so he doesn't need to write it himself. No recommendations here, are there? **No**. – Robert Koritnik May 06 '12 at 08:52
  • How long do you expect your range slider to be? Because if you set your granularity down to minute level and your range is long enough it will likely be that you won't be able to select all possible values. But having three sliders (first one to set date, second and third one to set time of those two dates) could be done properly. All you'd have to do is to think about usability of such a control and how to make it intuitive to use. Because you'd first need to drag date selector which would open time selector upon handle release. – Robert Koritnik May 06 '12 at 08:56
  • @RobertKoritnik okay, here's another, much more specific meta question to back me up: http://meta.stackexchange.com/questions/129153/are-im-looking-for-xyz-project-plugin-library-for-language-zyx-on-topic – Matt Ball May 06 '12 at 13:19
  • @MattBall: Ok. This is true. This question may result in answers with links. But not necessarily. I would ask **tfridge** to rephrase the question or ask a new one which would result in more development-like answers. But I would still keep it as is. There are many similar type questions on SO anyway and this one has specific requirements that may not have been solved before, so **it may likely attract answers with code** or at least solution suggestions. And that should be a good answer to this question. But to some extent you're right. – Robert Koritnik May 06 '12 at 13:31
  • @RobertKoritnik It will be ~1000px wide but it's not absolutely necessary that people can select down to an exact minute with the slider. Rather, I need the slider to trigger time-stamped events that are down to the minute. For navigation purposes you could scrub the slider to the start of a day, hit play, and that would be fine. – mhkeller May 06 '12 at 17:40

2 Answers2

16

Here is my fiddle for this (I was also looking for something and then decided to create one): http://jsfiddle.net/Lcrsd3jt/45/

html:

  <script type='text/javascript' src='//code.jquery.com/jquery-2.0.2.js'></script>
  <script type="text/javascript" src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
  <link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
    <div id="time-range">
        <p>Time Range: <span class="slider-time"></span> - <span class="slider-time2"></span>
        </p>
        <div class="sliders_step1">
            <div id="slider-range"></div>
        </div>
    </div>

js:

var dt_from = "2014/11/01 00:34:44";
var dt_to = "2014/11/24 16:37:43";

$('.slider-time').html(dt_from);
$('.slider-time2').html(dt_to);
var min_val = Date.parse(dt_from)/1000;
var max_val = Date.parse(dt_to)/1000;

function zeroPad(num, places) {
  var zero = places - num.toString().length + 1;
  return Array(+(zero > 0 && zero)).join("0") + num;
}
function formatDT(__dt) {
    var year = __dt.getFullYear();
    var month = zeroPad(__dt.getMonth()+1, 2);
    var date = zeroPad(__dt.getDate(), 2);
    var hours = zeroPad(__dt.getHours(), 2);
    var minutes = zeroPad(__dt.getMinutes(), 2);
    var seconds = zeroPad(__dt.getSeconds(), 2);
    return year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + ':' + seconds;
};


$("#slider-range").slider({
    range: true,
    min: min_val,
    max: max_val,
    step: 10,
    values: [min_val, max_val],
    slide: function (e, ui) {
        var dt_cur_from = new Date(ui.values[0]*1000); //.format("yyyy-mm-dd hh:ii:ss");
        $('.slider-time').html(formatDT(dt_cur_from));

        var dt_cur_to = new Date(ui.values[1]*1000); //.format("yyyy-mm-dd hh:ii:ss");                
        $('.slider-time2').html(formatDT(dt_cur_to));
    }
});

css:

#time-range p {
    font-family:"Arial", sans-serif;
    font-size:14px;
    color:#333;
}
.ui-slider-horizontal {
    height: 8px;
    background: #D7D7D7;
    border: 1px solid #BABABA;
    box-shadow: 0 1px 0 #FFF, 0 1px 0 #CFCFCF inset;
    clear: both;
    margin: 8px 0;
    -webkit-border-radius: 6px;
    -moz-border-radius: 6px;
    -ms-border-radius: 6px;
    -o-border-radius: 6px;
    border-radius: 6px;
}
.ui-slider {
    position: relative;
    text-align: left;
}
.ui-slider-horizontal .ui-slider-range {
    top: -1px;
    height: 100%;
}
.ui-slider .ui-slider-range {
    position: absolute;
    z-index: 1;
    height: 8px;
    font-size: .7em;
    display: block;
    border: 1px solid #5BA8E1;
    box-shadow: 0 1px 0 #AAD6F6 inset;
    -moz-border-radius: 6px;
    -webkit-border-radius: 6px;
    -khtml-border-radius: 6px;
    border-radius: 6px;
    background: #81B8F3;
    background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgi…pZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
    background-size: 100%;
    background-image: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(0%, #A0D4F5), color-stop(100%, #81B8F3));
    background-image: -webkit-linear-gradient(top, #A0D4F5, #81B8F3);
    background-image: -moz-linear-gradient(top, #A0D4F5, #81B8F3);
    background-image: -o-linear-gradient(top, #A0D4F5, #81B8F3);
    background-image: linear-gradient(top, #A0D4F5, #81B8F3);
}
.ui-slider .ui-slider-handle {
    border-radius: 50%;
    background: #F9FBFA;
    background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgi…pZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
    background-size: 100%;
    background-image: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(0%, #C7CED6), color-stop(100%, #F9FBFA));
    background-image: -webkit-linear-gradient(top, #C7CED6, #F9FBFA);
    background-image: -moz-linear-gradient(top, #C7CED6, #F9FBFA);
    background-image: -o-linear-gradient(top, #C7CED6, #F9FBFA);
    background-image: linear-gradient(top, #C7CED6, #F9FBFA);
    width: 22px;
    height: 22px;
    -webkit-box-shadow: 0 2px 3px -1px rgba(0, 0, 0, 0.6), 0 -1px 0 1px rgba(0, 0, 0, 0.15) inset, 0 1px 0 1px rgba(255, 255, 255, 0.9) inset;
    -moz-box-shadow: 0 2px 3px -1px rgba(0, 0, 0, 0.6), 0 -1px 0 1px rgba(0, 0, 0, 0.15) inset, 0 1px 0 1px rgba(255, 255, 255, 0.9) inset;
    box-shadow: 0 2px 3px -1px rgba(0, 0, 0, 0.6), 0 -1px 0 1px rgba(0, 0, 0, 0.15) inset, 0 1px 0 1px rgba(255, 255, 255, 0.9) inset;
    -webkit-transition: box-shadow .3s;
    -moz-transition: box-shadow .3s;
    -o-transition: box-shadow .3s;
    transition: box-shadow .3s;
}
.ui-slider .ui-slider-handle {
    position: absolute;
    z-index: 2;
    width: 22px;
    height: 22px;
    cursor: default;
    border: none;
    cursor: pointer;
}
.ui-slider .ui-slider-handle:after {
    content:"";
    position: absolute;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    top: 50%;
    margin-top: -4px;
    left: 50%;
    margin-left: -4px;
    background: #30A2D2;
    -webkit-box-shadow: 0 1px 1px 1px rgba(22, 73, 163, 0.7) inset, 0 1px 0 0 #FFF;
    -moz-box-shadow: 0 1px 1px 1px rgba(22, 73, 163, 0.7) inset, 0 1px 0 0 white;
    box-shadow: 0 1px 1px 1px rgba(22, 73, 163, 0.7) inset, 0 1px 0 0 #FFF;
}
.ui-slider-horizontal .ui-slider-handle {
    top: -.5em;
    margin-left: -.6em;
}
.ui-slider a:focus {
    outline:none;
}

You need to treat date-time as timestamp and just use standard slider for integer, recalculating date-time for the input (or whatever else) on the fly on slider move event.

Vladimir T
  • 340
  • 3
  • 8
  • Looks neat. I'm getting an error on that jsFiddle that says `closestHandle is undefined` tho. – mhkeller Jan 23 '15 at 21:13
  • I've just rechecked fiddle link - it works just fine in my Chrome 40.0.2214.93. What browser do you have problems with? – Vladimir T Jan 28 '15 at 12:39
  • 1
    Nice job..but this is not working in mozilla.Can anyone help with that.closestHandle is undefined error showing. – Megha Paul Feb 03 '16 at 08:48
  • Hi Paul, I can see that the date format I used looks like not supported by firefox. Just change the dates to var dt_from = "2014/11/01 00:34:44"; var dt_to = "2014/11/24 16:37:43"; (slashes instead of dashes) and it is fine in firefox as well – Vladimir T Feb 16 '16 at 07:14
3

In case anyone finds this thread, I was able to accomplish this by converting my time stamps to unix time and then breaking up my data by month. The current month's slider expands to the full-width of the screen so you can select as much as possible by scrubbing. Arrow keys accomplish the rest.

mhkeller
  • 713
  • 1
  • 8
  • 19
  • I need to scroll through arrow keys in both direction in Jquery UI slider.Thank you – heyjii Jan 04 '13 at 05:09
  • This functionality is already built-in to jQuery UI http://jqueryui.com/slider/. The handle needs to be in focus, so maybe set the focus through your JS using .focus() http://stackoverflow.com/questions/3383429/setting-focus-on-an-html-input-box-on-page-load If you need more help, maybe ask this as a separate thread. – mhkeller Sep 04 '13 at 03:58