Skip to content

disable_with doesn't work with link in Safari #306

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
pekeler opened this issue Feb 8, 2013 · 60 comments · May be fixed by #362
Open

disable_with doesn't work with link in Safari #306

pekeler opened this issue Feb 8, 2013 · 60 comments · May be fixed by #362

Comments

@pekeler
Copy link
Contributor

pekeler commented Feb 8, 2013

link_to "do it", :data => {:disable_with => 'Please wait...'}
Please note that this is not a remote link.

It works as expected in latest Chrome and latest Firefox, IE8, IE9.
In Safari (6.0.2) however it never shows "Please wait..."

@pekeler
Copy link
Contributor Author

pekeler commented Feb 9, 2013

testpage: https://gist.github.com/pekeler/4746738 (rendered without layout)
result: http://youtu.be/kwCWrvhQJ2c

@JangoSteve
Copy link
Member

I cannot reproduce this to save my life. I've tried on my own machine using Safari Version 6.0.2 (7536.26.17), and it works as expected.

@pekeler
Copy link
Contributor Author

pekeler commented Feb 9, 2013

My version of Safari seems to be different: Version 6.0.2 (8536.26.17)
this is on OSX 10.8.2

@pekeler
Copy link
Contributor Author

pekeler commented Feb 9, 2013

My wife's laptop has the same Safari version as yours on OSX 10.7.5. I can't reproduce it there, either. So it looks like a Safari on Mountain Lion specific problem.

@JangoSteve
Copy link
Member

That's really weird. I'll have to see if I can get anyone else in the office who can reproduce it.

@neerajsingh0101
Copy link

@pekeler if you can push this code to heroku and post a link here then that would make it easier to get more people to validate the result. Thanks.

@pekeler
Copy link
Contributor Author

pekeler commented Feb 19, 2013

I've created a minimal testcase on http://jsbin.com/aveseh/1/

@neerajsingh0101
Copy link

With safari version Version 6.0.2 (8536.26.17) it behaves fine for me .

On Tue, Feb 19, 2013 at 12:41 PM, Christian Pekeler <
[email protected]> wrote:

I've created a minimal testcase on http://jsbin.com/aveseh/1/


Reply to this email directly or view it on GitHubhttps://github.com//issues/306#issuecomment-13786179.

@pekeler
Copy link
Contributor Author

pekeler commented Feb 19, 2013

I just walked over to another computer with Mountain Lion, Safari 6.0.2. Exact same problem.

@travis
Copy link

travis commented Mar 1, 2013

