State of the jQuery UI Grid

Posted on by

We announced the Grid project back in February. Since then, we finished the first three stages and are now getting started on the fourth. In this post we’ll take a look at what we’ve built so far.

Grid

This is what we designed as the “zero feature grid”. All it does is enhance HTML tables, but it does that pretty well while also providing the right hooks for all kinds of other features that we can add on top of that. And that turns out to be really useful, as there are a bunch of things that regular HTML tables can’t do. With Grid, you get:

  • styling with the CSS framework, making it ThemeRoller-ready
  • a proper titlebar, based on the table’s caption
  • markup and styles necessary for scrolling of the table body, while keeping the header fixed

The API for the Grid controls what content to render, and how to present it:

  • The columns option specifies which columns to render. If not specified, it picks up existing table header elements.
  • The rowTemplate option allows the grid to render each row from a custom template. If this option is not provided, each row is generated based on the columns option.
  • The source option specifies the content to render, in the form of a plain array of objects. When not specified, existing table rows are used.
  • By default, the grid’s body grows with the number of rows. With heightStyle: ‘fill’, it stays at a fixed height and the body starts scrolling if there are more rows.
  • When picking up column information from the existing table headers, certain data-attributes are read. The grid itself uses only the data-property attribute (and the actual text of each header cell), but the dataFields option specifies a few more attributes that other components can use, such as “type”, “culture” and “format” to configure local sorting and filtering. If a grid add-on handles other data attributes, adding those to the dataFields option will make them automatically available as part of the columns option.

So far we only have an enhanced table, but often enough, a grid needs to be fed data from some remote resource. That’s where Dataview comes in.

Dataview

Dataview is a low-level abstraction for retrieving content. It has an API for specifying what content to retrieve, and an SPI (service provider interface), implemented by components that provide that content. There are built-in options for filtering, sorting and paging, and the design makes it easy to add more options, like grouping. The API is asynchronous by default, even for local data, so that all components relying on Dataview can work with both local and remote data.

Dataview only depends on Widget and Observable (we’ll get to that below), but not on Grid. This allows Dataview to be used in a variety of contexts. For example it could power a product listing, such as those on eBay or Amazon, where a table presentation is not the right format.

The Dataview SPI makes it easy to write implementations from scratch as well as to create reusable extensions.

As an example, we can use a custom dataview as the input for the Autocomplete widget. The same data is also displayed in the grid below the input field. This demonstrates how a Dataview can be used in multiple representations, where each decides on its own what data to show.

As for reusable extensions, we currently have three implemented:

  1. localDataview takes an input array and does sorting, paging and filtering on that array. It uses Globalize (see below) to implement filtering and sorting of localized numbers and dates. When combined with the grid on a table with existing content (without specifying the source option), you get a complete tablesorter.
  2. odataDataview takes a resource URL, pointing at a webservice that understands OData, the Open Data Protocol. While our implementation doesn’t yet cover all of the OData options, you can use it to sort, filter and page, without having to implement any custom request/response mapping. We have an example of a grid using the OData based Netflix API.
  3. preloaderDataview wraps a Dataview and adjusts the paging behaviour to load more data than rendered, paging locally before preloading another batch. In this Flickr API slideshow example we preload both the API responses and the actual images. This pushes all the loading in the background, allowing the user to page through images without interruptions.

All three need testing in actual projects before we can consider them stable. We’re also looking for other use cases for dataview that we might be missing.

Observable

Data binding is currently a common theme among newer JavaScript frameworks, with various competing solutions available. We don’t yet have a full-featured alternative, but we’ve developed a low-level abstraction that might power a data binding component in the future. We call this abstraction Observable. It provides an API for making changes on plain JavaScript objects and arrays that can be observed by listening to events that each change triggers. We’ve designed Observable to have a very small number of methods and events, with the purpose of making it easy to implement the same API in other contexts. These events are:

  • change: Triggered on objects after one or more properties have changed.
  • insert: Triggered on arrays after inserting one or more new items.
  • remove: Triggered on arrays after removing one or more items.
  • replaceAll: Triggered on arrays after replacing all items in an array.

That last event may seem odd at first, but this makes it possible to create a dataview, pass it to a grid, have the grid subscribe to events on that dataview’s output array, and then update itself when the dataview updates.

For all four events, Observable provides method counterparts:

  • property: to work on objects
  • insert, remove and replaceAll: to work on arrays.

