From 8ec3ae594d6ff06f1642a5e719766bf38ad074d5 Mon Sep 17 00:00:00 2001 From: John Bender Date: Wed, 22 Dec 2010 16:30:55 -0800 Subject: [PATCH] added keyCodes, Home and End working for range slider --- js/jquery.mobile.core.js | 128 +++++++++++++++++++----------- js/jquery.mobile.forms.slider.js | 130 ++++++++++++++++++++++++++----- 2 files changed, 192 insertions(+), 66 deletions(-) diff --git a/js/jquery.mobile.core.js b/js/jquery.mobile.core.js index 8de48421..593ab91a 100644 --- a/js/jquery.mobile.core.js +++ b/js/jquery.mobile.core.js @@ -8,68 +8,104 @@ */ (function( $, window, undefined ) { - + //jQuery.mobile configurable options $.extend( $.mobile, { - - //define the url parameter used for referencing widget-generated sub-pages. + + //define the url parameter used for referencing widget-generated sub-pages. //Translates to to example.html&ui-page=subpageIdentifier //hash segment before &ui-page= is used to make Ajax request subPageUrlKey: 'ui-page', - - //anchor links with a data-rel, or pages with a data-role, that match these selectors will be untrackable in history + + //anchor links with a data-rel, or pages with a data-role, that match these selectors will be untrackable in history //(no change in URL, not bookmarkable) nonHistorySelectors: 'dialog', - + //class assigned to page currently in view, and during transitions activePageClass: 'ui-page-active', - + //class used for "active" button state, from CSS framework activeBtnClass: 'ui-btn-active', - + //automatically handle link clicks through Ajax, when possible ajaxLinksEnabled: true, - + //automatically handle form submissions through Ajax, when possible ajaxFormsEnabled: true, - + //set default transition - 'none' for no transitions defaultTransition: 'slide', - + //show loading message during Ajax requests //if false, message will not appear, but loading classes will still be toggled on html el loadingMessage: "loading", - + //configure meta viewport tag's content attr: metaViewportContent: "width=device-width, minimum-scale=1, maximum-scale=1", - + //support conditions that must be met in order to proceed gradeA: function(){ return $.support.mediaquery; + }, + + //TODO might be useful upstream in jquery itself ? + keyCode: { + ALT: 18, + BACKSPACE: 8, + CAPS_LOCK: 20, + COMMA: 188, + COMMAND: 91, + COMMAND_LEFT: 91, // COMMAND + COMMAND_RIGHT: 93, + CONTROL: 17, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + INSERT: 45, + LEFT: 37, + MENU: 93, // COMMAND_RIGHT + NUMPAD_ADD: 107, + NUMPAD_DECIMAL: 110, + NUMPAD_DIVIDE: 111, + NUMPAD_ENTER: 108, + NUMPAD_MULTIPLY: 106, + NUMPAD_SUBTRACT: 109, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SHIFT: 16, + SPACE: 32, + TAB: 9, + UP: 38, + WINDOWS: 91 // COMMAND } }); - - + + //trigger mobileinit event - useful hook for configuring $.mobile settings before they're used $( window.document ).trigger('mobileinit'); -//support conditions +//support conditions //if device support condition(s) aren't met, leave things as they are -> a basic, usable experience, //otherwise, proceed with the enhancements if ( !$.mobile.gradeA() ) { return; - } + } //define vars for interal use var $window = $(window), $html = $('html'), $head = $('head'), - + //loading div which appears during Ajax requests //will not appear if $.mobile.loadingMessage is false - $loader = $.mobile.loadingMessage ? + $loader = $.mobile.loadingMessage ? $('
'+ ''+ '

'+ $.mobile.loadingMessage +'

'+ @@ -78,16 +114,16 @@ //add mobile, initial load "rendering" classes to docEl - $html.addClass('ui-mobile ui-mobile-rendering'); - - -//define & prepend meta viewport tag, if content is defined - $.mobile.metaViewportContent ? $("", { name: "viewport", content: $.mobile.metaViewportContent}).prependTo( $head ) : undefined; + $html.addClass('ui-mobile ui-mobile-rendering'); + + +//define & prepend meta viewport tag, if content is defined + $.mobile.metaViewportContent ? $("", { name: "viewport", content: $.mobile.metaViewportContent}).prependTo( $head ) : undefined; + - //expose some core utilities $.extend($.mobile, { - + // turn on/off page loading message. pageLoading: function ( done ) { if ( done ) { @@ -95,57 +131,57 @@ } else { if( $.mobile.loadingMessage ){ $loader.appendTo($.mobile.pageContainer).css({top: $(window).scrollTop() + 75}); - } + } $html.addClass( "ui-loading" ); } }, - + //scroll page vertically: scroll to 0 to hide iOS address bar, or pass a Y value silentScroll: function( ypos ) { // prevent scrollstart and scrollstop events $.event.special.scrollstart.enabled = false; setTimeout(function() { window.scrollTo( 0, ypos || 0 ); - },20); + },20); setTimeout(function() { $.event.special.scrollstart.enabled = true; }, 150 ); } - }); - - + }); + + //dom-ready inits $(function(){ - - //find present pages + + //find present pages var $pages = $("[data-role='page']"); - + $pages.each(function(){ $(this).attr('data-url', $(this).attr('id')); }); - + //set up active page $.mobile.startPage = $.mobile.activePage = $pages.first(); - + //set page container $.mobile.pageContainer = $.mobile.startPage.parent().addClass('ui-mobile-viewport'); - + //cue page loading message $.mobile.pageLoading(); - + //initialize all pages present $pages.page(); - + //trigger a new hashchange, hash or not $window.trigger( "hashchange", [ true ] ); - + //remove rendering class $html.removeClass('ui-mobile-rendering'); }); - - -//window load event + + +//window load event //hide iOS browser chrome on load - $window.load( $.mobile.silentScroll ); - + $window.load( $.mobile.silentScroll ); + })( jQuery, this ); diff --git a/js/jquery.mobile.forms.slider.js b/js/jquery.mobile.forms.slider.js index 7260d2ef..23270dc4 100644 --- a/js/jquery.mobile.forms.slider.js +++ b/js/jquery.mobile.forms.slider.js @@ -3,7 +3,7 @@ * Copyright (c) jQuery Project * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license -*/ +*/ (function($, undefined ) { $.widget( "mobile.slider", $.mobile.widget, { options: { @@ -11,19 +11,19 @@ $.widget( "mobile.slider", $.mobile.widget, { trackTheme: null, disabled: false }, - _create: function(){ + _create: function(){ var self = this, control = this.element, - - parentTheme = control.parents('[class*=ui-bar-],[class*=ui-body-]').eq(0), - + + parentTheme = control.parents('[class*=ui-bar-],[class*=ui-body-]').eq(0), + parentTheme = parentTheme.length ? parentTheme.attr('class').match(/ui-(bar|body)-([a-z])/)[2] : 'c', - + theme = this.options.theme ? this.options.theme : parentTheme, - + trackTheme = this.options.trackTheme ? this.options.trackTheme : parentTheme, - + cType = control[0].nodeName.toLowerCase(), selectClass = (cType == 'select') ? 'ui-slider-switch' : '', controlID = control.attr('id'), @@ -56,32 +56,32 @@ $.widget( "mobile.slider", $.mobile.widget, { if(cType == 'select'){ slider.wrapInner('
'); var options = control.find('option'); - + control.find('option').each(function(i){ var side = (i==0) ?'b':'a', corners = (i==0) ? 'right' :'left', theme = (i==0) ? ' ui-btn-down-' + trackTheme :' ui-btn-active'; - $('
').prependTo(slider); + $('
').prependTo(slider); $(''+$(this).text()+'').prependTo(handle); }); - - } - + + } + label.addClass('ui-slider'); - + control .addClass((cType == 'input') ? 'ui-slider-input' : 'ui-slider-switch') .keyup(function(){ self.refresh( $(this).val() ); }); - + $(document).bind($.support.touch ? "touchmove" : "mousemove", function(event){ if ( self.dragging ) { self.refresh( event ); return false; } }); - + slider .bind($.support.touch ? "touchstart" : "mousedown", function(event){ self.dragging = true; @@ -91,9 +91,9 @@ $.widget( "mobile.slider", $.mobile.widget, { self.refresh( event ); return false; }); - + slider - .add(document) + .add(document) .bind($.support.touch ? "touchend" : "mouseup", function(){ if ( self.dragging ) { self.dragging = false; @@ -116,6 +116,96 @@ $.widget( "mobile.slider", $.mobile.widget, { }); slider.insertAfter(control); + + // NOTE required to set focus properly :( + this.handle + .bind($.support.touch ? "touchstart" : "mousedown", function(){ + $(this).focus(); + }); + + this.handle.bind('keydown', function( event ) { + var ret = true, + index = $( this ).data( "aria-valuenow" ), + allowed, + curVal, + newVal, + step; + + if ( self.options.disabled ) { + return; + } + + switch ( event.keyCode ) { + case $.mobile.keyCode.HOME: + case $.mobile.keyCode.END: + case $.mobile.keyCode.PAGE_UP: + case $.mobile.keyCode.PAGE_DOWN: + case $.mobile.keyCode.UP: + case $.mobile.keyCode.RIGHT: + case $.mobile.keyCode.DOWN: + case $.mobile.keyCode.LEFT: + ret = false; + if ( !self._keySliding ) { + self._keySliding = true; + $( this ).addClass( "ui-state-active" ); + // allowed = self._start( event, index ); + // if ( allowed === false ) { + // return; + // } + } + break; + } + + // step = self.options.step; + // if ( self.options.values && self.options.values.length ) { + // curVal = newVal = self.values( index ); + // } else { + // curVal = newVal = self.value(); + // } + + switch ( event.keyCode ) { + case $.mobile.keyCode.HOME: + self.refresh(min); + break; + case $.mobile.keyCode.END: + self.refresh(max); + break; + case $.mobile.keyCode.PAGE_UP: + newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) ); + break; + case $.mobile.keyCode.PAGE_DOWN: + newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) ); + break; + case $.mobile.keyCode.UP: + case $.mobile.keyCode.RIGHT: + if ( curVal === self._valueMax() ) { + return; + } + newVal = self._trimAlignValue( curVal + step ); + break; + case $.mobile.keyCode.DOWN: + case $.mobile.keyCode.LEFT: + if ( curVal === self._valueMin() ) { + return; + } + newVal = self._trimAlignValue( curVal - step ); + break; + } + + return ret; + }) + .keyup(function( event ) { + var index = $( this ).data( "aria-valuenow" ); + + if ( self._keySliding ) { + self._keySliding = false; + // self._stop( event, index ); + // self._change( event, index ); + $( this ).removeClass( "ui-state-active" ); + } + + }); + handle.bind('click', function(e){ return false; }); this.refresh(); }, @@ -155,7 +245,7 @@ $.widget( "mobile.slider", $.mobile.widget, { //flip the stack of the bg colors if ( percent > 60 && cType === "select" ) { - + } this.handle.css("left", percent + "%"); this.handle.attr({ @@ -197,4 +287,4 @@ $.widget( "mobile.slider", $.mobile.widget, { } }); })( jQuery ); - +