Merge branch 'master' into fastclick

This commit is contained in:
Kin Blas 2011-01-28 13:05:05 -08:00
commit a4a18c9934
24 changed files with 633 additions and 287 deletions

View file

@ -1,15 +1,15 @@
<!DOCTYPE html>
<html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery Mobile Docs - Forms</title>
<link rel="stylesheet" href="../../themes/default/" />
<meta charset="utf-8" />
<title>jQuery Mobile Docs - Forms</title>
<link rel="stylesheet" href="../../themes/default/" />
<link rel="stylesheet" href="../_assets/css/jqm-docs.css"/>
<script type="text/javascript" src="../../js/jquery.js"></script>
<script type="text/javascript" src="../../js/"></script>
<script type="text/javascript" src="../docs/docs.js"></script>
</head>
<body>
</head>
<body>
<div data-role="page">
@ -18,13 +18,13 @@
</div><!-- /header -->
<div data-role="content">
<p>jQuery Mobile provides a complete set of finger-friendly form elements that are based on native HTML form elements.</p>
<h2>Form structure</h2>
<p>All forms should be wrapped in a <code>form</code> tag that has an <code>action</code> and <code>method</code> that will handle the form data processing on the server.</p>
<code>
&lt;form action=&quot;form.php&quot; method=&quot;post&quot;&gt;
...
@ -37,10 +37,10 @@
<h2>Auto-initialization of form elements</h2>
<p>By default, jQuery Mobile will automatically enhance certain native form controls into rich touch-friendly components. This is handled internally by finding form elements by tag name and running a plugin method on them, so for instance, a <code>select</code> element will be found and initialized with the "selectmenu" plugin, while an <code>input</code> element with a <code>type="checkbox"</code> will be enhanced with the "checkboxradio" plugin. Once initialized, you can address these enhanced components programmatically through their jQuery UI widget API methods (see documentation on available methods here: <a href="plugin-eventsmethods.html">Form Plugin Methods</a>). </p>
<h2>Preventing auto-initialization of form elements</h2>
<p>If you'd prefer that a particular form control be left untouched by jQuery Mobile, simply give that element the attribute <code>data-role="none"</code>. For example:</p>
<pre><code>
<pre><code>
&lt;label for=&quot;foo&quot;&gt;
&lt;select name=&quot;foo&quot; id=&quot;foo&quot; <strong>data-role=&quot;none&quot;</strong>&gt;
&lt;option value="a" &gt;A&lt;/option&gt;
@ -48,34 +48,36 @@
&lt;option value="c" &gt;C&lt;/option&gt;
&lt;/select&gt;
</code></pre>
<p>Or, if you'd like to prevent auto-initialization without adding attributes to your markup, you can customize the selector that is used for preventing auto-initialization by setting the page plugin's <code>keepNative</code> option (which defaults to <code>"[data-role="none"]</code>. Be sure to configure this option inside an event handler bound to the <code>mobileinit</code> event, so that it applies to the first page as well as subsequent pages that are loaded.</p>
<pre><code>
$(document).bind('mobileinit',function(){
<strong>$.mobile.page.prototype.options.keepNative = "select, input.foo, textarea.bar";</strong>
});
});
</pre></code>
<p>One special case is that of selects. The above sample will prevent any and all augmentation from taking place on select elements in the page if <code>select</code> is included. If you wish to retain the native performance, look/feel of the menu itself and benefit from the visual augmentation of the select button by jQuery Mobile you can set $.mobile.nativeSelectMenu to true in a <code>mobileinit</code> callback as a global setting or use <code>data-native="true"</code> on a case by case basis.</p>
<h2>Dynamic form layout</h2>
<p>In jQuery Mobile, all form elements are designed to be a flexible width so they will comfortably fit the width of any mobile device. One optimization built into the framework is that we present labels and form elements differently based on screen width. </p>
<p>If a page is fairly narrow (~480px), the labels are styled as block-level elements so they will stack on top of the form element to save horizontal space.</p>
<p>If a page is fairly narrow (~480px), the labels are styled as block-level elements so they will stack on top of the form element to save horizontal space.</p>
<p>On wider screens, the labels and form elements are styled to be on the same line in a 2-column layout to take advantage of the screen real estate.</p>
<h2>Field containers</h2>
<p>To improve the styling to labels and form elements on wider screens, we recommend wrapping a <code>div</code> or <code>fieldset </code>with the <code>data-role="fieldcontain"</code> attribute around each label/form element. The framework will add a thin vertical bottom border on this container to act as a field separator and visually align the label and form elements for quick scanning.</p>
<pre><code>
<pre><code>
&lt;div data-role=&quot;fieldcontain&quot;&gt;
...label/input code goes here...
&lt;/div&gt;
</code></pre>
</div><!-- /content -->
</div><!-- /page -->
</body>
</html>
</html>

View file

