jquery-ujs icon indicating copy to clipboard operation
jquery-ujs copied to clipboard

Should data-disable-with only disable clicked button?

Open allspiritseve opened this issue 13 years ago • 8 comments

If there are two submit buttons in a form, clicking one will cause all submit buttons with data-disable-with set to be disabled with their respective messages. This is sort of weird behavior since each submit button has a different action (e.g. clicking 'Preview' causes 'Send' to say 'Sending...' in my app, even though the email is being previewed and not sent). Maybe that's an edge case though, and I just can't use disable-with with multiple submit buttons.

allspiritseve avatar May 09 '12 06:05 allspiritseve

I'm thinking this is probably an edge case and also something we can't actually solve easily. The problem is, the disable-with functionality actually serves two purposes: 1) disable the elements so the form can't be re-submitted, and 2) provide the user with feedback that the form is being submitted.

I'd say 1 is the more important purpose of the two. If we make the disable-with only disable the button you clicked, then we'd be nixing 1, since users would be able to click one button and then the other.

Another solution is to disable the button you clicked with the "disable-with" text and then just disable any other buttons (without replacing the text). But this doesn't seem very straight forward from a least-surprise standpoint. Perhaps the best answer is to just not use disable-with if you need something less basic like this.

JangoSteve avatar Aug 14 '12 17:08 JangoSteve

I've come upon this problem, too, just now. My first stab at a solution is this bit of CoffeeScript in my application.js.coffee.

  jQuery.rails.disableFormElements = (form) ->
    submittedBy = form.data('ujs:submit-button')?.name
    form.find(jQuery.rails.disableSelector).each ->
      element = $(this)
      element.prop('disabled', true)
      if submittedBy && element.attr('name') == submittedBy
        method = if element.is('button') then 'html' else 'val'
        element.data('ujs:enable-with', element[method]())
        element[method](element.data('disable-with'))

The code redefines disableFormElements from jquery_ujs and uses ujs:submit-button that is set there.

mschuerig avatar Sep 12 '12 14:09 mschuerig

I have hit this edge case as well. I will try the coffeescript fix. [Update] I tried the patch and it works. Thank you.

sbeckeriv avatar Sep 29 '13 17:09 sbeckeriv

For me @mschuerig's override breaks the value being changed. I had to put

element[method](element.data('disable-with'))

Outside of the if because submittedBy was null.

DiegoSalazar avatar Oct 22 '14 17:10 DiegoSalazar

Ran in to the exact same problem as @allspiritseve.

It would be nice if the effect was isolated only to the clicked button.

yourtallness avatar Nov 05 '14 16:11 yourtallness

I know this is an old issue, but I also agree. Having all the buttons suddenly saying "Saving..." looks silly.

bethesque avatar Sep 20 '15 20:09 bethesque

We had multiple submit buttons with different values, so needed this (for jquery-rails 4.0.4):

jQuery.rails.disableFormElements = (form) ->
  submittedBy = form.data('ujs:submit-button')

  form.find(jQuery.rails.disableSelector).each ->
    element = $(this)
    if submittedBy && element.attr('name') == submittedBy.name && element.attr('value') == submittedBy.value
      # default jquery-rails behaviour
      jQuery.rails.disableFormElement(element);
    else
      # vanilla disable
      element.prop('disabled', true)

bethesque avatar Sep 28 '15 23:09 bethesque

This is a bit of an old issue, but I'm running across this as well. @bethesque's solution above works well on none remote forms, but not as at all on forms that are remote: true. For some reason, on those forms, form.data('ujs:submit-button') returns null.

The issue seems to be coming from here. Does anyone know why we're setting the value of ujs:submit-button to null on remote forms?

DavidVII avatar Sep 26 '16 20:09 DavidVII