Usage is consistent in both cases:

  • $.observable( object ).property( “name”, “Fred” );
  • $.observable( array ).insert({ name: “Peter” });

We’re still working on Observable. The next step is to find an abstraction for the array bindings, which would remove some overhead both from the Grid as well as from the todo-app demo.

When combining Observable with the Grid, we can easily add editing capabilities. In our grid editing demo, you can add, edit and remove developers from the table. Results are persisted via localStorage.

Instead of adding custom columns that have “Edit” and “Remove” buttons, we can use the selectable interaction to select one or more rows and then interact with the selection. In that demo, the selected array is also an observable array, which the second grid displays. Note that you can select rows on one page, go to the next page (you may need to add a few developers for a second page to show up), select more rows with command/ctrl-click (to extend the selection) and it will display all those rows in the second grid. The selected state is separated from the visual representation, making selection over multiple pages pretty easy.

Globalize

Globalize originally started as the jquery-global plugin. We rewrote it as part of the Grid project to be independent of jQuery, allowing usage on both client and server. Our localDataview implementation (mentioned above) uses it, and its also behind custom inputs like Spinner and Timepicker.

Mask, Timepicker, Selectmenu

These three custom inputs are being developed as part of the Grid project. They are intended to be used within the Grid for inline editing, as well as standalone in regular forms or websites. We’re getting close to landing all three in master, to release them as part of 1.9.

And more…

Work is still in progress on Template, Datepicker and other Custom Inputs. We’ll report back on those once we have more stable solutions.

Up next

We’re finishing existing components and are starting on Stage 4. For details, check out the main Grid wiki page.

So, when is it done?

Our Roadmap has the Grid on the 2.1 release, while the main focus for jQuery UI is on 1.9. In other words, there is a lot that needs to get done before we can put the Grid into a stable release and support it along with all the other components. At the same time, we encourage you to start testing the features outlined above now. Grid, Observable and Dataview are all pretty stable and working well. Globalize is a separate project that you should start using now if you want to support localized number and date handling on the clientside.

