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