Mobile-friendly Datetime Picker With jQuery And CSS3

Mobile-friendly Datetime Picker With jQuery And CSS3
File Size: 2.41 KB
Views Total:
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   

A fancy,mobile-, and user-friendly Datetime picker built with jQuery and CSS/CSS3. The date and time picker allows the users to select entry values by dragging and swiping the knob/dial control. It also supports automatically moving the focus between year, month, and day inputs when a value is selected.

How to use it:

1. Create the year, month and day inputs in the web page.

<div id="datetime">
  <span id="year" class="active field">YYYY</span>
  <span id="month" class="field">MMM</span>
  <span id="day" class="field">DD</span>
</div>

2. Create a virtual knob control below the Datetime picker.

<div id="virtual_knob">
  <div id="knob"></div>
  <div id="dial"></div>
</div>

3. The CSS styles for the Datetime picker.

#datetime {
  left: 50%;
  position: absolute;
  text-align: center;
  top: 30%;
  -webkit-transform: translateX(-50%) translateY(-50%);
  transform: translateX(-50%) translateY(-50%);
  width: 100%;
}

.field {
  cursor: pointer;
  transition: color 200ms, border-color 200ms;
  border-bottom: 2px solid;
  border-color: transparent;
  -webkit-tap-highlight-color: rgba(0,0,0,0);
}

.active {
  color: #44aa55;
  border-color: #44aa55;
}

4. The CSS styles for virtual knob control.

#virtual_knob {
  font-size: 28px;
  height: 120px;
  left: 50%;
  line-height: 58px;
  position: absolute;
  top: calc(50% + 40px);
  -webkit-transform: translateX(-50%) translateY(-50%);
  transform: translateX(-50%) translateY(-50%);
  width: 120px;
}

#knob {
  background-color: white;
  border: 1px solid #bbb;
  border-radius: 50%;
  box-shadow: 0px 1px 7px 1px rgba(32,32,32,.7);
  box-sizing: border-box;
  color: white;
  font-size: 28px;
  height: 80px;
  left: 20px;
  line-height: 58px;
  position: absolute;
  top: 20px;
  width: 80px;
}

#dial {
  background-color: #70757a;
  height: 14px;
  left: 58px;
  position: absolute;
  top: 24px;
  width: 2px;
}

5. Load the needed jQuery library and hammer.js at the bottom of the web page.

<script src="/path/to/jquery.min.js"></script> 
<script src="/path/to/hammer.min.js"></script> 

6. The JavaScript to activate the Datetime picker.

var date = new Date();
var months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
var days = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"];
var state = 0;

function moveFocus(direction) {
  if (direction === 'next') {
    if (state < 3) {
      state++;
      if (state === 1) {
        $('#year').toggleClass('active', false);
        $('#month').toggleClass('active', true);
      }
      else if (state === 2) {
        $('#month').toggleClass('active', false);
        $('#day').toggleClass('active', true);
      }
      else if (state === 3) {
        $('#day').toggleClass('active', false);
      }
    }
  }
  else if (direction === 'prev') {
    if (state > 0) {
      state--;
      if (state === 0) {
        $('#year').toggleClass('active', true);
        $('#month').toggleClass('active', false);
      }
      if (state === 1) {
        $('#year').toggleClass('active', true);
        $('#month').toggleClass('active', false);
      }
      else if (state === 2) {
        $('#month').toggleClass('active', true);
      }
    }
  }
}
function clearFocus() {
  $('#year').toggleClass('active', false);
  $('#month').toggleClass('active', false);
  $('#day').toggleClass('active', false);
}
function setFocus(newState) {
  if (newState >= 0 && newState < 3) {
    state = newState;

    clearFocus();

    if (state === 0) {
      $('#year').toggleClass('active', true);
    }
    if (state === 1) {
      $('#month').toggleClass('active', true);
    }
    else if (state === 2) {
      $('#day').toggleClass('active', true);
    }
  }
}

function setValue(change) {
  if (state === 0) {
    var y = date.getFullYear();
    date.setFullYear(y + change);
    $('#year').html(date.getFullYear());
  }
  if (state === 1) {
    var m = date.getMonth() + change;
    while (m < 0) m += 12;
    date.setMonth(m % 12);
    $('#month').html(months[date.getMonth()]);
  }
  if (state === 2) {
    var year = date.getFullYear();
    var month = date.getMonth();
    var dim = getDaysInMonth(year, month);
    var d = date.getDate() + change;
    while (d < 0) d += dim;

    var nd = d % dim;
    if (nd === 0) nd = dim;
    date.setDate(nd);
    $('#day').html(date.getDate());
  }
}

function getDaysInMonth(y, m) {
  return (/3|5|8|10/).test(m) ? 30:m === 1 ? (!(y % 4) && y % 100) || !(y % 400) ? 29:28:31;
}

$(function() {
  var virtual_knob = document.getElementById("virtual_knob");
  var mc = new Hammer(virtual_knob);
  var prevAngle = -1;

  mc.on("pan panstart panend tap", function(event) {
    console.log(event.type)
    if (event.type === 'panstart') {
      prevAngle = -90;
    }
    else if (event.type === 'panend' || event.type === 'tap') {
      moveFocus('next');
      virtual_knob.style.transform = 'translateX(-50%) translateY(-50%) rotate(0deg)';
      virtual_knob.style.webkitTransform = 'translateX(-50%) translateY(-50%) rotate(0deg)';
    }
    if (Math.abs(prevAngle - event.angle) > 300)
      prevAngle = -prevAngle;
    var a1 = Math.floor(event.angle / 30);
    var a2 = Math.floor(prevAngle / 30);
    if (a1 != a2) {
      setValue(a1 - a2);
    }

    if (event.type !== 'panend' && event.type !== 'tap') {
      virtual_knob.style.transform = 'translateX(-50%) translateY(-50%) rotate(' + (event.angle + 90) + 'deg)';
      virtual_knob.style.webkitTransform = 'translateX(-50%) translateY(-50%) rotate(' + (event.angle + 90) + 'deg)';
    }
    prevAngle = event.angle;
  });

  $('#year').html(date.getFullYear());
  $('#month').html(months[date.getMonth()]);
  $('#day').html(date.getDate());

  $('#year').click(function () { setFocus(0); });
  $('#month').click(function () { setFocus(1); });
  $('#day').click(function () { setFocus(2); });
});

This awesome jQuery plugin is developed by ainalem. For more Advanced Usages, please check the demo page or visit the official website.