We value your input and help. Please use the Developing jQuery UI forum, comment on individual wiki pages or visit us on IRC (#jqueryui-dev on Freenode). If you found a solution to an issue, send a pull request.

Dialog API Redesign

Posted on by

Continuing with the API redesign, we have some changes planned for the Dialog widget. We know that API changes like this are not without cost to our users, so we’d like to make it clear that except where specifically noted, jQuery UI Dialog in 1.9 will support the 1.8 API as well, and the deprecated APIs will not be removed until jQuery UI 2.0. Read more about the full jQuery UI API redesign.

API Redesign

Contain focus in dialog
We currently only contain focus inside modal dialogs. We will be changing this behavior to always contain focus, even in modeless dialogs. This will bring us more in line with the DHTML Style Guide. We’re not sure about implementing a key command to move the focus out of the dialog (such as F6) since that would require defining a system to track where focus should move.

Allow disabling dialogs
Dialogs don’t currently support being disabled. They do inherit the default behavior of adding the ui-state-disabled class, which makes the dialog look disabled, but the user can still interact with elements in the dialog. In order to support disabling a dialog, we will place a div over the dialog to prevent mouse interaction.

Ability to configure which element gains focus
When opening a dialog, we search for which elements are tabbable and we focus the first element that we find. If there are no tabbable elements, then we focus the dialog itself. We will be adding an autoFocus option, which will allow customizing which element gains focus. The option will accept a function which will return the element to focus. The default value for the option will be the current implementation. If no element is found using the option, the dialog will be focused.

Move dialog back to original DOM position on destroy
When dialogs are created they are moved to the end of the body. When dialogs are destroyed, they currently stay at the end of the body. We will be changing this behavior so the dialog is returned to the original position, if possible. This will be done by tracking either a sibling or the parent on create.

Automatic stacking
The stack option controls whether a dialog will move on top of other dialogs when it gains focus. Since this should always be the case, we will be removing the option and forcing the behavior. In addition, we will probably remove the moveToTop method since the proper dialog(s) should always be available to the user based on when they were opened and whether they are modal or modeless.

Saner modality
The current implementation for managing modal dialogs is a bit unwieldy, comparing the z-index of elements and often causing problems. We plan to simplify the implementation and switch to a hierarchy-based solution instead of a style-based solution.

Feedback

We’d love to hear your feedback on these changes. We want to make sure we address any issues the community may have before we finalize and implement these changes. If you have any feedback, please post it on the related forum post. Thanks.

ARIA Hackathon Summary

Posted on by

The original idea of the ARIA Hackathon was to get developers of jQuery UI and experts for ARIA together in one room, connect them, share knowledge and work on the accessibility of jQuery UI.

Meeting at the Inclusive Design Research Centre (IDRC) of OCAD University in Toronto, several members of the jQuery UI team (Richard, Scott, Dan, Jörn), various developers at OCAD (Michelle, Justin, Antranig, Harris), around Toronto (Ates, George, Darcy) and further away (Mat from Boston, Candace and William from the University of Washington and Jerry from the University of Illinois) learned a ton about testing and developing for screenreader users, about the ARIA standard and its process, as well as Mozilla’s efforts on accessibility.

  • Colin Clark gave an overview of the work of the IDRC team, including the Fluid project which makes use of jQuery UI.
  • Hans Hillen provided a lot of very practical insight on testing and developing with JAWS and NVDA and the ARIA spec and DHTML styleguide.
  • Jospeh Scheuhammer, heavily involved in the ARIA standards process, gave insight on how the process works like, how to provide feedback and which documents can and should be used along with the main specification.
  • David Bolter provided an overview of Mozilla’s efforts on Firefox accessibility, also covering the state and future of Firefox Mobile.
  • Finally Jennison Asuncion demonstrated usage of JAWS on regular websites, giving the spectators (or rather, listeners) a much better understanding of how a blind user actually uses a screenreader. He’s also an incredibly nice guy.

In a group discussion, we defined latest NVDA on latest Firefox as the supported setup for ARIA and acccessiblity, while also testing with JAWS on Windows and VoiceOver on OSX. We will accept reasonable patches for other or older ATs if the code is maintainable and doesn’t break ARIA in spec-conforming ATs.

After the two days of the main event, Hans and Jörn stayed till Friday to work on the keyboard and accessibility implementation of multiple jQuery UI widgets. Jörn also had meetings with Justin and Michelle at OCAD and Bobby and David at Mozilla to recruit them for jQuery UI and the Testing subteam (QUnit, TestSwarm). There is a lot of mutual interest that should lead to a lot more collaboration going forward.

Special thanks go out to IDRC and Colin Clark for hosting the event and Mozilla and David Bolter for funding some of the travel and lodging expenses.

For a mostly complete list of attendees (and links to Twitter and GitHub profiles) and various resources gathered during the event, visit the events page on our planning wiki.

API Redesigns: The Past, Present and Future

Posted on by

Back in November, we announced the first of many API redesigns. In that post, we briefly stated our overall goals:

jQuery UI is undergoing an API redesign which will slim down the size of the API in order to provide a more stable codebase that is easier to learn and use. We’ll be posting the proposed changes over the next few weeks in order to gather feedback from the community. Our goal is to support the old (current) and new (proposed) APIs simultaneously in 1.9 and then remove support for the old APIs in 2.0.

Now it’s three months later and two things are clear: 1) it’s taking more than a few weeks to post all of the proposed changes; and 2) we didn’t give enough information about the planned changes and the reasoning behind them.

The Past

When jQuery UI was first created, it was a combination of new and existing plugins. Pulling in existing, popular plugins was beneficial for everyone involved: jQuery UI was released earlier and with more plugins, the original authors’ hard work was publicly recognized and supported by the jQuery Project and the existing user base gained official support for the code they were using. Unfortunately, there was a downside to this approach. Because the existing plugins were written by different authors with different design principles and different coding styles, there wasn’t much consistency within jQuery UI. Between the 1.0 and 1.8 releases there were a few attempts to standardize various parts of the API, but there was never a coordinated effort large enough to make the necessary changes.

In addition to the inconsistencies between plugins, other problems started to appear over the past three and a half years. As users requested more and more features, the number of options, methods and events continued to grow. Over time, this led to what we have today, where something as simple as a draggable element has almost 30 options. On one hand, it’s impressive that so many various use cases can be handled, often with the use of just one or two of these options. On the other hand, finding the right one or two options to use can be a daunting task, especially for new users.

The Present

