{ height: 1%; } - Ruby on Rails and User Interface Design

CSS, UI Design, Ruby on Rails and cheese ... lots of cheese

On the Ajax Scaffold feedback

Posted by Richard White Sun, 26 Feb 2006 21:02:00 GMT

AjaxScaffold has been deprecated in favor of ActiveScaffold

The feedback from the Rails community has been great. Lots of love and kind words on both this blog and on the responses I saw on the RoR mailing list (which admittedly I don’t keep up with as much as I should, is there any way to get it to digest all the messages for 1 day rather than flooding my inbox with 30 emails per).

I did see some murmurs of bugs on unsupported browsers on one of the responses on the mailing list and there is a list of possible features/improvements (bottom of the orginal howto). I’d like to open it up and see what the community in general would like to see done next. Here are my thoughts on future development:

  • Sortable rows would be my #1 request. I despise pagination, am often skeptical of most “find” features and find that the ability to sort and scroll are all I need to find what I’m looking for. Sortable Rows +Added in 3.0.0
  • A print stylesheet would be easy and a nice touch in my opinion. Print Stylesheet ++
  • Ability to send different types of messages to the client, not just error one would be useful and easy to do as well. Support information and warning messages as well as error ones ++Added in 3.0.0
  • Having it update what other users enter on the screen I think is very important. Otherwise whats the point of it being Ajax if I have to refresh to see other’s changes. But admittedly my current projects don’t have interfaces where there would be multiple people editing the same list so this isn’t as important to me currently. Background list updating +
  • I’ll probably get some chastising for these next two but here goes. I don’t find supporting any browsers beyond the existing ones all that important. Something like 4% of the internet uses primarily some unsupported browser. Very edge case to me and a lot more headache than its worth. Supporting more browsers -
  • I’m not overly concerned with fallback methods so that it works when javascript isn’t enabled. If javascript isn’t enabled the person is a) not going to be able to use the rest of my application and b) probably isn’t in my core audience anyways. I honestly don’t even know much about fallback methods (tsk tsk I know) since I have no plans on using them (but I should still really learn what they are). Graceful degredation— Added in version 2.2.0

Addendum Thanks to one of our readers for pointing out what should really be my #1 request..

  • The generated scaffold should KNOW about and have dropdowns or autocomplete textfields for associations. I know others have ranted about this glaring shortcoming. I think the more scaffolding you generate you kind of resign yourself to the fact that its just not something Rails is going to give you. In fact to make it work I’d have to dig a level deeper than the current AjaxScaffold goes and actually change the base Rails generator. But this really should be a core feature of any interface generator. Anyways I’m putting this on the development stack just under my less ambitious plans for sorting and pagination.

My thoughts are obviously selfish and slanted towards what I need the scaffold for currently, which is exactly the kind of feedback I’d like from everyone out there. So let me have it :)

