Browse Source

js formatting

221V 3 years ago
parent
commit
83cf4660b9
5 changed files with 1253 additions and 1253 deletions
  1. 954 1025
      priv/js/calendar.js
  2. 89 73
      priv/js/comboLookup.js
  3. 96 69
      priv/js/nitro.js
  4. 92 69
      priv/js/sortable.js
  5. 22 17
      priv/js/validation.js

+ 954 - 1025
priv/js/calendar.js

@@ -7,685 +7,657 @@
 var pickers = {};
 
 var clLangs = {
-    ua: {
-        previousMonth : 'Попередній місяць',
-        nextMonth     : 'Наступний місяць',
-        months        : ['Січень','Лютий','Березень','Квітень','Травень','Червень','Липень','Серпень','Вересень','Жовтень','Листопад','Грудень'],
-        weekdays      : ['Неділя','Понеділок','Вівторок','Середа','Четвер','П’ятниця','Субота'],
-        weekdaysShort : ['Нд','Пн','Вв','Ср','Чт','Пт','Сб']
-    },
-    ru: {
-        previousMonth : 'Предыдущий месяц',
-        nextMonth     : 'Следующий месяц',
-        months        : ['Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],
-        weekdays      : ['Воскресенье','Понедельник','Вторник','Среда','Четверг','Пятница','Суббота'],
-        weekdaysShort : ['Вс','Пн','Вт','Ср','Чт','Пт','Сб']
-    },
-    en: {
-        previousMonth : 'Previous Month',
-        nextMonth     : 'Next Month',
-        months        : ['January','February','March','April','May','June','July','August','September','October','November','December'],
-        weekdays      : ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
-        weekdaysShort : ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
-    }
+  ua: {
+    previousMonth : 'Попередній місяць',
+    nextMonth     : 'Наступний місяць',
+    months        : ['Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень'],
+    weekdays      : ['Неділя', 'Понеділок', 'Вівторок', 'Середа', 'Четвер', 'П’ятниця', 'Субота'],
+    weekdaysShort : ['Нд', 'Пн', 'Вв', 'Ср', 'Чт', 'Пт', 'Сб']
+  },
+  ru: {
+    previousMonth : 'Предыдущий месяц',
+    nextMonth     : 'Следующий месяц',
+    months        : ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
+    weekdays      : ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'],
+    weekdaysShort : ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб']
+  },
+  en: {
+    previousMonth : 'Previous Month',
+    nextMonth     : 'Next Month',
+    months        : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+    weekdays      : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+    weekdaysShort : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
+  }
 };
-function getDateParamBySign(date,sign) {
-    sign = sign.toUpperCase();
-    var param;
-    switch(sign) {
-        case "YYYY":
-            param = date.getFullYear().toString();break;
-        case "YY":
-            param = date.getFullYear().toString().substr(2,2);break;
-        case "MM":
-            param = (date.getMonth()+1);
-            param = (param >= 10) ? param.toString() : ("0"+param.toString());
-            break;
-        case "DD":
-            param = (date.getDate() >= 10) ? date.getDate().toString() : ("0"+date.getDate().toString());
-            break;
-        default:
-            param = date.toDateString();
-    }
-    return param;
-}
 
-function formatter(date, format) {
-    date = date || new Date();
-    format = format || "DD.MM.YYYY";
-    var signs = format.match(/(Y{2,4})|(M{2})|(D{2})/g);
-    var params = [];
-    var reStr = '';
-    for(var i=0; i<signs.length; ++i) {
-        params.push(getDateParamBySign(date,signs[i]));
-        reStr += ((i+1) != signs.length) ? signs[i] + "(.)" : signs[i];
-    }
-    var re = new RegExp(reStr,'g');
-    var delimiters = re.exec(format);
-    delimiters.splice(0,1);
-    var value = "";
-    for(i=0; i<params.length; i++) {
-        value += ((i+1) != params.length) ? (params[i] + delimiters[i]) : params[i];
-    }
-    return value;
+function getDateParamBySign(date,sign){
+  sign = sign.toUpperCase();
+  var param;
+  switch(sign){
+    case "YYYY":
+      param = date.getFullYear().toString();
+      break;
+    case "YY":
+      param = date.getFullYear().toString().substr(2, 2);
+      break;
+    case "MM":
+      param = (date.getMonth() + 1);
+      param = (param >= 10) ? param.toString() : ("0" + param.toString());
+      break;
+    case "DD":
+      param = (date.getDate() >= 10) ? date.getDate().toString() : ("0"+date.getDate().toString());
+      break;
+    default:
+      param = date.toDateString();
+  }
+  return param;
 }
 
-function parser(str, format) {
-    format = format || "DD.MM.YYYY";
-    var signs = format.match(/(Y{2,4})|(M{2})|(D{2})/g);
-    var reStr = "(";
-    for(var i=0; i<signs.length; ++i) {
-        reStr += ".".repeat(signs[i].length) + (((i+1) != signs.length) ? ").(" : ")");
-    }
-    var re = new RegExp(reStr,'g');
-    var values = re.exec(str);
-    var year, month, day;
-    if (values && signs.length+1 == values.length) {
-        values = values.slice(1);
-        for(var i=0; i<signs.length; ++i) {
-            switch(signs[i].slice(0,1)){
-                case "Y": year = values[i]; break;
-                case "M": month = values[i]; break;
-                case "D": day = values[i]; break;
-            }
-        }
-        const res = new Date(year, month-1, day);
-        return res;
-    }
-    return null;
+function formatter(date, format){
+  date = date || new Date();
+  format = format || "DD.MM.YYYY";
+  var signs = format.match(/(Y{2,4})|(M{2})|(D{2})/g);
+  var params = [];
+  var reStr = '';
+  for(var i=0; i < signs.length; ++i){
+    params.push(getDateParamBySign(date,signs[i]));
+    reStr += ((i+1) != signs.length) ? signs[i] + "(.)" : signs[i];
+  }
+  var re = new RegExp(reStr, 'g');
+  var delimiters = re.exec(format);
+  delimiters.splice(0, 1);
+  var value = "";
+  for(i = 0; i < params.length; i++){
+    value += ((i+1) != params.length) ? (params[i] + delimiters[i]) : params[i];
+  }
+  return value;
 }
 
-// function parseDateFromInput(value) {
-//     if(isNaN(Date.parse(value))) {
-//         var res = /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/.exec(value);
-//         if(res && res.length == 4) { return new Date(res[3],(res[2]-1),res[1]); }
-//         else { return null; }
-//     }else{ return new Date(Date.parse(value)); }
-// }
-
-
-(function (root, factory)
-{
-    'use strict';
-
-    var moment;
-    if (typeof exports === 'object') {
-        // CommonJS module
-        // Load moment.js as an optional dependency
-        try { moment = require('moment'); } catch (e) {}
-        module.exports = factory(moment);
-    } else if (typeof define === 'function' && define.amd) {
-        // AMD. Register as an anonymous module.
-        define(function (req)
-        {
-            // Load moment.js as an optional dependency
-            var id = 'moment';
-            try { moment = req(id); } catch (e) {}
-            return factory(moment);
-        });
-    } else {
-        root.Pikaday = factory(root.moment);
+function parser(str, format){
+  format = format || "DD.MM.YYYY";
+  var signs = format.match(/(Y{2,4})|(M{2})|(D{2})/g);
+  var reStr = "(";
+  for(var i = 0; i < signs.length; ++i){
+    reStr += ".".repeat(signs[i].length) + (((i+1) != signs.length) ? ").(" : ")");
+  }
+  var re = new RegExp(reStr, 'g');
+  var values = re.exec(str);
+  var year, month, day;
+  if(values && signs.length + 1 == values.length){
+    values = values.slice(1);
+    for(var i = 0; i < signs.length; ++i){
+      switch(signs[i].slice(0, 1)){
+        case "Y":
+          year = values[i];
+          break;
+        case "M":
+          month = values[i];
+          break;
+        case "D":
+          day = values[i];
+          break;
+      }
     }
-}(this, function (moment)
-{
-    'use strict';
-
-    /**
-     * feature detection and helper functions
-     */
-    var hasMoment = typeof moment === 'function',
+    const res = new Date(year, month - 1, day);
+    return res;
+  }
+  return null;
+}
 
+//function parseDateFromInput(value){
+//  if(isNaN(Date.parse(value))){
+//    var res = /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/.exec(value);
+//    if(res && res.length == 4){
+//      return new Date(res[3], (res[2] - 1), res[1]);
+//    }else{
+//      return null;
+//    }
+//  }else{
+//    return new Date(Date.parse(value));
+//  }
+//}
+
+
+(function(root, factory){
+  'use strict';
+
+  var moment;
+  if(typeof exports === 'object'){
+    // CommonJS module
+    // Load moment.js as an optional dependency
+    try{
+      moment = require('moment');
+    }catch(e){}
+    module.exports = factory(moment);
+  }else if(typeof define === 'function' && define.amd){
+    // AMD. Register as an anonymous module.
+    define(function(req){
+      // Load moment.js as an optional dependency
+      var id = 'moment';
+      try{ moment = req(id); }catch(e){}
+      return factory(moment);
+    });
+  }else{
+    root.Pikaday = factory(root.moment);
+  }
+}(this, function(moment){
+  'use strict';
+
+  /**
+   * feature detection and helper functions
+   */
+  var hasMoment = typeof moment === 'function',
     hasEventListeners = !!window.addEventListener,
-
     document = window.document,
-
     sto = window.setTimeout,
 
-    addEvent = function(el, e, callback, capture)
-    {
-        if (hasEventListeners) {
-            el.addEventListener(e, callback, !!capture);
-        } else {
-            el.attachEvent('on' + e, callback);
-        }
+    addEvent = function(el, e, callback, capture){
+      if(hasEventListeners){
+        el.addEventListener(e, callback, !!capture);
+      }else{
+        el.attachEvent('on' + e, callback);
+      }
     },
 
-    removeEvent = function(el, e, callback, capture)
-    {
-        if (hasEventListeners) {
-            el.removeEventListener(e, callback, !!capture);
-        } else {
-            el.detachEvent('on' + e, callback);
-        }
+    removeEvent = function(el, e, callback, capture){
+      if(hasEventListeners){
+        el.removeEventListener(e, callback, !!capture);
+      }else{
+        el.detachEvent('on' + e, callback);
+      }
     },
 
-    fireEvent = function(el, eventName, data)
-    {
-        var ev;
-
-        if (document.createEvent) {
-            ev = document.createEvent('HTMLEvents');
-            ev.initEvent(eventName, true, false);
-            ev = extend(ev, data);
-            el.dispatchEvent(ev);
-        } else if (document.createEventObject) {
-            ev = document.createEventObject();
-            ev = extend(ev, data);
-            el.fireEvent('on' + eventName, ev);
-        }
+    fireEvent = function(el, eventName, data){
+      var ev;
+
+      if(document.createEvent){
+        ev = document.createEvent('HTMLEvents');
+        ev.initEvent(eventName, true, false);
+        ev = extend(ev, data);
+        el.dispatchEvent(ev);
+      }else if(document.createEventObject){
+        ev = document.createEventObject();
+        ev = extend(ev, data);
+        el.fireEvent('on' + eventName, ev);
+      }
     },
 
-    trim = function(str)
-    {
-        return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g,'');
+    trim = function(str){
+      return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g,'');
     },
 
-    hasClass = function(el, cn)
-    {
-        return (' ' + el.className + ' ').indexOf(' ' + cn + ' ') !== -1;
+    hasClass = function(el, cn){
+      return (' ' + el.className + ' ').indexOf(' ' + cn + ' ') !== -1;
     },
 
-    addClass = function(el, cn)
-    {
-        if (!hasClass(el, cn)) {
-            el.className = (el.className === '') ? cn : el.className + ' ' + cn;
-        }
+    addClass = function(el, cn){
+      if(!hasClass(el, cn)){
+        el.className = (el.className === '') ? cn : el.className + ' ' + cn;
+      }
     },
 
-    removeClass = function(el, cn)
-    {
-        el.className = trim((' ' + el.className + ' ').replace(' ' + cn + ' ', ' '));
+    removeClass = function(el, cn){
+      el.className = trim((' ' + el.className + ' ').replace(' ' + cn + ' ', ' '));
     },
 
-    isArray = function(obj)
-    {
-        return (/Array/).test(Object.prototype.toString.call(obj));
+    isArray = function(obj){
+      return (/Array/).test(Object.prototype.toString.call(obj));
     },
 
-    isDate = function(obj)
-    {
-        return (/Date/).test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime());
+    isDate = function(obj){
+      return (/Date/).test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime());
     },
 
-    isWeekend = function(date)
-    {
-        var day = date.getDay();
-        return day === 0 || day === 6;
+    isWeekend = function(date){
+      var day = date.getDay();
+      return day === 0 || day === 6;
     },
 
-    isLeapYear = function(year)
-    {
-        // solution by Matti Virkkunen: http://stackoverflow.com/a/4881951
-        return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
+    isLeapYear = function(year){
+      // solution by Matti Virkkunen: http://stackoverflow.com/a/4881951
+      return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
     },
 
-    getDaysInMonth = function(year, month)
-    {
-        return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
+    getDaysInMonth = function(year, month){
+      return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
     },
 
-    setToStartOfDay = function(date)
-    {
-        if (isDate(date)) date.setHours(0,0,0,0);
+    setToStartOfDay = function(date){
+      if(isDate(date)) date.setHours(0, 0, 0, 0);
     },
 
-    compareDates = function(a,b)
-    {
-        // weak date comparison (use setToStartOfDay(date) to ensure correct result)
-        return a.getTime() === b.getTime();
+    compareDates = function(a,b){
+      // weak date comparison (use setToStartOfDay(date) to ensure correct result)
+      return a.getTime() === b.getTime();
     },
 
-    extend = function(to, from, overwrite)
-    {
-        var prop, hasProp;
-        for (prop in from) {
-            hasProp = to[prop] !== undefined;
-            if (hasProp && typeof from[prop] === 'object' && from[prop] !== null && from[prop].nodeName === undefined) {
-                if (isDate(from[prop])) {
-                    if (overwrite) {
-                        to[prop] = new Date(from[prop].getTime());
-                    }
-                }
-                else if (isArray(from[prop])) {
-                    if (overwrite) {
-                        to[prop] = from[prop].slice(0);
-                    }
-                } else {
-                    to[prop] = extend({}, from[prop], overwrite);
-                }
-            } else if (overwrite || !hasProp) {
-                to[prop] = from[prop];
+    extend = function(to, from, overwrite){
+      var prop, hasProp;
+      for(prop in from){
+        hasProp = to[prop] !== undefined;
+        if(hasProp && typeof from[prop] === 'object' && from[prop] !== null && from[prop].nodeName === undefined){
+          if(isDate(from[prop])){
+            if(overwrite){
+              to[prop] = new Date(from[prop].getTime());
+            }
+          }else if(isArray(from[prop])){
+            if(overwrite){
+              to[prop] = from[prop].slice(0);
             }
+          }else{
+            to[prop] = extend({}, from[prop], overwrite);
+          }
+        }else if(overwrite || !hasProp){
+          to[prop] = from[prop];
         }
-        return to;
+      }
+      return to;
     },
 
-    adjustCalendar = function(calendar) {
-        if (calendar.month < 0) {
-            calendar.year -= Math.ceil(Math.abs(calendar.month)/12);
-            calendar.month += 12;
-        }
-        if (calendar.month > 11) {
-            calendar.year += Math.floor(Math.abs(calendar.month)/12);
-            calendar.month -= 12;
-        }
-        return calendar;
+    adjustCalendar = function(calendar){
+      if(calendar.month < 0){
+        calendar.year -= Math.ceil(Math.abs(calendar.month)/12);
+        calendar.month += 12;
+      }
+      if(calendar.month > 11){
+        calendar.year += Math.floor(Math.abs(calendar.month)/12);
+        calendar.month -= 12;
+      }
+      return calendar;
     },
 
     /**
      * defaults and localisation
      */
     defaults = {
+      // bind the picker to a form field
+      field: null,
 
-        // bind the picker to a form field
-        field: null,
-
-        // automatically show/hide the picker on `field` focus (default `true` if `field` is set)
-        bound: undefined,
+      // automatically show/hide the picker on `field` focus (default `true` if `field` is set)
+      bound: undefined,
 
-        // position of the datepicker, relative to the field (default to bottom & left)
-        // ('bottom' & 'left' keywords are not used, 'top' & 'right' are modifier on the bottom/left position)
-        position: 'bottom left',
+      // position of the datepicker, relative to the field (default to bottom & left)
+      // ('bottom' & 'left' keywords are not used, 'top' & 'right' are modifier on the bottom/left position)
+      position: 'bottom left',
 
-        // automatically fit in the viewport even if it means repositioning from the position option
-        reposition: true,
+      // automatically fit in the viewport even if it means repositioning from the position option
+      reposition: true,
 
-        // the default output format for `.toString()` and `field` value
-        format: 'DD.MM.YYYY',
+      // the default output format for `.toString()` and `field` value
+      format: 'DD.MM.YYYY',
 
-        // the initial date to view when first opened
-        defaultDate: null,
+      // the initial date to view when first opened
+      defaultDate: null,
 
-        // make the `defaultDate` the initial selected value
-        setDefaultDate: false,
+      // make the `defaultDate` the initial selected value
+      setDefaultDate: false,
 
-        // first day of week (0: Sunday, 1: Monday etc)
-        firstDay: 0,
+      // first day of week (0: Sunday, 1: Monday etc)
+      firstDay: 0,
 
-        // the minimum/earliest date that can be selected
-        minDate: null,
-        // the maximum/latest date that can be selected
-        maxDate: null,
+      // the minimum/earliest date that can be selected
+      minDate: null,
+      // the maximum/latest date that can be selected
+      maxDate: null,
 
-        // number of years either side, or array of upper/lower range
-        yearRange: 10,
+      // number of years either side, or array of upper/lower range
+      yearRange: 10,
 
-        // show week numbers at head of row
-        showWeekNumber: false,
+      // show week numbers at head of row
+      showWeekNumber: false,
 
-        // used internally (don't config outside)
-        minYear: 0,
-        maxYear: 9999,
-        minMonth: undefined,
-        maxMonth: undefined,
+      // used internally (don't config outside)
+      minYear: 0,
+      maxYear: 9999,
+      minMonth: undefined,
+      maxMonth: undefined,
 
-        startRange: null,
-        endRange: null,
+      startRange: null,
+      endRange: null,
 
-        isRTL: false,
+      isRTL: false,
 
-        // Additional text to append to the year in the calendar title
-        yearSuffix: '',
+      // Additional text to append to the year in the calendar title
+      yearSuffix: '',
 
-        // Render the month after year in the calendar title
-        showMonthAfterYear: false,
+      // Render the month after year in the calendar title
+      showMonthAfterYear: false,
 
-        // how many months are visible
-        numberOfMonths: 1,
+      // how many months are visible
+      numberOfMonths: 1,
 
-        // when numberOfMonths is used, this will help you to choose where the main calendar will be (default `left`, can be set to `right`)
-        // only used for the first display or when a selected date is not visible
-        mainCalendar: 'left',
+      // when numberOfMonths is used, this will help you to choose where the main calendar will be (default `left`, can be set to `right`)
+      // only used for the first display or when a selected date is not visible
+      mainCalendar: 'left',
 
-        // Specify a DOM element to render the calendar in
-        container: undefined,
+      // Specify a DOM element to render the calendar in
+      container: undefined,
 
-        // internationalization
-        i18n: clLangs.en,
+      // internationalization
+      i18n: clLangs.en,
 
-        // Theme Classname
-        theme: null,
+      // Theme Classname
+      theme: null,
 
-        // callback function
-        onSelect: null,
-        onOpen: null,
-        onClose: null,
-        onDraw: null
+      // callback function
+      onSelect: null,
+      onOpen: null,
+      onClose: null,
+      onDraw: null
     },
 
 
     /**
      * templating functions to abstract HTML rendering
      */
-    renderDayName = function(opts, day, abbr)
-    {
-        day += opts.firstDay;
-        while (day >= 7) {
-            day -= 7;
-        }
-        return abbr ? opts.i18n.weekdaysShort[day] : opts.i18n.weekdays[day];
+    renderDayName = function(opts, day, abbr){
+      day += opts.firstDay;
+      while(day >= 7){
+        day -= 7;
+      }
+      return abbr ? opts.i18n.weekdaysShort[day] : opts.i18n.weekdays[day];
     },
 
-    renderDay = function(opts)
-    {
-        if (opts.isEmpty) {
-            return '<td class="is-empty"></td>';
-        }
-        var arr = [];
-        if (opts.isDisabled) {
-            arr.push('is-disabled');
-        }
-        if (opts.isToday) {
-            arr.push('is-today');
-        }
-        if (opts.isSelected) {
-            arr.push('is-selected');
-        }
-        if (opts.isInRange) {
-            arr.push('is-inrange');
-        }
-        if (opts.isStartRange) {
-            arr.push('is-startrange');
-        }
-        if (opts.isEndRange) {
-            arr.push('is-endrange');
-        }
-        return '<td data-day="' + opts.day + '" class="' + arr.join(' ') + '">' +
-                 '<button class="pika-button pika-day" type="button" ' +
-                    'data-pika-year="' + opts.year + '" data-pika-month="' + opts.month + '" data-pika-day="' + opts.day + '">' +
-                        opts.day +
-                 '</button>' +
-               '</td>';
+    renderDay = function(opts){
+      if(opts.isEmpty){
+        return '<td class="is-empty"></td>';
+      }
+      var arr = [];
+      if(opts.isDisabled){
+        arr.push('is-disabled');
+      }
+      if(opts.isToday){
+        arr.push('is-today');
+      }
+      if(opts.isSelected){
+        arr.push('is-selected');
+      }
+      if(opts.isInRange){
+        arr.push('is-inrange');
+      }
+      if(opts.isStartRange){
+        arr.push('is-startrange');
+      }
+      if(opts.isEndRange){
+        arr.push('is-endrange');
+      }
+      return '<td data-day="' + opts.day + '" class="' + arr.join(' ') + '">' +
+               '<button class="pika-button pika-day" type="button" ' +
+                  'data-pika-year="' + opts.year + '" data-pika-month="' + opts.month + '" data-pika-day="' + opts.day + '">' +
+                    opts.day +
+               '</button>' +
+             '</td>';
     },
 
-    renderWeek = function (d, m, y) {
-        // Lifted from http://javascript.about.com/library/blweekyear.htm, lightly modified.
-        var onejan = new Date(y, 0, 1),
-            weekNum = Math.ceil((((new Date(y, m, d) - onejan) / 86400000) + onejan.getDay()+1)/7);
+    renderWeek = function(d, m, y){
+      // Lifted from http://javascript.about.com/library/blweekyear.htm, lightly modified.
+      var onejan = new Date(y, 0, 1),
+          weekNum = Math.ceil((((new Date(y, m, d) - onejan) / 86400000) + onejan.getDay() + 1) / 7);
         return '<td class="pika-week">' + weekNum + '</td>';
     },
 
-    renderRow = function(days, isRTL)
-    {
-        return '<tr>' + (isRTL ? days.reverse() : days).join('') + '</tr>';
+    renderRow = function(days, isRTL){
+      return '<tr>' + (isRTL ? days.reverse() : days).join('') + '</tr>';
     },
 
-    renderBody = function(rows)
-    {
-        return '<tbody>' + rows.join('') + '</tbody>';
+    renderBody = function(rows){
+      return '<tbody>' + rows.join('') + '</tbody>';
     },
 
-    renderHead = function(opts)
-    {
-        var i, arr = [];
-        if (opts.showWeekNumber) {
-            arr.push('<th></th>');
-        }
-        for (i = 0; i < 7; i++) {
-            arr.push('<th scope="col"><abbr title="' + renderDayName(opts, i) + '">' + renderDayName(opts, i, true) + '</abbr></th>');
-        }
-        return '<thead>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</thead>';
+    renderHead = function(opts){
+      var i, arr = [];
+      if(opts.showWeekNumber){
+        arr.push('<th></th>');
+      }
+      for(i = 0; i < 7; i++){
+        arr.push('<th scope="col"><abbr title="' + renderDayName(opts, i) + '">' + renderDayName(opts, i, true) + '</abbr></th>');
+      }
+      return '<thead>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</thead>';
     },
 
-    renderTitle = function(instance, c, year, month, refYear)
-    {
-        var i, j, arr,
-            opts = instance._o,
-            isMinYear = year === opts.minYear,
-            isMaxYear = year === opts.maxYear,
-            html = '<div class="pika-title">',
-            monthHtml,
-            yearHtml,
-            prev = true,
-            next = true;
-
-        for (arr = [], i = 0; i < 12; i++) {
-            arr.push('<option value="' + (year === refYear ? i - c : 12 + i - c) + '"' +
-                (i === month ? ' selected': '') +
-                ((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth) ? 'disabled' : '') + '>' +
-                opts.i18n.months[i] + '</option>');
-        }
-        monthHtml = '<div class="pika-label">' + opts.i18n.months[month] + '<select class="pika-select pika-select-month" tabindex="-1">' + arr.join('') + '</select></div>';
-
-        if (isArray(opts.yearRange)) {
-            i = opts.yearRange[0];
-            j = opts.yearRange[1] + 1;
-        } else {
-            i = year - opts.yearRange;
-            j = 1 + year + opts.yearRange;
-        }
-
-        for (arr = []; i < j && i <= opts.maxYear; i++) {
-            if (i >= opts.minYear) {
-                arr.push('<option value="' + i + '"' + (i === year ? ' selected': '') + '>' + (i) + '</option>');
-            }
-        }
-        yearHtml = '<div class="pika-label">' + year + opts.yearSuffix + '<select class="pika-select pika-select-year" tabindex="-1">' + arr.join('') + '</select></div>';
-
-        if (opts.showMonthAfterYear) {
-            html += yearHtml + monthHtml;
-        } else {
-            html += monthHtml + yearHtml;
-        }
-
-        if (isMinYear && (month === 0 || opts.minMonth >= month)) {
-            prev = false;
-        }
-
-        if (isMaxYear && (month === 11 || opts.maxMonth <= month)) {
-            next = false;
-        }
-
-        if (c === 0) {
-            html += '<button class="pika-prev' + (prev ? '' : ' is-disabled') + '" type="button">' + opts.i18n.previousMonth + '</button>';
+    renderTitle = function(instance, c, year, month, refYear){
+      var i, j, arr,
+          opts = instance._o,
+          isMinYear = year === opts.minYear,
+          isMaxYear = year === opts.maxYear,
+          html = '<div class="pika-title">',
+          monthHtml,
+          yearHtml,
+          prev = true,
+          next = true;
+
+      for(arr = [], i = 0; i < 12; i++){
+        arr.push('<option value="' + (year === refYear ? i - c : 12 + i - c) + '"' +
+          (i === month ? ' selected': '') +
+          ((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth) ? 'disabled' : '') + '>' +
+          opts.i18n.months[i] + '</option>');
+      }
+      monthHtml = '<div class="pika-label">' + opts.i18n.months[month] + '<select class="pika-select pika-select-month" tabindex="-1">' + arr.join('') + '</select></div>';
+
+      if(isArray(opts.yearRange)){
+        i = opts.yearRange[0];
+        j = opts.yearRange[1] + 1;
+      }else{
+        i = year - opts.yearRange;
+        j = 1 + year + opts.yearRange;
+      }
+
+      for(arr = []; i < j && i <= opts.maxYear; i++){
+        if(i >= opts.minYear){
+          arr.push('<option value="' + i + '"' + (i === year ? ' selected': '') + '>' + (i) + '</option>');
         }
-        if (c === (instance._o.numberOfMonths - 1) ) {
-            html += '<button class="pika-next' + (next ? '' : ' is-disabled') + '" type="button">' + opts.i18n.nextMonth + '</button>';
-        }
-
-        return html += '</div>';
+      }
+      yearHtml = '<div class="pika-label">' + year + opts.yearSuffix + '<select class="pika-select pika-select-year" tabindex="-1">' + arr.join('') + '</select></div>';
+
+      if(opts.showMonthAfterYear){
+        html += yearHtml + monthHtml;
+      }else{
+        html += monthHtml + yearHtml;
+      }
+
+      if(isMinYear && (month === 0 || opts.minMonth >= month)){
+        prev = false;
+      }
+
+      if(isMaxYear && (month === 11 || opts.maxMonth <= month)){
+        next = false;
+      }
+
+      if(c === 0){
+        html += '<button class="pika-prev' + (prev ? '' : ' is-disabled') + '" type="button">' + opts.i18n.previousMonth + '</button>';
+      }
+      if(c === (instance._o.numberOfMonths - 1)){
+        html += '<button class="pika-next' + (next ? '' : ' is-disabled') + '" type="button">' + opts.i18n.nextMonth + '</button>';
+      }
+
+      return html += '</div>';
     },
 
-    renderTable = function(opts, data)
-    {
-        return '<table cellpadding="0" cellspacing="0" class="pika-table">' + renderHead(opts) + renderBody(data) + '</table>';
+    renderTable = function(opts, data){
+      return '<table cellpadding="0" cellspacing="0" class="pika-table">' + renderHead(opts) + renderBody(data) + '</table>';
     },
 
 
     /**
      * Pikaday constructor
      */
-    Pikaday = function(options)
-    {
-        var self = this,
-            opts = self.config(options);
-
-        self._onMouseDown = function(e)
-        {
-            if (!self._v) {
-                return;
-            }
-            e = e || window.event;
-            var target = e.target || e.srcElement;
-            console.log(target);
-            if (!target) {
-                return;
-            }
+    Pikaday = function(options){
+      var self = this,
+          opts = self.config(options);
 
-            if (!hasClass(target.parentNode, 'is-disabled')) {
-                if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty')) {
-                    self.setDate(new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day')));
-                    if (opts.bound) {
-                        sto(function() {
-                            self.hide();
-                            if (opts.field) {
-                                opts.field.blur();
-                            }
-                        }, 100);
-                    }
-                }
-                else if (hasClass(target, 'pika-prev')) {
-                    self.prevMonth();
-                }
-                else if (hasClass(target, 'pika-next')) {
-                    self.nextMonth();
-                }
-            }
-            if (!hasClass(target, 'pika-select')) {
-                // if this is touch event prevent mouse events emulation
-                if (e.preventDefault) {
-                    e.preventDefault();
-                } else {
-                    e.returnValue = false;
-                    return false;
-                }
-            } else {
-                self._c = true;
-            }
-        };
-
-        self._onChange = function(e)
-        {
-            e = e || window.event;
-            var target = e.target || e.srcElement;
-            if (!target) {
-                return;
-            }
-            if (hasClass(target, 'pika-select-month')) {
-                self.gotoMonth(target.value);
-            }
-            else if (hasClass(target, 'pika-select-year')) {
-                self.gotoYear(target.value);
-            }
-        };
-
-        self._onInputChange = function(e)
-        {
-            var date;
-
-            if (e.firedBy === self) {
-                return;
-            }
-            if (hasMoment) {
-                date = moment(opts.field.value, opts.format);
-                date = (date && date.isValid()) ? date.toDate() : null;
-            }
-            else {
-                // date = parseDateFromInput(opts.field.value);
-                date = parser(opts.field.value, opts.format);
-            }
-            if (isDate(date)) {
-                self.setDate(date);
-            }else {
-                self.setDate(null);
-            }
-            if (!self._v) {
-                self.show();
-            }
-        };
-
-        self._onInputFocus = function()
-        {
-            self.show();
-        };
-
-        self._onInputClick = function()
-        {
-            self.show();
-        };
-
-        self._onInputBlur = function()
-        {
-            // IE allows pika div to gain focus; catch blur the input field
-            var pEl = document.activeElement;
-            do {
-                if (hasClass(pEl, 'pika-single')) {
-                    return;
-                }
-            }
-            while ((pEl = pEl.parentNode));
+      self._onMouseDown = function(e){
+        if(!self._v){
+          return;
+        }
+        e = e || window.event;
+        var target = e.target || e.srcElement;
+        console.log(target);
+        if(!target){
+          return;
+        }
 
-            if (!self._c) {
-                self._b = sto(function() {
-                    self.hide();
-                }, 50);
-            }
-            self._c = false;
-        };
-
-        self._onClick = function(e)
-        {
-            e = e || window.event;
-            var target = e.target || e.srcElement,
-                pEl = target;
-            if (!target) {
-                return;
-            }
-            if (!hasEventListeners && hasClass(target, 'pika-select')) {
-                if (!target.onchange) {
-                    target.setAttribute('onchange', 'return;');
-                    addEvent(target, 'change', self._onChange);
-                }
-            }
-            do {
-                if (hasClass(pEl, 'pika-single') || pEl === opts.trigger) {
-                    return;
-                }
-            }
-            while ((pEl = pEl.parentNode));
-            if (self._v && target !== opts.trigger && pEl !== opts.trigger) {
+        if(!hasClass(target.parentNode, 'is-disabled')){
+          if(hasClass(target, 'pika-button') && !hasClass(target, 'is-empty')){
+            self.setDate(new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day')));
+            if(opts.bound){
+              sto(function(){
                 self.hide();
-            }
-        };
-
-        self.el = document.createElement('div');
-        self.el.className = 'pika-single' + (opts.isRTL ? ' is-rtl' : '') + (opts.theme ? ' ' + opts.theme : '');
-
-        addEvent(self.el, 'mousedown', self._onMouseDown, true);
-        addEvent(self.el, 'touchend', self._onMouseDown, true);
-        addEvent(self.el, 'change', self._onChange);
-
-        if (opts.field) {
-            if (opts.container) {
-                opts.container.appendChild(self.el);
-            } else if (opts.bound) {
-                document.body.appendChild(self.el);
-            } else {
-                opts.field.parentNode.insertBefore(self.el, opts.field.nextSibling);
-            }
-            addEvent(opts.field, 'change', self._onInputChange);
-
-            if (!opts.defaultDate) {
-                if (hasMoment && opts.field.value) {
-                    opts.defaultDate = moment(opts.field.value, opts.format).toDate();
-                } else {
-                    opts.defaultDate = new Date(Date.parse(opts.field.value));
+                if(opts.field){
+                  opts.field.blur();
                 }
-                opts.setDefaultDate = true;
+              }, 100);
             }
+          }else if(hasClass(target, 'pika-prev')){
+            self.prevMonth();
+          }else if(hasClass(target, 'pika-next')){
+            self.nextMonth();
+          }
+        }
+        if(!hasClass(target, 'pika-select')){
+          // if this is touch event prevent mouse events emulation
+          if(e.preventDefault){
+            e.preventDefault();
+          }else{
+            e.returnValue = false;
+            return false;
+          }
+        }else{
+          self._c = true;
+        }
+      };
+
+      self._onChange = function(e){
+        e = e || window.event;
+        var target = e.target || e.srcElement;
+        if(!target){
+          return;
+        }
+        if(hasClass(target, 'pika-select-month')){
+          self.gotoMonth(target.value);
+        }else if(hasClass(target, 'pika-select-year')){
+          self.gotoYear(target.value);
         }
+      };
 
-        var defDate = opts.defaultDate;
+      self._onInputChange = function(e){
+        var date;
 
-        if (isDate(defDate)) {
-            if (opts.setDefaultDate) {
-                self.setDate(defDate, true);
-            } else {
-                self.gotoDate(defDate);
+        if(e.firedBy === self){
+          return;
+        }
+        if(hasMoment){
+          date = moment(opts.field.value, opts.format);
+          date = (date && date.isValid()) ? date.toDate() : null;
+        }else{
+          //date = parseDateFromInput(opts.field.value);
+          date = parser(opts.field.value, opts.format);
+        }
+        if(isDate(date)){
+          self.setDate(date);
+        }else{
+          self.setDate(null);
+        }
+        if(!self._v){
+          self.show();
+        }
+      };
+
+      self._onInputFocus = function(){
+        self.show();
+      };
+
+      self._onInputClick = function(){
+        self.show();
+      };
+
+      self._onInputBlur = function(){
+        // IE allows pika div to gain focus; catch blur the input field
+        var pEl = document.activeElement;
+        do{
+            if(hasClass(pEl, 'pika-single')){
+               return;
             }
-        } else {
-            self.gotoDate(new Date());
+        }while((pEl = pEl.parentNode));
+
+        if(!self._c){
+          self._b = sto(function(){
+            self.hide();
+          }, 50);
+        }
+        self._c = false;
+      };
+
+      self._onClick = function(e){
+        e = e || window.event;
+        var target = e.target || e.srcElement,
+            pEl = target;
+        if(!target){
+          return;
         }
+        if(!hasEventListeners && hasClass(target, 'pika-select')){
+          if(!target.onchange){
+            target.setAttribute('onchange', 'return;');
+            addEvent(target, 'change', self._onChange);
+          }
+        }
+        do{
+          if(hasClass(pEl, 'pika-single') || pEl === opts.trigger){
+            return;
+          }
+        }while((pEl = pEl.parentNode));
+        if(self._v && target !== opts.trigger && pEl !== opts.trigger){
+          self.hide();
+        }
+      };
+
+      self.el = document.createElement('div');
+      self.el.className = 'pika-single' + (opts.isRTL ? ' is-rtl' : '') + (opts.theme ? ' ' + opts.theme : '');
+
+      addEvent(self.el, 'mousedown', self._onMouseDown, true);
+      addEvent(self.el, 'touchend', self._onMouseDown, true);
+      addEvent(self.el, 'change', self._onChange);
+
+      if(opts.field){
+        if(opts.container){
+          opts.container.appendChild(self.el);
+        }else if(opts.bound){
+          document.body.appendChild(self.el);
+        }else{
+          opts.field.parentNode.insertBefore(self.el, opts.field.nextSibling);
+        }
+        addEvent(opts.field, 'change', self._onInputChange);
+
+        if(!opts.defaultDate){
+          if(hasMoment && opts.field.value){
+            opts.defaultDate = moment(opts.field.value, opts.format).toDate();
+          }else{
+            opts.defaultDate = new Date(Date.parse(opts.field.value));
+          }
+            opts.setDefaultDate = true;
+        }
+      }
+
+      var defDate = opts.defaultDate;
 
-        if (opts.bound) {
-            this.hide();
-            self.el.className += ' is-bound';
-            addEvent(opts.trigger, 'click', self._onInputClick);
-            addEvent(opts.trigger, 'focus', self._onInputFocus);
-            addEvent(opts.trigger, 'blur', self._onInputBlur);
-        } else {
-            this.show();
+      if(isDate(defDate)){
+        if(opts.setDefaultDate){
+          self.setDate(defDate, true);
+        }else{
+          self.gotoDate(defDate);
         }
+      }else{
+        self.gotoDate(new Date());
+      }
+
+      if(opts.bound){
+        this.hide();
+        self.el.className += ' is-bound';
+        addEvent(opts.trigger, 'click', self._onInputClick);
+        addEvent(opts.trigger, 'focus', self._onInputFocus);
+        addEvent(opts.trigger, 'blur', self._onInputBlur);
+      }else{
+        this.show();
+      }
     };
 
 
@@ -693,486 +665,443 @@ function parser(str, format) {
      * public Pikaday API
      */
     Pikaday.prototype = {
+      /**
+       * configure functionality
+       */
+      config: function(options){
+        if(!this._o){
+          this._o = extend({}, defaults, true);
+        }
 
+        var opts = extend(this._o, options, true);
+        opts.isRTL = !!opts.isRTL;
+        opts.field = (opts.field && opts.field.nodeName) ? opts.field : null;
+        opts.theme = (typeof opts.theme) === 'string' && opts.theme ? opts.theme : null;
+        opts.bound = !!(opts.bound !== undefined ? opts.field && opts.bound : opts.field);
+        opts.trigger = (opts.trigger && opts.trigger.nodeName) ? opts.trigger : opts.field;
+        opts.disableWeekends = !!opts.disableWeekends;
+        opts.disableDayFn = (typeof opts.disableDayFn) === 'function' ? opts.disableDayFn : null;
 
-        /**
-         * configure functionality
-         */
-        config: function(options)
-        {
-            if (!this._o) {
-                this._o = extend({}, defaults, true);
-            }
-
-            var opts = extend(this._o, options, true);
-
-            opts.isRTL = !!opts.isRTL;
-
-            opts.field = (opts.field && opts.field.nodeName) ? opts.field : null;
-
-            opts.theme = (typeof opts.theme) === 'string' && opts.theme ? opts.theme : null;
-
-            opts.bound = !!(opts.bound !== undefined ? opts.field && opts.bound : opts.field);
-
-            opts.trigger = (opts.trigger && opts.trigger.nodeName) ? opts.trigger : opts.field;
-
-            opts.disableWeekends = !!opts.disableWeekends;
-
-            opts.disableDayFn = (typeof opts.disableDayFn) === 'function' ? opts.disableDayFn : null;
-
-            var nom = parseInt(opts.numberOfMonths, 10) || 1;
-            opts.numberOfMonths = nom > 4 ? 4 : nom;
+        var nom = parseInt(opts.numberOfMonths, 10) || 1;
+        opts.numberOfMonths = nom > 4 ? 4 : nom;
 
-            if (!isDate(opts.minDate)) {
-                opts.minDate = false;
-            }
-            if (!isDate(opts.maxDate)) {
-                opts.maxDate = false;
-            }
-            if ((opts.minDate && opts.maxDate) && opts.maxDate < opts.minDate) {
-                opts.maxDate = opts.minDate = false;
-            }
-            if (opts.minDate) {
-                this.setMinDate(opts.minDate);
-            }
-            if (opts.maxDate) {
-                setToStartOfDay(opts.maxDate);
-                opts.maxYear  = opts.maxDate.getFullYear();
-                opts.maxMonth = opts.maxDate.getMonth();
-            }
-
-            if (isArray(opts.yearRange)) {
-                var fallback = new Date().getFullYear() - 10;
-                opts.yearRange[0] = parseInt(opts.yearRange[0], 10) || fallback;
-                opts.yearRange[1] = parseInt(opts.yearRange[1], 10) || fallback;
-            } else {
-                opts.yearRange = Math.abs(parseInt(opts.yearRange, 10)) || defaults.yearRange;
-                if (opts.yearRange > 100) {
-                    opts.yearRange = 100;
-                }
-            }
+        if(!isDate(opts.minDate)){
+          opts.minDate = false;
+        }
+        if(!isDate(opts.maxDate)){
+          opts.maxDate = false;
+        }
+        if((opts.minDate && opts.maxDate) && opts.maxDate < opts.minDate){
+          opts.maxDate = opts.minDate = false;
+        }
+        if(opts.minDate){
+          this.setMinDate(opts.minDate);
+        }
+        if(opts.maxDate){
+          setToStartOfDay(opts.maxDate);
+          opts.maxYear  = opts.maxDate.getFullYear();
+          opts.maxMonth = opts.maxDate.getMonth();
+        }
 
-            return opts;
-        },
-
-        /**
-         * return a formatted string of the current selection (using Moment.js if available or default formatter)
-         */
-        toString: function(format) {
-            return !isDate(this._d) ? '' : (hasMoment) ? moment(this._d).format(format || this._o.format) : formatter(this._d,this._o.format);
-        },
-
-        /**
-         * return a Moment.js object of the current selection (if available)
-         */
-        getMoment: function()
-        {
-            return hasMoment ? moment(this._d) : null;
-        },
-
-        /**
-         * set the current selection from a Moment.js object (if available)
-         */
-        setMoment: function(date, preventOnSelect)
-        {
-            if (hasMoment && moment.isMoment(date)) {
-                this.setDate(date.toDate(), preventOnSelect);
-            }
-        },
-
-        /**
-         * return a Date object of the current selection
-         */
-        getDate: function()
-        {
-            return isDate(this._d) ? new Date(this._d.getTime()) : null;
-        },
-
-        /**
-         * set the current selection
-         */
-        setDate: function(date, preventOnSelect)
-        {
-            if (!date) {
-                this._d = null;
-
-                if (this._o.field) {
-                    this._o.field.value = '';
-                    fireEvent(this._o.field, 'change', { firedBy: this });
-                }
+        if(isArray(opts.yearRange)){
+          var fallback = new Date().getFullYear() - 10;
+          opts.yearRange[0] = parseInt(opts.yearRange[0], 10) || fallback;
+          opts.yearRange[1] = parseInt(opts.yearRange[1], 10) || fallback;
+        }else{
+          opts.yearRange = Math.abs(parseInt(opts.yearRange, 10)) || defaults.yearRange;
+          if(opts.yearRange > 100){
+            opts.yearRange = 100;
+          }
+        }
 
-                return this.draw();
-            }
-            if (typeof date === 'string') {
-                date = new Date(Date.parse(date));
-            }
-            if (!isDate(date)) {
-                return;
-            }
+        return opts;
+      },
+
+      /**
+       * return a formatted string of the current selection (using Moment.js if available or default formatter)
+       */
+      toString: function(format){
+        return !isDate(this._d) ? '' : (hasMoment) ? moment(this._d).format(format || this._o.format) : formatter(this._d,this._o.format);
+      },
+
+      /**
+       * return a Moment.js object of the current selection (if available)
+       */
+      getMoment: function(){
+        return hasMoment ? moment(this._d) : null;
+      },
+
+      /**
+       * set the current selection from a Moment.js object (if available)
+       */
+      setMoment: function(date, preventOnSelect){
+        if(hasMoment && moment.isMoment(date)){
+          this.setDate(date.toDate(), preventOnSelect);
+        }
+      },
+
+      /**
+       * return a Date object of the current selection
+       */
+      getDate: function(){
+        return isDate(this._d) ? new Date(this._d.getTime()) : null;
+      },
+
+      /**
+       * set the current selection
+       */
+      setDate: function(date, preventOnSelect){
+        if(!date){
+          this._d = null;
+
+          if(this._o.field){
+            this._o.field.value = '';
+            fireEvent(this._o.field, 'change', { firedBy: this });
+          }
+
+          return this.draw();
+        }
+        if(typeof date === 'string'){
+          date = new Date(Date.parse(date));
+        }
+        if(!isDate(date)){
+          return;
+        }
 
-            var min = this._o.minDate,
-                max = this._o.maxDate;
+        var min = this._o.minDate,
+            max = this._o.maxDate;
 
-            if (isDate(min) && date < min) {
-                date = min;
-            } else if (isDate(max) && date > max) {
-                date = max;
-            }
+        if (isDate(min) && date < min){
+          date = min;
+        }else if(isDate(max) && date > max){
+          date = max;
+        }
 
-            this._d = new Date(date.getTime());
-            setToStartOfDay(this._d);
-            this.gotoDate(this._d);
+        this._d = new Date(date.getTime());
+        setToStartOfDay(this._d);
+        this.gotoDate(this._d);
 
-            if (this._o.field) {
-                this._o.field.value = this.toString();
-                fireEvent(this._o.field, 'change', { firedBy: this });
-            }
-            if (!preventOnSelect && typeof this._o.onSelect === 'function') {
-                this._o.onSelect.call(this, this.getDate());
-            }
-        },
+        if(this._o.field){
+          this._o.field.value = this.toString();
+          fireEvent(this._o.field, 'change', { firedBy: this });
+        }
+        if(!preventOnSelect && typeof this._o.onSelect === 'function'){
+          this._o.onSelect.call(this, this.getDate());
+        }
+      },
 
-        /**
-         * change view to a specific date
-         */
-        gotoDate: function(date)
-        {
-            var newCalendar = true;
+      /**
+       * change view to a specific date
+       */
+      gotoDate: function(date){
+        var newCalendar = true;
 
-            if (!isDate(date)) {
-                return;
-            }
+        if(!isDate(date)){
+          return;
+        }
 
-            if (this.calendars) {
-                var firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1),
-                    lastVisibleDate = new Date(this.calendars[this.calendars.length-1].year, this.calendars[this.calendars.length-1].month, 1),
-                    visibleDate = date.getTime();
-                // get the end of the month
-                lastVisibleDate.setMonth(lastVisibleDate.getMonth()+1);
-                lastVisibleDate.setDate(lastVisibleDate.getDate()-1);
-                newCalendar = (visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate);
-            }
+        if(this.calendars){
+          var firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1),
+              lastVisibleDate = new Date(this.calendars[this.calendars.length-1].year, this.calendars[this.calendars.length-1].month, 1),
+              visibleDate = date.getTime();
+          // get the end of the month
+          lastVisibleDate.setMonth(lastVisibleDate.getMonth() + 1);
+          lastVisibleDate.setDate(lastVisibleDate.getDate() - 1);
+          newCalendar = (visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate);
+        }
 
-            if (newCalendar) {
-                this.calendars = [{
-                    month: date.getMonth(),
-                    year: date.getFullYear()
-                }];
-                if (this._o.mainCalendar === 'right') {
-                    this.calendars[0].month += 1 - this._o.numberOfMonths;
-                }
-            }
+        if(newCalendar){
+          this.calendars = [{
+            month: date.getMonth(),
+            year: date.getFullYear()
+          }];
+          if(this._o.mainCalendar === 'right'){
+            this.calendars[0].month += 1 - this._o.numberOfMonths;
+          }
+        }
 
-            this.adjustCalendars();
-        },
+        this.adjustCalendars();
+      },
 
-        adjustCalendars: function() {
-            this.calendars[0] = adjustCalendar(this.calendars[0]);
-            for (var c = 1; c < this._o.numberOfMonths; c++) {
-                this.calendars[c] = adjustCalendar({
-                    month: this.calendars[0].month + c,
-                    year: this.calendars[0].year
-                });
-            }
-            this.draw();
-        },
-
-        gotoToday: function()
-        {
-            this.gotoDate(new Date());
-        },
-
-        /**
-         * change view to a specific month (zero-index, e.g. 0: January)
-         */
-        gotoMonth: function(month)
-        {
-            if (!isNaN(month)) {
-                this.calendars[0].month = parseInt(month, 10);
-                this.adjustCalendars();
-            }
-        },
-
-        nextMonth: function()
-        {
-            this.calendars[0].month++;
-            this.adjustCalendars();
-        },
-
-        prevMonth: function()
-        {
-            this.calendars[0].month--;
-            this.adjustCalendars();
-        },
-
-        /**
-         * change view to a specific full year (e.g. "2012")
-         */
-        gotoYear: function(year)
-        {
-            if (!isNaN(year)) {
-                this.calendars[0].year = parseInt(year, 10);
-                this.adjustCalendars();
-            }
-        },
-
-        /**
-         * change the minDate
-         */
-        setMinDate: function(value)
-        {
-            setToStartOfDay(value);
-            this._o.minDate = value;
-            this._o.minYear  = value.getFullYear();
-            this._o.minMonth = value.getMonth();
-        },
-
-        /**
-         * change the maxDate
-         */
-        setMaxDate: function(value)
-        {
-            this._o.maxDate = value;
-        },
-
-        setStartRange: function(value)
-        {
-            this._o.startRange = value;
-        },
-
-        setEndRange: function(value)
-        {
-            this._o.endRange = value;
-        },
-
-        /**
-         * refresh the HTML
-         */
-        draw: function(force)
-        {
-            if (!this._v && !force) {
-                return;
-            }
-            var opts = this._o,
-                minYear = opts.minYear,
-                maxYear = opts.maxYear,
-                minMonth = opts.minMonth,
-                maxMonth = opts.maxMonth,
-                html = '';
-
-            if (this._y <= minYear) {
-                this._y = minYear;
-                if (!isNaN(minMonth) && this._m < minMonth) {
-                    this._m = minMonth;
-                }
-            }
-            if (this._y >= maxYear) {
-                this._y = maxYear;
-                if (!isNaN(maxMonth) && this._m > maxMonth) {
-                    this._m = maxMonth;
-                }
-            }
+      adjustCalendars: function(){
+        this.calendars[0] = adjustCalendar(this.calendars[0]);
+        for(var c = 1; c < this._o.numberOfMonths; c++){
+          this.calendars[c] = adjustCalendar({
+            month: this.calendars[0].month + c,
+            year: this.calendars[0].year
+          });
+        }
+        this.draw();
+      },
+
+      gotoToday: function(){
+        this.gotoDate(new Date());
+      },
+
+      /**
+       * change view to a specific month (zero-index, e.g. 0: January)
+       */
+      gotoMonth: function(month){
+        if(!isNaN(month)){
+          this.calendars[0].month = parseInt(month, 10);
+          this.adjustCalendars();
+        }
+      },
+
+      nextMonth: function(){
+        this.calendars[0].month++;
+        this.adjustCalendars();
+      },
+
+      prevMonth: function(){
+        this.calendars[0].month--;
+        this.adjustCalendars();
+      },
+
+      /**
+       * change view to a specific full year (e.g. "2012")
+       */
+      gotoYear: function(year){
+        if(!isNaN(year)){
+          this.calendars[0].year = parseInt(year, 10);
+          this.adjustCalendars();
+        }
+      },
+
+      /**
+       * change the minDate
+       */
+      setMinDate: function(value){
+        setToStartOfDay(value);
+        this._o.minDate = value;
+        this._o.minYear  = value.getFullYear();
+        this._o.minMonth = value.getMonth();
+      },
+
+      /**
+       * change the maxDate
+       */
+      setMaxDate: function(value){
+        this._o.maxDate = value;
+      },
+
+      setStartRange: function(value){
+        this._o.startRange = value;
+      },
+
+      setEndRange: function(value){
+        this._o.endRange = value;
+      },
+
+      /**
+       * refresh the HTML
+       */
+      draw: function(force){
+        if(!this._v && !force){
+          return;
+        }
+        var opts = this._o,
+            minYear = opts.minYear,
+            maxYear = opts.maxYear,
+            minMonth = opts.minMonth,
+            maxMonth = opts.maxMonth,
+            html = '';
+
+        if(this._y <= minYear){
+          this._y = minYear;
+          if(!isNaN(minMonth) && this._m < minMonth){
+            this._m = minMonth;
+          }
+        }
+        if(this._y >= maxYear){
+          this._y = maxYear;
+          if(!isNaN(maxMonth) && this._m > maxMonth){
+            this._m = maxMonth;
+          }
+        }
 
-            for (var c = 0; c < opts.numberOfMonths; c++) {
-                html += '<div class="pika-lendar">' + renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year) + this.render(this.calendars[c].year, this.calendars[c].month) + '</div>';
-            }
+        for(var c = 0; c < opts.numberOfMonths; c++){
+          html += '<div class="pika-lendar">' + renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year) + this.render(this.calendars[c].year, this.calendars[c].month) + '</div>';
+        }
 
-            this.el.innerHTML = html;
+        this.el.innerHTML = html;
 
-            if (opts.bound) {
-                if(opts.field.type !== 'hidden') {
-                    sto(function() {
-                        opts.trigger.focus();
-                    }, 1);
-                }
-            }
+        if(opts.bound){
+          if(opts.field.type !== 'hidden'){
+            sto(function(){
+              opts.trigger.focus();
+            }, 1);
+          }
+        }
 
-            if (typeof this._o.onDraw === 'function') {
-                var self = this;
-                sto(function() {
-                    self._o.onDraw.call(self);
-                }, 0);
-            }
-        },
-
-        adjustPosition: function()
-        {
-            var field, pEl, width, height, viewportWidth, viewportHeight, scrollTop, left, top, clientRect;
-
-            if (this._o.container) return;
-
-            this.el.style.position = 'absolute';
-
-            field = this._o.trigger;
-            pEl = field;
-            width = this.el.offsetWidth;
-            height = this.el.offsetHeight;
-            viewportWidth = window.innerWidth || document.documentElement.clientWidth;
-            viewportHeight = window.innerHeight || document.documentElement.clientHeight;
-            scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
-
-            if (typeof field.getBoundingClientRect === 'function') {
-                clientRect = field.getBoundingClientRect();
-                left = clientRect.left + window.pageXOffset;
-                top = clientRect.bottom + window.pageYOffset;
-            } else {
-                left = pEl.offsetLeft;
-                top  = pEl.offsetTop + pEl.offsetHeight;
-                while((pEl = pEl.offsetParent)) {
-                    left += pEl.offsetLeft;
-                    top  += pEl.offsetTop;
-                }
-            }
+        if(typeof this._o.onDraw === 'function'){
+          var self = this;
+            sto(function(){
+              self._o.onDraw.call(self);
+            }, 0);
+        }
+      },
+
+      adjustPosition: function(){
+        var field, pEl, width, height, viewportWidth, viewportHeight, scrollTop, left, top, clientRect;
+        if(this._o.container) return;
+        this.el.style.position = 'absolute';
+        field = this._o.trigger;
+        pEl = field;
+        width = this.el.offsetWidth;
+        height = this.el.offsetHeight;
+        viewportWidth = window.innerWidth || document.documentElement.clientWidth;
+        viewportHeight = window.innerHeight || document.documentElement.clientHeight;
+        scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
+
+        if(typeof field.getBoundingClientRect === 'function'){
+          clientRect = field.getBoundingClientRect();
+          left = clientRect.left + window.pageXOffset;
+          top = clientRect.bottom + window.pageYOffset;
+        }else{
+          left = pEl.offsetLeft;
+          top  = pEl.offsetTop + pEl.offsetHeight;
+          while((pEl = pEl.offsetParent)){
+            left += pEl.offsetLeft;
+            top  += pEl.offsetTop;
+          }
+        }
 
-            // default position is bottom & left
-            if ((this._o.reposition && left + width > viewportWidth) ||
-                (
-                    this._o.position.indexOf('right') > -1 &&
-                    left - width + field.offsetWidth > 0
-                )
-            ) {
-                left = left - width + field.offsetWidth;
-            }
-            if ((this._o.reposition && top + height > viewportHeight + scrollTop) ||
-                (
-                    this._o.position.indexOf('top') > -1 &&
-                    top - height - field.offsetHeight > 0
-                )
-            ) {
-                top = top - height - field.offsetHeight;
-            }
+        // default position is bottom & left
+        if((this._o.reposition && left + width > viewportWidth) ||
+           (this._o.position.indexOf('right') > -1 &&
+            left - width + field.offsetWidth > 0)){
+              left = left - width + field.offsetWidth;
+        }
+        if((this._o.reposition && top + height > viewportHeight + scrollTop) ||
+           (this._o.position.indexOf('top') > -1 &&
+            top - height - field.offsetHeight > 0)){
+              top = top - height - field.offsetHeight;
+        }
 
-            this.el.style.left = left + 'px';
-            this.el.style.top = top + 'px';
-        },
-
-        /**
-         * render HTML for a particular month
-         */
-        render: function(year, month)
-        {
-            var opts   = this._o,
-                now    = new Date(),
-                days   = getDaysInMonth(year, month),
-                before = new Date(year, month, 1).getDay(),
-                data   = [],
-                row    = [];
-            setToStartOfDay(now);
-            if (opts.firstDay > 0) {
-                before -= opts.firstDay;
-                if (before < 0) {
-                    before += 7;
-                }
-            }
-            var cells = days + before,
-                after = cells;
-            while(after > 7) {
-                after -= 7;
-            }
-            cells += 7 - after;
-            for (var i = 0, r = 0; i < cells; i++)
-            {
-                var day = new Date(year, month, 1 + (i - before)),
-                    isSelected = isDate(this._d) ? compareDates(day, this._d) : false,
-                    isToday = compareDates(day, now),
-                    isEmpty = i < before || i >= (days + before),
-                    isStartRange = opts.startRange && compareDates(opts.startRange, day),
-                    isEndRange = opts.endRange && compareDates(opts.endRange, day),
-                    isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange,
-                    isDisabled = (opts.minDate && day < opts.minDate) ||
-                                 (opts.maxDate && day > opts.maxDate) ||
-                                 (opts.disableWeekends && isWeekend(day)) ||
-                                 (opts.disableDayFn && opts.disableDayFn(day)),
-                    dayConfig = {
-                        day: 1 + (i - before),
-                        month: month,
-                        year: year,
-                        isSelected: isSelected,
-                        isToday: isToday,
-                        isDisabled: isDisabled,
-                        isEmpty: isEmpty,
-                        isStartRange: isStartRange,
-                        isEndRange: isEndRange,
-                        isInRange: isInRange
-                    };
-
-                row.push(renderDay(dayConfig));
-
-                if (++r === 7) {
-                    if (opts.showWeekNumber) {
-                        row.unshift(renderWeek(i - before, month, year));
-                    }
-                    data.push(renderRow(row, opts.isRTL));
-                    row = [];
-                    r = 0;
-                }
-            }
-            return renderTable(opts, data);
-        },
-
-        isVisible: function()
-        {
-            return this._v;
-        },
-
-        show: function()
-        {
-            if (!this._v) {
-                removeClass(this.el, 'is-hidden');
-                this._v = true;
-                this.draw();
-                if (this._o.bound) {
-                    addEvent(document, 'click', this._onClick);
-                    this.adjustPosition();
-                }
-                if (typeof this._o.onOpen === 'function') {
-                    this._o.onOpen.call(this);
-                }
-            }
-        },
-
-        hide: function()
-        {
-            var v = this._v;
-            if (v !== false) {
-                if (this._o.bound) {
-                    removeEvent(document, 'click', this._onClick);
-                }
-                this.el.style.position = 'static'; // reset
-                this.el.style.left = 'auto';
-                this.el.style.top = 'auto';
-                addClass(this.el, 'is-hidden');
-                this._v = false;
-                if (v !== undefined && typeof this._o.onClose === 'function') {
-                    this._o.onClose.call(this);
-                }
-            }
-        },
-
-        /**
-         * GAME OVER
-         */
-        destroy: function()
-        {
-            this.hide();
-            removeEvent(this.el, 'mousedown', this._onMouseDown, true);
-            removeEvent(this.el, 'touchend', this._onMouseDown, true);
-            removeEvent(this.el, 'change', this._onChange);
-            if (this._o.field) {
-                removeEvent(this._o.field, 'change', this._onInputChange);
-                if (this._o.bound) {
-                    removeEvent(this._o.trigger, 'click', this._onInputClick);
-                    removeEvent(this._o.trigger, 'focus', this._onInputFocus);
-                    removeEvent(this._o.trigger, 'blur', this._onInputBlur);
-                }
-            }
-            if (this.el.parentNode) {
-                this.el.parentNode.removeChild(this.el);
+        this.el.style.left = left + 'px';
+        this.el.style.top = top + 'px';
+      },
+
+      /**
+       * render HTML for a particular month
+       */
+      render: function(year, month){
+        var opts   = this._o,
+            now    = new Date(),
+            days   = getDaysInMonth(year, month),
+            before = new Date(year, month, 1).getDay(),
+            data   = [],
+            row    = [];
+        setToStartOfDay(now);
+        if(opts.firstDay > 0){
+          before -= opts.firstDay;
+          if(before < 0){
+            before += 7;
+          }
+        }
+        var cells = days + before,
+            after = cells;
+        while(after > 7){
+          after -= 7;
+        }
+        cells += 7 - after;
+        for(var i = 0, r = 0; i < cells; i++){
+          var day = new Date(year, month, 1 + (i - before)),
+              isSelected = isDate(this._d) ? compareDates(day, this._d) : false,
+              isToday = compareDates(day, now),
+              isEmpty = i < before || i >= (days + before),
+              isStartRange = opts.startRange && compareDates(opts.startRange, day),
+              isEndRange = opts.endRange && compareDates(opts.endRange, day),
+              isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange,
+              isDisabled = (opts.minDate && day < opts.minDate) ||
+                           (opts.maxDate && day > opts.maxDate) ||
+                           (opts.disableWeekends && isWeekend(day)) ||
+                           (opts.disableDayFn && opts.disableDayFn(day)),
+              dayConfig = {
+                day: 1 + (i - before),
+                month: month,
+                year: year,
+                isSelected: isSelected,
+                isToday: isToday,
+                isDisabled: isDisabled,
+                isEmpty: isEmpty,
+                isStartRange: isStartRange,
+                isEndRange: isEndRange,
+                isInRange: isInRange
+              };
+
+          row.push(renderDay(dayConfig));
+          if(++r === 7){
+            if(opts.showWeekNumber){
+              row.unshift(renderWeek(i - before, month, year));
             }
+            data.push(renderRow(row, opts.isRTL));
+            row = [];
+            r = 0;
+          }
         }
-
+        return renderTable(opts, data);
+      },
+
+      isVisible: function(){
+        return this._v;
+      },
+
+      show: function(){
+        if(!this._v){
+          removeClass(this.el, 'is-hidden');
+          this._v = true;
+          this.draw();
+          if(this._o.bound){
+            addEvent(document, 'click', this._onClick);
+            this.adjustPosition();
+          }
+          if(typeof this._o.onOpen === 'function'){
+            this._o.onOpen.call(this);
+          }
+        }
+      },
+
+      hide: function(){
+        var v = this._v;
+        if(v !== false){
+          if(this._o.bound){
+            removeEvent(document, 'click', this._onClick);
+          }
+          this.el.style.position = 'static'; // reset
+          this.el.style.left = 'auto';
+          this.el.style.top = 'auto';
+          addClass(this.el, 'is-hidden');
+          this._v = false;
+          if(v !== undefined && typeof this._o.onClose === 'function'){
+            this._o.onClose.call(this);
+          }
+        }
+      },
+
+      /**
+       * GAME OVER
+       */
+      destroy: function(){
+        this.hide();
+        removeEvent(this.el, 'mousedown', this._onMouseDown, true);
+        removeEvent(this.el, 'touchend', this._onMouseDown, true);
+        removeEvent(this.el, 'change', this._onChange);
+        if(this._o.field){
+          removeEvent(this._o.field, 'change', this._onInputChange);
+          if(this._o.bound){
+            removeEvent(this._o.trigger, 'click', this._onInputClick);
+            removeEvent(this._o.trigger, 'focus', this._onInputFocus);
+            removeEvent(this._o.trigger, 'blur', this._onInputBlur);
+          }
+        }
+        if(this.el.parentNode){
+          this.el.parentNode.removeChild(this.el);
+        }
+      }
     };
-
     return Pikaday;
-
 }));
+
+

+ 89 - 73
priv/js/comboLookup.js

@@ -1,31 +1,33 @@
-function comboClear(dom) {
-    let elem = qi('comboContainer_' + dom)
-    if (elem) { elem.style.display = 'none' }
-    activeCombo = undefined; currentItem = undefined;
+function comboClear(dom){
+  let elem = qi('comboContainer_' + dom)
+  if(elem){ elem.style.display = 'none' }
+  activeCombo = undefined;
+  currentItem = undefined;
 }
 
-function comboSelect(dom, row, feed, mod, id) {
-    let elem = qi(dom); comboClear(dom);
-    if (qi(id)) elem.setAttribute("data-bind", qi(id).getAttribute('data-bind'));
-    elem.value = row;
-    elem.style.backgroundColor = 'white';
-    direct(tuple(atom('comboSelect'),
-                 string(dom),
-                 string(row),
-                 string(feed),
-                 atom(mod)));
+function comboSelect(dom, row, feed, mod, id){
+  let elem = qi(dom);
+  comboClear(dom);
+  if(qi(id)) elem.setAttribute("data-bind", qi(id).getAttribute('data-bind'));
+  elem.value = row;
+  elem.style.backgroundColor = 'white';
+  direct(tuple(atom('comboSelect'),
+               string(dom),
+               string(row),
+               string(feed),
+               atom(mod)));
 }
 
-function comboLookupChange(dom) {
+function comboLookupChange(dom){
   let elem = qi(dom);
-  if (elem && elem.value == "" && elem.getAttribute("data-bind")) {
+  if(elem && elem.value == "" && elem.getAttribute("data-bind")){
     elem.removeAttribute("data-bind");
   }
 }
 
-function comboLookupClick(dom, feed, mod) {
+function comboLookupClick(dom, feed, mod){
   var char = event.which || event.keyCode;
-  if (char ==  1 && !activeCombo && qi(dom).value == '') {
+  if(char ==  1 && !activeCombo && qi(dom).value == ''){
     activeCombo = dom;
     currentItem = undefined;
     direct(tuple(atom('comboKey'),
@@ -33,78 +35,92 @@ function comboLookupClick(dom, feed, mod) {
                 string(dom),
                 string(feed),
                 atom(mod)));
-    return
-  } else if(char ==  1 && activeCombo == dom){comboClear(dom);}
+    return ;
+  }else if(char ==  1 && activeCombo == dom){
+    comboClear(dom);
+  }
 }
 
-function comboLookupKeydown(dom, feed, mod) {
-    var char = event.which || event.keyCode;
-    if (char == 40 && !activeCombo && qi(dom).value == '') {
-        activeCombo = dom;
-        currentItem = undefined;
-        direct(tuple(atom('comboKey'),
-                     atom('all'),
-                     string(dom),
-                     string(feed),
-                     atom(mod)));
-        return
-    }
-    if (activeCombo && [38, 40].includes(char)) {
-        event.preventDefault();
-        console.log('Keycode: ' + char + ", DOM: " + dom);
-        if (char == 40) { set_focus( currentItem && ( !cycleEnabled || currentItem.nextSibling)
-                        ? currentItem.nextSibling : qi('comboContainer_' + dom).firstChild, true) }
-        if (char == 38) { set_focus( currentItem && ( !cycleEnabled || currentItem.previousSibling)
-                        ? currentItem.previousSibling : qi('comboContainer_' + dom).lastChild, true) }
+function comboLookupKeydown(dom, feed, mod){
+  var char = event.which || event.keyCode;
+  if(char == 40 && !activeCombo && qi(dom).value == ''){
+    activeCombo = dom;
+    currentItem = undefined;
+    direct(tuple(atom('comboKey'),
+                 atom('all'),
+                 string(dom),
+                 string(feed),
+                 atom(mod)));
+    return ;
+  }
+  if(activeCombo && [38, 40].includes(char)){
+    event.preventDefault();
+    console.log('Keycode: ' + char + ", DOM: " + dom);
+    if(char == 40){
+      set_focus(currentItem && ( !cycleEnabled || currentItem.nextSibling) ? 
+                  currentItem.nextSibling : qi('comboContainer_' + dom).firstChild, true);
+    }else if(char == 38){
+      set_focus(currentItem && ( !cycleEnabled || currentItem.previousSibling) ? 
+                  currentItem.previousSibling : qi('comboContainer_' + dom).lastChild, true);
     }
+  }
 }
 
-function comboLookupKeyup(dom, feed, mod) {
-    var char = event.which || event.keyCode;
-    if (char == 27 || (char == 8 || char == 46) && qi(dom).value == '') {
-        qi(dom).value = '';
-        comboClear(dom);
-        return
-    }
-    if (char == 13 && currentItem) { currentItem.click(); return }
-    if ([33, 34, 35, 36, 37, 39].includes(char)) { return }
-    if (activeCombo && [38, 40].includes(char)) { return }
-    else {
-        activeCombo = dom;
-        currentItem = undefined;
-        direct(tuple(atom('comboKey'),
-                     bin(qi(dom).value),
-                     string(dom),
-                     string(feed),
-                     atom(mod)));
-    }
+function comboLookupKeyup(dom, feed, mod){
+  var char = event.which || event.keyCode;
+  if(char == 27 || (char == 8 || char == 46) && qi(dom).value == ''){
+    qi(dom).value = '';
+    comboClear(dom);
+    return ;
+  }
+  if(char == 13 && currentItem){
+    currentItem.click();
+    return ;
+  }
+  if([33, 34, 35, 36, 37, 39].includes(char)){ return ; }
+  if(activeCombo && [38, 40].includes(char)){
+    return ;
+  }else{
+    activeCombo = dom;
+    currentItem = undefined;
+    direct(tuple(atom('comboKey'),
+                 bin(qi(dom).value),
+                 string(dom),
+                 string(feed),
+                 atom(mod)));
+  }
 }
 
-function comboLookupMouseMove(dom) {
-  set_focus(event.target.closest('.dropdown-item'), false)
+function comboLookupMouseMove(dom){
+  set_focus(event.target.closest('.dropdown-item'), false);
 }
 
-function set_focus(elem, scroll) {
-  if (elem) {
-    if(currentItem) {currentItem.className = "dropdown-item"}
-    elem.className = "dropdown-item focus"
-    if (scroll==true) {elem.scrollIntoView({block: "nearest", inline: "nearest"})}
+function set_focus(elem, scroll){
+  if(elem){
+    if(currentItem){
+      currentItem.className = "dropdown-item";
+    }
+    elem.className = "dropdown-item focus";
+    if(scroll==true){
+      elem.scrollIntoView({block: "nearest", inline: "nearest"});
+    }
     currentItem = elem
   }
 }
 
 document.addEventListener("click", () => {
-  if (activeCombo && event.target.className != 'triangle' &&
-    !event.target.closest('#comboContainer_' + activeCombo)) {
-    qi(activeCombo).value = '';
-    comboClear(activeCombo);
+  if(activeCombo && event.target.className != 'triangle' &&
+    !event.target.closest('#comboContainer_' + activeCombo)){
+      qi(activeCombo).value = '';
+      comboClear(activeCombo);
   }
-})
+});
 
-function comboLostFocus(e) { }
-function comboOnFocus(e) { }
-function comboLookupMouseOut(dom) { }
+function comboLostFocus(e){}
+function comboOnFocus(e){}
+function comboLookupMouseOut(dom){}
 
 var activeCombo = undefined
 var currentItem = undefined
 var cycleEnabled = false
+

+ 96 - 69
priv/js/nitro.js

@@ -1,80 +1,107 @@
 // Nitrogen Compatibility Layer
 
-function unbase64(base64) {
-    var binary_string = window.atob(base64);
-    var len = binary_string.length;
-    var bytes = new Uint8Array(len);
-    for (var i = 0; i < len; i++) bytes[i] = binary_string.charCodeAt(i);
-    return bytes.buffer;
+function unbase64(base64){
+  var binary_string = window.atob(base64);
+  var len = binary_string.length;
+  var bytes = new Uint8Array(len);
+  for(var i = 0; i < len; i++) bytes[i] = binary_string.charCodeAt(i);
+  return bytes.buffer;
 }
 
-// Nitrogen Compatibility Layer
+function direct(term){
+  ws.send(enc(tuple(atom('direct'), term)));
+}
 
-function direct(term) { ws.send(enc(tuple(atom('direct'),term))); }
-function validateSources() { return true; }
-function querySourceRaw(Id) {
-    var val, el = document.getElementById(Id);
-    if (!el) {
-       val = qs('input[name='+Id+']:checked'); val = val ? val.value : "";
-    } else switch (el.tagName) {
-        case 'FIELDSET':
-            val = qs('[id="'+Id+'"]:checked'); val = val ? val.value : ""; break;
-        case 'INPUT':
-            switch (el.getAttribute("type")) {
-                case 'radio': val = qs('input[name='+Id+']:checked'); val = val ? val.value : ""; break;
-                case 'checkbox': val = qs('input[id='+Id+']:checked'); val = val ? val.value : ""; break;
-                case 'date': val = Date.parse(el.value);  val = val && new Date(val) || ""; break;
-                case 'calendar': val = pickers[el.id]._d || ""; break;
-                case 'comboLookup': case 'hidden':
-                    if (el.hasAttribute('data-bind')) {
-                        val = { 'text' : el.value, 'bind' : el.getAttribute('data-bind')};
-                    } else {
-                        val = el.value;
-                    }
-                    break;
-                default: var edit = el.contentEditable;
-                    if (edit && edit === 'true') val = el.innerHTML;
-                    else val = el.value;
-            }
-            break;
+function validateSources(){ return true; }
+
+function querySourceRaw(Id){
+  var val,
+      el = document.getElementById(Id);
+  if(!el){
+    val = qs('input[name=' + Id + ']:checked');
+    val = val ? val.value : "";
+  }else switch (el.tagName){
+    case 'FIELDSET':
+      val = qs('[id="'+Id+'"]:checked'); val = val ? val.value : ""; break;
+    case 'INPUT':
+      switch(el.getAttribute("type")){
+        case 'radio':
+          val = qs('input[name=' + Id + ']:checked');
+          val = val ? val.value : "";
+          break;
+        case 'checkbox':
+          val = qs('input[id=' + Id + ']:checked');
+          val = val ? val.value : "";
+          break;
+        case 'date':
+          val = Date.parse(el.value);
+          val = val && new Date(val) || "";
+          break;
+        case 'calendar':
+          val = pickers[el.id]._d || "";
+          break;
+        case 'comboLookup':
+        case 'hidden':
+          if(el.hasAttribute('data-bind')){
+            val = {'text' : el.value, 'bind' : el.getAttribute('data-bind')};
+          }else{
+            val = el.value;
+          }
+          break;
         default:
-            if(el.getAttribute('data-text-input')) {
-              val = querySourceRaw(el.children[1].children[0].id);
-            }
-            else if (el.getAttribute('data-vector-input')) {
-                val = querySourceRaw(el.children[1].id);
-            } else if (el.getAttribute('data-edit-input')) {
-                val = querySourceRaw(el.children[0].children[0].children[0].id);
-            } else if (el.getAttribute('data-sortable-list')) {
-                val = getSortableValues('#' + el.id);
-            } else if (el.contentEditable === 'true') {
-                val = el.innerHTML;
-            } else {
-                val = el.value;
-                switch (val) {
-                    case "true": val = new Boolean(true); break;
-                    case "false": val = new Boolean(false); break;
-                }
-            }
-    }
-    return val;
+          var edit = el.contentEditable;
+          if(edit && edit === 'true'){
+            val = el.innerHTML;
+          }else{
+            val = el.value;
+          }
+      }
+      break;
+    default:
+      if(el.getAttribute('data-text-input')){
+        val = querySourceRaw(el.children[1].children[0].id);
+      }else if(el.getAttribute('data-vector-input')){
+        val = querySourceRaw(el.children[1].id);
+      }else if(el.getAttribute('data-edit-input')){
+        val = querySourceRaw(el.children[0].children[0].children[0].id);
+      }else if(el.getAttribute('data-sortable-list')){
+        val = getSortableValues('#' + el.id);
+      }else if(el.contentEditable === 'true'){
+        val = el.innerHTML;
+      }else{
+        val = el.value;
+        switch(val){
+          case "true":
+            val = new Boolean(true);
+            break;
+          case "false":
+            val = new Boolean(false);
+            break;
+        }
+      }
+  }
+  return val;
 }
 
-function querySourceConvert(qs) {
-    if (qs && qs.hasOwnProperty('text') && qs.hasOwnProperty('bind')) {
-        return dec(unbase64(qs.bind)); }
-    else if (qs instanceof Date) {
-        return tuple(number(qs.getFullYear()),
-                     number(qs.getMonth() + 1),
-                     number(qs.getDate())); }
-    else if (qs instanceof Boolean) {
-        return atom(qs.valueOf()); }
-    else if (qs instanceof Array) {
-        return list.apply(null, qs.map(querySourceConvert)); }
-    else { return bin(qs); }
+function querySourceConvert(qs){
+  if(qs && qs.hasOwnProperty('text') && qs.hasOwnProperty('bind')){
+    return dec(unbase64(qs.bind));
+  }else if(qs instanceof Date){
+    return tuple(number(qs.getFullYear()),
+                 number(qs.getMonth() + 1),
+                 number(qs.getDate()));
+  }else if(qs instanceof Boolean){
+    return atom(qs.valueOf());
+  }else if(qs instanceof Array){
+    return list.apply(null, qs.map(querySourceConvert));
+  }else{
+    return bin(qs);
+  }
 }
 
-function querySource(Id) {
-    var qs = querySourceRaw(Id);
-    return querySourceConvert(qs);
+function querySource(Id){
+  var qs = querySourceRaw(Id);
+  return querySourceConvert(qs);
 }
+
+

+ 92 - 69
priv/js/sortable.js

@@ -1,19 +1,41 @@
 "use strict";
 
-function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } }
+function _instanceof(left, right){
+  if(right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]){
+    return !!right[Symbol.hasInstance](left);
+  }else{
+    return left instanceof right;
+  }
+}
 
-function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+function _classCallCheck(instance, Constructor){
+  if(!_instanceof(instance, Constructor)){
+    throw new TypeError("Cannot call a class as a function");
+  }
+}
 
-function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+function _defineProperties(target, props){
+  for(var i = 0; i < props.length; i++){
+    var descriptor = props[i];
+    descriptor.enumerable = descriptor.enumerable || false;
+    descriptor.configurable = true;
+    if("value" in descriptor) descriptor.writable = true;
+    Object.defineProperty(target, descriptor.key, descriptor);
+  }
+}
 
-function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+function _createClass(Constructor, protoProps, staticProps){
+  if(protoProps) _defineProperties(Constructor.prototype, protoProps);
+  if(staticProps) _defineProperties(Constructor, staticProps);
+  return Constructor;
+}
 
-window.addEventListener('touchmove', function () {});
+window.addEventListener('touchmove', function(){});
 
 var Sortable =
 /*#__PURE__*/
-function () {
-  function Sortable(list, options) {
+function(){
+  function Sortable(list, options){
     _classCallCheck(this, Sortable);
     this.list = typeof list === 'string' ? document.querySelector(list) : list;
     this.items = Array.from(this.list.children);
@@ -31,23 +53,22 @@ function () {
 
   _createClass(Sortable, [{
     key: "dragStart",
-    value: function dragStart(e) {
+    value: function dragStart(e){
       var _this = this;
-
-      if (this.animation) return;
-      if (e.type === 'mousedown' && e.which !== 1) return;
-      if (e.type === 'touchstart' && e.touches.length > 1) return;
+      if(this.animation) return;
+      if(e.type === 'mousedown' && e.which !== 1) return;
+      if(e.type === 'touchstart' && e.touches.length > 1) return;
       this.handle = null;
       var el = e.target;
 
-      while (el) {
-        if (el.hasAttribute('data-sortable-handle')) this.handle = el;
-        if (el.hasAttribute('data-sortable-item')) this.item = el;
-        if (el.hasAttribute('data-sortable-list')) break;
+      while(el){
+        if(el.hasAttribute('data-sortable-handle')) this.handle = el;
+        if(el.hasAttribute('data-sortable-item')) this.item = el;
+        if(el.hasAttribute('data-sortable-list')) break;
         el = el.parentElement;
       }
 
-      if (!this.handle) return;
+      if(!this.handle) return;
       this.list.style.position = 'relative';
       this.list.style.height = this.list.offsetHeight + 'px';
       this.item.classList.add('is-dragging');
@@ -55,10 +76,10 @@ function () {
       this.listHeight = this.list.offsetHeight;
       this.startTouchY = this.getDragY(e);
       this.startTop = this.item.offsetTop;
-      var offsetsTop = this.items.map(function (item) {
+      var offsetsTop = this.items.map(function(item){
         return item.offsetTop;
       });
-      this.items.forEach(function (item, index) {
+      this.items.forEach(function(item, index){
         item.style.position = 'absolute';
         item.style.top = 0;
         item.style.left = 0;
@@ -66,58 +87,55 @@ function () {
         item.style.transform = "translateY(".concat(offsetsTop[index], "px)");
         item.style.zIndex = item == _this.item ? 2 : 1;
       });
-      setTimeout(function () {
-        _this.items.forEach(function (item) {
-          if (_this.item == item) return;
+      setTimeout(function(){
+        _this.items.forEach(function(item){
+          if(_this.item == item) return;
           item.style.transition = "transform ".concat(_this.options.animationSpeed, "ms ").concat(_this.options.animationEasing);
         });
       });
-      this.positions = this.items.map(function (item, index) {
+      this.positions = this.items.map(function(item, index){
         return index;
       });
       this.position = Math.round(this.startTop / this.listHeight * this.items.length);
       this.touch = e.type == 'touchstart';
-      window.addEventListener(this.touch ? 'touchmove' : 'mousemove', this.dragMove, {
-        passive: false
-      });
+      window.addEventListener(this.touch ? 'touchmove' : 'mousemove',
+        this.dragMove, {passive: false});
       window.addEventListener(this.touch ? 'touchend' : 'mouseup', this.dragEnd, false);
     }
-  }, {
+  },
+  {
     key: "dragMove",
-    value: function dragMove(e) {
+    value: function dragMove(e){
       var _this2 = this;
 
-      if (this.animation) return;
+      if(this.animation) return;
       var top = this.startTop + this.getDragY(e) - this.startTouchY;
       var newPosition = Math.round(top / this.listHeight * this.items.length);
       this.item.style.transform = "translateY(".concat(top, "px)");
-      this.positions.forEach(function (index) {
-        if (index == _this2.position || index != newPosition) return;
-
+      this.positions.forEach(function(index){
+        if(index == _this2.position || index != newPosition) return;
         _this2.swapElements(_this2.positions, _this2.position, index);
-
         _this2.position = index;
       });
-      this.items.forEach(function (item, index) {
+      this.items.forEach(function(item, index){
         if (item == _this2.item) return;
         item.style.transform = "translateY(".concat(_this2.positions.indexOf(index) * _this2.itemHeight, "px)");
       });
       e.preventDefault();
     }
-  }, {
+  },
+  {
     key: "dragEnd",
-    value: function dragEnd(e) {
+    value: function dragEnd(e){
       var _this3 = this;
-
       this.animation = true;
       this.item.style.transition = "all ".concat(this.options.animationSpeed, "ms ").concat(this.options.animationEasing);
       this.item.style.transform = "translateY(".concat(this.position * this.itemHeight, "px)");
       this.item.classList.remove('is-dragging');
-      setTimeout(function () {
+      setTimeout(function(){
         _this3.list.style.position = '';
         _this3.list.style.height = '';
-
-        _this3.items.forEach(function (item) {
+        _this3.items.forEach(function(item){
           item.style.top = '';
           item.style.left = '';
           item.style.right = '';
@@ -128,61 +146,65 @@ function () {
           item.style.zIndex = '';
         });
 
-        _this3.positions.map(function (i) {
+        _this3.positions.map(function(i){
           return _this3.list.appendChild(_this3.items[i]);
         });
 
         _this3.items = Array.from(_this3.list.children);
         _this3.animation = false;
       }, this.options.animationSpeed);
-      window.removeEventListener(this.touch ? 'touchmove' : 'mousemove', this.dragMove, {
-        passive: false
-      });
+      window.removeEventListener(this.touch ? 'touchmove' : 'mousemove',
+        this.dragMove, {passive: false});
       window.removeEventListener(this.touch ? 'touchend' : 'mouseup', this.dragEnd, false);
     }
-  }, {
+  },
+  {
     key: "swapElements",
-    value: function swapElements(array, a, b) {
+    value: function swapElements(array, a, b){
       var temp = array[a];
       array[a] = array[b];
       array[b] = temp;
     }
-  }, {
+  },
+  {
     key: "getDragY",
-    value: function getDragY(e) {
+    value: function getDragY(e){
       return e.touches ? (e.touches[0] || e.changedTouches[0]).pageY : e.pageY;
     }
-  }, {
+  },
+  {
     key: "removeItem",
-    value: function removeItem(item) {
+    value: function removeItem(item){
       this.items.splice(this.items.indexOf(item),1);
       item.remove();
     }
-  }, {
+  },
+  {
     key: "addItemFrom",
-    value: function addItemFrom(input) {
+    value: function addItemFrom(input){
       var value = querySourceRaw(input);
       var bind = '';
-      if (value && value.hasOwnProperty('text') && value.hasOwnProperty('bind')) {
+      if(value && value.hasOwnProperty('text') && value.hasOwnProperty('bind')){
         bind = value.bind;
         value = value.text;
       }
       var inputElement = document.getElementById(input);
-      if (bind !== '' && bind !== 'null') {
-        if (inputElement) {
+      if(bind !== '' && bind !== 'null'){
+        if(inputElement){
           inputElement.value = '';
           inputElement.removeAttribute("data-bind");
         }
         appendItemFromBind(this.list.id,value,bind);
       }
     }
-  }, {
+  },
+  {
     key: "getValues",
-    value: function getValues() {
-      return Array.from(this.items.map(function(item) {
+    value: function getValues(){
+      return Array.from(this.items.map(function(item){
         let text = item.children[1].firstChild.innerHTML;
         let bind = item.getAttribute('data-bind');
-        if (bind) return { 'text': text, 'bind': bind };
+        if(bind) return { 'text': text, 'bind': bind };
         return text;
       }));
     }
@@ -193,32 +215,31 @@ function () {
 
 var SortableMap = new Map([]);
 
-function createSortable(list) {
+function createSortable(list){
   SortableMap.set(list, new Sortable(list));
 }
 
-function removeSortableItem(list, item) {
+function removeSortableItem(list, item){
   SortableMap.get(list).removeItem(item);
 }
 
-function addSortableItemFrom(list, input) {
+function addSortableItemFrom(list, input){
   var value = querySourceRaw(input);
   var isAdded = SortableMap.get(list).items.map(el => el.textContent).includes(value.text || value);
-  if(qi(input).value != '' & !isAdded)
-    SortableMap.get(list).addItemFrom(input);
+  if(qi(input).value != '' & !isAdded) SortableMap.get(list).addItemFrom(input);
 }
 
-function getSortableValues(list) {
+function getSortableValues(list){
   let sortable = SortableMap.get(list)
-  if(sortable) {
+  if(sortable){
     return sortable.getValues();
-  } else {
+  }else{
     return Array.from([]);
   }
 }
 
-function appendItemFromBind(dom,value,bind) {
-  var sortable = SortableMap.get('#'+dom);
+function appendItemFromBind(dom, value, bind){
+  var sortable = SortableMap.get('#' + dom);
   var template = document.createElement('template');
   template.innerHTML =
     '<div class="list__item" data-sortable-item="data-sortable-item" style="" data-bind="'+ bind + '">' +
@@ -230,3 +251,5 @@ function appendItemFromBind(dom,value,bind) {
   sortable.list.appendChild(new_item);
   sortable.items.push(new_item);
 }
+
+

+ 22 - 17
priv/js/validation.js

@@ -1,20 +1,25 @@
 
-function validateSources(list) {
-    return list.reduce(function(acc,x) {
-        var event = new CustomEvent('validation');
-            event.initCustomEvent('validation',true,true,querySourceRaw(x));
-        var el = qi(x),
-            listener = el && el.validation,
-            res = !listener || listener && el.dispatchEvent(event);
-        if (!res) { console.log("Validation failed:" + x); }
-        if (el) el.style.background = res ? '' : 'pink';
-        return res && acc; },true); }
+function validateSources(list){
+  return list.reduce(function(acc, x){
+    var event = new CustomEvent('validation');
+        event.initCustomEvent('validation', true, true, querySourceRaw(x));
+    var el = qi(x),
+        listener = el && el.validation,
+        res = !listener || listener && el.dispatchEvent(event);
+    if(!res){ console.log("Validation failed:" + x); }
+    if(el) el.style.background = res ? '' : 'pink';
+    return res && acc;
+  },true);
+}
 
-(function () {
-   function CustomEvent ( event, params ) {
-       params = params || { bubbles: false, cancelable: false, detail: undefined };
-       var evt = document.createEvent( 'CustomEvent' );
-       evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
-       return evt;  };
+(function(){
+  function CustomEvent(event, params){
+    params = params || { bubbles: false, cancelable: false, detail: undefined };
+    var evt = document.createEvent( 'CustomEvent' );
+    evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
+    return evt;
+  }
   CustomEvent.prototype = window.Event.prototype;
-  window.CustomEvent = CustomEvent; })();
+  window.CustomEvent = CustomEvent;
+})();
+