Recognizing the existing problems, we approached the 1.8 release differently. We defined a new process for building plugins that focuses on simplified APIs that are easy to extend. With the success of the 1.8 release, especially the simplicity and flexibility of the Autocomplete widget, we were convinced that our new process was working. Having a new process and new standards, we decided to go back and redesign all of our existing plugins with the same design process. In October, the jQuery UI team got together in Boston to do a first pass at redesigning all of the existing plugins. A few weeks later we started posting the proposed changes to gather feedback from the community. We’re still working through some of the details for specific plugins.

Our goal is to have a completely refreshed project with the 2.0 release. We will have a much simpler API, better stability, full documentation and a full test suite for every plugin. However, getting there will require a lot of backward-incompatible changes. We’re aware of how painful that can be and we are doing everything we can to reduce the pain of upgrading. Specifically, we’re doing the following while implementing the new API:

  • Ensuring we have a full test suite for the 2.0 API
  • Creating a separate test suite for the 1.8 API
  • Re-implementing any deprecated functionality on top of the new functionality
  • Defaulting to the 1.8 API in cases where the old and new APIs cannot live side-by-side

This approach has several benefits, with one of the most important being that upgrading to 1.9 should not break any existing pages. In fact, the 1.9 release will have better support of the 1.8 API than any 1.8.x release. As plugins are refactored for 1.9, many bugs present in 1.8.x will be fixed and some of the fixes will not be easily ported to the 1.8 branch. Because the support for the 1.8 API in the 1.9 release is actually new code built on top of the 2.0 API, it benefits from these bug fixes. The addition of a full test suite for the 1.8 API ensures that these bugs are actually fixed in both APIs.

Defaulting to 100% support of the 1.8 API is great for upgrading to 1.9, but it doesn’t provide a way to determine if you’re ready to upgrade to only using the 2.0 API. In order to deal with this, we’ve added a new flag, jQuery.uiBackCompat. If you load jQuery, then set jQuery.uiBackCompat = false, then load jQuery UI, none of the 1.8 API will be loaded. This will result in only having the 2.0 API available and will allow you to test your pages for compatibility with the new API and provide confidence that you will be ready to upgrade to 2.0 when it is released.

The Future

When jQuery UI 2.0 is released, we will no longer support the 1.8 API. However, the 1.8 API compatibility layer from 1.9 should continue to work; it will just not be included in the 2.0 release and will no longer be officially supported. All new plugins will go through the new design process so large API changes like this should not occur again. Once the existing plugins have been updated to our new standards, we should be able to move the project forward much faster than we’ve previously been able to.

It’s worth mentioning that only widgets, utilities and effects are being refactored in 1.9. All interactions are going to be rewritten for 2.0 so they will be undergoing a different implementation process. As a user of jQuery UI, there shouldn’t be much perceived difference between the widget refactors and the interaction rewrites other than the release date.

We know that no one looks forward to refactoring existing code to work with API changes, and we’re working to make sure the transition process will be clear and simple.  We hope that you, our users, understand that we need take this opportunity to refine jQuery UI to make it more robust, extensible, and maintainable in the long term.

Tabs API Redesign

Posted on by

Continuing with the API redesign, we have some changes planned for the Tabs widget. We know that API changes like this are not without cost to our users, so we’d like to make it clear that except where specifically noted, jQuery UI Tabs in 1.9 will support the 1.8 API as well, and the deprecated APIs will not be removed until jQuery UI 2.0.

API Redesign

Remove rotation.
The rotate method will be removed as it is not very common and has always been implemented as a built-in extension anyway. This will actually be removed, not just deprecated in 1.9 since it has always existed as an extension. Christopher McCulloh has an enhanced rotation extension based on the original code.

Overhaul ajax tabs
The ajaxOptions and cache options are being removed in favor of a new event: beforeload. The beforeload event will receive a jqXHR object and the settings object that will be passed to jQuery.ajax(). ajaxOptions is replaced by modifying the settings passed to beforeload and caching can be implemented by calling event.preventDefault() to prevent the ajax call and jump straight to showing the tab. We will also be keeping the href attribute unmodified and storing the panel id in the aria-controls attribute. The aria-controls attribute will be set for all tabs, regardless of whether they are local or remote. This will remove the need for the url method, which is also being removed. It will be possible to pre-define a value in the aria-controls value for remote tabs, removing the need to specify the location in the title attribute (which is also being removed). The abort method will be removed since the jqXHR object will be directly accessible and you can therefore abort the ajax call directly. Another benefit of the beforeload event is when paired with the existing load event, you can create custom loading functionality; as such we are removing the spinner option.

