diff --git a/includes/mobile-view-functions.php b/includes/mobile-view-functions.php index f564b01..38a3efc 100644 --- a/includes/mobile-view-functions.php +++ b/includes/mobile-view-functions.php @@ -156,14 +156,13 @@ EOT; //Website function mobile_display_url($element){ //check for error - $error_class = ''; $error_message = ''; $span_required = ''; $guidelines = ''; + global $lang; if(!empty($element->is_error)){ - $error_class = 'class="error"'; - $error_message = "

{$element->error_message}

"; + $error_message = "

{$element->error_message}

"; } //check for required @@ -173,7 +172,7 @@ EOT; //check for guidelines if(!empty($element->guidelines)){ - $guidelines = "

id}\">{$element->guidelines}

"; + $guidelines = "

id}\">{$element->guidelines}

"; } //check for default value @@ -187,12 +186,14 @@ EOT; } $element_markup = << - -
- -
{$guidelines} {$error_message} - + {$element->title} {$span_required} + {$error_message} + {$guidelines} + EOT; return $element_markup; @@ -201,14 +202,13 @@ EOT; //Email function mobile_display_email($element){ //check for error - $error_class = ''; $error_message = ''; $span_required = ''; $guidelines = ''; + global $lang; if(!empty($element->is_error)){ - $error_class = 'class="error"'; - $error_message = "

{$element->error_message}

"; + $error_message = "

{$element->error_message}

"; } //check for required @@ -218,7 +218,7 @@ EOT; //check for guidelines if(!empty($element->guidelines)){ - $guidelines = "

id}\">{$element->guidelines}

"; + $guidelines = "

id}\">{$element->guidelines}

"; } //check for populated value, if exist, use it instead default_value @@ -227,12 +227,14 @@ EOT; } $element_markup = << - -
- -
{$guidelines} {$error_message} - + {$element->title} {$span_required} + {$error_message} + {$guidelines} + EOT; return $element_markup; @@ -309,14 +311,13 @@ EOT; //Phone - Simple function mobile_display_simple_phone($element){ //check for error - $error_class = ''; $error_message = ''; $span_required = ''; $guidelines = ''; + global $lang; if(!empty($element->is_error)){ - $error_class = 'class="error"'; - $error_message = "

{$element->error_message}

"; + $error_message = "

{$element->error_message}

"; } //check for required @@ -326,7 +327,7 @@ EOT; //check for guidelines if(!empty($element->guidelines)){ - $guidelines = "

id}\">{$element->guidelines}

"; + $guidelines = "

id}\">{$element->guidelines}

"; } //check for populated value @@ -335,12 +336,14 @@ EOT; } $element_markup = << - -
- -
{$guidelines} {$error_message} - + {$element->title} {$span_required} + {$error_message} + {$guidelines} +
    +
  • + +
  • +
EOT; return $element_markup; @@ -351,15 +354,13 @@ EOT; //Date - Normal function mobile_display_date($element){ //check for error - $error_class = ''; $error_message = ''; $span_required = ''; $guidelines = ''; global $lang; if(!empty($element->is_error)){ - $error_class = 'class="error"'; - $error_message = "

{$element->error_message}

"; + $error_message = "

{$element->error_message}

"; } //check for required @@ -369,7 +370,12 @@ EOT; //check for guidelines if(!empty($element->guidelines)){ - $guidelines = "

id}\">{$element->guidelines}

"; + $guidelines = "

id}\">{$element->guidelines}

"; + } + + //check for populated value, if exist, use it instead default_value + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; } $machform_path = ''; @@ -379,36 +385,19 @@ EOT; $element_markup = << - - - / - - - - / - - - - - - - - - Pick a date. - - - {$guidelines} {$error_message} - + {$element->title} {$span_required} + {$error_message} + {$guidelines} + EOT; return $element_markup; @@ -417,15 +406,13 @@ EOT; //Date - Normal function mobile_display_europe_date($element){ //check for error - $error_class = ''; $error_message = ''; $span_required = ''; $guidelines = ''; global $lang; if(!empty($element->is_error)){ - $error_class = 'class="error"'; - $error_message = "