Comments

  1. Bill said about 9 hours later:

    I’d like to see clickable column headers to sort the table by the column, ASC or DESC, and to set a default sort column for the initial display.

  2. Richard White said about 9 hours later:

    Bill: The only question there is how do you handle the inline forms when you sort… do your edit forms move around? what about adds? I guess thats the only question hindering that feature.

  3. Stefan said about 10 hours later:

    First of all, thanks for sharing! It works like a charm and is very cool. I added an export to Excel action and default sorting and I got a little dive log app going. I thought it would take months before I had the inline editing capabilities.

    I can understand your dislike for pagination but when you have 1000s of logs the list get very long and I think pagination is very good in my case. So I’m working on that and adding a Live Search feature (that’s also a suggestion).

  4. Richard White said about 12 hours later:

    Stefan: excellent points. I do detest pagination but do see its place. Just as long as there is an easy way to turn it off :) Are you interested in contributing any of those extras (excel, pagination, live search) you’ve built?

  5. Larry Kelly said about 16 hours later:

    Great stuff! I think clickable column headers to change sorting. Make sort and pagination work, and optional. Have default row per page more usefull. say 30 or 50.

  6. Stefan said about 17 hours later:

    I don’t mind sharing at all, but I’m afraid it isn’t much. To export to Excel I used http://wiki.rubyonrails.org/rails/pages/HowToExportToExcel and added <%= link_to “Export to Excel”, { :controller => “log”, :action => “export” } %> under the table. Very simple but works for now. Pagination and live search is next on my list. If the results are good I’ll share.

  7. Richard White said about 18 hours later:

    Stefan: Awesome I look forward to it, just email me either a link to a demo of your improvements and/or send me the code. If it looks good we’ll put it in there.

  8. Bill said about 19 hours later:

    Richard, I think the stuff that Court3ny posted to a comment on the original post about this generator (http://blog.caboo.se/articles/2006/02/02/more-cracked-out-scaffolding-element-twisty) has some good ideas about this. I’m not clear where the concern about the forms comes in though, to me its orthogonal.

  9. Sean said about 20 hours later:

    Very nice work with the Ajax Scaffold!

    +1 for Ajax Pagination

    I’d like to see just the div with the items reloaded instead of the entire page when using the Next/Prev links.

    For really long lists of items (i.e. 100’s and 1,000’s), I don’t see a better solution that pagination

  10. Scott McMillin said 1 day later:

    Richard, you’ve got two tbody tags in your list table (one for content, and one for error). Even though you’ve got one hidden, the code still isn’t valid and the table renders incorrectly (in FF at least). Otherwise, looking good – thanks!

  11. Phil said 1 day later:

    Is it possible to get the demo source as well, or an explanation of how to render the two tables (from different controllers, I assume) on the same page. Trying to accomplish something similar and am finding your generator very helpful.

  12. Alex said 1 day later:

    For those that don’t like pagination, and those that don’t see an alternative to pagination, have you seen Rico’s LiveGrid functionality?

    http://openrico.org/rico/livegrid.page

    I have only jsut stumbled accross your Ajax Scaffold so have not yet looked at what it wuld take to inegrate LiveGrid type functionality rather than pagination but it’s deffinately the better alternative in some instances.

  13. Richard White said 1 day later:

    Bill: Yeah I saw Court3ny’s post, unfortunately none of the stuff on his post works but I see where he is going. I don’t see the form issue as orthogonal at all though, I see it as very key. If I resort the form I don’t think I’d want my open edit elements to move (and with pagination to move off the page). I’m thinking that sorting would keep all form elements in place and just post a notice saying “When you save/cancel this element it may be moved off the page by your sort settings.” But figuring that out to me seems very important form a usability POV.

  14. Richard White said 1 day later:

    Scott: How is the code not valid? Multiple table bodies are perfectly valid XHTML and I don’t see any table rendering issues in FF. Let me know more precisely what you are referring to, what errors you are getting, etc. I’d like to track down that issue asap if it does exist.

  15. Richard White said 1 day later:

    Phil: Getting multiple scaffolds on the same page is as easy as creating a new view and pasting it the contents from the index.rhtml of each scaffolded model that you want on there. So if you wanted a page of customers and widgets you would create a new view and put into that view the code that is in /views/customer/index.rhtml and /views/widget/index.rhtml

  16. Richard White said 1 day later:

    Alex: I am familiar with LiveGrid. I believe that sort of solution would be more complex and the thought of having a couple of scaffolds on the same page all with their own scrollbars thrills me even less than pagination :) But it is certianly something to consider.

  17. Eric Pugh said 1 day later:

    I was discussing how to do this with a coworker just a day ago who sent me the link! This is really the kind of thing I’ve been looking for. We’ve been working with in place editing, but with logs of crufty javascript and it hasn’t worked too well.

    I agree with your dislike of pagination. Our first RoR app had pagination and the customer said “take it out”.. If the list is long, we’d rather let it load for 5 minutes and then use our browser to search! What we really want to do is provide some sort of live search that tells the customer “5000” rows found or “245” rows found, and then when they have narrowed it enough, then display the data.

    In terms of sorting, you could maybe have the rule that if an editable field is happening, you can’t sort. I’m probably either editing or searching/sorting, but not both simultanously….

    Great work!

  18. Richard White said 1 day later:

    Eric: Yeah I would say that having open edits and sorting at the same time is almost and edge case, I can’t see people doing that as part of their usual workflow. That said having it being stateful where in one mode you can edit and in one mode you can sort and do other list operations would be suboptimal imho. I think it either comes down to the solution i mentioned a few comments back or something that prompts the user what to do when they sort and have open edits ie. “do you want to save open forms and sort?” etc.

  19. conradwt@gmail.com said 1 day later:

    Hi, I’m new to RoR development. Thus, it would have been good to include an INSTALL document with the distribution because I’m not sure what file(s) to download and how to install it.

    Thanks in advance,

    -Conrad

  20. Phil said 1 day later:

    Oh course, the simple answer makes sense! Thanks again.

  21. Joe Van Dyk said 2 days later:

    I’d love to see a way to smartly do file uploads with this.

  22. Richard White said 2 days later:

    Joe: I think you posted something similar on the other article, care to elaborate more on what you mean.

  23. superbiji@gmail.com said 2 days later:

    Mantabbbbbbbbbb (Cool),

    I’ll check this out

  24. superbiji@gmail.com said 2 days later:

    How about adding “Save more” button to add multiple rows…

  25. Bobby the Newbie said 4 days later:

    Richard, I’m trying to figure out how to add this functionality: when i click on a table row, the slide-out DIV displays data, not a form to edit or create a record. My plan of attack is: link_to_remote (the_record_name), :action => show_details… how do I call the DIV to update? (Sorry for what is a very elementary question, I’m just a confused newbie.) I want users to be able to “preview” data, rather than edit. One other thing: instead of clicking on the link, is it possible to trigger the updated DIV with a hover?

  26. David said 5 days later:

    Bobby, I doing something that sounds similar. I think you’d want to just edit the relevant “_form.rhtml” doc to display only instead of using form tags. so you’d have this: <= @widget.name> instead of this: <%= text_field ‘widget’, ‘name’ %>

  27. dsalama said 5 days later:

    Richard, great work. I just upgraded my rails to the latest version 1.0.0 and your latest version of ajax scaffold. I noticed that when I use <= javascript_include_tag “ajax_scaffold” %>, it all works fine. However, when I ALSO include <= javascript_include_tag :defaults %> (regardless of which is defined first), the “Create New” doesn’t work. Is there some conflict between the two? I’m fairly new to using ajax with rails. thanks.

  28. dsalama said 5 days later:

    For some reason it didn’t include some text, so apologize for the repost. ... I noticed that when I use javascript_include_tag “ajax_scaffold”, it all works fine. However, when I ALSO include javascript_include_tag :defaults (regardless of which is defined first), the “Create New” doesn’t work…

  29. dsalama said 5 days later:

    Sorry for not doing this before. I tested with each individual rails javascript included and the problem occurs only when prototype is included. Is this normal?

  30. Jacob said 5 days later:

    Richard, this is really cool. I’d like to see the generated names be singular like rail’s scaffolding, ajax_scaffold user generates everything with ‘users’ instead of ‘user’ like rails. I have to go back and rename everything for consistency.

  31. Richard White said 5 days later:

    dsalama: That is definently not normal. I always have prototype in my javascript links in the header. Do MAKE SURE that ajax_scaffold.js is after prototype.js in the list. Otherwise I believe you will have problems. Feel free to email me any information you find out about this problem, a screenshot of any errors in your javascript console would be very helpful.

  32. Richard White said 5 days later:

    Jacob: I’m a little confused when I do “script/generate ajax_scaffold Widget Widget” all the generated files are of the singular form. Am I missing something or are you referring to something else?

  33. Rick Bradley said 5 days later:

    Richard—thanks for the good work. We’re using this to do scaffolding of new models/controllers in the “Centernet rewrite” (http://rewrite.rickbradley.com/) and it’s pretty slick.

    One thing that I think would make this tool that much more powerful is actually scaffolding associations (which, last I checked, are reflectable in ActiveRecord)—so that if Foo has_many Bars the list of Bars is shown on the Foo controller, with Add/Remove for the association.

    Just a thought. Thanks for the great work!

    Rick

  34. Jeremy said 5 days later:

    bgcolor: white;

    (I’m using a non-white bg in FFox, and these page look sloppy.)

    As an alternative to background list updating (which I agree, for a small project would be secondary priority), you might simply have any of the update calls also return any new data that’s found. Perhaps not as simple to impliment (personally, I would have any submits pass a current list of ids being viewed… but that could be sloppy), but it would cut down on traffic.

    Anyway, this is a superb addition to Rails. Add mine to the voices of thanks.

  35. Jeremy said 5 days later:

    (Re-reading my post, I see I wasn’t clear. Trying agin:) Rather than periodical updates, I would add to all of the update calls (edit-clicks, submit-clicks, delete-clicks) a list of currently-viewed ids. The return call would have a section (assuming you’re using XML or JSON—I haven’t yet looked into the source) for new data. That will avoid the traffic of periodic updates from a window that’s been sitting open for hours/days… and it’s intuitive to have the page check for changes to the main list whenever the user enters/alters data. That said, the simplest solution would, of course, be a button saying “check for changes”. I don’t think that would be too much clutter, it would be very intuitive, and it would be exremely simple to implement. Agile development would argue for such things. ; )

  36. Richard White said 6 days later:

    Rick: That’s a very good and often overlooked point, at least by people used to RoR. I’ve been resigned to the fact that scaffolding doesn’t generate those associations. I know Joel Spolsky even blogged that he was very disappointed by that. Changing that would require digging into the guts of the scaffolding code (not just adding stuff on top of the existing framework as the AjaxScaffold does). That said I think that would be a HUGE improvement. Consider it high on the radar.

  37. Richard White said 6 days later:

    Jeremy: Originally my thoughts for sorting, pagination and polling were very grandiose with such things as an engine for managing all of that (where to insert polled items in the sort, how and when to push things off the current page, how to sort while keeping edit/creates in place, how to handle those update/creates after etc). Needless to say that is a very daunting feature to add. I’m thinking that pagination/sorting/polling will be added but in a much more constrained way. You can only sort when all edit/creates are closed. Creating/Updating does not resort the list, you would have to click to resort it. Pagination is very basic and also only lets you change pages when all your open edits are closed. And polling would place the same constraints… basically adding the whole “close all your open forms” constraint makes all these simple list operations rather than some complicated diff. As far as the technical side of things, currently everything thats being passed back from the server is straight HTML, but even in a simple polling solution I would think it would involve XML or JSON that returns the new/updated elements deleted elements since your last request.

  38. Pascal said 6 days later:

    is that the article you were referring to: http://discuss.joelonsoftware.com/default.asp?joel.3.309321.113 ? It is signed “aHack”.

  39. Bill Guindon said 6 days later:

    Is this the ‘Joel’ post you mentioned? http://discuss.joelonsoftware.com/default.asp?joel.3.309321.3

    I don’t believe it was actually written by Joel btw, it’s signed by “a Hack”.

  40. Bill Guindon said 6 days later:

    Ok, that was freaky :)

  41. Pascal said 6 days later:

    :D must really be the righ one then

  42. Richard White said 7 days later:

    Bill & Pascal: Yeah thats exactly the one, thanks for finding it. Next time let each other know so we don’t have double posts like that ;)

  43. Aredridel said 10 days later:
    Highlighting WILL work and will repect any special CSS styles for table row background colors you have defined but their maybe be a significant performance cost especially if you have a lot of items on this table.

    Indeed it is a huge performance cost. With some thousand rows, 15 or 20 columns, the scripts on the page take some 60 seconds to run on my P3-800. I’d love a more efficient styling.

  44. Richard White said 10 days later:

    Aredridel: Yeah that’s the scenario where the current highlighting is best left turned off :) . The way to fix that will be to implement pagination.

  45. aicthai@yahoo.com said 16 days later:

    thank for your grate work!!!

    helpful for my project.

    1 question can use dropdownlist with ajax_scaffold ??

    sorry for my poor english.

  46. Jon said 18 days later:

    Really like this generator. My ideal generator would be automagically rearrange the table structure to handle tables with lots of columns. Doing it all in one row gets pretty unweidly, fast.

  47. Richard White said 18 days later:

    Jon: I think the solution to that would be to let you take out the columns that aren’t as important and put them into some sort of data pane that popups up inline much the same way that the edit/create forms do. I am still planning on writing an article on how to do that so stay tuned.

  48. Richard White said 18 days later:

    aicthai@yahoo.com: Yeah you can do dropdown lists but you have to put them into the form yourself. I assume you are talking about doing drop down for model associations. I’ll have an article up soon about how to do that.

  49. Julian Gall said 18 days later:

    If you run “script/destroy ajax_scaffold widget”, it removes .gif, .js and .css in the public folder. These may still be required for other scaffold that are not being destroyed.

  50. Richard White said 18 days later:

    Julian: I don’t really see any way around that. The Rails scaffolding framework really doesn’t provide a means for specifying certain files not to be deleted upons script/destroy. Your best bet is just not to use script/destroy (honestly I didn’t even know it existed) and delete things by hand if you don’t need them.

  51. wolfmanjm said 21 days later:

    This is excellent thanks. One additional suggestion is maybe to have an exclusion list that says to not generate input for certain columns, for instance created_on and modified_on are columns I use in all my tables (about 50 tables) and I need to go through and manually change all the forms right now to remove those, it would be nice to tell it to not generate the fields for those columns up front, especially as those are “special” fields anyway to rails.

  52. Richard White said 21 days later:

    wolfmanjm: I am going to put up an article this week on how you can have those types of rails specific fields removed from all your views with some application level code. Its fairly easy to do and hopefully that would solve your problem. I am very hesitant to add anything extra to the generation process in the form of switches, flags, exclusion lists or what have you.

  53. wolfmanjm (aka Jim Morris) said 21 days later:

    Thanks I look forward to that. I did use Dean’s suggestion of overriding content_columns, and that works very well except it does the exact opposite to what I want, I want to see the fields in the list but eliminate them from the edit forms. It is easy to do of course by just editing all the _form.rhtml files, but it gets tedious after about the 20’th or 30’th file :) It would be nice to not have the generator generate them in the first place. I hope your article will come up with a better solution, Thank you.

  54. Katsushiro said 22 days later:

    I’m gonna go ahead and add a suggestion for, if not a feature, at least a little help, maybe a how-to or workaround tip for file uploads. I’m using the ajax scaffold throught my project and having a lot of fun with it, figured out how to display images in rows, etc. However, I can’t seem to get file uploads (specifically, image uploads) to work.

    To be scific, I’m using the file_column library to easily handle uploads, and it works flawlessly on forms that are submitted via a regular page. But from within the ajax scaffold, it doesn’t work. It doesn’t give me any errors, just doesn’t upload the file when you hit the submit button on the form.

    I assume it has to do with the use of an XMLHttpRequest object to submit the form data, which can’t really handle file uploads.. but do you have any ideas or workarounds?

  55. wolfmanjm (aka Jim Morris) said 23 days later:

    I am curious how you would handle login forms within the ajax scaffold, using the standard type login method where any access will redirect to a login action and login form, then once logged in will continue onto the requested form. I have played around with doing a login form modelled after new.rhtml but can’t get it to work. Do I need to put some logic into list.rhtml that tests if login is required, and create a special partial for login, or is there an easier way? Thanks

  56. Katsushiro said 23 days later:

    Been working on my upload gripe, and I ran across this: http://www.kylemaxwell.com/articles/2006/02/11/form_remote_tag-enhancements

    Far as I can tell, that plugin tries to render form_remote_tag inside an IFrame. However, it doesn’t seem to be compatible with the Ajax Scaffold. If I install the plugin, any pages with the Ajax Scaffold return an error: undefined method `loading_indicator_tag’. The plugin does things to form_remote_tag in the JavascriptHelper, I’m guessing the conflict is there. I’m messing about and seeing if I can fix it or integrate what it does into the Ajax Scaffold system somehow. I’ll let you know if I come up with something.

  57. Richard White said 23 days later:

    Katsushiro: Sorry for the delay in my reply. I was going to pass along the same link to you as its the only solution I’ve heard of. That would be wonderful if you could take a look at what’s breaking it in the scaffold. Feel free to email me with your findings if you get to a point where you need my help. rrwhite at gmail

  58. Freddy said 24 days later:

    Hi,Richard I think if the Ajax Scaffold would adopt <div> while not <table>,it is much better easy extendable and effieciently reusable,I use your Ajax Scaffold to startup my web site development,at first it can reach the requirment,as the development procedure proceeds,i had to give it up for its table’s not easily extendable,eg: to display some comments on each item with ajax while cliking on the item.I had to rewrite most of the javascript to use <div>

  59. Hara said 36 days later:

    Excellent and very useful code. I would like to have two submit buttons which call different code in the controller. Also this code should remove the row from the table. Any hints on how can I do this? TIA

  60. Peter said 37 days later:

    like Katsushiro I was also trying to find a fix for image upload with file_column, after several failed approaches I succeeded by putting a second regular form before the form_remote_tag as a workarround – not terribly elegant I fear, but it works! congrats on a great piece of work

  61. Richard White said 37 days later:

    Freddy: Using a table does make things more difficult since a lot of common JS libraries don’t support them well. However the data really should be a table to keep it both semantically correct and to enable you to do things like sort a column. Your example is a bit vague, perhaps if you describe it in more detail I can suggest a solution that wouldn’t require you to rewrite everything.

  62. Richard White said 37 days later:

    Hara: This looks like a good resource for that question: http://tr.openmonkey.com/articles/2006/01/16/multiple-ajax-submit-buttons-in-a-rails-form

  63. Richard White said 37 days later:

    Peter: Would you mind emailing me your code so I can take a look at your workaround as well?

  64. Eden said 39 days later:

    First, ajax_scaffold is excellent. Thank you for sharing this tool. I am also a Kiko fan; keep up the great work.

    Do you have any plans to make ajax_scaffold into a “real” project. Put it up on Rubyforge or something? If not, then how about using web based issue tracking software (16bugs.com or host Trac)? Or perhaps just a wiki? I ask because I ran into an issue tonight and the only resource I found was reading through the many posts on your blog. Please consider using a more functional community oriented resource for issues.

    I ran ajax_scaffold with the intent of sectioning off some of my scaffolding under an admin interface as described on page 191 of AWDR.

    generate ajax_scaffold Admin::CertificationStatus

    Everything appeared to run just fine, but visiting admin/certification_statuses gives me a completely ajax free page. I did some investigating and found that layouts/admin/certification_statuses was not generated (in fact, the generate script reported “identical layouts/certification_statuses” from an earlier generate run). Creating layouts/admin and copying certification_statuses into it got everything working again.

    Is this a bug? Do you have a suggestion of where to look to patch this myself for the current version?

    Thank you for the excellent work. I think ajax_scaffold is one of the most useful tools I have seen for Rails.

  65. Eden said 39 days later:

    Quick follow-up to my last post. I managed to patch ajax_scaffold_generator.rb to correct the problem I described above.

    I changed: m.template ‘layout.rhtml’, “app/views/layouts/#{controller_file_name}.rhtml”

    to

    m.template 'layout.rhtml',
        File.join('app/views/layouts',
                controller_class_path,
                "#{controller_file_name}.rhtml")
  66. Eden said 39 days later:

    Sorry the formatting got hosed. Does your blog permit markup? I will try again with simple markup. FROM
    m.template ‘layout.rhtml’, “app/views/layouts/#{controller_file_name}.rhtml”
    TO

    m.template 'layout.rhtml',
        File.join('app/views/layouts',
                controller_class_path,
                "#{controller_file_name}.rhtml")
  67. Richard White said 39 days later:

    Eden: Thanks for the fix. AjaxScaffold is up on RubyForge. As far as setting up a wiki or a 16bugs account doing the latter is probably a good idea to keep track of these things.

  68. Peter said 42 days later:

    Hi Richard, sorry but I missed your code request errr, I can’t seem to find your email do you want me to post the code here? looking forward to the new version!, thanks very much

    Peter

  69. Richard White said 42 days later:

    Peter: just email it to me rrwhite AT gmail DOT com

Trackbacks

Use the following link to trackback from your own site:
http://www.height1percent.com/articles/trackback/16

(leave url/email »)

   Comment Markup Help Preview comment