Selected vs. active
In order to improve consistency within the jQuery UI suite, select/selected will be renamed to activate/active across the board. What this means for tabs is that the selected option will be renamed to active, the select event will be renamed to beforeactivate, and the show event will be renamed to activate. The beforeactivate and activate options will include references to the tab and content panel for the old and new tabs, similar to accordion. In addition, the select method will be removed in favor of the setting the active option. Lastly, the deselectable option will be removed in 1.9 since it was deprecated in 1.8.

Remove templating
All options related to templating are being removed. The templating in tabs is a one-off implementation and creates an inconsistency with the rest of jQuery UI. This change includes the removal of the idPrefix, tabTemplate, and panelTemplate options.

Adding and removing tabs
The add and remove methods will be removed in favor of a new refresh method. This is consistent with how new plugins are updated after initialization. Removing these methods also means that the add and remove events are being removed.

Enabling and Disabling tabs
Tabs will properly support disabling individual tabs or the entire tab set. A boolean can be used to disable the entire set or an array of indices can be provided to disable individual tabs. In addition, the enable and disable events will be removed for consistency with other widgets.

Remove length method
The length method will be removed as it doesn’t serve much purpose and can easily be calculated by counting the number of list items.

Remove cookie option
The cookie option will be removed as cookie support is not core to the plugin. Cross-page state management should be easy, but not be built-in.

Design changes still in flux
There are a few things that we still haven’t fully worked out. We plan on replacing the fx option with show and hide options for consistency with other widgets, but are still working through an open issue of how to support effects across plugins. We would also like to remove the load method but we need to verify that it can be built as an extension. Until we get into the new implementation, we won’t know if this is possible; if it’s not, the load method will remain in the plugin.

Feedback

We’d love to hear your feedback on these changes. We want to make sure we address any issues the community may have before we finalize and implement these changes. If you have any feedback, please post it on the related forum post. Thanks.

Unleash The Grid

Posted on by

The jQuery UI Team is proud to announce that we are building a rich, fast grid widget that will enhance an HTML table with data linking, sorting, paging, filtering, row selection, and inline editing. As part of this process, we’ll be building the features of the grid as standalone widgets and revisiting existing jQuery UI components. At the end of this process, not only will we have a grid, but also a better-tested, more feature-complete user interface library.

Current Progress

We are nearing completion of development on Stage 1 of the project, which encompasses the creation of a generic data model, data type parsing, and markup. This stage will culminate in a “zero feature grid,” an enhanced HTML table that supports the jQuery UI CSS Framework and serves as a base for other grid features. See the roadmap for details on work planned for future stages.

Development Approach

There are already a number of high quality jQuery grid plugins. We recognize they each have an impressive set of features, capabilities, and a level of use by members of the jQuery community. We are studying and applying practices and techniques from today’s most popular grid and data table plugins, including current favorites, SlickGrid, jqGrid, DataTables and a few that have not been updated in a while, like Tablesorter, Flexigrid, and Ingrid. We invite all authors and users of these and any other grid plugins to get involved in the design of the jQuery UI Grid.

Not Invented Here?

As you may imagine, we’re pretty big fans of the jQuery UI API. We believe that having a consistent interface to complex plugins is a big win for users. Sometimes in the past, we’ve adapted already-complete plugins. Unfortunately, this approach can lead to headaches related to legacy bugs, inconsistencies with the rest of our API, and lack of familiarity with the original design decisions. By building from the ground up, we can ensure that each line of code has been vetted and that any grid we call “jQuery UI’s” conforms to our standards.

More Than Just A Grid

We’re not just developing a grid, but rather designing and building modular and extensible components, like sorting, paging, filtering, and in-place editing, that can be combined into a grid. We’re confident that jQuery UI users will find compelling and creative uses for the new suite of tools that are being built to support the grid.

Refactoring Interactions

While jQuery UI’s mouse interaction plugins work well enough in many cases, we are well aware that they have lingering shortcomings – including their ability to work properly on tables. As part of the Grid development, we’ll be giving the interaction plugins a long-awaited refactoring to simplify their APIs, address edge cases, and generally ensure their suitability for a wider variety of contexts.

Join Us!

Do you want to help design and build the jQuery UI Grid? Share your feedback? Join us on the grid planning wiki page. You can stay up-to-date with development and test the latest iterations on jQuery UI’s grid branch.

Sponsors