@ -1,14 +1,14 @@
<!DOCTYPE html>
<html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery Mobile Docs - Forms</title>
<link rel="stylesheet" href="../../themes/default/" />
<meta charset="utf-8" />
<title>jQuery Mobile Docs - Forms</title>
<link rel="stylesheet" href="../../themes/default/" />
<link rel="stylesheet" href="../_assets/css/jqm-docs.css"/>
<script type="text/javascript" src="../../js/jquery.js"></script>
<script type="text/javascript" src="../../js/"></script>
</head>
<body>
</head>
<body>
<div data-role="page">
@ -17,43 +17,43 @@
</div><!-- /header -->
<div data-role="content">
<form action="#" method="get">
<h2>Form elements</h2>
<p>This page contains various progressive-enhancement driven form controls. Native elements are sometimes hidden from view, but their values are maintained so the form can be submitted normally. </p>
<p>Browsers that don't support the custom controls will still deliver a usable experience, because all are based on native form elements.</p>
<div data-role="fieldcontain">
<label for="name">Text Input:</label>
<input type="text" name="name" id="name" value="" />
</div>
<div data-role="fieldcontain">
<label for="textarea">Textarea:</label>
<textarea cols="40" rows="8" name="textarea" id="textarea"></textarea>
</div>
<div data-role="fieldcontain">
<label for="search">Search Input:</label>
<input type="search" name="password" id="search" value="" />
</div>
<div data-role="fieldcontain">
<label for="slider2">Flip switch:</label>
<select name="slider2" id="slider2" data-role="slider">
<option value="off">Off</option>
<option value="on">On</option>
</select>
</select>
</div>
<div data-role="fieldcontain">
<label for="slider">Slider:</label>
<input type="range" name="slider" id="slider" value="0" min="0" max="100" />
</div>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>Choose as many snacks as you'd like:</legend>
@ -62,7 +62,7 @@
<input type="checkbox" name="checkbox-2a" id="checkbox-2a" class="custom" />
<label for="checkbox-2a">Doritos</label>
<input type="checkbox" name="checkbox-3a" id="checkbox-3a" class="custom" />
<label for="checkbox-3a">Fritos</label>
@ -70,7 +70,7 @@
<label for="checkbox-4a">Sun Chips</label>
</fieldset>
</div>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup" data-type="horizontal">
<legend>Font styling:</legend>
@ -81,10 +81,10 @@
<label for="checkbox-7"><em>i</em></label>
<input type="checkbox" name="checkbox-8" id="checkbox-8" class="custom" />
<label for="checkbox-8">u</label>
<label for="checkbox-8">u</label>
</fieldset>
</div>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>Choose a pet:</legend>
@ -101,7 +101,7 @@
<label for="radio-choice-4">Lizard</label>
</fieldset>
</div>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup" data-type="horizontal">
<legend>Layout view:</legend>
@ -113,7 +113,7 @@
<label for="radio-choice-e">Gallery</label>
</fieldset>
</div>
<div data-role="fieldcontain">
<label for="select-choice-1" class="select">Choose shipping method:</label>
<select name="select-choice-1" id="select-choice-1">
@ -123,10 +123,11 @@
<option value="overnight">Overnight</option>
</select>
</div>
<div data-role="fieldcontain">
<label for="select-choice-3" class="select">Your state:</label>
<select name="select-choice-3" id="select-choice-3">
<option>Custom menu...</option>
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
@ -180,17 +181,73 @@
</select>
</div>
<div data-role="fieldcontain">
<label for="select-choice-native" class="select">Your state:</label>
<select name="select-choice-native" id="select-choice-native" data-native="true">
<option>Native menu...</option>
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
<option value="DE">Delaware</option>
<option value="FL">Florida</option>
<option value="GA">Georgia</option>
<option value="HI">Hawaii</option>
<option value="ID">Idaho</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="KS">Kansas</option>
<option value="KY">Kentucky</option>
<option value="LA">Louisiana</option>
<option value="ME">Maine</option>
<option value="MD">Maryland</option>
<option value="MA">Massachusetts</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="MO">Missouri</option>
<option value="MT">Montana</option>
<option value="NE">Nebraska</option>
<option value="NV">Nevada</option>
<option value="NH">New Hampshire</option>
<option value="NJ">New Jersey</option>
<option value="NM">New Mexico</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="ND">North Dakota</option>
<option value="OH">Ohio</option>
<option value="OK">Oklahoma</option>
<option value="OR">Oregon</option>
<option value="PA">Pennsylvania</option>
<option value="RI">Rhode Island</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="TX">Texas</option>
<option value="UT">Utah</option>
<option value="VT">Vermont</option>
<option value="VA">Virginia</option>
<option value="WA">Washington</option>
<option value="WV">West Virginia</option>
<option value="WI">Wisconsin</option>
<option value="WY">Wyoming</option>
</select>
</div>
<div class="ui-body ui-body-b">
<fieldset class="ui-grid-a">
<div class="ui-block-a"><button type="submit" data-theme="d">Cancel</button></div>
<div class="ui-block-b"><button type="submit" data-theme="a">Submit</button></div>
<div class="ui-block-b"><button type="submit" data-theme="a">Submit</button></div>
</fieldset>
</div>
</form>
</div><!-- /content -->
</div><!-- /page -->
</body>
</html>
</html>

View file

