mirror of
https://github.com/Hopiu/jquery-mobile.git
synced 2026-03-23 09:20:28 +00:00
307 lines
7.5 KiB
JavaScript
307 lines
7.5 KiB
JavaScript
/*
|
|
* 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.prependTo( aside.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( "<span>" ).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( "<span class='ui-li-dec'>" + (counter++) + ". </span>" );
|
|
}
|
|
|
|
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( "<div data-role='page'><div data-role='content'></div></div>" )
|
|
.parent()
|
|
.before( "<div data-role='header' data-theme='" + o.headerTheme + "'><div class='ui-title'>" + title + "</div></div>" )
|
|
.after( persistentFooterID ? $( "<div>", { "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( "<a href='#" + id + "'>" + title + "</a>" );
|
|
}).listview();
|
|
}
|
|
});
|
|
|
|
})( jQuery );
|