/* * jQuery Mobile Framework : "listview" plugin * Copyright (c) jQuery Project * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license */ (function($, undefined ) { $.widget( "mobile.listview", $.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() { $( this ).attr( "tabindex", "0" ); }); this._itemApply( $list, $list ); this.refresh( true ); //keyboard events for menu items $list.keydown(function( e ) { var target = $( 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( "vclick" ); return false; break; } }); }, _itemApply: function( $list, item ) { // TODO class has to be defined in markup item.find( ".ui-li-count" ) .addClass( "ui-btn-up-" + ($list.jqmData( "counttheme" ) || this.options.countTheme) + " ui-btn-corner-all" ); item.find( "h1, h2, h3, h4, h5, h6" ).addClass( "ui-li-heading" ); item.find( "p, dl" ).addClass( "ui-li-desc" ); $list.find( "li" ).find( ">img:eq(0), >a:first>img:eq(0)" ).addClass( "ui-li-thumb" ).each(function() { $( this ).closest( "li" ) .addClass( $(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 ( $.support.cssPseudoElement || !$.nodeName( item[0], "ol" ) ) { return; } }, _removeCorners: function(li){ li .add( li.find(".ui-btn-inner, .ui-li-link-alt, .ui-li-thumb") ) .removeClass( "ui-corner-top ui-corner-bottom ui-corner-br ui-corner-bl ui-corner-tr ui-corner-tl" ); }, refresh: function( create ) { this._createSubPages(); var o = this.options, $list = this.element, self = this, dividertheme = $list.jqmData( "dividertheme" ) || o.dividerTheme, li = $list.children( "li" ), counter = $.support.cssPseudoElement || !$.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 = $( this ), itemClass = "ui-li"; // If we're creating the element, we update it regardless if ( !create && item.hasClass( "ui-li" ) ) { return; } var itemTheme = item.jqmData("theme") || o.theme; var a = item.find( "a" ); if ( a.length ) { var icon = item.jqmData("icon"); item .buttonMarkup({ wrapperEls: "div", shadow: false, corners: false, iconpos: "right", icon: a.length > 1 || icon === false ? false : icon || "arrow-r", theme: itemTheme }); a.first().addClass( "ui-link-inherit" ); if ( a.length > 1 ) { itemClass += " ui-li-has-alt"; var last = a.last(), splittheme = $list.jqmData( "splittheme" ) || last.jqmData( "theme" ) || o.splitTheme; last .appendTo(item) .attr( "title", last.text() ) .addClass( "ui-li-link-alt" ) .empty() .buttonMarkup({ shadow: false, corners: false, theme: itemTheme, icon: false, iconpos: false }) .find( ".ui-btn-inner" ) .append( $( "" ).buttonMarkup({ shadow: true, corners: true, theme: splittheme, iconpos: "notext", icon: $list.jqmData( "spliticon" ) || last.jqmData( "icon" ) || o.splitIcon } ) ); } } else if ( item.jqmData( "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-" + itemTheme; } if( o.inset ){ if ( pos === 0 ) { 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" ); if(item.next().next().length){ self._removeCorners( item.next() ); } } if ( pos === li.length - 1 ) { 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(item.prev().prev().length){ self._removeCorners( item.prev() ); } } } if ( counter && itemClass.indexOf( "ui-li-divider" ) < 0 ) { item .find( ".ui-link-inherit" ).first() .addClass( "ui-li-jsnumbering" ) .prepend( "" + (counter++) + ". " ); } item.add( item.find( ".ui-btn-inner" ) ).addClass( itemClass ); if ( !create ) { self._itemApply( $list, item ); } }); }, //create a string for ID/subpage url creation _idStringEscape: function( str ){ return str.replace(/[^a-zA-Z0-9]/g, '-'); }, _createSubPages: function() { var parentList = this.element, parentPage = parentList.closest( ".ui-page" ), parentId = parentPage.jqmData( "url" ), o = this.options, self = this, persistentFooterID = parentPage.find( ":jqmData(role='footer')" ).jqmData( "id" ); $( parentList.find( "li>ul, li>ol" ).toArray().reverse() ).each(function( i ) { var list = $( this ), parent = list.parent(), nodeEls = $( list.prevAll().toArray().reverse() ), nodeEls = nodeEls.length ? nodeEls : $( "" + $.trim(parent.contents()[ 0 ].nodeValue) + "" ), title = nodeEls.first().text(),//url limits to first 30 chars of text id = parentId + "&" + $.mobile.subPageUrlKey + "=" + self._idStringEscape(title + " " + i), theme = list.jqmData( "theme" ) || o.theme, countTheme = list.jqmData( "counttheme" ) || parentList.jqmData( "counttheme" ) || o.countTheme, newPage = list.wrap( "
" ) .parent() .before( "
" + title + "
" ) .after( persistentFooterID ? $( "
") : "" ) .parent() .attr( "data-" + $.mobile.ns + "url", id ) .attr( "data-" + $.mobile.ns + "theme", theme ) .attr( "data-" + $.mobile.ns + "count-theme", countTheme ) .appendTo( $.mobile.pageContainer ); newPage.page(); var anchor = parent.find('a:first'); if (!anchor.length) { anchor = $("").html( nodeEls || title ).prependTo(parent.empty()); } anchor.attr('href','#' + id); }).listview(); } }); })( jQuery );