10

I asked about this on the jquery forum a few weeks ago without luck, so I will try again here :)

I've made a simple widget for a project I'm working on, but I have encountered an odd problem.

It is easiest to explain it with an example implementation. http://decko.dk/buttontest

On the page there are 3 button. The first one is my drop down widget. The next one is a regular disabled button (A) and the last one a regular enabled button (B). If you then refresh the page (press F5 or whatever) the enabled button is mysteriously now disabled. I have no clue why this happens, but if button A is not disabled to begin with, button B will not be disabled when refreshing. Also, if I remove the call to insertAfter in my widget-code, the button will not be disabled. Can anyone shed light on why this strange behavior occurs?

By the way, I have only been able to reproduce this in Firefox.

Decko
  • 18,553
  • 2
  • 29
  • 39
  • thanks for asking this, buddy - I ran into the same problem – Yuval Karmi Aug 27 '10 at 16:56
  • 1
    I found this question searching for a solution to a related problem, where Chrome and FF would not display a disabled jQuery UI button as disabled (it looked just like an enabled button only you couldn't click it and tooltips on it didn't work), it only seemed to work as expected on Opera. After some fiddling around, it seems the "problem" was that I was using the "regular" jQuery's `.attr('disabled', 'disabled')` and `.removeAttr('disabled')` instead of jQuery UI's `.button('option', 'disabled', aBoolean)`. Once I switched to the latter it worked across browsers. Hope that helps someone. – Amos M. Carpenter Dec 03 '12 at 00:12

5 Answers5

12

I believe this is a bug in how Firefox remembers form field/control values and states:

  1. After the first page load, there are three <button> elements in the document, and <button id="button_a"> is disabled. (When the jQuery UI styled button is enabled or disabled, it sets the underlying element to the same state.)
  2. Firefox remembers that the second <button> is disabled.
  3. After a page refresh, before any scripts are run, Firefox restores form fields and controls. It disables the second <button>, but since no script has been run, the second button is <button id="button_b">.
  4. When jQuery UI creates the styled button for <button id="button_b">, it sees that it is disabled and continues to style it as disabled.

There are two issues here:

  1. How Firefox remembers which elements are disabled. It's not taking into account dynamic elements. I suggest filing a bug with Mozilla for this.
  2. Form elements stay disabled after a page refresh. I'm not sure if this is the correct behaviour, but there are two bugzilla reports on this.

The test case can simplify down to just adding a <button> element dynamically and disabling <button id="button_a">, no jQuery / jQuery UI necessary:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>disabled button test</title>
    <script type="text/javascript">
    window.onload = function () {
        var a = document.getElementById('button_a'),
            menu = document.createElement('button');
        menu.appendChild(document.createTextNode('Menu'));
        document.body.insertBefore(menu, a);
        a.disabled = true;
    };
    </script>
</head>
<body>
    <button id="button_a">A</button>
    <button id="button_b">B</button>
</body>
</html>
Jeffery To
  • 11,836
  • 1
  • 27
  • 42
  • That was what I was thinking as well but hoped it was a jquery bug (as this would be a lot easier to fix). But with the code you show it is absolutely a "caching" bug in Firefox. – Decko Apr 27 '10 at 11:34
5

I've been getting this problem also and worked out it was down to silly behaviour in firefox, my fix was as so:

before:

//set up the buttons
$("button").button();

after:

//set up the buttons (and make sure firefox behaves)
$("button").button().attr("autocomplete", "off");
Chris Simpson
  • 7,821
  • 10
  • 48
  • 68
  • Not sure what 'autocomplete' is supposed to do for a button - didn't work for me. I used `$('button').removeAttr('disabled').button();` instead. – asgeo1 Jun 21 '11 at 21:32
  • There have been a couple of versions of firefox since so this behavior may have changed but the autocomplete off seemed to prevent firefox's annoying habit of saving the state of controls when a page was refreshed – Chris Simpson Jun 21 '11 at 23:22
  • You can just set the `autocomplete="off"` attribute in the html markup. – guzart Jun 27 '12 at 01:36
  • @UberNeet: Yes, but for those of us who are not using HTML 5 yet and are conscious of standards, that attribute is invalid, whereas doing it via JS/jQuery isn't. Might be a semantic thing, but there you go :-) – Amos M. Carpenter Dec 03 '12 at 00:06
0

Setting the Expires HTTP header to a date in the past, solved the problem for me in Firefox 6.0.

Mark
  • 473
  • 6
  • 7
0

Here is the solution I found works really well in all browsers...

I give each button (that can be disabled) a class 'js_submit'

I then re-enable any disabled buttons with class 'js_submit' on the pagehide event that fires when a page is unloaded.

I wrap the event assignment inside a try catch to prevent browsers that don't support this event from throwing an error (such as IE).

Here is the code:

<input id="button" type="button" value="Submit" class="js_submit" />


// Fix for firefox bfcache:
try {
    window.addEventListener('pagehide', PageHideHandler, false);
} catch (e) { }

//Fires when a page is unloaded:
function PageHideHandler() {
    //re-enable disabled submit buttons:
    $('.js_submit').attr('disabled', false);
}
George Filippakos
  • 16,359
  • 15
  • 81
  • 92
-2

In my case it was a Bootstrap bug

<input id="appointmentBtn" type="button" 
ng-click="addAppointment()" class="btn btn-primary btn-xs 
disabled" value="Add Appointment"> 

Instead it should have been

<input id="appointmentBtn" type="button" 
ng-click="addAppointment()" class="btn-primary btn-xs 
disabled" value="Add Appointment">
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Gautam
  • 9
  • 3