jquery-mobile/js/jquery.mobile.listview.js
jblas@adobe.com 729cda075a Merge branch 'master' into fastclick
Resolved Conflicts:
	js/jquery.mobile.buttonMarkup.js
	js/jquery.mobile.event.js
	js/jquery.mobile.forms.checkboxradio.js
	js/jquery.mobile.forms.select.js
	js/jquery.mobile.listview.js
2011-03-27 21:00:22 -07:00

327 lines
8.3 KiB
JavaScript

/*
* 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( $( "<span>" ).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( "<span class='ui-li-dec'>" + (counter++) + ". </span>" );
}
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 : $( "<span>" + $.trim(parent.contents()[ 0 ].nodeValue) + "</span>" ),
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( "<div data-" + $.mobile.ns + "role='page'><div data-" + $.mobile.ns + "role='content'></div></div>" )
.parent()
.before( "<div data-" + $.mobile.ns + "role='header' data-" + $.mobile.ns + "theme='" + o.headerTheme + "'><div class='ui-title'>" + title + "</div></div>" )
.after( persistentFooterID ? $( "<div data-" + $.mobile.ns + "role='footer' data-" + $.mobile.ns + "id='"+ 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 = $("<a></a>").html( nodeEls || title ).prependTo(parent.empty());
}
anchor.attr('href','#' + id);
}).listview();
}
});
})( jQuery );