Attaching mouse events to a disabled input element

Posted by Dan on Apr 23, 2010 @ 3:08 PM

I was doing some UI work this morning and ran into a bit of a problem. We have some HTML input elements that need to be disabled so the user can not interact with them. The problem is, we wanted to display a message to the user if they tried to interact with the element. While some browsers respond to a mousedown event, Firefox and Opera ignore all mouse-related events on a disabled form field. Since they seem to completely ignore mouse interaction, that means not even event delegation works.

After thinking about various ways to work around the behavior, I thought the most elegant solution might be to add an overlay over the disabled element which I'd use as the hotspot for mouse interaction. The overlay lays on top of the element and intercepts all mouse interaction.

Let's look at some sample HTML:

<label for="normal">
  <input type="checkbox" disabled="disabled" />
  Disabled Option
</label>

With a little jQuery magic, we can find the disabled element, get the parent <label /> element and then place a <div /> element over where the label element resides. The code looks like this:

// on DOM ready
$(document).ready(function (){
  // attach a click behavior to all checkboxes
  $(":checkbox").click(function (){
    alert("Clicked!");
  });

  // find the disabled elements
  var $disabled = $("#overlay-example input:disabled");

  // loop through each of the disable elements and create an overlay
  $disabled.each(function (){
    // get the disabled element
    var $self = $(this)
      // get it's parent label element
      , $parent = $self.closest("label")
      // create an overlay
      , $overlay = $("<div />");

    // style the overlay
    $overlay.css({
      // position the overlay in the same real estate as the original parent element 
        position: "absolute"
      , top: $parent.position().top
      , left: $parent.position().left
      , width: $parent.outerWidth()
      , height: $parent.outerHeight()
      , zIndex: 10000
      // IE needs a color in order for the layer to respond to mouse events
      , backgroundColor: "#fff"
      // set the opacity to 0, so the element is transparent
      , opacity: 0
    })
    // attach the click behavior
    .click(function (){
      // trigger the original event handler
      return $self.trigger("click");
    });

    // add the overlay to the page  
    $parent.append($overlay);
  });
});

You can see a live example here.

Categories: JavaScript, HTML/ColdFusion, jQuery

9 Comments

  • Awesome! Thanks!
  • Thanks, i have implemented it using prototype.js today,

    The trick with color for IE saved me a day (or more). I would never think abot something like adding the color. Why?
  • @Bartosz:

    IE has lots of weird quirks. I suspect it has to do w/the the hasLayout issues, but I didn't really dig into the problem. It's just a problem I've run into from time-to-time. IE can have problems w/transparent pixels not being clickable.
  • Thanks for posting this Dan. I was using this to add jquery tooltips to disabled buttons.

    I made two modifications that worked for me. Because my button was floating in a div, the surrounding label was not at the same position as the button. So I changed the overlay to be at $self.position rather than $parent.position.

    Lastly, as I found here:
    http://stackoverflow.com/questions/2173040/jquery-...

    It was beneficial to put this code in the $(window).load event rather than document ready.

    Thanks again
  • Thanks very much for this tip; I encountered the same issue myself after doing some user-testing on a form I was working on. Same situation; we needed to give feedback to explain why this element was disabled.
  • its not working with 1.9.1 jquery libs.


    any other good solution ?
  • @Tejas:

    Just change $self.trigger("click") to $self.triggerHandler("click") it will work.

    Here's a working example:
    http://jsfiddle.net/dswitzer/7rThR/
  • same issue i want in selectbox.i got it but selectbox style is changed
  • thanks, this really works well! i wanted to display web forms in an iframe, so that the user could mouse over controls and see the ids, but without allowing them to operate the form. this was just what i needed

Comments for this entry have been disabled.