This work is made possible by the generous donations by individuals as well as corporate sponsors. These sponsors have donated financial and development resources to ensure the grid work can go forward over the next 5-6 months.

In particular, the jQuery project would like to thank the following sponsors (as of today) of the jQuery UI Grid project:

Double Platinum Grid Sponsors

  • Microsoft – The Microsoft Web Platform and Tools team builds many technologies for developing web sites including ASP.NET, ASP.NET MVC, IIS, Visual Web Developer and Web Matrix.
  • Adobe – Adobe Systems Incorporated offers business, creative, and mobile software solutions that revolutionize how the world engages with ideas and information.
  • Platinum Grid Sponsor

  • Wijmo – Wijmo is a complete kit of over 30 jQuery UI Widgets. It is a mixture of jQuery, CSS3, SVG, and HTML5 that, when combined, become an unstoppable force on the web.

If you or your company is interested in being a sponsor of the jQuery UI Grid, please get in touch.

Position API Redesign

Posted on by

Continuing with the API redesign, we have some changes planned for the Position utility.

API Redesign

Merge offset option into the my and at options
The offset option will be removed in favor of including the offset as part of the my or at options.
For example, while you would currently do:

$( "#elem" ).position({
    my: "left top",
    at: "left top",
    of: "#otherElem",
    offset: "50 20"
});

You would now do:

$( "#elem" ).position({
    my: "left+50 top+20",
    at: "left top",
    of: "#otherElem"
});

Regardless of whether you include the offset in the my or at option, the offset will always adjust based on the final position, just like the offset option currently does. We also plan on supporting percentages, so you can offset the element based on a percent of its width or height. If you specify a percentage in the my option, then the percentage will be based on the size of the element being positioned. If you specify a percentage in the at option, then the percentage will be based on the size of the element being positioned against.
For example, to place an element 1/4 of the way down the screen and horizontally centered, you could do:

$( "#elem" ).position({
    my: "center top",
    at: "center top+25%",
    of: window
});

And to position an element so that only the left 10% of it is visible, you could do:

$( "#elem" ).position({
    my: "left-10% center",
    at: "right center",
    of: window
});

Better collision handling
Currently the collision handling is fairly simple. If you enable collision (by specifying fit or flip) then the plugin will detect if there is a collision and if there is, it will move the element accordingly. However, depending on the size of the element, this adjustment may actually cause even less of the element to be visible. We plan on making the collision handling smarter so that it will never make the positioning worse. There will be no change in the API, just better handling for collisions.

Feedback

We’d love to hear your feedback on these changes. We want to make sure we address any issues the community may have before we finalize and implement these changes. If you have any feedback, please post it on the related forum post. Thanks.

Progressbar API Redesign

Posted on by

As previously stated, jQuery UI is undergoing an API redesign which will slim down the size of the API in order to provide a more stable codebase that is easier to learn and use. This post lists out the details of the proposed changes for the Progressbar widget along with the reasoning behind each change.

API Redesign

Add support for indeterminate progress bars.
We had previously said that indeterminate progress bars should be a separate widget. However, there is a common enough use case where you may want to start providing feedback about that a task has started before you know the actual progress. In this case you may want to start with an indeterminate progress bar and switch to a determinate progress bar as soon as you have enough information to provide details. In order to support this, we will allow the value option to be set to false to indicate that the progress bar should be indeterminate.

Switching from an indeterminate state to a determinate state would look like this:

$( "#progressbar" ).progressbar({
    value: false
});

// later when you find out more information
$( "#progressbar" ).progressbar( "option", {
    value: 15,
    max: 250
});

Feedback

We’d love to hear your feedback on these changes. We want to make sure we address any issues the community may have before we finalize and implement these changes. If you have any feedback, please post it on the related forum post. Thanks.

Accordion API Redesign

Posted on by

jQuery UI is undergoing an API redesign which will slim down the size of the API in order to provide a more stable codebase that is easier to learn and use. We’ll be posting the proposed changes over the next few weeks in order to gather feedback from the community. Our goal is to support the old (current) and new (proposed) APIs simultaneously in 1.9 and then remove support for the old APIs in 2.0. This post lists out the details of the proposed changes for the Accordion widget along with the reasoning behind each change.

API Redesign

Remove navigation and navigationFilter option.
The navigation-related options are being removed in favor of setting the active option during initialization. The built-in navigation filter didn’t always make sense and was turned off by default. We plan on adding a demo which shows how to implement the current navigation functionality as well a demo which shows how to use a cookie to store the active panel.

