" ),
selectID = select.attr( "id" ),
@@ -151,6 +151,36 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
//disable if specified
if( o.disabled ){ this.disable(); }
+ //support for using the native select menu with a custom button
+ if( o.useNativeMenu ){
+
+ select
+ .appendTo(button)
+ .bind( "touchstart mousedown", function( e ){
+ //add active class to button
+ button.addClass( $.mobile.activeBtnClass );
+
+ //ensure button isn't clicked
+ e.stopPropagation();
+ })
+ .bind( "focus mouseover", function(){
+ button.trigger( "mouseover" );
+ })
+ .bind( "blur mouseout", function(){
+ button
+ .trigger( "mouseout" )
+ .removeClass( $.mobile.activeBtnClass );
+ });
+
+ button.attr( "tabindex", "-1" );
+ }
+ else {
+ select
+ .attr( "tabindex", "-1" )
+ .focus(function(){
+ $(this).blur();
+ button.focus();
+ });
//events on native select
select
.change(function(){
@@ -189,6 +219,8 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
}
});
+ }
+
//events for list items
list.delegate("li:not(.ui-disabled, .ui-li-divider)", "click", function(event){
diff --git a/themes/default/jquery.mobile.forms.select.css b/themes/default/jquery.mobile.forms.select.css
index 8023f435..efefcf5a 100644
--- a/themes/default/jquery.mobile.forms.select.css
+++ b/themes/default/jquery.mobile.forms.select.css
@@ -3,8 +3,10 @@
* Copyright (c) jQuery Project
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses.
*/
-.ui-select { display: block; }
+.ui-select { display: block; position: relative; }
.ui-select select { position: absolute; left: -9999px; top: -9999px; }
+.ui-select a select { cursor: pointer; -webkit-appearance: button; left: 0; top:0; width: 100%; height: 100%; opacity: 0; }
+
.ui-select .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; }
.ui-select .ui-btn-icon-right .ui-icon { right: 15px; }
From aa234961cca905cccb77b1f1339de6dd6bb43a63 Mon Sep 17 00:00:00 2001
From: John Bender
Date: Tue, 25 Jan 2011 22:50:55 -0800
Subject: [PATCH 03/30] whitespace correction on rebase fix
---
js/jquery.mobile.forms.select.js | 65 ++++++++++++++++----------------
1 file changed, 33 insertions(+), 32 deletions(-)
diff --git a/js/jquery.mobile.forms.select.js b/js/jquery.mobile.forms.select.js
index 9b0e7fb0..d3bc924a 100644
--- a/js/jquery.mobile.forms.select.js
+++ b/js/jquery.mobile.forms.select.js
@@ -181,43 +181,44 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
$(this).blur();
button.focus();
});
- //events on native select
- select
- .change(function(){
- self.refresh();
- })
- .focus(function(){
- $(this).blur();
- button.focus();
- });
- //button events
- button
- .bind( "touchstart" ,function( event ){
- //set startTouches to cached copy of
- $( this ).data( "startTouches", $.extend({}, event.originalEvent.touches[ 0 ]) );
- })
- .bind( $.support.touch ? "touchend" : "mouseup" , function( event ){
- //if it's a scroll, don't open
- if( $( this ).data( "moved" ) ){
- $( this ).removeData( "moved" );
- }
- else{
- self.open();
- }
- event.preventDefault();
- })
- .bind( "touchmove", function( event ){
- //if touch moved enough, set data moved and don't open menu
- var thisTouches = event.originalEvent.touches[ 0 ],
+ //events on native select
+ select
+ .change(function(){
+ self.refresh();
+ })
+ .focus(function(){
+ $(this).blur();
+ button.focus();
+ });
+
+ //button events
+ button
+ .bind( "touchstart" ,function( event ){
+ //set startTouches to cached copy of
+ $( this ).data( "startTouches", $.extend({}, event.originalEvent.touches[ 0 ]) );
+ })
+ .bind( $.support.touch ? "touchend" : "mouseup" , function( event ){
+ //if it's a scroll, don't open
+ if( $( this ).data( "moved" ) ){
+ $( this ).removeData( "moved" );
+ }
+ else{
+ self.open();
+ }
+ event.preventDefault();
+ })
+ .bind( "touchmove", function( event ){
+ //if touch moved enough, set data moved and don't open menu
+ var thisTouches = event.originalEvent.touches[ 0 ],
startTouches = $( this ).data( "startTouches" ),
deltaX = Math.abs(thisTouches.pageX - startTouches.pageX),
deltaY = Math.abs(thisTouches.pageY - startTouches.pageY);
- if( deltaX > 10 || deltaY > 10 ){
- $( this ).data( "moved", true );
- }
- });
+ if( deltaX > 10 || deltaY > 10 ){
+ $( this ).data( "moved", true );
+ }
+ });
}
From 244e46b8edacc5a4af852eb6fd3d98c0369ab127 Mon Sep 17 00:00:00 2001
From: John Bender
Date: Tue, 25 Jan 2011 23:11:15 -0800
Subject: [PATCH 04/30] data-native attribute check for native select menus
Fixes #847
---
js/jquery.mobile.forms.select.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/js/jquery.mobile.forms.select.js b/js/jquery.mobile.forms.select.js
index d3bc924a..db6689dd 100644
--- a/js/jquery.mobile.forms.select.js
+++ b/js/jquery.mobile.forms.select.js
@@ -115,6 +115,9 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
menuType;
+ // set to native menu
+ o.useNativeMenu = select.is( "[data-native]");
+
// add counter for multi selects
if( isMultiple ){
self.buttonCount = $('')
From fa2b1903de82264c34b266f2a4598a71aa6b6df2 Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 17:56:20 -0500
Subject: [PATCH 05/30] only add a back button when there's a history entry to
return to.
---
js/jquery.mobile.page.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/jquery.mobile.page.js b/js/jquery.mobile.page.js
index 309c40b3..c79fbd77 100644
--- a/js/jquery.mobile.page.js
+++ b/js/jquery.mobile.page.js
@@ -75,7 +75,7 @@ $.widget( "mobile.page", $.mobile.widget, {
// auto-add back btn on pages beyond first view
if ( o.addBackBtn && role === "header" &&
- ($.mobile.urlHistory.getPrev() || $(".ui-page").length > 1) &&
+ $.mobile.urlHistory.stack.length > 0 &&
!leftbtn && $this.data( "backbtn" ) !== false ) {
$( ""+ o.backBtnText +"" )
From 20c86f655ebbda68ebe7b9da2bf2e31157ac9d9e Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 17:58:16 -0500
Subject: [PATCH 06/30] combined path.isExternal tests
---
tests/unit/navigation/navigation_core.js | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/tests/unit/navigation/navigation_core.js b/tests/unit/navigation/navigation_core.js
index d67a08d7..f98ed7bb 100644
--- a/tests/unit/navigation/navigation_core.js
+++ b/tests/unit/navigation/navigation_core.js
@@ -81,13 +81,10 @@
});
+
test( "path.isExternal is working properly", function(){
same( $.mobile.path.isExternal( location.href ), false, "same domain is not external" );
same( $.mobile.path.isExternal( "http://example.com" ), true, "example.com is external" );
- });
-
-
- test( "path.isExternal method is working properly", function(){
same($.mobile.path.isExternal("mailto:"), true, "mailto protocol");
same($.mobile.path.isExternal("http://foo.com"), true, "http protocol");
same($.mobile.path.isExternal("http://www.foo.com"), true, "http protocol with www");
From 3484c401c2fc6fead3ab912abd7192daf4d2805a Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 18:02:15 -0500
Subject: [PATCH 07/30] added unit test for path.hasProtocol
---
tests/unit/navigation/navigation_core.js | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/tests/unit/navigation/navigation_core.js b/tests/unit/navigation/navigation_core.js
index f98ed7bb..001d465d 100644
--- a/tests/unit/navigation/navigation_core.js
+++ b/tests/unit/navigation/navigation_core.js
@@ -81,6 +81,12 @@
});
+ test( "path.hasProtocol is working properly", function(){
+ same( $.mobile.path.hasProtocol( "tel:5559999" ), true, "value in tel protocol format has protocol" );
+ same( $.mobile.path.hasProtocol( location.href ), true, "location href has protocol" );
+ same( $.mobile.path.hasProtocol( "foo/bar/baz.html" ), false, "simple directory path has no protocol" );
+ same( $.mobile.path.hasProtocol( "file://foo/bar/baz.html" ), true, "simple directory path with file:// has protocol" );
+ });
test( "path.isExternal is working properly", function(){
same( $.mobile.path.isExternal( location.href ), false, "same domain is not external" );
From 6a1cbc0953bd6e14b9156f989e47532818434ba6 Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 18:07:21 -0500
Subject: [PATCH 08/30] added unit tests for path.isRelative. Test coverage for
$.mobile.path is now complete!
---
tests/unit/navigation/navigation_core.js | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tests/unit/navigation/navigation_core.js b/tests/unit/navigation/navigation_core.js
index 001d465d..f7a7a415 100644
--- a/tests/unit/navigation/navigation_core.js
+++ b/tests/unit/navigation/navigation_core.js
@@ -87,6 +87,13 @@
same( $.mobile.path.hasProtocol( "foo/bar/baz.html" ), false, "simple directory path has no protocol" );
same( $.mobile.path.hasProtocol( "file://foo/bar/baz.html" ), true, "simple directory path with file:// has protocol" );
});
+
+ test( "path.isRelative is working properly", function(){
+ same( $.mobile.path.isRelative("#foo/bar"), false, "path starting with a # is not relative" );
+ same( $.mobile.path.isRelative("/foo/bar"), false, "path starting with a / is not relative" );
+ same( $.mobile.path.isRelative("http://example.com/foo"), false, "full url path is not relative" );
+ same( $.mobile.path.isRelative("foo/bar.html"), true, "simple path is relative" );
+ });
test( "path.isExternal is working properly", function(){
same( $.mobile.path.isExternal( location.href ), false, "same domain is not external" );
From 423e6fb276b65d4ddd5a9b61fd4695c363de85be Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 18:51:22 -0500
Subject: [PATCH 09/30] added complete test coverage for $.mobile.urlHistory
methods and properties
---
tests/unit/navigation/navigation_core.js | 53 +++++++++++++++++++++++-
1 file changed, 52 insertions(+), 1 deletion(-)
diff --git a/tests/unit/navigation/navigation_core.js b/tests/unit/navigation/navigation_core.js
index f7a7a415..3838a437 100644
--- a/tests/unit/navigation/navigation_core.js
+++ b/tests/unit/navigation/navigation_core.js
@@ -78,7 +78,6 @@
test( "path.stripHash is working properly", function(){
same( $.mobile.path.stripHash( "#bar" ), "bar", "returns a hash without the # prefix");
-
});
test( "path.hasProtocol is working properly", function(){
@@ -110,4 +109,56 @@
same($.mobile.path.isExternal("#foo"), false, "local id reference");
});
+
+ test( "urlHistory is working properly", function(){
+ //urlHistory
+ same( $.type( $.mobile.urlHistory.stack ), "array", "urlHistory.stack is an array" );
+
+ //preload the stack
+ $.mobile.urlHistory.stack[0] = { url: "foo", transition: "bar" };
+ $.mobile.urlHistory.stack[1] = { url: "baz", transition: "shizam" };
+ $.mobile.urlHistory.stack[2] = { url: "shizoo", transition: "shizaah" };
+
+ //active index
+ same( $.mobile.urlHistory.activeIndex , 0, "urlHistory.activeIndex is 0" );
+
+ //getActive
+ same( $.type( $.mobile.urlHistory.getActive() ) , "object", "active item is an object" );
+ same( $.mobile.urlHistory.getActive().url , "foo", "active item has url foo" );
+ same( $.mobile.urlHistory.getActive().transition , "bar", "active item has transition bar" );
+
+ //get prev / next
+ same( $.mobile.urlHistory.getPrev(), undefined, "urlHistory.getPrev() is undefined when active index is 0" );
+ $.mobile.urlHistory.activeIndex = 1;
+ same( $.mobile.urlHistory.getPrev().url, "foo", "urlHistory.getPrev() has url foo when active index is 1" );
+ $.mobile.urlHistory.activeIndex = 0;
+ same( $.mobile.urlHistory.getNext().url, "baz", "urlHistory.getNext() has url baz when active index is 0" );
+
+ //add new
+ $.mobile.urlHistory.activeIndex = 2;
+ $.mobile.urlHistory.addNew("test");
+ same( $.mobile.urlHistory.stack.length, 4, "urlHistory.addNew() adds an item after the active index" );
+ same( $.mobile.urlHistory.activeIndex, 3, "urlHistory.addNew() moves the activeIndex to the newly added item" );
+
+ //clearForward
+ $.mobile.urlHistory.activeIndex = 0;
+ $.mobile.urlHistory.clearForward();
+ same( $.mobile.urlHistory.stack.length, 1, "urlHistory.clearForward() clears the url stack after the active index" );
+ });
+
+ //url listening
+ asyncTest( "ability to disable our hash change event listening", function(){
+ $.mobile.urlHistory.listeningEnabled = false;
+ var stillListening = false;
+ $(document).bind("pagebeforehide", function(){
+ stillListening = true;
+ });
+ location.hash = "foozball";
+ setTimeout(function(){
+ start();
+ ok( $.mobile.urlHistory.listeningEnabled == stillListening, "urlHistory.listeningEnabled = false disables default hashchange event handler");
+ location.hash = "";
+ }, 1000);
+ });
+
})(jQuery);
\ No newline at end of file
From d1976fa26559173b22b43a4a58f1eea0f2f98484 Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 18:57:14 -0500
Subject: [PATCH 10/30] removed click handler on back button - used
data-rel='back' instead.
---
js/jquery.mobile.page.js | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/js/jquery.mobile.page.js b/js/jquery.mobile.page.js
index c79fbd77..94661660 100644
--- a/js/jquery.mobile.page.js
+++ b/js/jquery.mobile.page.js
@@ -78,12 +78,7 @@ $.widget( "mobile.page", $.mobile.widget, {
$.mobile.urlHistory.stack.length > 0 &&
!leftbtn && $this.data( "backbtn" ) !== false ) {
- $( ""+ o.backBtnText +"" )
- .click(function() {
- history.back();
- return false;
- })
- .prependTo( $this );
+ $( ""+ o.backBtnText +"" ).prependTo( $this );
}
//page title
From 32a0d2fa4cd23e90898047eacce3fdacd1db9327 Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 18:57:34 -0500
Subject: [PATCH 11/30] unit test - initial page should have no back button
---
tests/unit/page/page_core.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/unit/page/page_core.js b/tests/unit/page/page_core.js
index bc610320..ce28dfe1 100644
--- a/tests/unit/page/page_core.js
+++ b/tests/unit/page/page_core.js
@@ -27,3 +27,6 @@ test( "unnested bar anchors are styled", function(){
ok($('.ui-bar > a').hasClass('ui-btn'));
});
+test( "no auto-generated back button exists on first page", function(){
+ ok( !$('.ui-header > [data-rel="back"]').length );
+});
From c91ca3a12950c711b703c3ed675c9aa339b58c88 Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 20:23:10 -0500
Subject: [PATCH 12/30] removed an old demo
---
.../progressbar/_progressbar-static.html | 36 -------------------
1 file changed, 36 deletions(-)
delete mode 100644 experiments/progressbar/_progressbar-static.html
diff --git a/experiments/progressbar/_progressbar-static.html b/experiments/progressbar/_progressbar-static.html
deleted file mode 100644
index 9934054a..00000000
--- a/experiments/progressbar/_progressbar-static.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
- jQuery Mobile Framework - Static Progressbar Example
-
-
-
-
-
-
-
-
-
Static Progressbar
-
-
-
-
-
-
Just a simple static progressbar, for future reference.
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
From 4e0d54a629b353d72b9beed453e3b3dc4594357a Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 20:28:52 -0500
Subject: [PATCH 13/30] refactored Maggie's datepicker edits so that they
overwrite & extend the UI's datepicker plugin and automatically convert
type=date inputs to datepickers when the scripts are included. These changes
make the datepicker plugin good enough to offer as an optional extension to
jQuery Mobile (but not include it in the build by default, as it needs to be
rewritten first - far too heavy to include unless you need it!).
---
experiments/ui-datepicker/index.html | 58 +++++--------------
...er.css => jquery.ui.datepicker.mobile.css} | 8 ++-
.../jquery.ui.datepicker.mobile.js | 55 ++++++++++++++++++
3 files changed, 74 insertions(+), 47 deletions(-)
rename experiments/ui-datepicker/{jquery.ui.datepicker.css => jquery.ui.datepicker.mobile.css} (80%)
mode change 100755 => 100644
create mode 100644 experiments/ui-datepicker/jquery.ui.datepicker.mobile.js
diff --git a/experiments/ui-datepicker/index.html b/experiments/ui-datepicker/index.html
index 4f3e36e9..5d54f774 100644
--- a/experiments/ui-datepicker/index.html
+++ b/experiments/ui-datepicker/index.html
@@ -5,66 +5,34 @@
jQuery Mobile Framework - Datepicker
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
Datepicker Styled for mobile
-
+
The included files extend the jQuery UI datepicker to make it suitable for touch devices. Keep in mind that we're binding to the "mobileinit" event to set input types of "date" back to text after enhancing, so they don't clash with native datepicker implementations.
diff --git a/experiments/ui-datepicker/jquery.ui.datepicker.css b/experiments/ui-datepicker/jquery.ui.datepicker.mobile.css
old mode 100755
new mode 100644
similarity index 80%
rename from experiments/ui-datepicker/jquery.ui.datepicker.css
rename to experiments/ui-datepicker/jquery.ui.datepicker.mobile.css
index 91b2e9a9..c9853a6c
--- a/experiments/ui-datepicker/jquery.ui.datepicker.css
+++ b/experiments/ui-datepicker/jquery.ui.datepicker.mobile.css
@@ -12,8 +12,8 @@ div.hasDatepicker{ display: block; padding: 0; overflow: visible; margin: 8px 0
.ui-datepicker .ui-datepicker-header { position:relative; padding:.4em 0; border-bottom: 0; font-weight: bold; }
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { padding: 1px 0 1px 2px; position:absolute; top: .5em; margin-top: 0; text-indent: -9999px; }
-.ui-datepicker .ui-datepicker-prev { left:2px; }
-.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev { left:6px; }
+.ui-datepicker .ui-datepicker-next { right:6px; }
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
@@ -23,6 +23,10 @@ div.hasDatepicker{ display: block; padding: 0; overflow: visible; margin: 8px 0
.ui-datepicker td { border-width: 1px; padding: 0; text-align: center; }
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em 0; font-weight: bold; margin: 0; border-width: 0; text-align: center; text-decoration: none; }
+.ui-datepicker-calendar th { padding-top: .3em; padding-bottom: .3em; }
+.ui-datepicker-calendar th span, .ui-datepicker-calendar span.ui-state-default { opacity: .3; }
+.ui-datepicker-calendar td a { padding-top: .5em; padding-bottom: .5em; }
+
.min-width-480px {
div.hasDatepicker { width: 63%; display: inline-block; margin: 0; }
}
\ No newline at end of file
diff --git a/experiments/ui-datepicker/jquery.ui.datepicker.mobile.js b/experiments/ui-datepicker/jquery.ui.datepicker.mobile.js
new file mode 100644
index 00000000..9f1e168e
--- /dev/null
+++ b/experiments/ui-datepicker/jquery.ui.datepicker.mobile.js
@@ -0,0 +1,55 @@
+/*
+* jQuery Mobile Framework : temporary extension to port jQuery UI's datepicker for mobile
+* Copyright (c) jQuery Project
+* Dual licensed under the MIT or GPL Version 2 licenses.
+* http://jquery.org/license
+*/
+(function($, undefined ) {
+
+ //cache previous datepicker ui method
+ var prevDp = $.fn.datepicker;
+
+ //rewrite datepicker
+ $.fn.datepicker = function( options ){
+
+ var dp = this;
+
+ //call cached datepicker plugin
+ prevDp.call( this, options );
+
+ //extend with some dom manipulation to update the markup for jQM
+ //call immediately
+ function updateDatepicker(){
+ $( ".ui-datepicker-header", dp ).addClass("ui-body-c ui-corner-top").removeClass("ui-corner-all");
+ $( ".ui-datepicker-prev, .ui-datepicker-next", dp ).attr("href", "#");
+ $( ".ui-datepicker-prev", dp ).buttonMarkup({iconpos: "notext", icon: "arrow-l", shadow: true, corners: true});
+ $( ".ui-datepicker-next", dp ).buttonMarkup({iconpos: "notext", icon: "arrow-r", shadow: true, corners: true});
+ $( ".ui-datepicker-calendar th", dp ).addClass("ui-bar-c");
+ $( ".ui-datepicker-calendar td", dp ).addClass("ui-body-c");
+ $( ".ui-datepicker-calendar a", dp ).buttonMarkup({corners: false, shadow: false});
+ $( ".ui-datepicker-calendar a.ui-state-active", dp ).addClass("ui-btn-active"); // selected date
+ $( ".ui-datepicker-calendar a.ui-state-highlight", dp ).addClass("ui-btn-up-e"); // today"s date
+ $( ".ui-datepicker-calendar .ui-btn", dp ).each(function(){
+ var el = $(this);
+ // remove extra button markup - necessary for date value to be interpreted correctly
+ el.html( el.find( ".ui-btn-text" ).text() );
+ });
+ };
+
+ //update now
+ updateDatepicker();
+
+ // and on click
+ $( dp ).click( updateDatepicker );
+
+ //return jqm obj
+ return this;
+ };
+
+ //bind to pagecreate to automatically enhance date inputs
+ $( ".ui-page" ).live( "pagecreate", function(){
+ $( "input[type='date'], input[data-type='date']" ).each(function(){
+ $(this).after( $( "" ).datepicker({ altField: "#" + $(this).attr( "id" ), showOtherMonths: true }) );
+ });
+ });
+})( jQuery );
\ No newline at end of file
From b50d6a74c28e2cec1f0730fd9ccdf584c6983b97 Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 20:48:25 -0500
Subject: [PATCH 14/30] improved datepicker usage instructions and linked it up
from the forms index under "experimental"
---
docs/forms/index.html | 7 ++++++-
experiments/ui-datepicker/index.html | 31 +++++++++++++++++++++++++---
2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/docs/forms/index.html b/docs/forms/index.html
index 8c8cfe17..5d88d6a6 100755
--- a/docs/forms/index.html
+++ b/docs/forms/index.html
@@ -33,8 +33,13 @@
The included files extend the jQuery UI datepicker to make it suitable for touch devices. Keep in mind that we're binding to the "mobileinit" event to set input types of "date" back to text after enhancing, so they don't clash with native datepicker implementations.
-
+
The included files extend the jQuery UI datepicker to make it suitable for touch devices. This plugin is not included in jQuery Mobile by default, so you'll need to include the files yourself if you'd like to use them. Scroll down for usage instructions.
+
+
+
+
Usage Instructions
+
+
This plugin is not included in jQuery Mobile by default, so you'll need to include the following files in order to use it:
You'll also want to configure the page plugin to convert "date" input elements to "text" inputs after they're enhanced with our datepicker, so that no native datepicker will conflict with the custom one we're adding. To do this, bind to the "mobileinit" event and set input types of "date" back to text using the page plugin's options:
We'd recommend wrapping the label and input in a fieldcontain div for presentation purposes, and these elements should be placed within a form element for C-Grade browser accessibility.
+
+
Note: This plugin is not included in jQuery Mobile by default, so you'll need to include the following files in order to use it:
Be sure to place this event binding in a script that loads after jQuery, but before jQuery Mobile. Check this page's source for an example.
+
+
From 61bee4e27629583556f208d78ec8e447825defb4 Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 21:02:08 -0500
Subject: [PATCH 16/30] fixed issue with select menus not opening again after
you close them.
---
js/jquery.mobile.dialog.js | 2 +-
js/jquery.mobile.forms.select.js | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/js/jquery.mobile.dialog.js b/js/jquery.mobile.dialog.js
index b87aa537..d7229f6c 100644
--- a/js/jquery.mobile.dialog.js
+++ b/js/jquery.mobile.dialog.js
@@ -49,7 +49,7 @@ $.widget( "mobile.dialog", $.mobile.widget, {
}
})
//destroy the dialog after hiding
- .bind("pagehide",function(){
+ .bind("pagehide.dialog",function(){
self.destroy();
$(this).remove();
});
diff --git a/js/jquery.mobile.forms.select.js b/js/jquery.mobile.forms.select.js
index f892cddf..915e6b11 100644
--- a/js/jquery.mobile.forms.select.js
+++ b/js/jquery.mobile.forms.select.js
@@ -160,6 +160,9 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
$(this).blur();
button.focus();
});
+
+ //unbind dialog destroy on close
+ menuPage.unbind("pagehide.dialog");
//button events
button
From 9a492d06fd0608002793ed8b5ab9f2cf70a59a15 Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 22:04:36 -0500
Subject: [PATCH 17/30] allow form data to be passed to $.mobile.changePage as
a query string or object.
---
js/jquery.mobile.navigation.js | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/js/jquery.mobile.navigation.js b/js/jquery.mobile.navigation.js
index 957cf713..ec4d72a5 100644
--- a/js/jquery.mobile.navigation.js
+++ b/js/jquery.mobile.navigation.js
@@ -299,6 +299,10 @@
isFormRequest = true;
//make get requests bookmarkable
if( data && type == 'get' ){
+ if($.type( data ) == "object" ){
+ data = $.param(data);
+ }
+
url += "?" + data;
data = undefined;
}
From df0514337158e1293d3487beac0f679fce07eb9e Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 22:44:32 -0500
Subject: [PATCH 18/30] edited some nav model info - needs filling out, but
outdated info is removed now at least
---
docs/pages/docs-navmodel.html | 29 +++++++++--------------------
1 file changed, 9 insertions(+), 20 deletions(-)
diff --git a/docs/pages/docs-navmodel.html b/docs/pages/docs-navmodel.html
index 8faa5cb1..1cac0dd4 100644
--- a/docs/pages/docs-navmodel.html
+++ b/docs/pages/docs-navmodel.html
@@ -22,7 +22,7 @@
A "page" in jQuery Mobile consists of an element (usually a div) with a data-role attribute set to "page", which generally contains div elements with roles of "header", "content", and "footer", each containing common markup, forms, and custom jQuery Mobile widgets.
-
The basic workflow with page loading is as follows: first, a page is requested with a normal HTTP request, and subsequent "pages" are then requested and injected into that page's DOM. Because of this, the DOM may have a number of "pages" in it at a time, each of which can be re-visited by linking to its ID attribute.
+
The basic workflow with page loading is as follows: first, a page is requested with a normal HTTP request, and subsequent "pages" are then requested and injected into that page's DOM. Because of this, the DOM may have a number of "pages" in it at a time, each of which can be re-visited by linking to its data-url attribute.
When a url is initially requested, there may be one or more "pages" in the response, and only the first one will be shown. The advantage of storing more than one "page" is that it allows you to pre-fetch static pages that are likely to be visited.
@@ -52,31 +52,20 @@
jQuery Mobile manages http requests using a combination of generated absolute URL paths and manipulating a generated <base> element's href attribute. The combination of these two approaches allows us to create URLs that contain full path information for loading pages, and a base element to properly direct asset requests made by those loaded pages (such as images and stylesheets).
-
jQuery Mobile core contains 4 internal functions for manipulating a base url to be used in normalizing relative http requests:
-
Note: These functions have changed - docs will be updated soon!
-
-
getPathDir: function that returns a path with the last "/"-split segment removed (which is assumed to be a file url).
-
getBaseURL: function that returns either the location.hash, or a path specified via its argument, with the last segment removed.
-
setBaseURL: sets the <base> element's href attribute to the value of getBaseURL()
-
resetBaseURL: sets the <base> element's href attribute to the relative path of the initially-http-requested page.
-
These are called at certain times during page requests and transitions:
- On DOM ready, during the initial page load, a <base> element is created and appended to the <head> of the page. Immediately after that, resetBaseURL() is called to set the <base> element's href to location.pathname.
-
-
Whenever a link with a relative URL is clicked, the $.mobile.changePage() function will prefixed that link's href with the value of getBaseURL(), which creates a full path to that file, relative to the document.
-
-
Changing the hash value triggers the hashchange event handler, which first calls resetBaseURL(), and makes an Ajax request to the value of the hash (which is already a full path, requiring no base url). After that request is sent, setBaseURL() is called, which resets the <base> element's href attribute to the value of getBaseURL() and allows any references to images, stylesheets, and scripts within that page to be requested with a proper base path.
+
TODO: update description of internal base and urlHistory objects
+
Auto-generated pages and sub-hash urls
-
Some plugins may choose to dynamically break a page's content into separate navigable pages, which can then be reached via deep links. One example of this would be the Listview plugin, which will break a nested UL (or OL) into separate pages, which are each given an ID so they can be linked to like any normal "page" in jQuery Mobile. However, in order to link to these pages, the page that generates them must first be requested from the server. To make this work, pages that are auto-generated by plugins use the following special ID structure:
- <div id="page.html&subpageidentifier">
+
Some plugins may choose to dynamically break a page's content into separate navigable pages, which can then be reached via deep links. One example of this would be the Listview plugin, which will break a nested UL (or OL) into separate pages, which are each given a data-url attribute so they can be linked to like any normal "page" in jQuery Mobile. However, in order to link to these pages, the page that generates them must first be requested from the server. To make this work, pages that are auto-generated by plugins use the following special data-url structure:
+ <div data-url="page.html&subpageidentifier">
-
So, for example, a page generated by the listview plugin may have an ID like this: id="artists.html&ui-page=listview-1"
+
So, for example, a page generated by the listview plugin may have an data-url attribute like this: data-url="artists.html&ui-page=listview-1"
When a page is requested, jQuery Mobile knows to split the URL at "&ui-page" and make an HTTP request to the portion of the URL before that key. In the case of the listview example mentioned above, the URL would look like this: http://example.com/artists.html&ui-page=listview-1
- ...and jQuery Mobile would request artists.html, which would then generate its sub-pages, creating the div with id="artists.html&ui-page=listview-1", which it will then display as the active page.
+ ...and jQuery Mobile would request artists.html, which would then generate its sub-pages, creating the div with data-url="artists.html&ui-page=listview-1", which it will then display as the active page.
-
Note that the ID of the element contains the full URL path, not just the portion after &ui-page=. This allows jQuery Mobile to use a single consistent mechanism that matches URLs to page IDs.
+
Note that the data-url attribute of the element contains the full URL path, not just the portion after &ui-page=. This allows jQuery Mobile to use a single consistent mechanism that matches URLs to page data-url attributes.
Cases when Ajax navigation will not be used
@@ -96,7 +85,7 @@
When linking to directories, without a filename url, (such as href="typesofcats/" instead of href="typesofcats/index.html"), you must provide a trailing slash. This is because jQuery Mobile assumes the section after the last "/" character in a url is a filename, and it will remove that section when creating base urls from which future pages will be referenced.
-
Any unique assets referenced by pages in a jQuery Mobile-driven site should be placed inside the "page" element (the element with a data-role attribute of "page"). For example, links to styles and scripts that are specific to a particular page can be referenced inside that div. However, a better approach is to use jQuery Mobile's page events to trigger specific scripting when certain pages load.
+
Any unique assets referenced by pages in a jQuery Mobile-driven site should be placed inside the "page" element (the element with a data-role attribute of "page"). For example, links to styles and scripts that are specific to a particular page can be referenced inside that div. However, a better approach is to use jQuery Mobile's page events to trigger specific scripting when certain pages load. Note: you can return a page from the server with a data-url already specified in the markup, and jQuery Mobile will use that for the hash update. This allows you to ensure directory paths resolve with a trailing slash and will therefore be used in the base url path for future requests.
Conversely, any non-unique assets (those used site-wide) should be referenced in the <head> section of an HTML document, or at the very least, outside of the "page" element, to prevent running scripts more than once.
The "ui-page" key name used in sub-hash url references can be set to any value you'd like, so as to blend into your URL structure. This value is stored in jQuery.mobile.subPageUrlKey.
From 3ade4e34488554add070bfcf8774754d3e9107ea Mon Sep 17 00:00:00 2001
From: scottjehl
Date: Wed, 26 Jan 2011 22:46:06 -0500
Subject: [PATCH 19/30] removed outlines on active, focus states in favor of
theme hover states
---
themes/default/jquery.mobile.button.css | 1 +
1 file changed, 1 insertion(+)
diff --git a/themes/default/jquery.mobile.button.css b/themes/default/jquery.mobile.button.css
index e9590e73..47436a08 100644
--- a/themes/default/jquery.mobile.button.css
+++ b/themes/default/jquery.mobile.button.css
@@ -4,6 +4,7 @@
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses.
*/
.ui-btn { display: block; text-align: center; cursor:pointer; position: relative; margin: .5em 5px; padding: 0; }
+.ui-btn:focus, .ui-btn:active { outline: none; }
.ui-header .ui-btn, .ui-footer .ui-btn, .ui-bar .ui-btn { display: inline-block; font-size: 13px; margin: 0; }
.ui-btn-inline { display: inline-block; }
.ui-btn-inner { padding: .6em 25px; display: block; height: 100%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; position: relative; }
From b81248f2381659cfa83c4959af5f1c3512ac8327 Mon Sep 17 00:00:00 2001
From: John Bender
Date: Wed, 26 Jan 2011 21:20:40 -0800
Subject: [PATCH 20/30] fixed android select menu failure with a delay. I'm
doubtful that this is the best solution to the problem but the cause was the
click being passed through to the screen or the select menu itself a split
second after opening. Open to alternatives. Fixes #873
---
js/jquery.mobile.forms.select.js | 41 +++++++++++++++++-------------
tests/unit/select/index.html | 9 +++++++
tests/unit/select/select_events.js | 32 +++++++++++++++++++++++
3 files changed, 64 insertions(+), 18 deletions(-)
diff --git a/js/jquery.mobile.forms.select.js b/js/jquery.mobile.forms.select.js
index db6689dd..e8d79ba5 100644
--- a/js/jquery.mobile.forms.select.js
+++ b/js/jquery.mobile.forms.select.js
@@ -156,7 +156,6 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
//support for using the native select menu with a custom button
if( o.useNativeMenu ){
-
select
.appendTo(button)
.bind( "touchstart mousedown", function( e ){
@@ -176,8 +175,7 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
});
button.attr( "tabindex", "-1" );
- }
- else {
+ } else {
select
.attr( "tabindex", "-1" )
.focus(function(){
@@ -197,7 +195,7 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
//button events
button
- .bind( "touchstart" ,function( event ){
+ .bind( "touchstart" , function( event ){
//set startTouches to cached copy of
$( this ).data( "startTouches", $.extend({}, event.originalEvent.touches[ 0 ]) );
})
@@ -205,8 +203,7 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
//if it's a scroll, don't open
if( $( this ).data( "moved" ) ){
$( this ).removeData( "moved" );
- }
- else{
+ } else {
self.open();
}
event.preventDefault();
@@ -222,12 +219,10 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
$( this ).data( "moved", true );
}
});
-
}
//events for list items
list.delegate("li:not(.ui-disabled, .ui-li-divider)", "click", function(event){
-
// clicking on the list item fires click on the link in listview.js.
// to prevent this handler from firing twice if the link isn't clicked on,
// short circuit unless the target is the link
@@ -260,16 +255,19 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
});
//events on "screen" overlay + close button
- screen.add( headerClose ).add( menuPageClose ).click(function(event){
- self.close();
- event.preventDefault();
+ screen
+ .add( headerClose )
+ .add( menuPageClose )
+ .bind("click", function(event){
+ self.close();
+ event.preventDefault();
- // if the dialog's close icon was clicked, prevent the dialog's close
- // handler from firing. selectmenu's should take precedence
- if( $.contains(menuPageClose[0], event.target) ){
- event.stopImmediatePropagation();
- }
- });
+ // if the dialog's close icon was clicked, prevent the dialog's close
+ // handler from firing. selectmenu's should take precedence
+ if( $.contains(menuPageClose[0], event.target) ){
+ event.stopImmediatePropagation();
+ }
+ });
},
_buildList: function(){
@@ -457,10 +455,15 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
focusMenuItem();
}
+
+ // wait before the dialog can be closed
+ setTimeout(function(){
+ self.isOpen = true;
+ }, 400);
},
close: function(){
- if( this.options.disabled ){ return; }
+ if( this.options.disabled || !this.isOpen ){ return; }
var self = this;
function focusButton(){
@@ -484,6 +487,8 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
focusButton();
}
+ // allow the dialog to be closed again
+ this.isOpen = false;
},
disable: function(){
diff --git a/tests/unit/select/index.html b/tests/unit/select/index.html
index 0d932231..0aeae0b9 100644
--- a/tests/unit/select/index.html
+++ b/tests/unit/select/index.html
@@ -61,6 +61,15 @@
+
+
+
+
+
+
+
+
Data attribute support
+
You can specify any jQuery Mobile button data- attribute on a select element too. In this example, we're setting the theme, icon and inline properties though data- attributes.
+
+
+
+
+
+
+
+
From d1ab6bb02761e3d04d5ea0ab4ea76e58e8dfdfba Mon Sep 17 00:00:00 2001
From: John Bender
Date: Thu, 27 Jan 2011 22:44:23 -0800
Subject: [PATCH 24/30] fixed broken select menu test
---
tests/unit/select/select_events.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/unit/select/select_events.js b/tests/unit/select/select_events.js
index 4867f118..7da894c8 100644
--- a/tests/unit/select/select_events.js
+++ b/tests/unit/select/select_events.js
@@ -16,7 +16,7 @@
same(menu.parents('.ui-dialog').length, 1);
// select and close the dialog
- menu.find('li').click();
+ menu.parents('ui-dialog').find("span.ui-icon-delete").click();
//bring up the dialog again
select.trigger(mouseUpTouchEnd);
From 3197f7e61a505cba0b171d237286fc73b0a060d3 Mon Sep 17 00:00:00 2001
From: John Bender
Date: Thu, 27 Jan 2011 22:50:40 -0800
Subject: [PATCH 25/30] corrected a duplicate id which was causing the two
similarly identified selects to have doubled menu page header titles
---
docs/forms/forms-all.html | 58 +++++++++++++++++++--------------------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/docs/forms/forms-all.html b/docs/forms/forms-all.html
index 83d8d118..665988fb 100755
--- a/docs/forms/forms-all.html
+++ b/docs/forms/forms-all.html
@@ -1,14 +1,14 @@
-
-
+
+
-
- jQuery Mobile Docs - Forms
-
+
+ jQuery Mobile Docs - Forms
+
-
-
+
+
@@ -17,43 +17,43 @@
-
+
-
\ No newline at end of file
+
From 1afb3a08f0638b9407d2a788ab13d3e0feb6303c Mon Sep 17 00:00:00 2001
From: John Bender
Date: Thu, 27 Jan 2011 22:53:17 -0800
Subject: [PATCH 26/30] whitespace corrections in core
---
js/jquery.mobile.core.js | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/js/jquery.mobile.core.js b/js/jquery.mobile.core.js
index 4464da24..d8c041ab 100644
--- a/js/jquery.mobile.core.js
+++ b/js/jquery.mobile.core.js
@@ -29,14 +29,14 @@
//automatically handle clicks and form submissions through Ajax, when same-domain
ajaxEnabled: true,
-
- // TODO: deprecated - remove at 1.0
- //automatically handle link clicks through Ajax, when possible
- ajaxLinksEnabled: true,
- // TODO: deprecated - remove at 1.0
- //automatically handle form submissions through Ajax, when possible
- ajaxFormsEnabled: true,
+ // TODO: deprecated - remove at 1.0
+ //automatically handle link clicks through Ajax, when possible
+ ajaxLinksEnabled: true,
+
+ // TODO: deprecated - remove at 1.0
+ //automatically handle form submissions through Ajax, when possible
+ ajaxFormsEnabled: true,
//set default transition - 'none' for no transitions
defaultTransition: 'slide',
From e5fd56985c4d386ded5d4f1923b22e3cbb6f1788 Mon Sep 17 00:00:00 2001
From: John Bender
Date: Thu, 27 Jan 2011 23:20:57 -0800
Subject: [PATCH 27/30] added global native select configuration, docs to
follow. Also corrected selector error when reloading a lib in tests
---
js/jquery.mobile.core.js | 2 ++
js/jquery.mobile.forms.select.js | 4 ++--
tests/jquery.testHelper.js | 2 +-
tests/unit/select/index.html | 18 ++++++++++++++++++
tests/unit/select/select_events.js | 9 +++++++--
5 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/js/jquery.mobile.core.js b/js/jquery.mobile.core.js
index d8c041ab..348564a6 100644
--- a/js/jquery.mobile.core.js
+++ b/js/jquery.mobile.core.js
@@ -48,6 +48,8 @@
//configure meta viewport tag's content attr:
metaViewportContent: "width=device-width, minimum-scale=1, maximum-scale=1",
+ nativeSelectMenus: false,
+
//support conditions that must be met in order to proceed
gradeA: function(){
return $.support.mediaquery;
diff --git a/js/jquery.mobile.forms.select.js b/js/jquery.mobile.forms.select.js
index 0d42b07e..b4eaa1e1 100644
--- a/js/jquery.mobile.forms.select.js
+++ b/js/jquery.mobile.forms.select.js
@@ -116,7 +116,7 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
menuType;
// set to native menu
- o.useNativeMenu = select.is( "[data-native]");
+ o.useNativeMenu = $.mobile.nativeSelectMenus || select.is( "[data-native]" );
// add counter for multi selects
if( isMultiple ){
@@ -159,7 +159,7 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
.change(function(){
self.refresh();
});
-
+
//unbind dialog destroy on close
menuPage.unbind("pagehide.dialog");
diff --git a/tests/jquery.testHelper.js b/tests/jquery.testHelper.js
index 35a28269..b1d94bad 100644
--- a/tests/jquery.testHelper.js
+++ b/tests/jquery.testHelper.js
@@ -21,7 +21,7 @@
reloadLib: function(libName){
if(this.reloads[libName] === undefined) {
this.reloads[libName] = {
- lib: $("script[src$=" + libName + "]"),
+ lib: $("script[src$='" + libName + "']"),
count: 0
};
}
diff --git a/tests/unit/select/index.html b/tests/unit/select/index.html
index 0aeae0b9..b2cdcee8 100644
--- a/tests/unit/select/index.html
+++ b/tests/unit/select/index.html
@@ -70,6 +70,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/unit/select/select_events.js b/tests/unit/select/select_events.js
index 7da894c8..8b23a65c 100644
--- a/tests/unit/select/select_events.js
+++ b/tests/unit/select/select_events.js
@@ -3,9 +3,10 @@
*/
(function($){
- var mouseUpTouchEnd = $.support.touch ? "touchend" : "mouseup";
+ var mouseUpTouchEnd = $.support.touch ? "touchend" : "mouseup",
+ libName = "jquery.mobile.forms.select.js";
- module('jquery.mobile.select.js');
+ module(libName);
test( "a large select menu should come up in a dialog many times", function(){
var menu, select = $("#select-choice-many-container a");
@@ -54,4 +55,8 @@
stop();
});
+ test( "selects marked with data-native=true should not bring up the custom menu", function(){
+ $("#select-choice-native-button").trigger(mouseUpTouchEnd);
+ same($("#select-choice-native-menu").parent(".ui-selectmenu-hidden").length, 1);
+ });
})(jQuery);
\ No newline at end of file
From 2dfa09bcf7c96ec43dca3c029032f0faa5b43fd4 Mon Sep 17 00:00:00 2001
From: John Bender
Date: Thu, 27 Jan 2011 23:42:56 -0800
Subject: [PATCH 28/30] updated docs to include $.mobile.nativeSelectMenus
---
docs/forms/docs-forms.html | 48 +++++++++++----------
docs/forms/forms-selects.html | 80 +++++++++++++++++++----------------
2 files changed, 68 insertions(+), 60 deletions(-)
diff --git a/docs/forms/docs-forms.html b/docs/forms/docs-forms.html
index df42b651..11b429f8 100755
--- a/docs/forms/docs-forms.html
+++ b/docs/forms/docs-forms.html
@@ -1,15 +1,15 @@
-
-
+
+
-
- jQuery Mobile Docs - Forms
-
+
+ jQuery Mobile Docs - Forms
+
-
-
+
+
If no items are selected, the button's text will default to the placeholder text.
If no placeholder element exists, the default button text will be blank and the header will appear with just a close button. Because this isn't a friendly user experience, we recommended that you always specify a placeholder element when using multiple select boxes.
When a select is large enough to where the menu will open in a new page, the placeholder text is displayed in the button when no items are selected, and the label text is displayed in the menu's header. This differs from smaller overlay menus where the placeholder text is displayed in both the button and the header, and from full-page single selects where the placeholder text is not used at all.
You can specify any jQuery Mobile button data- attribute on a select element too. In this example, we're setting the theme, icon and inline properties though data- attributes.
-
+
You can specify any jQuery Mobile button data- attribute on a select element too. In this example, we're setting the theme, icon and inline properties though data- attributes.