[101] | 1 | /*
|
---|
| 2 | * jQuery Mobile Framework : plugin to provide a date and time picker.
|
---|
| 3 | * Copyright (c) JTSage
|
---|
| 4 | * CC 3.0 Attribution. May be relicensed without permission/notification.
|
---|
| 5 | * https://github.com/jtsage/jquery-mobile-datebox
|
---|
| 6 | */
|
---|
| 7 | /* FLIPBOX Mode */
|
---|
| 8 |
|
---|
| 9 | (function($) {
|
---|
| 10 | $.extend( $.mobile.datebox.prototype.options, {
|
---|
| 11 | themeTireHigh: 'e',
|
---|
| 12 | themeTirePick: 'a',
|
---|
| 13 | themeTire: 'd',
|
---|
| 14 | useSetButton: true,
|
---|
| 15 | tireField: {
|
---|
| 16 | 'Tr': [ 15, 16, 17, 18 ],
|
---|
| 17 | 'Tw': [ 7, 8, 9, 10 ],
|
---|
| 18 | 'TW': [ 2, 3, 4, 5 ]
|
---|
| 19 | },
|
---|
| 20 | tireFieldOrder: ['Tr', 'Tw', 'TW'],
|
---|
| 21 | tireOutput: '%Xrr x %Xww, %XWyrs',
|
---|
| 22 | tireDefault: [17,8,5],
|
---|
| 23 | tireboxlang: {
|
---|
| 24 | // This structure interfaces with __() -> if it exists, strings are looked up here after i8n fails,
|
---|
| 25 | // and before going to 'default' - the name syntax is <mode>lang
|
---|
| 26 | 'tireTitleString': 'Tire Radius, Width, and Warrenty',
|
---|
| 27 | 'tireYears':'years',
|
---|
| 28 | 'tireSet':'Looks Good'
|
---|
| 29 | }
|
---|
| 30 | });
|
---|
| 31 | $.extend( $.mobile.datebox.prototype, {
|
---|
| 32 | '_tireboxDoSet': function () {
|
---|
| 33 | // If this function exists, it overrides the 'doset' method of the 'datebox' event.
|
---|
| 34 | // The name syntax is _<mode>DoSet
|
---|
| 35 | var w = this, o = this.options;
|
---|
| 36 | if ( typeof w.tireChoice === 'undefined' ) { w.tireChoice = this._makeDate(this.d.input.val()); }
|
---|
| 37 | w.d.input.trigger('datebox', {'method':'set', 'value':w._formatter(o.tireOutput,w.tireChoice), 'date':w.tireChoice});
|
---|
| 38 | },
|
---|
| 39 | '_tbox_offset': function (fld, amount) {
|
---|
| 40 | // This is *not* an automatic override, used below specificly.
|
---|
| 41 | var w = this, x,
|
---|
| 42 | o = this.options,
|
---|
| 43 | witch = $.inArray(fld, ['Tr', 'Tw', 'TW']),
|
---|
| 44 | base = o.tireField[fld].slice();
|
---|
| 45 |
|
---|
| 46 | if ( amount > 0 ) {
|
---|
| 47 | for ( x = 0; x < 5; x++ ) {
|
---|
| 48 | $.merge(base, o.tireField[fld]);
|
---|
| 49 | }
|
---|
| 50 | } else {
|
---|
| 51 | base.reverse();
|
---|
| 52 | amount = amount * -1;
|
---|
| 53 | for ( x = 0; x < 5; x++ ) {
|
---|
| 54 | $.merge(base, o.tireField[fld].slice().reverse());
|
---|
| 55 | }
|
---|
| 56 | }
|
---|
| 57 | w.tireChoice[witch] = base[$.inArray(w.tireChoice[witch], base) + amount];
|
---|
| 58 | if ( o.useImmediate ) { w.d.input.trigger('datebox', {'method':'set', 'value':w._formatter(o.tireOutput,w.tireChoice), 'date':w.tireChoice}); }
|
---|
| 59 | w.refresh();
|
---|
| 60 | },
|
---|
| 61 | '_tbox_arr': function (type, choice) {
|
---|
| 62 | var base = this.options.tireField[type], x,
|
---|
| 63 | before = [],
|
---|
| 64 | after = [],
|
---|
| 65 | found = false;
|
---|
| 66 |
|
---|
| 67 | for ( x in base ) {
|
---|
| 68 | if ( found === false && base[x] !== choice ) {
|
---|
| 69 | before.push(base[x]);
|
---|
| 70 | } else if ( base[x] === choice ) {
|
---|
| 71 | found = true;
|
---|
| 72 | } else {
|
---|
| 73 | after.push(base[x]);
|
---|
| 74 | }
|
---|
| 75 | }
|
---|
| 76 |
|
---|
| 77 | while ( before.length < 10 ) {
|
---|
| 78 | for ( x = base.length; x > 0; x-- ) {
|
---|
| 79 | before.unshift(base[x-1]);
|
---|
| 80 | }
|
---|
| 81 | }
|
---|
| 82 | while ( before.length > 10 ) {
|
---|
| 83 | before.shift();
|
---|
| 84 | }
|
---|
| 85 |
|
---|
| 86 | while ( after.length < 10 ) {
|
---|
| 87 | for ( x = 0; x < base.length; x++ ) {
|
---|
| 88 | after.push(base[x]);
|
---|
| 89 | }
|
---|
| 90 | }
|
---|
| 91 | after.length = 10;
|
---|
| 92 |
|
---|
| 93 | before.push(choice);
|
---|
| 94 |
|
---|
| 95 | return $.merge($.merge([], before), after);
|
---|
| 96 | },
|
---|
| 97 | '_tbox_pos': function () {
|
---|
| 98 | var w = this,
|
---|
| 99 | ech = null,
|
---|
| 100 | top = null,
|
---|
| 101 | par = this.d.intHTML.find('.ui-datebox-flipcontent').innerHeight(),
|
---|
| 102 | tot = null;
|
---|
| 103 |
|
---|
| 104 | w.d.intHTML.find('.ui-datebox-flipcenter').each(function() {
|
---|
| 105 | ech = $(this);
|
---|
| 106 | top = ech.innerHeight();
|
---|
| 107 | ech.css('top', ((par/2)-(top/2)+4)*-1);
|
---|
| 108 | });
|
---|
| 109 | w.d.intHTML.find('ul').each(function () {
|
---|
| 110 | ech = $(this);
|
---|
| 111 | par = ech.parent().innerHeight();
|
---|
| 112 | top = ech.find('li').first();
|
---|
| 113 | tot = ech.find('li').size() * top.outerHeight();
|
---|
| 114 | top.css('marginTop', ((tot/2)-(par/2)+(top.outerHeight()/2))*-1);
|
---|
| 115 | });
|
---|
| 116 | }
|
---|
| 117 | });
|
---|
| 118 | $.extend( $.mobile.datebox.prototype._parser, {
|
---|
| 119 | // If this stucture exists, it is called instead of the usual date input parser.
|
---|
| 120 | // The name of the structure is the same as the mode name - it recieves a string
|
---|
| 121 | // as the input, which is the current value of the input element, pre-sanitized
|
---|
| 122 | 'tirebox' : function ( str ) {
|
---|
| 123 | var o = this.options, i,
|
---|
| 124 | adv = o.tireOutput,
|
---|
| 125 | found = o.tireDefault,
|
---|
| 126 | exp_input = null,
|
---|
| 127 | exp_format = null;
|
---|
| 128 |
|
---|
| 129 | adv = adv.replace(/%(X|0|-)*([a-z])/gi, function(match, pad, oper) {
|
---|
| 130 | switch (oper) {
|
---|
| 131 | case 'r':
|
---|
| 132 | case 'w':
|
---|
| 133 | case 'W': return '(' + match + '|' +'[0-9]+' + ')';
|
---|
| 134 | default: return '.+?';
|
---|
| 135 | }
|
---|
| 136 | });
|
---|
| 137 |
|
---|
| 138 | adv = new RegExp('^' + adv + '$');
|
---|
| 139 | exp_input = adv.exec(str);
|
---|
| 140 | exp_format = adv.exec(o.tireOutput);
|
---|
| 141 |
|
---|
| 142 | if ( exp_input === null || exp_input.length !== exp_format.length ) {
|
---|
| 143 | return o.tireDefault;
|
---|
| 144 | }
|
---|
| 145 |
|
---|
| 146 | for ( i=0; i<exp_input.length; i++ ) { //0rad 1wid 2yrs
|
---|
| 147 | if ( exp_format[i].match(/^%.*r$/) ) { found[0] = parseInt(exp_input[i],10); }
|
---|
| 148 | if ( exp_format[i].match(/^%.*w$/) ) { found[1] = parseInt(exp_input[i],10); }
|
---|
| 149 | if ( exp_format[i].match(/^%.*W$/) ) { found[2] = parseInt(exp_input[i],10); }
|
---|
| 150 | }
|
---|
| 151 | return found;
|
---|
| 152 | }
|
---|
| 153 | });
|
---|
| 154 | $.extend( $.mobile.datebox.prototype._customformat, {
|
---|
| 155 | // If this stucture exists, the formatter will call it when it encounters a special string
|
---|
| 156 | // %X<whatever> - it recieves the single letter operater, and the current "date" value
|
---|
| 157 | 'tirebox' : function ( oper, val ) {
|
---|
| 158 | switch ( oper ) {
|
---|
| 159 | case 'r': return val[0];
|
---|
| 160 | case 'w': return val[1];
|
---|
| 161 | case 'W': return val[2];
|
---|
| 162 | }
|
---|
| 163 | }
|
---|
| 164 | });
|
---|
| 165 | $.extend( $.mobile.datebox.prototype._build, {
|
---|
| 166 | // This builds the actual interface, and is called on *every* refresh. (after each "movement")
|
---|
| 167 | 'tirebox': function () {
|
---|
| 168 | var w = this,
|
---|
| 169 | o = this.options, i, y, hRow, tmp, lineArr,
|
---|
| 170 | uid = 'ui-datebox-',
|
---|
| 171 | currentChoice = this._makeDate(this.d.input.val()),
|
---|
| 172 | flipBase = $("<div class='ui-overlay-shadow'><ul></ul></div>"),
|
---|
| 173 | ctrl = $("<div>", {"class":uid+'flipcontent'});
|
---|
| 174 |
|
---|
| 175 | if ( typeof w.tireChoice === 'undefined' ) { w.tireChoice = currentChoice.slice(); }
|
---|
| 176 |
|
---|
| 177 | if ( typeof w.d.intHTML !== 'boolean' ) {
|
---|
| 178 | w.d.intHTML.empty().remove();
|
---|
| 179 | }
|
---|
| 180 |
|
---|
| 181 | w.d.input.on('datebox', function (e,p) {
|
---|
| 182 | if ( p.method === 'postrefresh' ) {
|
---|
| 183 | w._tbox_pos();
|
---|
| 184 | }
|
---|
| 185 | });
|
---|
| 186 |
|
---|
| 187 | w.d.headerText = ((w._grabLabel() !== false)?w._grabLabel():w.__('tireTitleString'));
|
---|
| 188 | w.d.intHTML = $('<span>');
|
---|
| 189 |
|
---|
| 190 | w.fldOrder = o.tireFieldOrder;
|
---|
| 191 |
|
---|
| 192 | $('<div class="'+uid+'header"><table style="width:250px; margin-left:15px; text-align:center"><tr><td>Radius</td><td>Width</td><td>Warrenty</td></tr></table></div>').appendTo(w.d.intHTML).find('td').css('width', '33%');
|
---|
| 193 |
|
---|
| 194 | w.d.intHTML.append(ctrl);
|
---|
| 195 |
|
---|
| 196 | for ( y=0; y<w.fldOrder.length; y++ ) {
|
---|
| 197 | switch (w.fldOrder[y]) {
|
---|
| 198 | case 'Tr':
|
---|
| 199 | lineArr = w._tbox_arr('Tr', w.tireChoice[0]);
|
---|
| 200 | hRow = w._makeEl(flipBase, {'attr': {'field':'Tr','amount':1} });
|
---|
| 201 | for ( i in lineArr ) {
|
---|
| 202 | tmp = (i!=10)?((lineArr[i]===currentChoice[0])?o.themeTireHigh:o.themeTire):o.themeTirePick;
|
---|
| 203 | $('<li>', {'class':'ui-body-'+tmp})
|
---|
| 204 | .html('<span>'+lineArr[i]+'</span>').appendTo(hRow.find('ul'));
|
---|
| 205 |
|
---|
| 206 | }
|
---|
| 207 | hRow.appendTo(ctrl);
|
---|
| 208 | break;
|
---|
| 209 | case 'Tw':
|
---|
| 210 | lineArr = w._tbox_arr('Tw', w.tireChoice[1]);
|
---|
| 211 | hRow = w._makeEl(flipBase, {'attr': {'field':'Tw','amount':1} });
|
---|
| 212 | for ( i in lineArr ) {
|
---|
| 213 | tmp = (i!=10)?((lineArr[i]===currentChoice[1])?o.themeTireHigh:o.themeTire):o.themeTirePick;
|
---|
| 214 | $('<li>', {'class':'ui-body-'+tmp})
|
---|
| 215 | .html('<span>'+lineArr[i]+'</span>').appendTo(hRow.find('ul'));
|
---|
| 216 |
|
---|
| 217 | }
|
---|
| 218 | hRow.appendTo(ctrl);
|
---|
| 219 | break;
|
---|
| 220 | case 'TW':
|
---|
| 221 | lineArr = w._tbox_arr('TW', w.tireChoice[2]);
|
---|
| 222 | hRow = w._makeEl(flipBase, {'attr': {'field':'TW','amount':1} });
|
---|
| 223 | for ( i in lineArr ) {
|
---|
| 224 | tmp = (i!=10)?((lineArr[i]===currentChoice[2])?o.themeTireHigh:o.themeTire):o.themeTirePick;
|
---|
| 225 | $('<li>', {'class':'ui-body-'+tmp})
|
---|
| 226 | .html('<span>'+lineArr[i]+' '+w.__('tireYears')+'</span>').appendTo(hRow.find('ul'));
|
---|
| 227 |
|
---|
| 228 | }
|
---|
| 229 | hRow.appendTo(ctrl);
|
---|
| 230 | break;
|
---|
| 231 |
|
---|
| 232 | }
|
---|
| 233 | }
|
---|
| 234 |
|
---|
| 235 | $("<div>", {"class":uid+'flipcenter ui-overlay-shadow'}).css('pointerEvents', 'none').appendTo(w.d.intHTML);
|
---|
| 236 |
|
---|
| 237 | if ( o.useSetButton ) {
|
---|
| 238 | y = $('<div>', {'class':uid+'controls'});
|
---|
| 239 |
|
---|
| 240 | if ( o.useSetButton ) {
|
---|
| 241 | $('<a href="#">'+w.__('tireSet')+'</a>')
|
---|
| 242 | .appendTo(y).buttonMarkup({theme: o.theme, icon: 'check', iconpos: 'left', corners:true, shadow:true})
|
---|
| 243 | .on(o.clickEvent, function(e) {
|
---|
| 244 | e.preventDefault();
|
---|
| 245 | w.d.input.trigger('datebox', {'method':'set', 'value':w._formatter(o.tireOutput,w.tireChoice), 'date':w.tireChoice});
|
---|
| 246 | w.d.input.trigger('datebox', {'method':'close'});
|
---|
| 247 | });
|
---|
| 248 | }
|
---|
| 249 | y.appendTo(w.d.intHTML);
|
---|
| 250 | }
|
---|
| 251 |
|
---|
| 252 | if ( w.wheelExists ) { // Mousewheel operation, if plugin is loaded
|
---|
| 253 | w.d.intHTML.on('mousewheel', '.ui-overlay-shadow', function(e,d) {
|
---|
| 254 | e.preventDefault();
|
---|
| 255 | w._tbox_offset($(this).jqmData('field'), ((d<0)?1:-1)*$(this).jqmData('amount'));
|
---|
| 256 | });
|
---|
| 257 | }
|
---|
| 258 |
|
---|
| 259 | w.d.intHTML.on(w.drag.eStart, 'ul', function(e,f) {
|
---|
| 260 | if ( !w.drag.move ) {
|
---|
| 261 | if ( typeof f !== "undefined" ) { e = f; }
|
---|
| 262 | w.drag.move = true;
|
---|
| 263 | w.drag.target = $(this).find('li').first();
|
---|
| 264 | w.drag.pos = parseInt(w.drag.target.css('marginTop').replace(/px/i, ''),10);
|
---|
| 265 | w.drag.start = w.touch ? e.originalEvent.changedTouches[0].pageY : e.pageY;
|
---|
| 266 | w.drag.end = false;
|
---|
| 267 | e.stopPropagation();
|
---|
| 268 | e.preventDefault();
|
---|
| 269 | }
|
---|
| 270 | });
|
---|
| 271 |
|
---|
| 272 | w.d.intHTML.on(w.drag.eStart, '.'+uid+'flipcenter', function(e) { // Used only on old browsers and IE.
|
---|
| 273 | if ( !w.drag.move ) {
|
---|
| 274 | w.drag.target = w.touch ? e.originalEvent.changedTouches[0].pageX - $(e.currentTarget).offset().left : e.pageX - $(e.currentTarget).offset().left;
|
---|
| 275 | w.drag.tmp = w.d.intHTML.find('.'+uid+'flipcenter').innerWidth() / (( $.inArray('a', w.fldOrder) > -1 && w.__('timeFormat') !== 12 )?w.fldOrder.length-1:w.fldOrder.length);
|
---|
| 276 | $(w.d.intHTML.find('ul').get(parseInt(w.drag.target / w.drag.tmp,10))).trigger(w.drag.eStart,e);
|
---|
| 277 | }
|
---|
| 278 | });
|
---|
| 279 | }
|
---|
| 280 | });
|
---|
| 281 | $.extend( $.mobile.datebox.prototype._drag, {
|
---|
| 282 | // This contains the code that the drag and drop (or touch move) code uses
|
---|
| 283 | 'tirebox': function() {
|
---|
| 284 | var w = this,
|
---|
| 285 | o = this.options,
|
---|
| 286 | g = this.drag;
|
---|
| 287 |
|
---|
| 288 | $(document).on(g.eMove, function(e) {
|
---|
| 289 | if ( g.move && o.mode === 'tirebox' ) {
|
---|
| 290 | g.end = w.touch ? e.originalEvent.changedTouches[0].pageY : e.pageY;
|
---|
| 291 | g.target.css('marginTop', (g.pos + g.end - g.start) + 'px');
|
---|
| 292 | e.preventDefault();
|
---|
| 293 | e.stopPropagation();
|
---|
| 294 | return false;
|
---|
| 295 | }
|
---|
| 296 | });
|
---|
| 297 |
|
---|
| 298 | $(document).on(g.eEnd, function(e) {
|
---|
| 299 | if ( g.move && o.mode === 'tirebox' ) {
|
---|
| 300 | g.move = false;
|
---|
| 301 | if ( g.end !== false ) {
|
---|
| 302 | e.preventDefault();
|
---|
| 303 | e.stopPropagation();
|
---|
| 304 | g.tmp = g.target.parent().parent();
|
---|
| 305 | w._tbox_offset(g.tmp.jqmData('field'), (parseInt((g.start - g.end) / g.target.innerHeight(),10) * g.tmp.jqmData('amount')));
|
---|
| 306 | }
|
---|
| 307 | g.start = false;
|
---|
| 308 | g.end = false;
|
---|
| 309 | }
|
---|
| 310 | });
|
---|
| 311 | }
|
---|
| 312 | });
|
---|
| 313 | })( jQuery );
|
---|