FWIW we noticed an issue with disabled_with on Safari, but with an <input type=submit. The submit button on a form won't change when we click the submit input. What's really insane is that if we do this:

    disableFormElements: function(form) {
      alert('hams')
      form.find(rails.disableSelector).each(function() {

and then click through the alert dialog, the button changes disabled text. Also, if we cancel the next page load before the screen changes, the button changes to the disable text. So this seems like a pretty classic example of javascript timing insanity. Frankly, the prospect of descending into the caves of madness to debug this is too much for us right now, and we iceboxed the issue.

Hopefully this helps point someone in the right direction.

@eploko
Copy link

eploko commented Mar 20, 2013

Have just stumbled upon this exact issue. :(
Mountain Lion 10.8.3, Safari 6.0.3 (8536.28.10). Works fine in Chrome.
Any suggestions if not for a fix then for a workaround would be greatly appreciated.

@pzgz
Copy link

pzgz commented Jun 11, 2013

Same problem here, the text doesn't get changed by text in 'disable-with' on safari, worked fine on chrome. I am using safari "Version 6.1 (8537.43.58)"

@xaviershay
Copy link

Can reproduce on Safari 6.0.5 (8536.30.1), OSX 10.8.4.

@pekeler
Copy link
Contributor Author

pekeler commented Aug 31, 2013

Yup, still broken in Safari 6.0.5 (8536.30.1)
now also broken in Chrome 29.0.1547.57
and broken in IE 10

still working in Firefox 23.0.1

@barkerja
Copy link

Add Safari Version 7.0 (9537.71) (Mavericks GM) to the list of not working either.

@lucasmazza
Copy link
Contributor

@pekeler your test case on jsbin isn't working for me as pulling the rails.js from GitHub does not provides the right mime type, so I rewrote it and tested on Safari Version 6.1 (8537.71) and Chrome Version 30.0.1599.101 under OSX 10.8.5. My test is here https://dl.dropboxusercontent.com/u/3258720/jquery-ujs-306/index.html

Are anyone else still facing this issue with a recent version of the jquery-ujs code? Other test cases that are doing something else that we are missing would be very helpful to finish this long running issue once in for all 😄

@JangoSteve
Copy link
Member

I'm guessing this is still an issue, as we've never done anything to solve it. If someone could submit a patch, that'd be great. I'd be happy with a patch that solved the issue even without a test case (provided it doesn't break any existing tests).

@uberllama
Copy link

+1 to this not working with Safari 7.0 (9537.71).

@jalendra-webonise
Copy link

+1 doesn't work with safari. checked with 7.0

@joker-777
Copy link

Hi, short question...
Is also the disabling functionality broken or only the display of the disable text?

@uberllama
Copy link

In my test cases, the disabling functionality was totally borked. No state change, no text change.

@jbmyid
Copy link

jbmyid commented Dec 3, 2013

Actually Safari is not allowing to manipulate the form element (submit tag) after form submit. Tried first change the text and then submit but then the commit can not be accessed.

@joker-777
Copy link

Does it only break with a form submit field or also with a normal link?

@jbmyid
Copy link

jbmyid commented Dec 4, 2013

I haven't checked it for link but its breaking for submit field.

@uberllama
Copy link

Any progress on this issue, guys? It's a big one.

@lucasmazza
Copy link
Contributor

I still can't reproduce this with Safari 7.0.1 (9537.73.11). Would be awesome to have a reproducible test case or example somewhere to try to get to the bottom or this.

@alecguintu
Copy link

@pekeler A so it's a different one than the original post? Is there a post on this already I can check?

@martijnrusschen
Copy link

Is someone working on this? Having the same issue and cannot find a working solution for it...

@debajit
Copy link

debajit commented Nov 5, 2014

The problem still exists in Safari 7. using

submit_tag "title", data: { disable_with: "disabled text" }

does not work in Safari either. Please let me know how I could fix this.

@geetfun
Copy link

geetfun commented Dec 14, 2014

disable_with works on Safari 8.0.2 for me

@pekeler
Copy link
Contributor Author

pekeler commented Dec 14, 2014

@geetfun not for me

Safari 8.0.2 broken
FF 34.0.5 works
Chrome 39 broken
IE 11 broken

@velobuff
Copy link

<button class="btn btn-default" data-disable-with="<i class='fa fa-spinner fa-spin'></i> Saving..." name="button" type="submit">Save Post</button>
On OSX 10.9.5 Build 13F34:
Safari Version 7.1.2 (9537.85.11.5) 💔
Chrome Version 39.0.2171.95 (64-bit) ❤️

If you press Submit and then hit the 🔙 button in Safari, the button now appears the way it would if disable-with worked (it's disabled and has the disable-with html)!

I tried removing turbolinks but that made no difference :/

@elsurudo
Copy link

Also having this issue.

OS X 10.10.2
Safari 8.0.3

Anyone got a decent workaround?

@mike-ball
Copy link

I have the same issue. data-disable-with works find in Chrome, but not in Safari.

OS X 10.10.2 (14C109)
Safari 8.0.3 (10600.3.18)

It's really frustrating, since I prefer to develop locally using Safari.

@amal007
Copy link

amal007 commented Mar 2, 2015

any idea how to fix this in Safari.

@ericboehs
Copy link

This is simply a display problem in Safari. If you try clicking the submit button twice it doesn't submit twice. To verify this, inspect the element and then click the submit button, you'll see the HTML change (value is replaced and disabled attribute is added).

Safari doesn't update the displayed page after the form submit is fired (even though the DOM changed). If we wanted to fix this visual bug we'd need to intercept the submit event, update the DOM, then submit the form ourself (carefully though as we don't want to double submit). See http://stackoverflow.com/a/28404683/282720

I think the main desire of this feature is to prevent double form submission and that is working correctly. Perhaps this should be closed in favor of a radar bug submitted to Apple.

Edit: Just noticed this is regarding link_to and not form submit. I can't reproduce @pekeler's problem in Safari 8 unless I use a form submit button.

@edgarjs
Copy link

edgarjs commented Apr 2, 2015

Using Safari 8.0.4 (10600.4.10.7) still doesn't work (in some cases). I tried the test pages from this thread and also created one myself, disable works in all those cases but still doesn't on my real form.

I removed all other javascript from my app and just left jquery and ujs files, but no luck. Then I went and debugged a little bit and if I remove the timeout from this line it works perfectly.

It seems like a UI blocking issue to me, once the timeout has returned the form is already submitting and safari doesn't care anymore to update it. But if we update it just before it submits, it does it correctly.

Not sure what the timeout is for though? Comments say it's for the button to be serialized, but why do we need the button serialized? (Some may need it of course, but most forms don't). Would it be possible to add a setting for letting the timeout or remove it?

@rapcal
Copy link

rapcal commented Apr 24, 2015

I have a similar issue on Safari with a submit_tag with an :onclick to show an overlay. It doesn't work either, which seems to confirm the display problem mentioned by @ericboehs

@rapcal
Copy link

rapcal commented Apr 24, 2015

By the way - and that's even worse usability-wise - when you hit the back button the overlay is there... IMHO this issue should be closed since it doesn't seem to be jquery-ujs specific

@lyushenko
Copy link

I had a similar issue on Safari 8.0.6 and here's my approach of solving this issue:

%button{ class: 'btn btn-action js-submit', data: { method: :put, 'href' => '...', disable_with: "<i class='icon icon-spinner icon-spin'></i>".html_safe }} Submit
$('.js-select-plan').click(function(event) {
  event.preventDefault();
  var $target     = $(this),
      href        = $target.data('href'),
      method      = $target.data('method'),
      formTarget  = $target.attr('target'),
      csrfToken   = $('meta[name=csrf-token]').attr('content'),
      csrfParam   = $('meta[name=csrf-param]').attr('content'),
      form        = $('<form method="post" action="' + href + '"></form>'),
      metaData    = '<input name="_method" value="' + method + '" type="hidden" />';

  if (csrfParam !== undefined && csrfToken !== undefined) {
    metaData += '<input name="' + csrfParam + '" value="' + csrfToken + '" type="hidden" />';
  }

  if (formTarget) {
    form.attr('target', formTarget);
  }

  // disable button/link element
  var contentMethod = $target.is('button') ? 'html' : 'val';
  var replacement   = $target.data('disable-with');
  $target.data('ujs:enable-with', $target[contentMethod]());
  if (replacement !== undefined) {
    $target[contentMethod](replacement);
  }
  $target.prop('disabled', true);

  form.hide().append(metaData).appendTo('body');
  setTimeout(function(){
    form.submit();
  }, 50);
});

This works like a charm in all browsers. For better flexibility you might want to wrap this in a helper.

@kelso
Copy link

kelso commented Jul 16, 2015

Still doesn't work in Safari 9.0 (El Capitan). Firefox + Chrome are OK.

@thiensubs
Copy link

Yes. It isn't working with safari in ipad or iphone. :(

@walterdavis
Copy link

Try this, it seems to be working here: https://gist.github.com/walterdavis/b6410bef6333d3487687#file-rails-js-L262

@dapi
Copy link

dapi commented Sep 18, 2015

+1 does not work in Safari 8.0.8

@jbmyid
Copy link

jbmyid commented Sep 21, 2015

We can hide the button and display same as link with disable with text in button style..just an idea

@orlando
Copy link

orlando commented Dec 24, 2015

This looks like a Safari bug/feature. The only way to make it work is to delay the form submission (Like prevent the first form submit and trigger a new one later on). This will give the render engine a little bit of time to catch up and display the disabled-text.

For example, in

jquery-ujs/src/rails.js

Lines 493 to 494 in 1d8a0ad

// Slight timeout so that the submit button gets properly serialized
setTimeout(function(){ rails.disableFormElements(form); }, 13);
, change it to

if (!e.isTrigger) {
  e.preventDefault();
  rails.disableFormElements(form);
  setTimeout(function(){ form.trigger('submit'); }, 13);
}

I'm not 100% positive if jquery-ujs should handle this. I right now have it as a workaround that I load after jquery-ujs https://gist.github.com/orlando/bacff31757b80b86e062

@thanhtuong
Copy link

thanhtuong commented Jul 22, 2016

Thanks @orlando! It worked but only for click on the button. If I press enter, it's not work!

@collimarco
Copy link

+1 Does not work in Safari 10 (tested with f.submit "title", data: { disable_with: "disabled text" })

@jpowell
Copy link

jpowell commented Aug 4, 2017

+1 only works for forms with remote: true. Does not work in examples above nor in iOS simulator

Note: it appears to prevent double submission of the form, but does not replace the text

@orlando
Copy link

orlando commented Aug 4, 2017

@jpowell this is not a jquery-ujs bug since this works for the rest of the browsers, is how Safari handles forms submissions which is totally different than the rest. In my case I needed to support Safari so I added a workaround but is not like a final fix (since Safari doesn't even flush pending paints after the submit button is pressed and that's why you see the magic number 13 there).

@jpowell
Copy link

jpowell commented Aug 4, 2017

@orlando thanks for the response. I've done similar things before in the past, but was shooting in the dark to see if a wider solution had been come to without monkey patching something together myself.

Thanks again.

@hopsoft
Copy link

hopsoft commented Jan 6, 2018

Here's a quick hack that leverages addEventListener useCapture that seems to be working. Note that if you show a spinner or some other type of animation, Safari will halt the animation when the form actually submits.

document.addEventListener(
  'click',
  event => {
    let element = event.target;
    if (element.dataset.disableWith) {
      element.disabled = true;
      element.innerHTML = element.dataset.disableWith;
      let $form = $(element).closest('form');
      if ($form.length) {
        event.preventDefault();
        setTimeout(() => $form.submit(), 300);
      }
    }
  },
  true
);

@miguelpeniche
Copy link

Thanks for that @hopsoft, working like a charm!

@miguelpeniche
Copy link

Hey @hopsoft when using your solution (which works), then jQuery callbacks don't work.

For example

$(document).on("click", ".btn-test", function(e) {
  alert("Working");
});

<button class="btn-test btn-1">Save</button>
<button class="btn-test btn-2" data-disable-with="Saving">Save</button>

When I click btn-1 everything works fine, but when I click btn-2 no alert whatsoever.

Do you know how to fix that?

@hopsoft
Copy link

hopsoft commented Jan 11, 2019

@bengalamx You could try something like this.

document.addEventListener(
  'click',
  event => {
    let element = event.target;
    if (element.dataset.disableWithSafari) return;
    if (element.dataset.disableWith) {
      element.disabled = true;
      element.innerHTML = element.dataset.disableWith;
      let $form = $(element).closest('form');
      if ($form.length) {
        event.preventDefault();
        setTimeout(() => $form.submit(), 300);
        element.dataset.disableWithSafari = true;
        element.click();
      }
    }
  },
  true
);

Disclaimer: It's a hack and I haven't tested it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.