By now, the Drupal contributed repository grew so big that there are likely multiple solutions to the same problems there. Maybe these solutions solve the tasks with different angles, have slightly different features, but at their core, they aim at solving the same issue. So it is getting harder for site builders to pick the modules they want to use (and drupal.org is planned to offer more tools in helping with the selection). When it comes to core inclusion though, one needs to very clearly define the requirements and meet core goals, such as lean and mean implementation, maintainability and reusability.
With Mark Boulton's and Leisa Reichelt's suggestion to have most of the Drupal administration interface show up in an overlay on top of the public facing webpage, we are again at such technology crossroads. Drupal 6 at least has two contributed modules to implement a similar-looking solution: Popups API and Modal Frame API. Both got their pros when I researched for possible overlay implementations, and frankly, when there are already two modules implemented for the same complex task, why would we start from scratch?
The goals for the core overlay (purposely not called a modal dialog) is to take up most of the window with a dim background on the original page content. The overlay would have a close button on its right side and possibly tabs on top to switch to different subpages (loaded via Ajax or will already be on the same page, but hidden). We don't need the overlay to be moveable or resizable. We don't need to show multiples at once, since it only makes sense to show one. However, the overlay should work well with the header so that when an option is selected, it keeps being active in the header, and the header should work so one can pick another area to work on without first closing the overlay.
With different tabs or without tabs but otherwise consistent look elsewhere:
For easier evaluation of how we can meet these goals, I've ported both above mentioned modules to Drupal 7 and implemented Drupal 7 user experience "skins" for them. In the case of Popups module, it was a skin which the module already supports via an internal API, with Modal Frame API, it was an actual glue module which mapped elements marked up for being displayed in the overlay to a style similar to what Mark and Leisa suggests. Neither of them is pixel perfect to what is to be done, but the initial goal was to have D7 versions to evaluate and discuss the implementation internals, so we can fix up styling once we picked either one or a third way.
You can find my Popups module port patch at http://drupal.org/node/466732#comment-1681554 and the Modal Frame API port patch at http://drupal.org/node/491224#comment-1703366 but to make all these easier to test with the D7UX header in progress, all this code is available with the glue modules and custom skins in the D7UX code repository. You can try out both by installing with the d7ux install profile and then either turning on the "Popups API" module or the "D7UX overlay look" module. Make sure to only have one of them enabled at once and let Drupal install their dependencies. Switch between the two implementations by switching between the two modules.
Overlay implemented via modal frame API module (the close button is not yet themed to look like on the mockups, but think of that as a minor detail):
Let's go beyond the UI and compare the modules:
Popups API | Modal Frame API | |
---|---|---|
Started | December 2007 | May 2009 |
Maintainer | starbow: http://drupal.org/user/33290 | markus_petrux: http://drupal.org/user/39593 |
Contents | Popups API, popups admin (admin mapper) and popups test modules (for human testing), skins | Modal Frame API, Example glue module for testing |
Based on | Lots of custom code based on jQuery | Small amount of custom code based on jQuery UI and jQuery |
Codebase | Light on PHP code, heavy on JS | Light on both PHP and JS code, jQuery UI makes up for it |
Overlay rendering | Ajax request for a JSON object which contains the rendered content of the page, JS and CSS files to be loaded for the page and Drupal messages | Ajax request for a fully rendered HTML page which is themed by the Modal Frame API module to only include the main region and some wrapper code. |
Overlay display | Merges rendered overlay into main HTML document; merges in CSS and JS files (possible ID collision) | iframe element added to the page (no requirement for CSS and JS merging) |
Stacked popups | Supported, only one visible at a time | Not supported |
Dirty forms (unsaved edited form warnings) support | Supported via custom code | Supported via http://drupal.org/project/dirtyforms |
Form submission in popups | Reloads originating page (via Ajax or full reload) or runs custom callback | Overrides form submit redirection and closes overlay |
We are obviously at crossroads with picking our ways. The Popups module approach already has numerous core patches which were suggested earlier, while Modal Frame API leverages jQuery UI to lessen custom code burden and iframes to avoid colissions in merging HTML documents, which might be more attractive.
What did I miss in my comparison? Did I miss another alternative? What do you think a core solution should look like? jQuery UI to core? Just a targeted custom implementation for our own needs? IFrames or HTML merging? JSON output or overlay specific theming? These are general conceptual questions, so I choose to write a blog post to try and start a conversation instead of using the issue queue, which would be useful for more targeted questions. However, answers to some of the questions infer answers to others. What do you think?
I'm thinking Modal Frame API
I'm thinking Modal Frame API and jQuery UI should go into core (at least partially, maybe not the translations) ... but I'm interested to learn what others have to say on this.
I'm already considering to
I'm already considering to implement Popups API for some of my modules (namely admin_menu, Wysiwyg API, and more).
I think that starbow worked hard to let Popups API rock. Very important factor:
+ Allows stacked overlays/dialogs/foobar
That, of course, may not be a requirement for Drupal core, but it would be a pain to load a bloat of additional JavaScript to get it right. A usable UI, whether delivered by core or contrib, simply requires modals/popups to quickly perform additional actions.
OTOH, using jQuery UI and less custom code is also an important factor, because it means:
+ Standards
+ Extensible framework/design
The CSS ID collisions are probably a show-stopper for Popups API, but we already started to replace CSS IDs with classes lately:
http://drupal.org/node/482636
It seems logical to advance on that.
IFRAMEs introduce different issues, such as missing context and passing JavaScript settings from the opening window to the child, which most often are very hard to tackle. Dynamically loaded content usually wants to interact with the containing page.
We recently allowed AJAX/AHAH callbacks to extend Drupal.settings and are thus passing extended settings to all behaviors for this very reason.
Hence, my vote would go for both: Popups API using jQuery UI to get most tasks done.
Ideally, we get both maintainers to join forces on a merged approach.
Well, it seems clear we're
Well, it seems clear we're moving towards using much more javascript in the core UI, and that brings an obvious question: include a UI library or create our own? Including jQueryUI would seem a bit of a no brainer with jQuery itself already in core.
For me a big question is performance (but then I still have a 2002 vintage G4 mac as my main machine!).
jQueryUI is themeable, but how that meshes with drupal themes, if at all is another issue. Less of an issue for core perhaps.
As for Pop-ups vs Modal dialog, I suspect you'll get a lot of support for Pop-ups simply because it's been around a lot longer and people have actually used it, but Modal clearly carries a lot less baggage (jQueryUI aside).
Just checked out d7ux repo for a closer look :)
That d7ux repo is very
That d7ux repo is very handy!
Right now Popups seems a lot more slick, and a little faster. But perhaps that's because it attempts less animation (modal does fade in around the edges).
Without having reviewed the
Without having reviewed the modules in question, I find the iframe approach much cleaner. ID collision can always be solved, but it won't stop inherited styles from affecting various types of content loaded into the DOM. Iframes sound a lot easier to deal with, theming-wise. I also like the lightweight footprint of Modal Form API. While I love jQuery, the less JS code the better.
As for jQuery UI, I think it's a logical step in the right direction. I find it a bit limiting at the moment (see ExtJS for what is possible), but if we were to include a UI library it would have to be this.
I'll definitely have a look at the d7ux installation profile, this is exciting stuff!
I'm really quite surprised
I'm really quite surprised that we're talking about having a modal dialogue in core. When Mark and Leisa first starting work with the Drupal community I remember one of them saying how surprised they where that nearly everyone who works with Drupal a lot uses the URL bar like a command line; when we want to administer content we think admin/content/node, rather than the series of corresponding mouse clicks. We work with Drupal this way because this is the way the internet works. The RESTful paradigm where addressable URLs have meaning and serve as the representation of a actual resource is something we should preserve (to the extent that it exists) in the administrative parts of Drupal.
To do otherwise assumes we'll always know where 'administration' stops, 'normal' usage begins, and how 'administration' will work. These sorts of assumptions have no place in Drupal core.
degrading
I think Drupal has this core concept of degrading if there is no Javascript (when there will be no modal dialogs either), so this should all work in that case too. Then that would obviously have discreet URLs for the different admin tasks, just like you experience it now. I don't think we have the luxury to not implement it in a degrading way.
Great, I'm glad we're not
Great, I'm glad we're not going to ditch the non-js world. But what do you think about my second point regarding the usefulness of having modal dialogues in core?
Since it's clear that this modal system is going to need to be optional (for non-js compatibility at least as you point out, and to support admin interface customization as I've said) will it live in a optional core module?
If so, what is the point of adding this complex set of javascript driven user interactions to the core maintenance workload?
optional things
Well, almost anything in core should be optional. Whatever is in core can be overridden at least via alter hooks, disabling modules, revoking permissions, turning knobs, etc. The fact that this should be possible to be disabled and it should degrade and let people to modify and override it does not make it less core worthy in itself, since all other core components should have the same customizability.
As much as we all love
As much as we all love Starbow, if a solution involves including JQuery UI, it's a worthwhile investment in the Drupal project. It also seems like the Modal Frame API is a more modern solution, but that's from a quick glance.
@Dries I'm interested in why
@Dries I'm interested in why you like Modal Frame API. Is it because it's smaller? Is it because it uses jQuery UI? If so, would moving popups API to use jQuery UI change your answer?
To me it seems popups api, with stacked dialogs, gives us the most flexibility. I think sun is probably right in saying that if we can get popups api using jQuery UI that would be ideal.
setting requirements first
I think we should set our requirements first for a core "overlay" solution. I think it is not part of the requirements to support staked popups, but I it would be a good idea to clear this out, so we know better. I think it would be somewhat unintuitive to have you select a content type to post your new content to, getting the form and then when you close your node submission, you get back the selection form which you still need to close, wouldn't it?
IMHO, that example is not a
IMHO, that example is not a good example. I'm pretty sure that Popups API allows to replace the content of an existing overlay/modal/dialog.
A better example is: Consider you create a new story that uses a fixed/static taxonomy vocabulary to categorize stories. Now you find out that your story requires a new term. Kawumm! What do you do? Copy all form values. Go to the taxonomy term administration to add the term. Go back to the node creation form and re-insert your form values so you can finally select the new term.
That's the case where usability in stateless systems sucks most. Our goal should be to provide quicker access to interfaces and pages that are related to the current task or context. Stacked overlays/modals/dialogs are one key instrument to get there.
the mockup above
Well, look at the mockup above. The category example is supposed to be solved right there with an "Add new category" link. It's behavior is not specified, so we can assume that it expands out to an AHAH term addition form. In this case, it might be better to actually provide the functionality in context compared to opening layers of windows for people, from which they'd need to navigate back to their original page. (Not that I think this mockup covers multiple vocabularies or considerable number of terms, or other complexities with term selection).
AHAH not needed
We solved that a long time ago. Just send user to 'admin/content/taxonomy/term/add?destination=' . drupal_get_destination(). User goes back to proper place after adding a term. We'll need stronger justification than this for putting a popup in core.
I'll give the d7ux repository a try. Ultimately, thats the only way to evaluate if the UX is much improved.
The combination of jQuery UI
The combination of jQuery UI and an updated popups API sounds reasonable too. sun had some good arguments in favor of popups API.
jQuery UI sounds like a no-brainer if we can stomach the size increase.
Just to be clear: my statement was not based on a in-depth analysis or practical experience using those modules. I think we should trust those that have worked with both, and that know what they are talking about (i.e. not me).
Given that Gabor actually used both, I'd love to get his recommendation too. His initial experience it not unimportant either.
Popup API's focus
Popups API focuses on integration with Forms API. It's focus is on submitting forms and then seamlessly updating the original page. This is an interesting problem, and I found that it got an order of magnitude trickier when I tried it with iFrames. If all you are doing is showing a single form and then doing a full reload on the underlying page, then the iFrame approach is nice, because it does not effect the original page.
I would recommend checking out the screencast demoing stackable Popups before you dismiss them (http://www.citris-uc.org/files/bdug/popups_modules_march_2009.swf). One of the key signs of getting usability right is that when you show it to people, they just shrug and say "Of course". But there are still some interesting technical issues to work out with this approach, both with element id's and making sure the correct javascript is loaded at the right time. If you can accomplish what you want to accomplish with a simpler solution, then that is probably the right way to go.
As for jQuery UI, I have been trying for over a year to get an answer on whether or not it was going to be included in Drupal 7. I would have been happy to rewrite Popups based on it months ago, but I don't have the time at the moment.
Updating the parent page is possible with modal frames
Tao wrote: "I found that it got an order of magnitude trickier when I tried it with iFrames"
I think I solved this problem with Modal Frame. When you open a modal frame, you can give it an onSubmit callback that will get arguments that can be sent from a submit handler on the server side. On that submit callback you can do whatever you wish to the parent page.
I'm using it in Subnodes by taxonomy module to edit child nodes using a modal frame, and then, on submit, updating the result on the parent page, this time using ajax. Child nodes are rendered on tabs on the parent node (where the tab name is a taxonomy term that adds meaning to the relationship). That's a module I wrote for a particular need. Games are a content type, that need a Game/platform content type as a child to hold attributes related to a game for each particular game platform.
Then I was writing Node Relationships (provides automatic back references and search/create and reference extensions to node reference fields), which also needs modal frames for the search/create and reference feature, so I decided to extract the modal frame code in the other module into a separate module that would be reused by both.
I decided to use iframes because I wanted to avoid the problems related to AJAX (namespace collisions, etc.). Then, I opted to use jQuery UI dialog because we are already using jQuery UI for other things.
It's been a surprise for me to see there was interest in Modal Frame API, being considered for this D7UX initiative. I had no particular interest in including it in core. I just made it as a result of particular interests related to the site I'm working on. That being said, I would be more than happy to help find a good pattern for D7UX.
As I see it, both Popups API and Modal Frame API have pros and cons. My implementation of jQuery UI dialog was focussed on providing a modal iframe, so it does not allow more than one modal dialog on the same parent page. This could be worked out, of course. On the other hand, the problem I see in Popups API is the fact that it provides its own library to deal with popups. Since we already need jQuery, which is already a pretty big library, on of the goals was not to add more js stuff, and Popups API was kind of blacklisted, honestly.
The good thing in jQuery UI is that it shares a lot of code between components. Components that we may already need for other things, such as tabs, calendar popups, etc. And it seems the jQuery UI API is getting more and more mature, specially since 1.6/1.7. It manages complex things, and it does pretty well, IMHO. I'm in the land of "don't reinvent the wheel", we have a nice library here that resolves a lot of hard stuff for us. IMHO, it worths, despite the fact that upgrading may mean additional costs. That's something to put in contrast to the effort that needs to deal with browser differences and all that stuff.
So, I would say it would be nice if Popups API was rewritten to reuse jQuery UI dialog. And maybe then it could also include support for iFrames, something that is not very well supported in jQuery UI at this moment either, so my Modal Frame API was a bit more complex than it could have been.
JQuery UI
I think we should bite the bullet and include JQuery UI into core. It seems mature enough by now, and it would allow more consistent widgets in the future.
Not too impressed with overlay
I installed the d7ux profile with modal frame and clicked around. I can't get excited about the overlay concept. It does not give enough of a boost in user experience to justify the code complexity. I have no qualms about this in Contrib. I have used the D6 version of admin theme and enjoyed it. But I can't figure out how it is being used in the d7ux profile. All the admin pages are in garland.
And WTF is up with the node form changes. I like what we did with the vertical tabs. This is a step backward IMO. The meta tab leads to an odd collapsed fieldset presentation. Is that supposed to be vertical tabs? Is there an issue where I can comment on this?
node form
Moshe, the node form patches are at http://drupal.org/node/472126 and http://drupal.org/node/491846 Please provide your feedback!
I've used both
The iframes in Modal Frame API are sturdier for all the reasons mentioned.
Popups 2 API is a really marvelous piece of code that I've learned a great deal by reading, and I think the integration with Form API is a significant difference from Modal Frame API. The targeting of an update to the base page is also very interesting and useful.
Have you evaluated iframe vs. no-iframe popups in various browsers? In Safari and Firefox on Mac, I can drag a non-iframe dialog around on the page and it's very smooth. If I drag an iframe around, it's obviously slower with redraw delays.
This difference leads me to use iframes in circumstances where I need them: large forms, complex AHAH/AJAX stuff in the iframe'd page. I use non-iframe popups when I'm doing something like a lightbox for an image in a gallery or a zoomed video player.
It would be ideal to port popups to jQuery UI so the styling and instantiation could be synchronized between iframe and non-iframe popups.
no drag-and-drop
Well, in this case, we would not need any drag and drop support for the overlay, so that was not part of the requirements.
I wasn't really talking about
I wasn't really talking about drag and drop. I was simply talking about draggable dialogs. Maybe I'm in the minority, but I like to play with my UI like kids play with their food. Flipping, poking, toggling, hovering... I can really make it go.
The iframe feels a lot more resource intensive than a no-iframe popup. It feels slower and heavier.
"resource intensive" means?
The document on the iframe should be as fast as any other page in the site. So there's room for improvements. Maybe using minified versions of jQuery UI, css/js compression, etc.
Or what do you exactly mean by "iframe feels a lot more resource intensive" ?
I think patching the core
I think patching the core with some semantic heavy dialog API (as Popups API and Modal Frame API are) may not meet the requirements of a generic widget API.
The real problem is a missing jQuery UI layer API for Drupal. A "drupalized" approach (at least from my understanding) would define the widget appearance by templates or theme function, get the options from some database tables and render the widget by some necessary JavaScript code. Methods and events (f. e. opening a dialog and resize listener) can be realized via PHP or JavaScript, f. e. as a FAPI enhancement.
And this is all about a feature request for the jQuery UI module, as I stated in this thread http://drupal.org/node/454382.
The whole discussion of "spoiling" the clean core with stuff like this really worries me.
Take a look at Squarespace
Have any of you guys seen the Squarespace administrative UI? It is nothing short of astonishing.
On the whole, Squarespace can't touch the power and flexibility of Drupal + CCK + Views, but their administrative interface is an excellent glimpse of what Drupal's admin UI could be like if it continues along the direction highlighted in this post.
Just take a look at some of these video demos.
It's scary how many of their administrative structures mirror those of Drupal.
Yeah SquareSpace is really
Yeah SquareSpace is really cool and I think this is something Drupal should be aiming for. I've got really high hopes for D7UX it's looking really good.
- Sean Bannister
lightbox over a modalframe
Hi,
There seems to be 'popup experts' downhere ;-)
I use noderelationships module and would like to preview the node from the modalframe (lets say in a lightbox), but OVER the modalframe.
Actually, my lightbox is restricted to the modalframe border.
Is there a way to overpass this restriction ?
Thanks per advance
Popups API with other Ajax widgets
I have noticed that Popups don't work properly, for instance, with Hierarchical Select and some other modules. Basically, you need to attach all needed js before you can use the Ajax select inside of a popup. I'm still struggling to find out how to do this...
Has anybody overcome this?