@ -1,15 +1,15 @@
<!DOCTYPE html>
<html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery Mobile Docs - Forms</title>
<link rel="stylesheet" href="../../themes/default/" />
<meta charset="utf-8" />
<title>jQuery Mobile Docs - Forms</title>
<link rel="stylesheet" href="../../themes/default/" />
<link rel="stylesheet" href="../_assets/css/jqm-docs.css"/>
<script type="text/javascript" src="../../js/jquery.js"></script>
<script type="text/javascript" src="../../js/"></script>
<script type="text/javascript" src="../docs/docs.js"></script>
</head>
<body>
</head>
<body>
<div data-role="page">
@ -18,19 +18,19 @@
</div><!-- /header -->
<div data-role="content">
<form action="#" method="get">
<h2>Select menus</h2>
<p>The select menus are driven off native <code>select</code> elements, but the native selects are hidden from view and replaced with more style-friendly markup. The replacement buttons and menus are ARIA-enabled and are keyboard accessible on the desktop as well. </p>
<p>When clicked, if the menu has room it will appear as an overlay listbox, but if there are too many options to fit in the window without scrolling, the page content is wrapped in a div and hidden, and the menu is appended as a whole new page. This lets us take advantage of native scrolling while the menu is in use. </p>
<p>To add a select widget to your page, start with a standard <code>select</code> element populated with a set of <code>option</code> elements. Set the <code>for</code> attribute of the <code>label</code> to match the ID of the <code>select</code> so they are semantically associated. Wrap them in a <code>div</code> with the <code>data-role="fieldcontain"</code> attribute to help visually group it in a longer form. </p>
<p>The framework will find all <code>select</code> elements and automatically enhance them into the custom select menus.</p>
<pre><code>
<pre><code>
&lt;div data-role=&quot;fieldcontain&quot;&gt;
&lt;label for=&quot;select-choice-1&quot; class=&quot;select&quot;&gt;Choose shipping method:&lt;/label&gt;
&lt;select name=&quot;select-choice-1&quot; id=&quot;select-choice-1&quot;&gt;
@ -41,7 +41,7 @@
&lt;/select&gt;
&lt;/div&gt;
</code></pre>
<p> If there is a small number of options that will fit on the device's screen, it will appear as a small overlay with a pop transition.</p>
<div data-role="fieldcontain">
@ -114,36 +114,95 @@
</div>
<h2>Data attribute support</h2>
<p>You can specify any jQuery Mobile button data- attribute on a select element too.</p>
<div data-role="fieldcontain">
<label for="select-choice-11" class="select">Actions</label>
<select name="select-choice-11" id="select-choice-11" data-theme="a" data-icon="gear" data-inline="true">
<option value="edit">Edit</option>
<option value="delete">Delete</option>
</select>
</div>
<h2>Option to use native menus</h2>
<p>The custom select menus add the ability to theme the select and provide visual consistency across platforms In addition, it fixes over some missing functionality on certain platforms: <code>optgroup</code> support on Android, multi-select capability on WebOS, and adds an elegant way to handle placeholder values (explained below).</p>
<p>However, there is overhead involved in parsing the native select to build a custom menu and if the number of selects or options within are fairly large, this can impact the performance of the page. By adding the <code>data-native="true"</code> attribute to the <code>select</code>, the framework will use the browser's native select menu when the select button is clicked. Because this option doesn't use any of the custom menu parsing and menu generation logic, it is significantly faster than the custom menu version.</p>
<p>You can also set the global configuration <code>$.mobile.nativeSelectMenus</code> to true in a callback bound to the <code>mobileinit</code> event to achieve the same effect. The following must be included in the page after jQuery is loaded but before jQuery Mobile.</p>
<code>
<pre>
$(document).bind('mobileinit',function(){
$.mobile.nativeSelectMenus = true;
});
</pre>
</code>
<div data-role="fieldcontain">
<label for="select-choice-3" class="select">Your state:</label>
<select name="select-choice-3" id="select-choice-3" data-native="true">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
<option value="DE">Delaware</option>
<option value="FL">Florida</option>
<option value="GA">Georgia</option>
<option value="HI">Hawaii</option>
<option value="ID">Idaho</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="KS">Kansas</option>
<option value="KY">Kentucky</option>
<option value="LA">Louisiana</option>
<option value="ME">Maine</option>
<option value="MD">Maryland</option>
<option value="MA">Massachusetts</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="MO">Missouri</option>
<option value="MT">Montana</option>
<option value="NE">Nebraska</option>
<option value="NV">Nevada</option>
<option value="NH">New Hampshire</option>
<option value="NJ">New Jersey</option>
<option value="NM">New Mexico</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="ND">North Dakota</option>
<option value="OH">Ohio</option>
<option value="OK">Oklahoma</option>
<option value="OR">Oregon</option>
<option value="PA">Pennsylvania</option>
<option value="RI">Rhode Island</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="TX">Texas</option>
<option value="UT">Utah</option>
<option value="VT">Vermont</option>
<option value="VA">Virginia</option>
<option value="WA">Washington</option>
<option value="WV">West Virginia</option>
<option value="WI">Wisconsin</option>
<option value="WY">Wyoming</option>
</select>
</div>
<h2>Placeholder options</h2>
<p>It's common for developers to include a &quot;null&quot; option in their select element to force a user to choose an option. If a placeholder option is present in your markup, jQuery Mobile will hide them in the overlay menu, showing only valid choices to the user, and display the placeholder text inside the menu as a header. Examples of null options are either:</p>
<p>It's common for developers to include a &quot;null&quot; option in their select element to force a user to choose an option. If a placeholder option is present in your markup, jQuery Mobile will hide them in the overlay menu, showing only valid choices to the user, and display the placeholder text inside the menu as a header. A placeholder option is added when the framework finds:</p>
<ul>
<li>An option with no value attribute (or an empty value attribute)</li>
<li>An option with no text node</li>
<li>An option with a <code>data-placeholder="true"</code> attribute. (This allows you to use an option that has a value and a textnode as a placeholder option).</li>
</ul>
<p>You can disable this feature through the selectmenu plugin's <code>hidePlaceholderMenuItems</code> option, like this:</p>
<pre>
<code>
$.mobile.selectmenu.prototype.options.hidePlaceholderMenuItems = false;
</code>
</pre>
<p>Here's a demo of various placeholder options:</p>
<div data-role="fieldcontain">
<label for="select-choice-4" class="select">Choose shipping method:</label>
<select name="select-choice-4" id="select-choice-4">
@ -153,9 +212,9 @@ $.mobile.selectmenu.prototype.options.hidePlaceholderMenuItems = false;
<option value="express">Express: next day</option>
<option value="overnight">Overnight</option>
</select>
</div>
</div>
<div data-role="fieldcontain">
<label for="select-choice-5" class="select">Choose shipping method:</label>
<select name="select-choice-5" id="select-choice-5">
@ -166,8 +225,8 @@ $.mobile.selectmenu.prototype.options.hidePlaceholderMenuItems = false;
<option value="overnight">Overnight</option>
</select>
</div>
<div data-role="fieldcontain">
<label for="select-choice-6" class="select">Choose shipping method:</label>
<select name="select-choice-6" id="select-choice-6">
@ -178,7 +237,7 @@ $.mobile.selectmenu.prototype.options.hidePlaceholderMenuItems = false;
<option value="overnight">Overnight</option>
</select>
</div>
<h2>Disabled options</h2>
<p>jQuery Mobile will automatically disable and style option tags with the <code>disabled</code> attribute. In the demo below, the second option &quot;Rush: 3 days&quot; has been set to disabled.</p>
@ -191,7 +250,7 @@ $.mobile.selectmenu.prototype.options.hidePlaceholderMenuItems = false;
<option value="overnight">Overnight</option>
</select>
</div>
<h2>Optgroup support</h2>
<p>If a select menu contains <code>optgroup</code> elements, jQuery Mobile will create a divider &amp; group items based on the <code>label</code> attribute's text:</p>
@ -211,11 +270,11 @@ $.mobile.selectmenu.prototype.options.hidePlaceholderMenuItems = false;
</optgroup>
</select>
</div>
<h2>Multiple selects</h2>
<p>If the <code>multiple</code> attribute is present in your markup, jQuery Mobile will enhance the element with a few extra considerations:</p>
<ul>
<li>A header element will be created inside the menu and display the placeholder text and a close button.</li>
<li>Clicking on an item inside the overlay menu will not close the widget.</li>
@ -225,7 +284,7 @@ $.mobile.selectmenu.prototype.options.hidePlaceholderMenuItems = false;
<li>If no items are selected, the button's text will default to the placeholder text.</li>
<li>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.</li>
</ul>
<div data-role="fieldcontain">
<label for="select-choice-9" class="select">Choose shipping method(s):</label>
<select name="select-choice-9" id="select-choice-9" multiple="multiple">
@ -236,9 +295,9 @@ $.mobile.selectmenu.prototype.options.hidePlaceholderMenuItems = false;
<option value="overnight">Overnight</option>
</select>
</div>
<p>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 <code>label</code> 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.</p>
<div data-role="fieldcontain">
<label for="select-choice-10" class="select">Choose state(s):</label>
<select name="select-choice-10" id="select-choice-10" multiple="multiple">
@ -296,6 +355,19 @@ $.mobile.selectmenu.prototype.options.hidePlaceholderMenuItems = false;
</select>
</div>
<h2>Data attribute support</h2>
<p>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.</p>
<div data-role="fieldcontain">
<label for="select-choice-11" class="select">Actions</label>
<select name="select-choice-11" id="select-choice-11" data-theme="a" data-icon="gear" data-inline="true">
<option value="edit">Edit user</option>
<option value="delete">Delete user</option>
</select>
</div>
</form>
</div><!-- /content -->
</div><!-- /page -->

