jquery-mobile/js/jquery.mobile.forms.select.js

201 lines
4.8 KiB
JavaScript
Raw Normal View History

2010-09-10 22:23:13 +00:00
/*
* jQuery Mobile Framework : "customSelect" plugin (based on code from Filament Group,Inc)
* 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($){
$.fn.customSelect = function(options){
return $(this).each(function(){
2010-10-11 18:41:17 +00:00
var select = $(this)
.attr( "tabindex", "-1" )
.wrap( "<div class='ui-select'>" ),
selectID = select.attr( "id" ),
label = $( "label[for="+ selectID +"]" )
.addClass( "ui-select" ),
2010-09-10 22:23:13 +00:00
//extendable options
2010-10-11 18:41:17 +00:00
o = $.extend({
chooseText: label.text(),
theme: select.data("theme")
2010-10-11 18:41:17 +00:00
}, options),
2010-09-10 22:23:13 +00:00
2010-10-11 18:41:17 +00:00
buttonId = selectID + "-button",
menuId = selectID + "-menu",
thisPage = select.closest( ".ui-page" ),
menuType,
currScroll,
button = $( "<a>", {
"href": "#",
"role": "button",
"title": "select menu",
"id": buttonId,
"aria-haspopup": "true",
"aria-owns": menuId
})
.text( $( this.options.item(this.selectedIndex) ).text() )
.insertBefore( select )
.buttonMarkup({
iconpos: 'right',
icon: 'arrow-d',
theme: o.theme
2010-10-11 18:41:17 +00:00
}),
menuPage = $( "<div data-role='dialog' data-theme='a'>" +
"<div data-role='header' data-theme='b'>" +
"<div class='ui-title'>" + o.chooseText + "</div>"+
"</div>"+
"<div data-role='content'></div>"+
"</div>" )
.appendTo( $.pageContainer )
2010-10-11 18:41:17 +00:00
.page(),
menuPageContent = menuPage.find( ".ui-content" ),
screen = $( "<div>", {
"class": "ui-listbox-screen ui-overlay ui-screen-hidden fade"
})
.appendTo( thisPage ),
listbox = $( "<div>", { "class": "ui-listbox ui-listbox-hidden ui-body-a ui-overlay-shadow ui-corner-all pop"} )
.insertAfter(screen),
list = $( "<ul>", {
"class": "ui-listbox-list",
"id": menuId,
"role": "listbox",
"aria-labelledby": buttonId
})
.appendTo( listbox );
//populate menu
2010-10-11 18:41:17 +00:00
select.find( "option" ).each(function( i ){
var selected = (select[0].selectedIndex == i),
anchor = $("<a>", {
"aria-selected": selected,
"role": "option",
"href": "#"
})
.text( $(this).text() );
$( "<li>", {
"class": selected ? "ui-btn-active" : '',
"data-icon": "checkbox-on"
})
.append( anchor )
.appendTo( list );
});
2010-10-11 18:41:17 +00:00
//now populated, create listview
list.listview();
2010-10-11 18:41:17 +00:00
function showmenu(){
var menuHeight = list.outerHeight();
currScroll = [ $(window).scrollLeft(), $(window).scrollTop() ];
if( menuHeight > window.innerHeight - 80 || !$.support.scrollTop ){
2010-10-11 18:41:17 +00:00
menuType = "page";
menuPageContent.append( list );
$.changePage(menuPage, undefined);
2010-10-11 18:41:17 +00:00
}
else {
menuType = "overlay";
screen
.height( $(document).height() )
.removeClass('ui-screen-hidden');
listbox
.append( list )
.removeClass( "ui-listbox-hidden" )
.css({
top: $(window).scrollTop() + (window.innerHeight/2),
"margin-top": -menuHeight/2,
left: window.innerWidth/2,
"margin-left": -1* listbox.outerWidth() / 2
2010-10-11 18:56:16 +00:00
})
.addClass("in");
2010-10-11 18:41:17 +00:00
}
};
function hidemenu(){
if(menuType == "page"){
$.changePage([menuPage,thisPage], undefined, true);
2010-10-11 18:41:17 +00:00
}
else{
screen.addClass( "ui-screen-hidden" );
2010-10-11 18:56:16 +00:00
listbox.addClass( "ui-listbox-hidden" ).removeAttr( "style" ).removeClass("in");
2010-10-11 18:41:17 +00:00
}
};
//page show/hide events
menuPage
.bind("pageshow", function(){
list.find( ".ui-btn-active" ).focus();
return false;
})
.bind("pagehide", function(){
window.scrollTo(currScroll[0], currScroll[1]);
select.focus();
listbox.append( list ).removeAttr('style');
2010-10-11 18:41:17 +00:00
return false;
});
//select properties,events
2010-09-10 22:23:13 +00:00
select
.change(function(){
2010-10-11 18:41:17 +00:00
var $el = select.get(0);
button.find( ".ui-btn-text" ).text( $($el.options.item($el.selectedIndex)).text() );
2010-09-10 22:23:13 +00:00
})
.focus(function(){
$(this).blur();
button.focus();
2010-10-11 18:41:17 +00:00
});
//button events
button.mousedown(function(event){
2010-10-11 18:41:17 +00:00
showmenu();
return false;
2010-09-10 22:23:13 +00:00
});
//apply click events for items
2010-10-11 18:41:17 +00:00
list
.find("li")
.mousedown(function(){
2010-10-11 18:41:17 +00:00
//deselect active
list.find( "li" )
.removeClass( "ui-btn-active" )
.children(0)
.attr( "aria-selected", "false");
//select this one
$(this)
.addClass( "ui-btn-active" )
.find( "a" )
.attr( "aria-selected", "true");
//update select
var newIndex = list.find( "li" ).index( this ),
2010-09-10 22:23:13 +00:00
prevIndex = select[0].selectedIndex;
2010-10-11 18:41:17 +00:00
select[0].selectedIndex = newIndex;
//trigger change event
if(newIndex !== prevIndex){
select.trigger( "change" );
2010-09-10 22:23:13 +00:00
}
2010-10-11 18:41:17 +00:00
//hide custom select
hidemenu();
2010-09-10 22:23:13 +00:00
return false;
2010-10-11 18:41:17 +00:00
});
2010-09-10 22:23:13 +00:00
//hide on outside click
screen.click(function(){
2010-10-11 18:41:17 +00:00
hidemenu();
return false;
2010-09-10 22:23:13 +00:00
});
});
};
})(jQuery);