{$element->error_message}

"; + $error_message = "

{$element->error_message}

"; } //check for required @@ -435,45 +422,29 @@ EOT; //check for guidelines if(!empty($element->guidelines)){ - $guidelines = "

id}\">{$element->guidelines}

"; + $guidelines = "

id}\">{$element->guidelines}

"; } - $machform_path = ''; - if(!empty($element->machform_path)){ - $machform_path = $element->machform_path; + //check for populated value, if exist, use it instead default_value + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; } + $element_markup = << - - - / - - - - / - - - - - - - - - Pick a date. - - - {$guidelines} {$error_message} - + {$element->title} {$span_required} + {$error_message} + {$guidelines} + EOT; return $element_markup; @@ -483,14 +454,13 @@ EOT; //Multiple Choice function mobile_display_radio($element){ //check for error - $error_class = ''; $error_message = ''; $span_required = ''; $guidelines = ''; + global $lang; if(!empty($element->is_error)){ - $error_class = 'class="error"'; - $error_message = "

{$element->error_message}

"; + $error_message = "

{$element->error_message}

"; } //check for required @@ -500,7 +470,7 @@ EOT; //check for guidelines if(!empty($element->guidelines)){ - $guidelines = "

id}\">{$element->guidelines}

"; + $guidelines = "

id}\">{$element->guidelines}