View file

@ -33,8 +33,13 @@
<li><a href="forms-themes.html">Theming forms</a></li>
<li><a href="forms-sample.html">Submitting forms</a></li>
<li><a href="plugin-eventsmethods.html">Plugin methods</a></li>
<!--<li><a href="api-forms.html">API documentation</a></li>-->
</ul>
<ul data-role="listview" data-inset="true">
<li data-role="list-divider">Experimental Form Plugins</li>
<li><a href="../../experiments/ui-datepicker/" rel="external">Datepicker</a></li>
</ul>
</div><!-- /ui-body wrapper -->
</div><!-- /page -->

View file

@ -22,7 +22,7 @@
<p>A "page" in jQuery Mobile consists of an element (usually a <code>div</code>) with a <code>data-role</code> attribute set to <code>"page"</code>, which generally contains <code>div</code> elements with roles of <code>"header"</code>, <code>"content"</code>, and <code>"footer"</code>, each containing common markup, forms, and custom jQuery Mobile widgets.</p>
<p>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 <code>ID</code> attribute.</p>
<p>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 <code>data-url</code> attribute.</p>
<p>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.</p>
@ -52,31 +52,20 @@
<p>jQuery Mobile manages http requests using a combination of generated absolute URL paths and manipulating a generated <code>&lt;base&gt;</code> 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).</p>
<p>jQuery Mobile core contains 4 internal functions for manipulating a base url to be used in normalizing relative http requests:</p>
<p><strong>Note: These functions have changed - docs will be updated soon!</strong></p>
<ul>
<li><p>getPathDir: function that returns a path with the last "/"-split segment removed (which is assumed to be a file url).</p></li>
<li><p>getBaseURL: function that returns either the location.hash, or a path specified via its argument, with the last segment removed.</p></li>
<li><p>setBaseURL: sets the <code>&lt;base&gt;</code> element's <code>href</code> attribute to the value of <code>getBaseURL()</code></p></li>
<li><p>resetBaseURL: sets the <code>&lt;base&gt;</code> element's <code>href</code> attribute to the relative path of the initially-http-requested page.</p></li>
</ul><p>These are called at certain times during page requests and transitions:
On DOM ready, during the initial page load, a <code>&lt;base&gt;</code> element is created and appended to the <code>&lt;head&gt;</code> of the page. Immediately after that, <code>resetBaseURL()</code> is called to set the <code>&lt;base&gt;</code> element's href to <code>location.pathname</code>.</p>
<p>Whenever a link with a relative URL is clicked, the <code>$.mobile.changePage()</code> function will prefixed that link's href with the value of <code>getBaseURL()</code>, which creates a full path to that file, relative to the document.</p>
<p>Changing the hash value triggers the hashchange event handler, which first calls <code>resetBaseURL()</code>, 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, <code>setBaseURL()</code> is called, which resets the <code>&lt;base&gt;</code> element's <code>href</code> attribute to the value of <code>getBaseURL()</code> and allows any references to images, stylesheets, and scripts within that page to be requested with a proper base path.</p>
<p><strong>TODO: update description of internal base and urlHistory objects</strong></p>
<h2>Auto-generated pages and sub-hash urls</h2>
<p>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:
<code>&lt;div id="page.html&amp;subpageidentifier"&gt;</code></p>
<p>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:
<code>&lt;div data-url="page.html&amp;subpageidentifier"&gt;</code></p>
<p>So, for example, a page generated by the listview plugin may have an ID like this: <code>id="artists.html&amp;ui-page=listview-1"</code></p>
<p>So, for example, a page generated by the listview plugin may have an data-url attribute like this: <code>data-url="artists.html&amp;ui-page=listview-1"</code></p>
<p>When a page is requested, jQuery Mobile knows to split the URL at "&amp;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&amp;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&amp;ui-page=listview-1", which it will then display as the active page.</p>
...and jQuery Mobile would request artists.html, which would then generate its sub-pages, creating the div with data-url="artists.html&amp;ui-page=listview-1", which it will then display as the active page.</p>
<p><em>Note that the ID of the element contains the full URL path, not just the portion after &amp;ui-page=. This allows jQuery Mobile to use a single consistent mechanism that matches URLs to page IDs.</em></p>
<p><em>Note that the data-url attribute of the element contains the full URL path, not just the portion after &amp;ui-page=. This allows jQuery Mobile to use a single consistent mechanism that matches URLs to page data-url attributes.</em></p>
<h2>Cases when Ajax navigation will not be used</h2>
@ -96,7 +85,7 @@
<ul>
<li><p>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.</p></li>
<li><p>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.</p></li>
<li><p>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. <strong>Note: </strong> 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.</p></li>
<li><p>Conversely, any non-unique assets (those used site-wide) should be referenced in the <code>&lt;head&gt;</code> section of an HTML document, or at the very least, outside of the "page" element, to prevent running scripts more than once.</p></li>
<li><p>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 <code>jQuery.mobile.subPageUrlKey</code>.</p></li>
</ul>