Merge the autoHeight, fillSpace and clearStyle options into a new option called fixedHeight
The autoHeight, fillSpace and clearStyle options all deal with similar issues and therefore cannot be used together. Having three options for the same feature (how tall the panels should be) creates a complex and confusing API. These three options are being replaced by a single boolean option called fixedHeight. When set to true (the default), all panels will have the same height. If the accordion has a height of “auto”, then all panels will be as tall as the tallest panel (equivalent of autoHeight: true). If the accordion has an explicit height, then all panels will be sized based on that height (equivalent of fillSpace: true). When fixedHeight is set to false, no calculations will be done for the height of the panels and they will be sized based on their content (equivalent of clearStyle: true).

Rename icon.headerSelected option to icon.activeHeader
This option is being renamed for consistency both within Accordion (active vs. selected when dealing with the active panel) and within the full jQuery UI suite.

Remove activate method
The activate method will be removed in favor of updating the active option. The inclusion of the activate method doesn’t simplify the use of the accordion and therefore isn’t necessary.

Rename resize method to refresh
This method is being renamed for consistency within the full jQuery UI suite. However, this will continue to only handle size changes for now. We do plan on supporting adding/removing panels in the future.

Rename changestart event to beforeactivate
This event is being renamed for consistency both within Accordion (activate vs. change when dealing with the active panel) and within the full jQuery UI suite.

Rename change event to activate
This event is being renamed for consistency both within Accordion (activate vs. change when dealing with the active panel) and within the full jQuery UI suite.

Add .ui-accordion-heading class
There is currently no class being added to the headings for each panel. This results in the stylesheet using .ui-accordion-header a for styling, which makes adding additional anchors to the headers difficult. To solve this, we will add a class to the first child of each header and use the new class for styling.

Feedback

We’d love to hear your feedback on these changes. We want to make sure we address any issues the community may have before we finalize and implement these changes. If you have any feedback, please post it on the related forum post. Thanks.

Extensible Autocomplete

Posted on by

The release of the Autocomplete widget in jQuery UI 1.8 was a pretty important milestone for the jQuery UI team. If you’ve looked at the widget, you may have noticed that there are only four options, far fewer than our other plugins. Unlike progressbar, our plugin with the fewest options, Autocomplete’s small API isn’t a direct result of the plugin’s simplicity. In fact, Autocomplete is quite complex.

When designing the Autocomplete widget, we started with Jörn Zaefferer’s Autocomplete plugin, which has 21 options, as a model. Admittedly, Jörn’s plugin does more for you out of the box than ours, but our smaller API is just as flexible and has the bonus of being easier to learn and use. A lot of thought, discussion, and prototyping went into narrowing down the list of 21 options to 4.

Out of the box, Autocomplete provides support for local data sources and remote (JSON) data sources by simply providing an array or url to the source option. Support for JSONP, XML, and caching can all be layered on top in just a few lines of code.

There’s also a set of extensions hosted by me that provide additional options for the Autocomplete widget. The html option (demo) allows you to specify whether your labels should be interpreted as HTML or text. There’s also the selectFirst option (demo) which automatically activates the first item when the menu is shown, reducing the number of keystrokes necessary to select an option. The autoSelect option (demo) allows a user to type out a valid option and tab away from the field without having to select the item from the menu. If the value entered by the user is valid, the select event will be triggered just as if the user had explicitly chosen the item from the menu. I also have an accent folding extension (demo) that makes it easier for users to select values with accented characters. For example, if there is an item with the text “Jörn”, the user would normally have to type the umlaut in order to see the item. However, if the accent folding extension is loaded, the user can type “Jorn” and they will still see the result.

Going a step further, you can use custom data formats and define custom displays. For example, you can categorize the results or display additional information such as item descriptions and images. There’s even an example of expandable search results (Note: this is just a prototype based on a demo from Roman Chyla, it is not full-featured. See the forum thread for more details). You can even support multiple words from a single text field.

Finally, there’s the combobox demo that brings Autocomplete functionality to select elements. The combobox hides the select element and instead displays a text field for the user to type in. The possible values are determined by parsing the options from the select, and the user can view all options by clicking a button next to the text field. For a detailed explanation of how the combobox works, check out Jörn’s article on Learning jQuery.