/* * jQuery Mobile Framework : listview plugin * Copyright (c) jQuery Project * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. * Note: Code is in draft form and is subject to change */ (function( jQuery ) { jQuery.widget( "mobile.listview", jQuery.mobile.widget, { options: { theme: "c", countTheme: "c", headerTheme: "b", dividerTheme: "b", splitIcon: "arrow-r", splitTheme: "b", inset: false }, _create: function() { var $list = this.element, o = this.options; // create listview markup $list .addClass( "ui-listview" ) .attr( "role", "listbox" ) if ( o.inset ) { $list.addClass( "ui-listview-inset ui-corner-all ui-shadow" ); } $list.delegate( ".ui-li", "focusin", function() { jQuery( this ).attr( "tabindex", "0" ); }); this._itemApply( $list, $list ); this.refresh( true ); //keyboard events for menu items $list.keydown(function( e ) { var target = jQuery( e.target ), li = target.closest( "li" ); // switch logic based on which key was pressed switch ( e.keyCode ) { // up or left arrow keys case 38: var prev = li.prev(); // if there's a previous option, focus it if ( prev.length ) { target .blur() .attr( "tabindex", "-1" ); prev.find( "a" ).first().focus(); } return false; break; // down or right arrow keys case 40: var next = li.next(); // if there's a next option, focus it if ( next.length ) { target .blur() .attr( "tabindex", "-1" ); next.find( "a" ).first().focus(); } return false; break; case 39: var a = li.find( "a.ui-li-link-alt" ); if ( a.length ) { target.blur(); a.first().focus(); } return false; break; case 37: var a = li.find( "a.ui-link-inherit" ); if ( a.length ) { target.blur(); a.first().focus(); } return false; break; // if enter or space is pressed, trigger click case 13: case 32: target.trigger( "click" ); return false; break; } }); // tapping the whole LI triggers click on the first link $list.delegate( "li", "click", function(event) { if ( !jQuery( event.target ).closest( "a" ).length ) { jQuery( this ).find( "a" ).first().trigger( "click" ); return false; } }); }, _itemApply: function( $list, item ) { // TODO class has to be defined in markup item.find( ".ui-li-count" ) .addClass( "ui-btn-up-" + ($list.data( "counttheme" ) || this.options.countTheme) + " ui-btn-corner-all" ); item.find( "h1, h2, h3, h4, h5, h6" ).addClass( "ui-li-heading" ); item.find( "p, ul, dl" ).addClass( "ui-li-desc" ); item.find( "img" ).addClass( "ui-li-thumb" ).each(function() { jQuery( this ).closest( "li" ) .addClass( jQuery(this).is( ".ui-li-icon" ) ? "ui-li-has-icon" : "ui-li-has-thumb" ); }); var aside = item.find( ".ui-li-aside" ); if ( aside.length ) { aside.each(function(i, el) { $(el).prependTo( $(el).parent() ); //shift aside to front for css float }); } if ( jQuery.support.cssPseudoElement || !jQuery.nodeName( item[0], "ol" ) ) { return; } }, refresh: function( create ) { this._createSubPages(); var o = this.options, $list = this.element, dividertheme = $list.data( "dividertheme" ) || o.dividerTheme, li = $list.children( "li" ), counter = jQuery.support.cssPseudoElement || !jQuery.nodeName( $list[0], "ol" ) ? 0 : 1; if ( counter ) { $list.find( ".ui-li-dec" ).remove(); } li.attr({ "role": "option", "tabindex": "-1" }); li.first().attr( "tabindex", "0" ); li.each(function( pos ) { var item = jQuery( this ), itemClass = "ui-li"; // If we're creating the element, we update it regardless if ( !create && item.hasClass( "ui-li" ) ) { return; } var a = item.find( "a" ); if ( a.length ) { item .buttonMarkup({ wrapperEls: "div", shadow: false, corners: false, iconpos: "right", icon: item.data("icon") || "arrow-r", theme: o.theme }); a.first().addClass( "ui-link-inherit" ); if ( a.length > 1 ) { itemClass += " ui-li-has-alt"; var last = a.last(); last .attr( "title", last.text() ) .addClass( "ui-li-link-alt" ) .empty() .buttonMarkup({ shadow: false, corners: false, theme: o.theme, icon: false, iconpos: false }) .find( ".ui-btn-inner" ) .append( jQuery( "" ).buttonMarkup({ shadow: true, corners: true, theme: $list.data( "splittheme" ) || last.data( "theme" ) || o.splitTheme, iconpos: "notext", icon: $list.data( "spliticon" ) || last.data( "icon" ) || o.splitIcon } ) ); } } else if ( item.data( "role" ) === "list-divider" ) { itemClass += " ui-li-divider ui-btn ui-bar-" + dividertheme; item.attr( "role", "heading" ); //reset counter when a divider heading is encountered if ( counter ) { counter = 1; } } else { itemClass += " ui-li-static ui-btn-up-" + o.theme; } if ( pos === 0 ) { item.find( "img" ).addClass( "ui-corner-tl" ); if ( o.inset ) { itemClass += " ui-corner-top"; item .add( item.find( ".ui-btn-inner" ) ) .find( ".ui-li-link-alt" ) .addClass( "ui-corner-tr" ) .end() .find( ".ui-li-thumb" ) .addClass( "ui-corner-tl" ); } } else if ( pos === li.length - 1 ) { item.find( "img" ).addClass( "ui-corner-bl" ); if ( o.inset ) { itemClass += " ui-corner-bottom"; item .add( item.find( ".ui-btn-inner" ) ) .find( ".ui-li-link-alt" ) .addClass( "ui-corner-br" ) .end() .find( ".ui-li-thumb" ) .addClass( "ui-corner-bl" ); } } if ( counter && itemClass.indexOf( "ui-li-divider" ) < 0 ) { item .find( ".ui-link-inherit" ).first() .addClass( "ui-li-jsnumbering" ) .prepend( "" + (counter++) + ". " ); } item.addClass( itemClass ); if ( !create ) { this._itemApply( $list, item ); } }); }, _createSubPages: function() { var parentList = this.element, parentPage = parentList.closest( ".ui-page" ), parentId = parentPage.attr( "id" ), o = this.options, persistentFooterID = parentPage.find( "[data-role='footer']" ).data( "id" ); jQuery( parentList.find( "ul, ol" ).toArray().reverse() ).each(function( i ) { var list = jQuery( this ), parent = list.parent(), title = parent.contents()[ 0 ].nodeValue.split("\n")[0], id = parentId + "&" + $.mobile.subPageUrlKey + "=" + $.mobile.idStringEscape(title + " " + i), theme = list.data( "theme" ) || o.theme, countTheme = list.data( "counttheme" ) || parentList.data( "counttheme" ) || o.countTheme, newPage = list.wrap( "
" ) .parent() .before( "
" + title + "
" ) .after( persistentFooterID ? $( "
", { "data-role": "footer", "data-id": persistentFooterID, "class": "ui-footer-duplicate" } ) : "" ) .parent() .attr({ id: id, "data-theme": theme, "data-count-theme": countTheme }) .appendTo( jQuery.pageContainer ); newPage.page(); parent.html( "" + title + "" ); }).listview(); } }); })( jQuery );