View file

@ -1,36 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery Mobile Framework - Static Progressbar Example</title>
<link rel="stylesheet" href="themes/default/" />
<script type="text/javascript" src="../../js/jquery.js"></script>
<script type="text/javascript" src="../../js/"></script>
</head>
<body>
<div data-role="page" class="ui-body-c">
<div data-role="header">
<h1>Static Progressbar</h1>
</div>
<div data-role="content">
<h2>Just a simple static progressbar, for future reference.</h2>
<style type="text/css">
.progress { margin: 1em 0; }
.progress-filled { height: 1.5em; margin: -1px; }
</style>
<div class="progress ui-bar-c ui-btn-corner-all">
<div class="progress-filled ui-btn-up-b ui-btn-corner-left" style="width: 30%;"></div>
</div>
</div>
</div>
</body>
</html>

View file

@ -5,67 +5,71 @@
<title>jQuery Mobile Framework - Datepicker</title>
<link rel="stylesheet" href="../../themes/default/" />
<link rel="stylesheet" href="../../docs/_assets/css/jqm-docs.css" />
<script type="text/javascript" src="../../js/jquery.js"></script>
<script type="text/javascript" src="../../js/"></script>
<link rel="stylesheet" href="jquery.ui.datepicker.mobile.css" />
<script src="../../js/jquery.js"></script>
<script>
//reset type=date inputs to text
$( document ).bind( "mobileinit", function(){
$.mobile.page.prototype.options.degradeInputs.date = true;
});
</script>
<script src="../../js/"></script>
<script src="jQuery.ui.datepicker.js"></script>
<script src="jquery.ui.datepicker.mobile.js"></script>
</head>
<body>
<div data-role="page">
<link rel="stylesheet" href="jquery.ui.datepicker.css" />
<!-- style overrides -->
<style type="text/css">
.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; }
</style>
<script type="text/javascript" src="jQuery.ui.datepicker.js"></script>
<script type="text/javascript">
$(function(){
/* datepicker workaround - update markup and classes for Mobile */
var updateDatepicker = function(){
$('.ui-datepicker-header').addClass('ui-body-c ui-corner-top').removeClass('ui-corner-all');
$('.ui-datepicker-prev, .ui-datepicker-next').attr('href', '#');
$('.ui-datepicker-prev').buttonMarkup({iconpos: 'notext', icon: 'arrow-l', shadow: true, corners: true});
$('.ui-datepicker-next').buttonMarkup({iconpos: 'notext', icon: 'arrow-r', shadow: true, corners: true});
$('.ui-datepicker-calendar th').addClass('ui-bar-c');
$('.ui-datepicker-calendar td').addClass('ui-body-c');
$('.ui-datepicker-calendar a').buttonMarkup({corners: false, shadow: false});
$('.ui-datepicker-calendar a.ui-state-active').addClass('ui-btn-active'); // selected date
$('.ui-datepicker-calendar a.ui-state-highlight').addClass('ui-btn-up-e'); // today's date
$('.ui-datepicker-calendar .ui-btn').each(function(){
var el = $(this), text = el.find('.ui-btn-text');
el.html(text.text()); // remove extra button markup - necessary for date value to be interpreted correctly
});
};
/* create the datepicker as usual */
$('input[type=date]').after( $('<div />').datepicker({ altField: '#date', showOtherMonths: true }) );
/* update the datepicker when it loads, or whenever it's clicked (required because it's redrawn) */
updateDatepicker(); // if you show the datepicker on input focus, call updateDatepicker on the focus event instead
$('.ui-datepicker').click(updateDatepicker);
});
</script>
<div data-role="header">
<h1>Datepicker Styled for mobile</h1>
<h1>jQuery UI's Datepicker Styled for mobile</h1>
</div>
<div data-role="content">
<p>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.</p>
<form action="#" method="get">
<div data-role="fieldcontain">
<label for="date">Date Input:</label>
<input type="date" name="date" id="date" value="" />
</div>
</div>
</form>
<h2>Usage Instructions</h2>
<p>The datepicker auto-generates from a regular <code>input</code> element with a <code>type="date"</code> attribute.</p>
<pre><code>
&lt;label for=&quot;date&quot;&gt;Date Input:&lt;/label&gt;
&lt;input type=&quot;date&quot; name=&quot;date&quot; id=&quot;date&quot; value=&quot;&quot; /&gt;
</code></pre>
<p>We'd recommend wrapping the label and input in a fieldcontain div for presentation purposes, and these elements should be placed within a <code>form</code> element for C-Grade browser accessibility.</p>
<p><strong>Note:</strong> This plugin is not included in jQuery Mobile by default, so you'll need to include the following files in order to use it:</p>
<pre><code>
&lt;link rel=&quot;stylesheet&quot; href=&quot;jquery.ui.datepicker.mobile.css&quot; /&gt;
&lt;script src=&quot;jQuery.ui.datepicker.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;jquery.ui.datepicker.mobile.js&quot;&gt;&lt;/script&gt;
</code></pre>
<p>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:</p>
<pre><code>
&lt;script&gt;
//reset type=date inputs to text
$( document ).bind( &quot;mobileinit&quot;, function(){
$.mobile.page.prototype.options.degradeInputs.date = true;
});
&lt;/script&gt;
</code></pre>
<p>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.</p>
</div>

