From 11c8cc61d13dd3b5ed1cf8ac25f218c2e8bd4491 Mon Sep 17 00:00:00 2001 From: "yonghwi0324.park" Date: Fri, 12 Apr 2013 16:10:09 +0900 Subject: [PATCH] Fastscroll: Add a user interaction at the omitted items. Users can jump to a list divider even if shortcut items are omitted. And its popup is displayed. Change-Id: I22569c08fdba63f1fa35473a86c1a14234f65e6c --- demos/tizen-winsets/widgets/fastscroll.html | 2 + src/js/widgets/jquery.mobile.tizen.fastscroll.js | 239 +++++++++++++++++------ tests/unit-tests/fastscroll/fastscroll-tests.js | 7 +- 3 files changed, 184 insertions(+), 64 deletions(-) diff --git a/demos/tizen-winsets/widgets/fastscroll.html b/demos/tizen-winsets/widgets/fastscroll.html index 55de45e..cbf6795 100644 --- a/demos/tizen-winsets/widgets/fastscroll.html +++ b/demos/tizen-winsets/widgets/fastscroll.html @@ -53,6 +53,8 @@
  • O
  • Organza
  • Orlando
  • +
  • 1
  • +
  • 1st Store
  • diff --git a/src/js/widgets/jquery.mobile.tizen.fastscroll.js b/src/js/widgets/jquery.mobile.tizen.fastscroll.js index f1e3db3..dd53ca8 100644 --- a/src/js/widgets/jquery.mobile.tizen.fastscroll.js +++ b/src/js/widgets/jquery.mobile.tizen.fastscroll.js @@ -102,6 +102,7 @@ define( [ '../jquery.mobile.tizen.scrollview' ], function ( ) { _primaryLanguage: null, _secondLanguage: null, + _dividerMap: {}, _create: function () { var $el = this.element, @@ -183,10 +184,27 @@ define( [ '../jquery.mobile.tizen.scrollview' ], function ( ) { l = listItem.offset().left - shortcutsListOffset.left, t = listItem.offset().top - shortcutsListOffset.top, r = l + Math.abs(listItem.outerWidth( true ) ), - b = t + Math.abs(listItem.outerHeight( true ) ); + b = t + Math.abs(listItem.outerHeight( true ) ), + unit, + baseTop, + baseBottom, + omitSet, + i; if ( coords.x >= l && coords.x <= r && coords.y >= t && coords.y <= b ) { - self._hitItem( listItem ); + if ( listItem.text() !== "." ) { + self._hitItem( listItem ); + } else { + omitSet = listItem.data( "omitSet" ); + unit = ( b - t ) / omitSet.length; + for ( i = 0; i < omitSet.length; i++ ) { + baseTop = t + ( i * unit ); + baseBottom = baseTop + unit; + if ( coords.y >= baseTop && coords.y <= baseBottom ) { + self._hitOmitItem( listItem, omitSet.charAt( i ) ); + } + } + } return false; } return true; @@ -220,25 +238,55 @@ define( [ '../jquery.mobile.tizen.scrollview' ], function ( ) { } ); }, - _hitItem: function ( listItem ) { + _hitOmitItem: function ( listItem, text ) { var self = this, - $popup = self.scrollview.find( '.ui-fastscroll-popup' ); + $popup = self.scrollview.find( '.ui-fastscroll-popup' ), + divider = self._dividerMap[ text ]; - if ( typeof listItem.data( 'divider' ) !== "undefined" ) { - self.jumpToDivider( $( listItem.data( 'divider' ) ) ); + if ( typeof divider !== "undefined" ) { + self.jumpToDivider( $( divider ) ); } - if ( listItem.text() !== "." ) { - $popup.text( listItem.text() ) - .css( { marginLeft: -( $popup.width() / 2 ), - marginTop: -( $popup.height() / 2 ), - padding: $popup.css( "paddingTop" ) } ) - .width( $popup.height() ) - .show(); + $popup.text( text ) + .css( { marginLeft: -( $popup.width() / 2 ), + marginTop: -( $popup.height() / 2 ), + padding: $popup.css( "paddingTop" ) } ) + .width( $popup.height() ) + .show(); + + $( listItem ).addClass( "ui-fastscroll-hover" ); + if ( listItem.index() === 0 ) { + $( listItem ).addClass( "ui-fastscroll-hover-first-item" ); + } + if ( listItem.index() > 0 ) { + $( listItem ).siblings().eq( listItem.index() - 1 ).addClass( "ui-fastscroll-hover-up" ); + } + $( listItem ).siblings().eq( listItem.index() ).addClass( "ui-fastscroll-hover-down" ); + }, + + _hitItem: function ( listItem ) { + var self = this, + $popup = self.scrollview.find( '.ui-fastscroll-popup' ), + text = listItem.text(), + divider; + + if ( text === "#" ) { + divider = self._dividerMap.number; } else { - $popup.hide(); + divider = self._dividerMap[ text ]; } + if ( typeof divider !== "undefined" ) { + self.jumpToDivider( $( divider ) ); + } + + $popup.text( text ) + .css( { marginLeft: -( $popup.width() / 2 ), + marginTop: -( $popup.height() / 2 ), + padding: $popup.css( "paddingTop" ) } ) + .width( $popup.height() ) + .show(); + $( listItem ).addClass( "ui-fastscroll-hover" ); if ( listItem.index() === 0 ) { $( listItem ).addClass( "ui-fastscroll-hover-first-item" ); @@ -254,8 +302,10 @@ define( [ '../jquery.mobile.tizen.scrollview' ], function ( ) { $popup = self.scrollview.find( '.ui-fastscroll-popup' ); listItem.focusin( function ( e ) { + self.shortcutsList.attr( "aria-hidden", false ); self._hitItem( listItem ); }).focusout( function ( e ) { + self.shortcutsList.attr( "aria-hidden", true ); $popup.hide(); $( ".ui-fastscroll-hover" ).removeClass( "ui-fastscroll-hover" ); $( ".ui-fastscroll-hover-first-item" ).removeClass( "ui-fastscroll-hover-first-item" ); @@ -336,11 +386,60 @@ define( [ '../jquery.mobile.tizen.scrollview' ], function ( ) { return omitInfo; }, + _createDividerMap: function () { + var self = this, + primaryCharacterSet = self._primaryLanguage ? self._primaryLanguage.replace( /,/g, "" ) : null, + secondCharacterSet = self._secondLanguage ? self._secondLanguage.replace( /,/g, "" ) : null, + numberSet = "0123456789", + dividers = self.element.find( '.ui-li-divider' ), + map = {}, + matchToDivider, + makeCharacterSet, + indexChar, + i; + + matchToDivider = function ( index, divider ) { + if ( $( divider ).text() === indexChar ) { + map[ indexChar ] = divider; + } + }; + + makeCharacterSet = function ( index, divider ) { + primaryCharacterSet += $( divider ).text(); + }; + + if ( primaryCharacterSet === null ) { + primaryCharacterSet = ""; + dividers.each( makeCharacterSet ); + } + + for ( i = 0; i < primaryCharacterSet.length; i++ ) { + indexChar = primaryCharacterSet.charAt( i ); + dividers.each( matchToDivider ); + } + + if ( secondCharacterSet !== null ) { + for ( i = 0; i < secondCharacterSet.length; i++ ) { + indexChar = secondCharacterSet.charAt( i ); + dividers.each( matchToDivider ); + } + } + + dividers.each( function ( index, divider ) { + if ( numberSet.search( $( divider ).text() ) !== -1 ) { + map.number = divider; + return false; + } + }); + + self._dividerMap = map; + }, + indexString: function ( indexAlphabet ) { var self = this, characterSet = []; - if ( typeof indexAlphabet === " undefined" ) { + if ( typeof indexAlphabet === "undefined" ) { return self._primaryLanguage + ":" + self._secondLanguage; } @@ -358,7 +457,9 @@ define( [ '../jquery.mobile.tizen.scrollview' ], function ( ) { contentHeight = self._contentHeight(), shapItem = $( '
  • ' ), omitIndex = 0, - matchToDivider, + makeCharacterSet, + makeOmitSet, + itemHandler, containerHeight, shortcutsItems, shortcutItem, @@ -380,15 +481,32 @@ define( [ '../jquery.mobile.tizen.scrollview' ], function ( ) { size, i; - matchToDivider = function ( index, divider ) { - if ( $( divider ).text() === indexChar ) { - shortcutItem.data( 'divider', divider ) - .bind( 'vclick', function ( e ) { - $( divider ).next().focus(); - } ); + makeCharacterSet = function ( index, divider ) { + primaryCharacterSet += $( divider ).text(); + }; + + makeOmitSet = function ( index, length ) { + var count, + omitSet = ""; + + for ( count = 0; count < length; count++ ) { + omitSet += primaryCharacterSet[ index + count ]; + } + + return omitSet; + }; + + itemHandler = function ( e ) { + var text = $( this ).text(), + matchDivider = self._dividerMap[ text ]; + + if ( typeof matchDivider !== "undefined" ) { + $( matchDivider ).next().focus(); } }; + self._createDividerMap(); + self.shortcutsList.find( 'li' ).remove(); // get all the dividers from the list and turn them into shortcuts @@ -411,63 +529,58 @@ define( [ '../jquery.mobile.tizen.scrollview' ], function ( ) { self.shortcutsList.append( shapItem ); self._focusItem( shapItem ); - if ( primaryCharacterSet !== null ) { - padding = parseInt( shapItem.css( "padding" ), 10 ); - minHeight = shapItem.height() + ( padding * 2 ); - maxNumOfItems = parseInt( ( contentHeight / minHeight ) - 1, 10 ); - numOfItems = primaryCharacterSet.length; + if ( primaryCharacterSet === null ) { + primaryCharacterSet = ""; + dividers.each( makeCharacterSet ); + } - maxNumOfItems = secondCharacterSet ? maxNumOfItems - 2 : maxNumOfItems; + padding = parseInt( shapItem.css( "padding" ), 10 ); + minHeight = shapItem.height() + ( padding * 2 ); + maxNumOfItems = parseInt( ( contentHeight / minHeight ) - 1, 10 ); + numOfItems = primaryCharacterSet.length; - if ( maxNumOfItems < 3 ) { - shapItem.remove(); - return; - } + maxNumOfItems = secondCharacterSet ? maxNumOfItems - 2 : maxNumOfItems; - omitInfo = self._omit( numOfItems, maxNumOfItems ); + if ( maxNumOfItems < 3 ) { + shapItem.remove(); + return; + } - for ( i = 0; i < primaryCharacterSet.length; i++ ) { - indexChar = primaryCharacterSet.charAt( i ); - shortcutItem = $( '
  • ' + indexChar + '
  • ' ); + omitInfo = self._omit( numOfItems, maxNumOfItems ); - self._focusItem( shortcutItem ); - dividers.each( matchToDivider ); + for ( i = 0; i < primaryCharacterSet.length; i++ ) { + indexChar = primaryCharacterSet.charAt( i ); + shortcutItem = $( '
  • ' + indexChar + '
  • ' ); - if ( typeof omitInfo !== "undefined" && omitInfo[ omitIndex ] > 1 ) { - shortcutItem = $( '
  • .
  • ' ); - i += omitInfo[ omitIndex ] - 1; - } + self._focusItem( shortcutItem ); - shapItem.before( shortcutItem ); - omitIndex++; + if ( typeof omitInfo !== "undefined" && omitInfo[ omitIndex ] > 1 ) { + shortcutItem = $( '
  • .
  • ' ); + shortcutItem.data( "omitSet", makeOmitSet( i, omitInfo[ omitIndex ] ) ); + i += omitInfo[ omitIndex ] - 1; + } else { + shortcutItem.bind( 'vclick', itemHandler ); } - if ( secondCharacterSet !== null ) { - lastIndex = secondCharacterSet.length - 1; - seconds = []; - - seconds.push( secondCharacterSet.charAt( 0 ) ); - seconds.push( secondCharacterSet.charAt( lastIndex ) ); + shapItem.before( shortcutItem ); + omitIndex++; + } - for ( i = 0; i < seconds.length; i++ ) { - indexChar = seconds[ i ]; - shortcutItem = $( '
  • ' + indexChar + '
  • ' ); + if ( secondCharacterSet !== null ) { + lastIndex = secondCharacterSet.length - 1; + seconds = []; - self._focusItem( shortcutItem ); - dividers.each( matchToDivider ); + seconds.push( secondCharacterSet.charAt( 0 ) ); + seconds.push( secondCharacterSet.charAt( lastIndex ) ); - shapItem.before( shortcutItem ); - } - } - } else { - dividers.each( function ( index, divider ) { - indexChar = $( divider ).text(); + for ( i = 0; i < seconds.length; i++ ) { + indexChar = seconds[ i ]; shortcutItem = $( '
  • ' + indexChar + '
  • ' ); - shortcutItem.data( 'divider', divider ); self._focusItem( shortcutItem ); + shortcutItem.bind( 'vclick', itemHandler ); shapItem.before( shortcutItem ); - } ); + } } containerHeight = self.shortcutsContainer.outerHeight(); diff --git a/tests/unit-tests/fastscroll/fastscroll-tests.js b/tests/unit-tests/fastscroll/fastscroll-tests.js index 7e0bc53..2fad2b0 100644 --- a/tests/unit-tests/fastscroll/fastscroll-tests.js +++ b/tests/unit-tests/fastscroll/fastscroll-tests.js @@ -10,7 +10,8 @@ var unit_fastscroll = function ( list ) { var widget, shortcut, - divider; + divider, + indexString = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z:ㄱ,ㄴ,ㄷ,ㄹ,ㅁ,ㅂ,ㅅ,ㅇ,ㅈ,ㅊ,ㅋ,ㅌ,ㅍ,ㅎ" ; widget = list.parentsUntil(".ui-content").parent().find(".ui-fastscroll"); @@ -24,6 +25,10 @@ for ( i = 0; i < divider.length; i++ ) { equal( $( divider[i] ).text(), $( shortcut[i] ).text(), "Shortcut"); } + + /* indexString */ + list.fastscroll( "indexString", indexString ); + equal( list.fastscroll( "indexString" ), indexString, "indexString" ); }; test( "shortcut", function () { -- 2.7.4