JavaScript and URL helpers need some love regarding best practices

There is absoltely no reason/explaination to do so. And I don't see it happening. Many of us use those helpers in most of the projects, and it works for us like a charm.

[...]

Rails is not forcing you to use those helpers or RJS.

The notion that there's huge chunks of Rails that may or may not be used or are being needlessly loaded makes me squirm a bit.

James

1) I like button_to_remote as an alias for submit_to_remote.

I've just posted a patch to http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/581-button_to_remote-aliases-submit_to_remote

3) Requiring all post/delete actions to be buttons is a personal choice that you're more than free to make for your project. It wouldn't fly with my designers at 37signals. Rails shouldn't be dictating how the UI of an application should look or feel.

Correct me if I'm wrong but a little CSS can make a button look like a link and even behave like one (including a hover effect). I've only tried it in Safari and FF3 for the moment but I think I remember that it worked in IE6/7 just fine.

4) I agree with koz's analysis of the fallback of link_to_remote. We have an even better way currently where you can set :url in the html options and thus get a different fallback.

I know that but you seem to misinterpret my intent. All I was proposing was a sensible default in the event that the user has JavaScript disabled. I made this suggestion because I'm a good boy :wink: and I use link_to_remote almost exclusively for GET requests where the URL of the link would mostly be the same as for the AJAX request. Question to everyone: Would it make sense to only default the :href attribute to the value of :url if the link_to_remote handles a GET request but leave it at "#" for POST/PUT/DELETE since they're likely to be wrong anyways?

Correct me if I'm wrong but a little CSS can make a button look like a link and even behave like one (including a hover effect). I've only tried it in Safari and FF3 for the moment but I think I remember that it worked in IE6/7 just fine.

Another possibility is to have button_to_remote actually use a <button> tag. button tags can be styled nicely and can have inner html content. It may even be sensible to make button_to work like this as well and change the current to submit_to. One issue I recall that needs to be handled differently with a button is the form's action url. Anything after ? is ignored, so any parameters need to be added as hidden fields in the form.

Just a thought.

Joe

The notion that there's huge chunks of Rails that may or may not be used or are being needlessly loaded makes me squirm a bit.

Methods never called are hardly going to break the bank on performance or memory usage. There's about a billion other things that should be higher up your squirm list.

Correct me if I'm wrong but a little CSS can make a button look like a link and even behave like one (including a hover effect). I've only tried it in Safari and FF3 for the moment but I think I remember that it worked in IE6/7 just fine.

Wouldn't this defeat the entire purpose of *not* using a link. The rationale as I understand it is 'links should be safe to click'. If it looks like a link, acts like a link, but still isn't safe, then we're worse off than with the current implementations. It still surprises people but it depends on crazy css stuff.

Wouldn't this defeat the entire purpose of *not* using a link. The rationale as I understand it is 'links should be safe to click'. If it looks like a link, acts like a link, but still isn't safe, then we're worse off than with the current implementations. It still surprises people but it depends on crazy css stuff.

Definitely - I was actually just trying to make a point that you *can* make a button look like a link and still conform with the general consensus that non-GET actions should be put in a form rather than a link. I should probably learn to not comment on every minor nuance but instead focus on the more important stuff! :wink: The other 4 comments I wrote on David's comments IMO are actually way more important, so I guess we should focus on them. And I'll try to shut my pert mouth and try to focus on the topic as well - I promise! :wink:

Question to everyone: Would it make sense to only default the :href attribute to the value of :url if the link_to_remote handles a GET request but leave it at "#" for POST/PUT/DELETE since they're likely to be wrong anyways?

Try a patch for this and see what people think. It sounds good enough if the implementation isn't too hairy.

If you guys agree to this (especially the core team), I'd start thinking about that and maybe start implementing it next week. I'd totally love if someone else cared to join me in the effort.

I don't think we need to add anything quite that complicated to actionpack. We bundle prototype and support it with some helpers etc. Whatever faults prototype may have choosing something is better than making it a configuration option which needlessly confuses people who just want an ajax form.

If there's anything which is currently difficult to replace with a simple plugin, then we can investigate it. But given the good job the jrails guys have done, I don't think we need anything here.

IMO that would be a quick win and I'd be happy to implement it as well.

I've heard rumours that sam stephenson was thinking around ways to make those helpers nice and unobtrusive by default. If we can have unobtrusive code that's just as simple (i.e. one helper call) as the obtrusive kind, then I say we just go down that path. But again, I'm not aware of any clear best practise in that space that we could latch on to.

> 1) I like button_to_remote as an alias for submit_to_remote.

I've just posted a patch tohttp://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/58…

Applied (with button_to_remote being the primary, submit_to_remote being the alias). Thanks!

> 3) Requiring all post/delete actions to be buttons is a personal > choice that you're more than free to make for your project. It > wouldn't fly with my designers at 37signals. Rails shouldn't be > dictating how the UI of an application should look or feel.

Correct me if I'm wrong but a little CSS can make a button look like a link and even behave like one (including a hover effect). I've only tried it in Safari and FF3 for the moment but I think I remember that it worked in IE6/7 just fine.

That seems to defeat the purpose of the change. Switching one hack for another. I'm -1 on this.

> 4) I agree with koz's analysis of the fallback of link_to_remote. We > have an even better way currently where you can set :url in the html > options and thus get a different fallback.