View file

@ -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; }
}

View file

@ -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( $( "<div />" ).datepicker({ altField: "#" + $(this).attr( "id" ), showOtherMonths: true }) );
});
});
})( jQuery );

View file

@ -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',
@ -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;

View file

@ -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();
});

View file

@ -18,7 +18,8 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
menuPageTheme: 'b',
overlayTheme: 'a',
hidePlaceholderMenuItems: true,
closeText: 'Close'
closeText: 'Close',
useNativeMenu: false
},
_create: function(){
@ -27,7 +28,6 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
o = this.options,
select = this.element
.attr( "tabindex", "-1" )
.wrap( "<div class='ui-select'>" ),
selectID = select.attr( "id" ),
@ -115,6 +115,9 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
menuType;
// set to native menu
o.useNativeMenu = $.mobile.nativeSelectMenus || select.is( "[data-native]" );
// add counter for multi selects
if( isMultiple ){
self.buttonCount = $('<span>')
@ -155,43 +158,72 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
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 ],
//unbind dialog destroy on close
menuPage.unbind("pagehide.dialog");
//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();
});
//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 );
}
});
}
//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
@ -224,16 +256,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(){
@ -421,10 +456,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(){
@ -448,6 +488,8 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
focusButton();
}
// allow the dialog to be closed again
this.isOpen = false;
},
disable: function(){

View file

@ -105,6 +105,14 @@ $(document).bind("mobileinit.htmlclass", function(){
//add orientation class to HTML element on flip/resize.
if(event.orientation){
$html.removeClass( "portrait landscape" ).addClass( event.orientation );
//Set the min-height to the size of the fullscreen. This is to fix issue #455
if( event.orientation === 'portrait' ) {
$( '.ui-page' ).css( 'minHeight', ( screen.availHeight >= screen.availWidth ) ? screen.availHeight : screen.availWidth);
} else {
$( '.ui-page' ).css( 'minHeight', ( screen.availHeight <= screen.availWidth ) ? screen.availHeight : screen.availWidth);
}
$.mobile.silentScroll();
}
//add classes to HTML element for min/max breakpoints
detectResolutionBreakpoints();

View file

@ -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;
}
@ -318,6 +322,7 @@
//function for transitioning between two existing pages
function transitionPages() {
$.mobile.silentScroll();
//get current scroll distance
var currScroll = $window.scrollTop(),
@ -337,9 +342,6 @@
to.data("page")._trigger("beforeshow", {prevPage: from});
function loadComplete(){
$.mobile.pageLoading( true );
reFocus( to );
if( changeHash !== false && url ){
if( !back ){
@ -356,8 +358,9 @@
removeActiveLinkClass();
//jump to top or prev scroll, if set
$.mobile.silentScroll( to.data( 'lastScroll' ) );
//jump to top or prev scroll, sometimes on iOS the page has not rendered yet. I could only get by this with a setTimeout, but would like to avoid that.
$.mobile.silentScroll( to.data( 'lastScroll' ) );
reFocus( to );
//trigger show/hide events, allow preventing focus change through return false
from.data("page")._trigger("hide", null, {nextPage: to});
@ -387,16 +390,21 @@
if(transition && (transition !== 'none')){
$.mobile.pageLoading( true );
if( $.inArray(transition, perspectiveTransitions) >= 0 ){
addContainerClass('ui-mobile-viewport-perspective');
}
addContainerClass('ui-mobile-viewport-transitioning');
// animate in / out
from.addClass( transition + " out " + ( reverse ? "reverse" : "" ) );
/* animate in / out
* This is in a setTimeout because we were often seeing pages in not animate across but rather go straight to
* the 'to' page. The loadComplete would still fire, so the browser thought it was applying the animation. From
* what I could tell this was a problem with the classes not being applied yet.
*/
setTimeout(function() { from.addClass( transition + " out " + ( reverse ? "reverse" : "" ) );
to.addClass( $.mobile.activePageClass + " " + transition +
" in " + ( reverse ? "reverse" : "" ) );
" in " + ( reverse ? "reverse" : "" ) ); } , 0);
// callback - remove classes, etc
to.animationComplete(function() {
@ -407,6 +415,7 @@
});
}
else{
$.mobile.pageLoading( true );
from.removeClass( $.mobile.activePageClass );
to.addClass( $.mobile.activePageClass );
loadComplete();

View file

@ -37,6 +37,12 @@ $.widget( "mobile.page", $.mobile.widget, {
if ( this._trigger( "beforeCreate" ) === false ) {
return;
}
if( $( "html" ).hasClass( 'portrait' ) ) {
$elem.css( 'minHeight', ( screen.availHeight >= screen.availWidth ) ? screen.availHeight : screen.availWidth);
} else {
$elem.css( 'minHeight', ( screen.availHeight <= screen.availWidth ) ? screen.availHeight : screen.availWidth);
}
//some of the form elements currently rely on the presence of ui-page and ui-content
// classes so we'll handle page and content roles outside of the main role processing
@ -75,15 +81,10 @@ $.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 ) {
$( "<a href='#' class='ui-btn-left' data-icon='arrow-l'>"+ o.backBtnText +"</a>" )
.click(function() {
history.back();
return false;
})
.prependTo( $this );
$( "<a href='#' class='ui-btn-left' data-rel='back' data-icon='arrow-l'>"+ o.backBtnText +"</a>" ).prependTo( $this );
}
//page title

View file

@ -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
};
}

View file

@ -78,16 +78,25 @@
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(){
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.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" );
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");
@ -100,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);

View file

@ -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 );
});

View file

@ -61,6 +61,33 @@
</style>
<div id="foo" data-role="page">
<div data-role="fieldcontain" id="select-choice-few-container">
<select name="select-choice-few" id="select-choice-few">
<option value="standard">Standard: 7 day</option>
<option value="rush">Rush: 3 days</option>
<option value="express">Express: next day</option>
<option value="overnight">Overnight</option>
</select>
</div>
<div data-role="fieldcontain" id="select-choice-native-container">
<select name="select-choice-native" id="select-choice-native" data-native="true">
<option value="standard">Standard: 7 day</option>
<option value="rush">Rush: 3 days</option>
<option value="express">Express: next day</option>
<option value="overnight">Overnight</option>
</select>
</div>
<div data-role="fieldcontain" id="select-choice-global-native-container">
<select name="select-choice-global-native" id="select-choice-global-native">
<option value="standard">Standard: 7 day</option>
<option value="rush">Rush: 3 days</option>
<option value="express">Express: next day</option>
<option value="overnight">Overnight</option>
</select>
</div>
<div data-role="fieldcontain" id="select-choice-many-container">
<label for="select-choice-many" class="select">Your state:</label>
<select name="select-choice-many" id="select-choice-many">

View file

@ -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");
@ -16,10 +17,46 @@
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);
same(menu.parents('.ui-dialog').length, 1);
});
test( "firing an immediate click on the select screen overlay doesn't close it", function(){
$.Event.prototype.originalEvent = {
touches: [ 'foo' ]
};
$("#select-choice-few-button").trigger(mouseUpTouchEnd);
$(".ui-selectmenu-screen").click();
same($("#select-choice-few-menu").parent(".ui-selectmenu-hidden").length, 0);
});
test( "firing a click at least 400 ms later on the select screen overlay does close it", function(){
$.Event.prototype.originalEvent = {
touches: [ 'foo' ]
};
$("#select-choice-few-button").trigger(mouseUpTouchEnd);
// click the first menu item
setTimeout(function(){
$("#select-choice-few-menu a:first").click();
}, 400);
// verify the menu is hidden
setTimeout(function(){
same($("#select-choice-few-menu").parent(".ui-selectmenu-hidden").length, 1);
start();
}, 500);
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);

View file

@ -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; }

