Development Update – Week of July 18th, 2011
Beta 2 very soon, Beta 3 in the wings
As you can see from the last few blog posts, we’ve been making some big improvements under the covers to make the library more extensible, robust and performant in addition to adding some nice developer tools as we go. At this stage, we are going to focus on final testing for the current feature set so we can release Beta 2 in the next week or so.
We still have a number of important improvements that we feel are critical to land but don’t want to hold up Beta 2, so we’ve decided to move these into third beta release. In Beta 3, we will be adding a few items that we haven’t had time to completely test and bullet-proof yet like DOM size management, pushState support and extensibility hooks for developers. The improved cross-browser page transitions are close to landing, but we’re not yet sure whether they will make it in for Beta 2 or 3 at this point.
This additional beta will push out our project 1.0 release by a few weeks, but we feel that these improvements are critical to making our first major release a success. Now, onto the things we’ve been working on this week!
Page wrapper: Now optional
The framework is now more flexible with document structure so now the
data-role=page wrapper element is optional. This will ease integration with existing sites, as well as mashups with external content. Previously, if you didn’t wrap your page in a container with this role, the framework wouldn’t enhance the page widgets but now it doesn’t need a page wrapper in the markup to trigger initialization.
The page, header, content, and footer
data-role elements have always been optional, but now with this page wrapper change, there is no required markup at all – just start building you page content. Here is an example of a page with none of these structural elements in the markup and everything works great.
Behind the scenes, the framework will inject the page wrapper if you don’t include it in the markup because it’s needed for managing pages, but the starting markup can now be extremely simple. Note that in a multi-page setup, you are required to have page wrappers in your markup in order to group the content into multiple pages.
Widgets: Now decoupled for flexible builds
We’ve wanted to decouple all our widgets from the page plugin for a long time now and we’re happy to announce that we just landed this change. So what exactly does decoupled mean anyway? Well, the individual widgets and utilities have always been broken out into separate script files. However, the page plugin was responsible for handling the auto-initialization all of the official plugins found in the markup at page creation. This situation made it impossible to remove plugins you don’t need without causing errors, and generally set a bad precedent for future widget additions.
Now, pretty much all the widgets in the jQuery Mobile library are completely decoupled so they can simply be deleted if not needed for a particular project. This change allows you to dramatically reduce the size of the library by only including the specific set of widgets or features you need, in addition to the handful of required, core files. While we still plan to do more decoupling and cleanup, the following files are now decoupled and can safely be removed from the make file before you do a custom build:
- page sections (header/content/footer, previously in page plugin)
- links (ordinary link theming previously in page plugin)
We will work on a dependency map because a few widgets rely on others to work. For example, the button markup plugin is called by many of the widgets above, so it can only be excluded but if you’re not using any of the widgets that depend on buttons.
We’re still working out our recommendations for mapping plugin dependencies and decoupling things even further. Ultimately, this will be surfaced in a download builder tool, so stay tuned!
New “create” event: Easily enhance all widgets at once
While the page plugin no longer calls each plugin specifically, it does dispatch a “pagecreate” event, which most widgets use to auto-initialize themselves. As long as a widget plugin script is referenced, it will automatically enhance any instances of the widgets it finds on the page, just like before. For example, if the selectmenu plugin is loaded, it will enhance any selects it finds within a newly created page.
This structure now allows us to add a new
create event that can be triggered on any element, saving you the task of manually initializing each plugin contained in that element. Until now, if a developer loaded in content via Ajax or dynamically generated markup, they needed to manually initialize all contained plugins (listview button, select, etc.) to enhance the widgets in the markup.
Now, our handy
create event will initialize all the necessary plugins within that markup, just like how the page creation enhancement process works. If you were to use Ajax to load in a block of HTML markup (say a login form), you can trigger
create to automatically transform all the widgets it contains (inputs and buttons in this case) into the enhanced versions. The code for this scenario would be:
$( ...new markup that contains widgets... ).appendTo( ".ui-page" ).trigger( "create" );
Create vs. refresh: An important distinction
Note that there is an important difference between the
create event and
refresh method that some widgets have. The
create event is suited for enhancing raw markup that contains one or more widgets. The
refresh method that some widgets have should be used on existing (already enhanced) widgets that have been manipulated programmatically and need the UI be updated to match.
For example, if you had a page where you dynamically appended a new unordered list with
data-role=listview attribute after page creation, triggering
create on a parent element of that list would transform it into a listview styled widget. If more list items were then programmatically added, calling the listview’s
refresh method would update just those new list items to the enhanced state and leave the existing list items untouched.
Error in new page.sections js when data-add-back-btn=”true” on page (issue 2119) -Fixed a problem when pages have the data-add-back-btn set to true causing an error. Thanks jgable!
Email input type doesn’t receive input field styles (issue 2117) – When using email as the input type for an input field, jQuery Mobile does not correctly enhance them post-decoupling. Thanks commadelimited! Also fixed URL and tel input types for the same regression.
Hide loading message for loadPage should be to not show the loading message – It’s default use case is to fetch a page that is not yet active so this is distracting. However, changePage should cause it to show because loadPage is being called during a page change. This was causing the loader to show when using the new page precache option.
Get the latest builds on the jQuery CDN
To take advantage of the daily improvements happening in jQuery Mobile, be sure to check out out the new daily and latest builds that are now available on the jQuery CDN for hotlinking. This allows you to upgrade to the latest code without waiting for the next official release.
Here are the three files to include in the head of your page to always be viewing the latest in Git:
<link href="http://code.jquery.com/mobile/latest/jquery.mobile.min.css" rel="stylesheet" type="text/css" /> <script src="http://code.jquery.com/jquery-1.6.2.min.js"></script> <script src="http://code.jquery.com/mobile/latest/jquery.mobile.min.js"></script>
Please keep in mind that this the unstable, development version so we don’t recommend linking to the latest in a production site or app but it’s great for development and testing.