"; } $option_markup = ''; @@ -527,17 +497,19 @@ EOT; } } - $option_markup .= "id}_{$option->id}\" name=\"element_{$element->id}\" class=\"element radio\" type=\"radio\" value=\"{$option->id}\" {$checked} />\n"; - $option_markup .= "\n"; + $option_markup .= "
  • \n"; + $option_markup .= "".$option->option."\n"; + $option_markup .= "id}_{$option->id}\" name=\"element_{$element->id}\" type=\"radio\" value=\"{$option->id}\" {$checked} />\n"; + $option_markup .= "
  • \n"; } $element_markup = << - - + {$element->title} {$span_required} + {$error_message} + {$guidelines} +
      {$option_markup} - {$guidelines} {$error_message} - +
    EOT; return $element_markup; @@ -626,14 +598,13 @@ EOT; //Dropdown function mobile_display_select($element){ //check for error - $error_class = ''; $error_message = ''; $span_required = ''; $guidelines = ''; + global $lang; if(!empty($element->is_error)){ - $error_class = 'class="error"'; - $error_message = "

    {$element->error_message}

    "; + $error_message = "

    {$element->error_message}

    "; } //check for required @@ -643,10 +614,10 @@ EOT; //check for guidelines if(!empty($element->guidelines)){ - $guidelines = "

    id}\">{$element->guidelines}

    "; + $guidelines = "

    id}\">{$element->guidelines}

    "; } - $option_markup = ''; + $option_markup = "
  • \n"; + $element_markup = << - -
    - -
    {$guidelines} {$error_message} - + EOT; return $element_markup; @@ -801,15 +765,13 @@ EOT; //Time function mobile_display_time($element){ //check for error - $error_class = ''; $error_message = ''; $span_required = ''; $guidelines = ''; global $lang; if(!empty($element->is_error)){ - $error_class = 'class="error"'; - $error_message = "

    {$element->error_message}

    "; + $error_message = "

    {$element->error_message}

    "; } //check for required @@ -819,9 +781,10 @@ EOT; //check for guidelines if(!empty($element->guidelines)){ - $guidelines = "

    id}\">{$element->guidelines}

    "; + $guidelines = "

    id}\">{$element->guidelines}

    "; } + if(!empty($element->populated_value['element_'.$element->id.'_4']['default_value'])){ if($element->populated_value['element_'.$element->id.'_4']['default_value'] == 'AM'){ $selected_am = 'selected'; @@ -844,25 +807,20 @@ EOT; } $element_markup = << - - - : - - - - {$seconds_separator} - - - {$seconds_markup} - - - - {$guidelines} {$error_message} - + {$element->title} {$span_required} + {$error_message} + {$guidelines} +
      +
    • + {$element->title} + HH:MM:SS + + + + + +
    • +
    EOT; return $element_markup; @@ -1931,7 +1889,7 @@ EOT; //If you would like to remove the "Powered by MachForm" link, please contact us at customer.service@appnitro.com before doing so $form_markup = << + @@ -1940,7 +1898,10 @@ EOT; + + + {$form->name} @@ -2334,7 +2295,7 @@ EOT; } $form_markup = << + @@ -2344,6 +2305,7 @@ EOT; + {$form->name} @@ -2494,7 +2456,7 @@ EOT; } $form_markup = << + diff --git a/mobile/apple/css/forms.css b/mobile/apple/css/forms.css index d5d8145..a00237d 100644 --- a/mobile/apple/css/forms.css +++ b/mobile/apple/css/forms.css @@ -70,3 +70,12 @@ textarea.large width:98%; height:7.5em; } + + +.datefield { + color:blue; + float:right; + position:relative; + top:12px; + right:10px; +} diff --git a/mobile/apple/css/spinningwheel.css b/mobile/apple/css/spinningwheel.css new file mode 100644 index 0000000..53c5df3 --- /dev/null +++ b/mobile/apple/css/spinningwheel.css @@ -0,0 +1,92 @@ +#sw-wrapper { + position:absolute; z-index:1000; + left:0; + width:100%; + font-family:helvetica, sans-serif; + background:rgba(0,0,0,0.7); + text-align:left; +} + +#sw-header { + position:relative; + width:100%; height:43px; + border-top:1px solid #000; border-bottom:1px solid #000; + background:url(../images/sw-header.png) 0 0 repeat-x; + opacity: 0.9; +} + +#sw-cancel, #sw-done { + position:absolute; + top:7px; + height:20px; line-height:20px; + padding:0 5px; margin:0; + border-width:5px; + font-size:12px; font-weight:bold; + text-shadow:rgba(0,0,0,0.8) 0 -1px 0; + color:#fff; +} + +#sw-cancel { + left:7px; + float:left; + -webkit-border-image:url(../images/sw-button-cancel.png) 5; +} + +#sw-done { + right:7px; + float:right; + -webkit-border-image:url(../images/sw-button-done.png) 5; +} + +.sw-pressed { opacity:0.4; } + +#sw-slots-wrapper { + position:relative; z-index:999; + display:block; + height:215px; + padding:0 11px; + overflow:hidden; +} + +#sw-slots { + display:table; + width:100%; + background:#fcfcfc; +} + +#sw-slots div { + display:table-cell; + height:100%; + padding-top:86px; + border-left:2px solid #0d0e0f; + background-color:#fcfcfc; + background-image: url(../images/sw-slot-border.png); + background-position: 0 0, 100% 0; + background-repeat: repeat-y; +} + +#sw-slots div:first-child { border:0; } + +#sw-slots ul { + padding:0 0 85px 0; margin:0; + list-style:none; +} + +#sw-slots .sw-right { text-align:right; } +#sw-slots .sw-shrink { width:1%; } +#sw-slots .sw-readonly { background:#ddd; } + +#sw-slots li { + padding:0 8px; + height:44px; + overflow:hidden; + font:bold 24px/44px Helvetica,sans-serif; +} + +#sw-frame { + position:absolute; z-index:1000; + left:0; right:0; bottom:0; + height:183px; + border-width:16px; + -webkit-border-image:url(../images/sw-alpha.png) 16; +} \ No newline at end of file diff --git a/mobile/apple/images/sw-alpha.png b/mobile/apple/images/sw-alpha.png new file mode 100644 index 0000000..b80659a Binary files /dev/null and b/mobile/apple/images/sw-alpha.png differ diff --git a/mobile/apple/images/sw-button-cancel.png b/mobile/apple/images/sw-button-cancel.png new file mode 100644 index 0000000..cea9e38 Binary files /dev/null and b/mobile/apple/images/sw-button-cancel.png differ diff --git a/mobile/apple/images/sw-button-done.png b/mobile/apple/images/sw-button-done.png new file mode 100644 index 0000000..a1e8f32 Binary files /dev/null and b/mobile/apple/images/sw-button-done.png differ diff --git a/mobile/apple/images/sw-header.png b/mobile/apple/images/sw-header.png new file mode 100644 index 0000000..db4ec27 Binary files /dev/null and b/mobile/apple/images/sw-header.png differ diff --git a/mobile/apple/images/sw-slot-border.png b/mobile/apple/images/sw-slot-border.png new file mode 100644 index 0000000..d9f6026 Binary files /dev/null and b/mobile/apple/images/sw-slot-border.png differ diff --git a/mobile/apple/javascript/calendar.js b/mobile/apple/javascript/calendar.js new file mode 100644 index 0000000..f12043a --- /dev/null +++ b/mobile/apple/javascript/calendar.js @@ -0,0 +1,77 @@ +function openTimePicker(elem1,elem2,elem3,elem4,elem5) { + var now = new Time(); + var hours = { }; + var minutes = { }; + var seconds = { }; + + for( var i = 0; i < 24; i += 1 ) { + hours[i] = i; + } + + for( i = 0; i < 60; i += 1 ) { + minutes[i] = i; + seconds[i] = i; + } + + alert('jur'); + + SpinningWheel.addSlot(hours, 'right', now.getHours()); + SpinningWheel.addSlot(minutes, 'right', now.getMinutes()); + SpinningWheel.addSlot(seconds, 'right', now.getSeconds()); + + SpinningWheel.setCancelAction(function(){ + //document.getElementById(elem1).innerHTML = "cancelled"; + }); + + SpinningWheel.setDoneAction(function(){ + var results = SpinningWheel.getSelectedValues(); + + var ap = "AM"; + if (results.keys[0] > 11) { ap = "PM"; } + if (results.keys[0] > 12) { results.keys[0] = results.keys[0] - 12; } + if (results.keys[0] == 0) { results.keys[0] = 12; } + + document.getElementById(elem1).innerHTML = results.values.join(' '); + document.getElementById(elem2).value = results.keys.join(' '); + document.getElementById(elem3).value = results.keys[0]; + document.getElementById(elem4).value = results.keys[1]; + document.getElementById(elem5).value = results.keys[2]; + document.getElementById(elem6).value = ap; + }); + + SpinningWheel.open(); +} + +function openCalendar(elem1,elem2,elem3,elem4,elem5) { + var now = new Date(); + var days = { }; + var years = { }; + var months = { 1: 'Ene', 2: 'Feb', 3: 'Mar', 4: 'Abr', 5: 'May', 6: 'Jun', 7: 'Jul', 8: 'Ago', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dic' }; + + for( var i = 1; i < 32; i += 1 ) { + days[i] = i; + } + + for( i = now.getFullYear()-10; i < now.getFullYear()+10; i += 1 ) { + years[i] = i; + } + + SpinningWheel.addSlot(days, 'right', now.getDate()); + SpinningWheel.addSlot(months, '', now.getMonth()); + SpinningWheel.addSlot(years, 'right', now.getFullYear()); + + SpinningWheel.setCancelAction(function(){ + //document.getElementById(elem1).innerHTML = "cancelled"; + }); + SpinningWheel.setDoneAction(function(){ + var results = SpinningWheel.getSelectedValues(); + document.getElementById(elem1).innerHTML = results.values.join(' '); + document.getElementById(elem2).value = results.keys.join(' '); + document.getElementById(elem3).value = results.keys[0]; + document.getElementById(elem4).value = results.keys[1]; + document.getElementById(elem5).value = results.keys[2]; + }); + + SpinningWheel.open(); +} + diff --git a/mobile/apple/javascript/spinningwheel.js b/mobile/apple/javascript/spinningwheel.js new file mode 100644 index 0000000..c71d5e6 --- /dev/null +++ b/mobile/apple/javascript/spinningwheel.js @@ -0,0 +1,492 @@ +/** + * + * Find more about the Spinning Wheel function at + * http://cubiq.org/spinning-wheel-on-webkit-for-iphone-ipod-touch/11 + * + * Copyright (c) 2009 Matteo Spinelli, http://cubiq.org/ + * Released under MIT license + * http://cubiq.org/dropbox/mit-license.txt + * + * Version 1.4 - Last updated: 2009.07.09 + * + */ + +var SpinningWheel = { + cellHeight: 44, + friction: 0.003, + slotData: [], + + + /** + * + * Event handler + * + */ + + handleEvent: function (e) { + if (e.type == 'touchstart') { + this.lockScreen(e); + if (e.currentTarget.id == 'sw-cancel' || e.currentTarget.id == 'sw-done') { + this.tapDown(e); + } else if (e.currentTarget.id == 'sw-frame') { + this.scrollStart(e); + } + } else if (e.type == 'touchmove') { + this.lockScreen(e); + + if (e.currentTarget.id == 'sw-cancel' || e.currentTarget.id == 'sw-done') { + this.tapCancel(e); + } else if (e.currentTarget.id == 'sw-frame') { + this.scrollMove(e); + } + } else if (e.type == 'touchend') { + if (e.currentTarget.id == 'sw-cancel' || e.currentTarget.id == 'sw-done') { + this.tapUp(e); + } else if (e.currentTarget.id == 'sw-frame') { + this.scrollEnd(e); + } + } else if (e.type == 'webkitTransitionEnd') { + if (e.target.id == 'sw-wrapper') { + this.destroy(); + } else { + this.backWithinBoundaries(e); + } + } else if (e.type == 'orientationchange') { + this.onOrientationChange(e); + } else if (e.type == 'scroll') { + this.onScroll(e); + } + }, + + + /** + * + * Global events + * + */ + + onOrientationChange: function (e) { + window.scrollTo(0, 0); + this.swWrapper.style.top = window.innerHeight + window.pageYOffset + 'px'; + this.calculateSlotsWidth(); + }, + + onScroll: function (e) { + this.swWrapper.style.top = window.innerHeight + window.pageYOffset + 'px'; + }, + + lockScreen: function (e) { + e.preventDefault(); + e.stopPropagation(); + }, + + + /** + * + * Initialization + * + */ + + reset: function () { + this.slotEl = []; + + this.activeSlot = null; + + this.swWrapper = undefined; + this.swSlotWrapper = undefined; + this.swSlots = undefined; + this.swFrame = undefined; + }, + + calculateSlotsWidth: function () { + var div = this.swSlots.getElementsByTagName('div'); + for (var i = 0; i < div.length; i += 1) { + this.slotEl[i].slotWidth = div[i].offsetWidth; + } + }, + + create: function () { + var i, l, out, ul, div; + + this.reset(); // Initialize object variables + + // Create the Spinning Wheel main wrapper + div = document.createElement('div'); + div.id = 'sw-wrapper'; + div.style.top = window.innerHeight + window.pageYOffset + 'px'; // Place the SW down the actual viewing screen + div.style.webkitTransitionProperty = '-webkit-transform'; + div.innerHTML = '
    Cancelar
    Guardar
    '; + + document.body.appendChild(div); + + this.swWrapper = div; // The SW wrapper + this.swSlotWrapper = document.getElementById('sw-slots-wrapper'); // Slots visible area + this.swSlots = document.getElementById('sw-slots'); // Pseudo table element (inner wrapper) + this.swFrame = document.getElementById('sw-frame'); // The scrolling controller + + // Create HTML slot elements + for (l = 0; l < this.slotData.length; l += 1) { + // Create the slot + ul = document.createElement('ul'); + out = ''; + for (i in this.slotData[l].values) { + out += '
  • ' + this.slotData[l].values[i] + '<' + '/li>'; + } + ul.innerHTML = out; + + div = document.createElement('div'); // Create slot container + div.className = this.slotData[l].style; // Add styles to the container + div.appendChild(ul); + + // Append the slot to the wrapper + this.swSlots.appendChild(div); + + ul.slotPosition = l; // Save the slot position inside the wrapper + ul.slotYPosition = 0; + ul.slotWidth = 0; + ul.slotMaxScroll = this.swSlotWrapper.clientHeight - ul.clientHeight - 86; + ul.style.webkitTransitionTimingFunction = 'cubic-bezier(0, 0, 0.2, 1)'; // Add default transition + + this.slotEl.push(ul); // Save the slot for later use + + // Place the slot to its default position (if other than 0) + if (this.slotData[l].defaultValue) { + this.scrollToValue(l, this.slotData[l].defaultValue); + } + } + + this.calculateSlotsWidth(); + + // Global events + document.addEventListener('touchstart', this, false); // Prevent page scrolling + document.addEventListener('touchmove', this, false); // Prevent page scrolling + window.addEventListener('orientationchange', this, true); // Optimize SW on orientation change + window.addEventListener('scroll', this, true); // Reposition SW on page scroll + + // Cancel/Done buttons events + document.getElementById('sw-cancel').addEventListener('touchstart', this, false); + document.getElementById('sw-done').addEventListener('touchstart', this, false); + + // Add scrolling to the slots + this.swFrame.addEventListener('touchstart', this, false); + }, + + open: function () { + this.create(); + + this.swWrapper.style.webkitTransitionTimingFunction = 'ease-out'; + this.swWrapper.style.webkitTransitionDuration = '400ms'; + this.swWrapper.style.webkitTransform = 'translate3d(0, -260px, 0)'; + }, + + + /** + * + * Unload + * + */ + + destroy: function () { + this.swWrapper.removeEventListener('webkitTransitionEnd', this, false); + + this.swFrame.removeEventListener('touchstart', this, false); + + document.getElementById('sw-cancel').removeEventListener('touchstart', this, false); + document.getElementById('sw-done').removeEventListener('touchstart', this, false); + + document.removeEventListener('touchstart', this, false); + document.removeEventListener('touchmove', this, false); + window.removeEventListener('orientationchange', this, true); + window.removeEventListener('scroll', this, true); + + this.slotData = []; + this.cancelAction = function () { + return false; + }; + + this.cancelDone = function () { + return true; + }; + + this.reset(); + + document.body.removeChild(document.getElementById('sw-wrapper')); + }, + + close: function () { + this.swWrapper.style.webkitTransitionTimingFunction = 'ease-in'; + this.swWrapper.style.webkitTransitionDuration = '400ms'; + this.swWrapper.style.webkitTransform = 'translate3d(0, 0, 0)'; + + this.swWrapper.addEventListener('webkitTransitionEnd', this, false); + }, + + + /** + * + * Generic methods + * + */ + + addSlot: function (values, style, defaultValue) { + if (!style) { + style = ''; + } + + style = style.split(' '); + + for (var i = 0; i < style.length; i += 1) { + style[i] = 'sw-' + style[i]; + } + + style = style.join(' '); + + var obj = { 'values': values, 'style': style, 'defaultValue': defaultValue }; + this.slotData.push(obj); + }, + + getSelectedValues: function () { + var index, count, + i, l, + keys = [], values = []; + + for (i in this.slotEl) { + // Remove any residual animation + this.slotEl[i].removeEventListener('webkitTransitionEnd', this, false); + this.slotEl[i].style.webkitTransitionDuration = '0'; + + if (this.slotEl[i].slotYPosition > 0) { + this.setPosition(i, 0); + } else if (this.slotEl[i].slotYPosition < this.slotEl[i].slotMaxScroll) { + this.setPosition(i, this.slotEl[i].slotMaxScroll); + } + + index = -Math.round(this.slotEl[i].slotYPosition / this.cellHeight); + + count = 0; + for (l in this.slotData[i].values) { + if (count == index) { + keys.push(l); + values.push(this.slotData[i].values[l]); + break; + } + + count += 1; + } + } + + return { 'keys': keys, 'values': values }; + }, + + + /** + * + * Rolling slots + * + */ + + setPosition: function (slot, pos) { + this.slotEl[slot].slotYPosition = pos; + this.slotEl[slot].style.webkitTransform = 'translate3d(0, ' + pos + 'px, 0)'; + }, + + scrollStart: function (e) { + // Find the clicked slot + var xPos = e.targetTouches[0].clientX - this.swSlots.offsetLeft; // Clicked position minus left offset (should be 11px) + + // Find tapped slot + var slot = 0; + for (var i = 0; i < this.slotEl.length; i += 1) { + slot += this.slotEl[i].slotWidth; + + if (xPos < slot) { + this.activeSlot = i; + break; + } + } + + // If slot is readonly do nothing + if (this.slotData[this.activeSlot].style.match('readonly')) { + this.swFrame.removeEventListener('touchmove', this, false); + this.swFrame.removeEventListener('touchend', this, false); + return false; + } + + this.slotEl[this.activeSlot].removeEventListener('webkitTransitionEnd', this, false); // Remove transition event (if any) + this.slotEl[this.activeSlot].style.webkitTransitionDuration = '0'; // Remove any residual transition + + // Stop and hold slot position + var theTransform = window.getComputedStyle(this.slotEl[this.activeSlot]).webkitTransform; + theTransform = new WebKitCSSMatrix(theTransform).m42; + if (theTransform != this.slotEl[this.activeSlot].slotYPosition) { + this.setPosition(this.activeSlot, theTransform); + } + + this.startY = e.targetTouches[0].clientY; + this.scrollStartY = this.slotEl[this.activeSlot].slotYPosition; + this.scrollStartTime = e.timeStamp; + + this.swFrame.addEventListener('touchmove', this, false); + this.swFrame.addEventListener('touchend', this, false); + + return true; + }, + + scrollMove: function (e) { + var topDelta = e.targetTouches[0].clientY - this.startY; + + if (this.slotEl[this.activeSlot].slotYPosition > 0 || this.slotEl[this.activeSlot].slotYPosition < this.slotEl[this.activeSlot].slotMaxScroll) { + topDelta /= 2; + } + + this.setPosition(this.activeSlot, this.slotEl[this.activeSlot].slotYPosition + topDelta); + this.startY = e.targetTouches[0].clientY; + + // Prevent slingshot effect + if (e.timeStamp - this.scrollStartTime > 80) { + this.scrollStartY = this.slotEl[this.activeSlot].slotYPosition; + this.scrollStartTime = e.timeStamp; + } + }, + + scrollEnd: function (e) { + this.swFrame.removeEventListener('touchmove', this, false); + this.swFrame.removeEventListener('touchend', this, false); + + // If we are outside of the boundaries, let's go back to the sheepfold + if (this.slotEl[this.activeSlot].slotYPosition > 0 || this.slotEl[this.activeSlot].slotYPosition < this.slotEl[this.activeSlot].slotMaxScroll) { + this.scrollTo(this.activeSlot, this.slotEl[this.activeSlot].slotYPosition > 0 ? 0 : this.slotEl[this.activeSlot].slotMaxScroll); + return false; + } + + // Lame formula to calculate a fake deceleration + var scrollDistance = this.slotEl[this.activeSlot].slotYPosition - this.scrollStartY; + + // The drag session was too short + if (scrollDistance < this.cellHeight / 1.5 && scrollDistance > -this.cellHeight / 1.5) { + if (this.slotEl[this.activeSlot].slotYPosition % this.cellHeight) { + this.scrollTo(this.activeSlot, Math.round(this.slotEl[this.activeSlot].slotYPosition / this.cellHeight) * this.cellHeight, '100ms'); + } + + return false; + } + + var scrollDuration = e.timeStamp - this.scrollStartTime; + + var newDuration = (2 * scrollDistance / scrollDuration) / this.friction; + var newScrollDistance = (this.friction / 2) * (newDuration * newDuration); + + if (newDuration < 0) { + newDuration = -newDuration; + newScrollDistance = -newScrollDistance; + } + + var newPosition = this.slotEl[this.activeSlot].slotYPosition + newScrollDistance; + + if (newPosition > 0) { + // Prevent the slot to be dragged outside the visible area (top margin) + newPosition /= 2; + newDuration /= 3; + + if (newPosition > this.swSlotWrapper.clientHeight / 4) { + newPosition = this.swSlotWrapper.clientHeight / 4; + } + } else if (newPosition < this.slotEl[this.activeSlot].slotMaxScroll) { + // Prevent the slot to be dragged outside the visible area (bottom margin) + newPosition = (newPosition - this.slotEl[this.activeSlot].slotMaxScroll) / 2 + this.slotEl[this.activeSlot].slotMaxScroll; + newDuration /= 3; + + if (newPosition < this.slotEl[this.activeSlot].slotMaxScroll - this.swSlotWrapper.clientHeight / 4) { + newPosition = this.slotEl[this.activeSlot].slotMaxScroll - this.swSlotWrapper.clientHeight / 4; + } + } else { + newPosition = Math.round(newPosition / this.cellHeight) * this.cellHeight; + } + + this.scrollTo(this.activeSlot, Math.round(newPosition), Math.round(newDuration) + 'ms'); + + return true; + }, + + scrollTo: function (slotNum, dest, runtime) { + this.slotEl[slotNum].style.webkitTransitionDuration = runtime ? runtime : '100ms'; + this.setPosition(slotNum, dest ? dest : 0); + + // If we are outside of the boundaries go back to the sheepfold + if (this.slotEl[slotNum].slotYPosition > 0 || this.slotEl[slotNum].slotYPosition < this.slotEl[slotNum].slotMaxScroll) { + this.slotEl[slotNum].addEventListener('webkitTransitionEnd', this, false); + } + }, + + scrollToValue: function (slot, value) { + var yPos, count, i; + + this.slotEl[slot].removeEventListener('webkitTransitionEnd', this, false); + this.slotEl[slot].style.webkitTransitionDuration = '0'; + + count = 0; + for (i in this.slotData[slot].values) { + if (i == value) { + yPos = count * this.cellHeight; + this.setPosition(slot, yPos); + break; + } + + count -= 1; + } + }, + + backWithinBoundaries: function (e) { + e.target.removeEventListener('webkitTransitionEnd', this, false); + + this.scrollTo(e.target.slotPosition, e.target.slotYPosition > 0 ? 0 : e.target.slotMaxScroll, '150ms'); + return false; + }, + + + /** + * + * Buttons + * + */ + + tapDown: function (e) { + e.currentTarget.addEventListener('touchmove', this, false); + e.currentTarget.addEventListener('touchend', this, false); + e.currentTarget.className = 'sw-pressed'; + }, + + tapCancel: function (e) { + e.currentTarget.removeEventListener('touchmove', this, false); + e.currentTarget.removeEventListener('touchend', this, false); + e.currentTarget.className = ''; + }, + + tapUp: function (e) { + this.tapCancel(e); + + if (e.currentTarget.id == 'sw-cancel') { + this.cancelAction(); + } else { + this.doneAction(); + } + + this.close(); + }, + + setCancelAction: function (action) { + this.cancelAction = action; + }, + + setDoneAction: function (action) { + this.doneAction = action; + }, + + cancelAction: function () { + return false; + }, + + cancelDone: function () { + return true; + } +}; \ No newline at end of file