View file

@ -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; }

View file

@ -259,7 +259,7 @@
color: #3E3E3E;
font-weight: bold;
text-shadow: 0 1px 1px #fff;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#f0f0f0,
#e9eaeb);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -279,7 +279,7 @@
color: #333333;
text-shadow: 0 1px 0 #fff;
background: #f0f0f0;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#eeeeee,
#dddddd);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -310,7 +310,7 @@
cursor: pointer;
text-shadow: 0 1px 1px #f6f6f6;
text-decoration: none;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#fefefe,
#eeeeee);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -329,7 +329,7 @@
color: #101010;
text-decoration: none;
text-shadow: 0 1px 1px #fff;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#ededed,
#dadada);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -346,7 +346,7 @@
font-weight: bold;
color: #111111;
text-shadow: 0 1px 1px #ffffff;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#eeeeee,
#fdfdfd);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -372,7 +372,7 @@
background: #bbb;
color: #333;
text-shadow: 0 1px 0 #eee;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#ddd,
#bbb);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -433,7 +433,7 @@
cursor: pointer;
text-shadow: 0 1px 1px #fff;
text-decoration: none;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#fdfdfd,
#eeeeee);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -450,7 +450,7 @@
font-weight: bold;
color: #111;
text-shadow: 0 1px 1px #ffffff;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#eeeeee,
#ffffff);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -464,7 +464,7 @@
font-weight: bold;
color: #111;
text-shadow: none;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#cccccc,
#eeeeee);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -487,7 +487,7 @@
background: #fadb4e;
color: #333;
text-shadow: 0 1px 0 #fff;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#fceda7,
#fadb4e);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -514,7 +514,7 @@
color: #333333;
text-shadow: 0 1px 0 #fff;
background: #faeb9e;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#fff,
#faeb9e);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -545,7 +545,7 @@
text-shadow: 0 1px 1px #fe3;
text-decoration: none;
text-shadow: 0 1px 0 #fff;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#fceda7,
#fadb4e);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -563,7 +563,7 @@
color: #111;
text-decoration: none;
text-shadow: 0 1px 1px #fff;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#fcf0b5,
#fbe26f);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -581,7 +581,7 @@
font-weight: bold;
color: #111;
text-shadow: 0 1px 1px #ffffff;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#fadb4e,
#fceda7);
background-image: -webkit-gradient(linear,left top,left bottom,
@ -618,7 +618,7 @@ a.ui-link-inherit {
cursor: pointer;
text-shadow: 0 -1px 1px #145072;
text-decoration: none;
background-image: -moz-linear-gradient(,
background-image: -moz-linear-gradient(top,
#85bae4,
#5393c5);
background-image: -webkit-gradient(linear,left top,left bottom,

View file

@ -159,7 +159,8 @@ Built by David Kaneda and maintained by Jonathan Stark.
.ui-mobile-viewport-transitioning,
.ui-mobile-viewport-transitioning .ui-page {
width: 100%;
height: 100%;
height: 120%; /* we want to make sure we take up enough to keep the scroll top hidden during transition, but not too much to overflow our buffer */
overflow: hidden;
}
.flip {