I know that but you seem to misinterpret my intent. All I was proposing was a sensible default in the event that the user has JavaScript disabled. I made this suggestion because I'm a good boy :wink: and I use link_to_remote almost exclusively for GET requests where the URL of the link would mostly be the same as for the AJAX request. Question to everyone: Would it make sense to only default the :href attribute to the value of :url if the link_to_remote handles a GET request but leave it at "#" for POST/PUT/DELETE since they're likely to be wrong anyways?

I like the spirit of that. I kinda wonder if it becomes a little too magical. Some times the fallback URL will be set, some times it won't. And if the implementor hasn't considered this and used a respond_to block, expecting that all calls will be JS, then the non-JS user will just end up seeing JS fragment code as his reply. Which seems to be worse than a link not doing anything.

I think the safest thing in this case is simply to do nothing unless the implementor has explicitly decided to allow for fallback scenarios. And if he has, it'll be no problem for him to add the :url parameter himself.

Most of my applications aren't designed to work with JS turned off anyway. In fact, I bet that the majority of Ajax applications out there are just the same. The effort to make it work in non-JS mode is not worth the energy considering the tiny constituency for most people. Thus we should make that scenario as smooth and logical as possible while still allowing for someone to make a non-JS fallback work if they put in a little extra effort.

So how about the following idea: We should abstract the current functionality and create an AbstractJavaScriptGenerator that (maybe) provides common functionality sits in as a parent for PrototypeGenerator, JQueryGenerator, MooToolsGenerator, etc. In the config, we'd then have something like config.action_view.javascript_framework = :whatever that defaults to :prototype. Both, view helpers and RJS, should then use the methods of the respective generator. Moreover, we'd probably need to move each framework into its own subdirectory in /public/javascripts and then modify the javascript_include_tag :all to first load /public/ javascripts/:framework and then (non-recursively) load all other files in the root.

I like that approach a lot. It definitely needs to be concrete, though. So as we develop AbstractJavaScriptGenerator, we need to make sure that it can span to be implemented as JQueryGenerator and MooToolsGenerator or whatever. So a patch to core would be contingent on the availability of at least 2 preferably 3 implementations of it. I like config.action_view.javascript_generator as the option now that we're going with *Generator as the class.

How about making it configurable like my other suggestion? We could have something like config.action_view.use_unobtrusive_javascript = true that modifies *_to_remote in that it removes the onclick/onsubmit event and instead adds a default CSS class (e.g. "remote", but maybe also configurable) so we can easily add our unobtrusive JS layer to it (using lowpro or whatever).

If all the unobtrusive approach needs is a class, then why bother with link_to_remote at all? Why not just use link_to and add the class?

I like the spirit of that. I kinda wonder if it becomes a little too magical. Some times the fallback URL will be set, some times it won't. And if the implementor hasn't considered this and used a respond_to block, expecting that all calls will be JS, then the non-JS user will just end up seeing JS fragment code as his reply. Which seems to be worse than a link not doing anything.

I think the safest thing in this case is simply to do nothing unless the implementor has explicitly decided to allow for fallback scenarios. And if he has, it'll be no problem for him to add the :url parameter himself.

You've got a valid point. Not sure there, to be honest. Maybe some other folks like to chime in and give their opinion on this subject? I don't want to force the issue since it's not _that_ big of a deal but I think it would be a step in the right direction.

Most of my applications aren't designed to work with JS turned off anyway. In fact, I bet that the majority of Ajax applications out there are just the same. The effort to make it work in non-JS mode is not worth the energy considering the tiny constituency for most people. Thus we should make that scenario as smooth and logical as possible while still allowing for someone to make a non-JS fallback work if they put in a little extra effort.

Ha, this is _so_ true and I said pretty much the same to my client but guess what - they couldn't care less! :slight_smile: As long as we're talking about SaaS (where you can put it in the "system requirements" on the signup page), admin areas of a page or a page that ultimately has only a few users that you can influence. that's a perfectly valid approach. But as soon as you can't really control the user flow and the success of a page depends of _every_ user, you can't afford to lose a user just because they have JS disabled. I'm experiencing this first hand right now, hence my strong pro-unobtrusiveness attitude.

I like that approach a lot. It definitely needs to be concrete, though. So as we develop AbstractJavaScriptGenerator, we need to make sure that it can span to be implemented as JQueryGenerator and MooToolsGenerator or whatever. So a patch to core would be contingent on the availability of at least 2 preferably 3 implementations of it. I like config.action_view.javascript_generator as the option now that we're going with *Generator as the class.

Definitely. It'd probably be a good idea to ask the JRails developers to join in the effort since they already have some experience in this. Plus, having at least two concrete implementations that implement the abstract interface IMO proves that the interface is robust and will probably only need a few tweaks here and there to also incorporate other implementations.

Anyway, I've looked at the current implementation and I think this would be pretty major change. I guess this needs a GitHub fork and at least one person with a certain experience available in IRC or here at the mailing list if questions regarding the current implementation arise. Do you think that could be arranged?

If all the unobtrusive approach needs is a class, then why bother with link_to_remote at all? Why not just use link_to and add the class?

Ouch, you got me there! :wink: At the moment I override link_to_remote with this behavior as soon as I'm going unobtrusive (for a quick and dirty interface, I usually prefer the obtrusive implementation). It kinda hits the eye better like e.g. div_for(@post) instead of <div id="<%= @post.id %>"> - that's why I prefer to name it link_to_remote although it doesn't include the inline JS.

But you're probably right - it's not worth the fuzz. We should probably be looking at the JSGenerator abstraction - I feel that this is way more important and that quite a bunch of people would love JS- agnostic Rails!

It seems counter intuitive IMHO to feature RESTful resources yet have delete as a link. The same way RESTful resources teach good design by default, a proper delete would also.