293

Apparently a disabled <input> is not handled by any event

Is there a way to work around this issue ?

<input type="text" disabled="disabled" name="test" value="test" /> 
$(':input').click(function () { $(this).removeAttr('disabled'); }) 

Here, I need to click on the input to enable it. But if I don't activate it, the input should not be posted.

3
  • 1
    Here is a good alternative blog.pengoworks.com/index.cfm/2010/4/23/… Commented Oct 18, 2010 at 19:52
  • You can use the CSS-pretend-disable and loop over the inputs in onSubmit handler, disabling the non-activated ones for real. Commented Jul 9, 2015 at 16:22
  • 3
    Just a side note for readers: if you don't mind the input beign posted just use readonly instead of disabled. I know this is not what the OP asked but someone might be in the same situation as me... Commented May 7, 2021 at 11:00

12 Answers 12

308

Disabled elements don't fire mouse events. Most browsers will propagate an event originating from the disabled element up the DOM tree, so event handlers could be placed on container elements. However, Firefox doesn't exhibit this behaviour, it just does nothing at all when you click on a disabled element.

I can't think of a better solution but, for complete cross browser compatibility, you could place an element in front of the disabled input and catch the click on that element. Here's an example of what I mean:

<div style="display:inline-block; position:relative;"> <input type="text" disabled /> <div style="position:absolute; left:0; right:0; top:0; bottom:0;"></div> </div>​ 

jq:

$("div > div").click(function (evt) { $(this).hide().prev("input[disabled]").prop("disabled", false).focus(); });​ 

Example: http://jsfiddle.net/RXqAm/170/ (updated to use jQuery 1.7 with prop instead of attr).

Sign up to request clarification or add additional context in comments.

14 Comments

Small thing: if you're using the disabled attribute with no value, that implies HTML rather than XHTML, in which case the closing slash is unnecessary.
@Tim: indeed it is unnecessary, but it's still valid HTML. It's just a force of habit really and I feel like it looks better.
Thx Andy, this is quite smart. Isn't there simpler ? Do you know why do desabled inputs are not handleable ?
This doesn't make sense: any other html element handles mouse events, why not a disabled element (eg. mouseenter, etc.)
You can stop the disabled element from "throwing away" your clicks by putting input[disabled] {pointer-events:none} in your CSS. Then the click behaves as if you clicked the parent element. IMHO this is the simplest, cleanest solution, but it unfortunately only works for browsers that support the pointer-events CSS property: caniuse.com/#search=pointer-events
|
127

Disabled elements "eat" clicks in some browsers - they neither respond to them, nor allow them to be captured by event handlers anywhere on either the element or any of its containers.

IMHO the simplest, cleanest way to "fix" this (if you do in fact need to capture clicks on disabled elements like the OP does) is just to add the following CSS to your page:

input[disabled] {pointer-events:none} 

This will make any clicks on a disabled input fall through to the parent element, where you can capture them normally. (If you have several disabled inputs, you might want to put each into an individual container of its own, if they aren't already laid out that way - an extra <span> or a <div>, say - just to make it easy to distinguish which disabled input was clicked).


The downside is that this trick unfortunately won't works for older browsers that don't support the pointer-events CSS property. (It should work from IE 11, FF v3.6, Chrome v4): caniuse.com/#search=pointer-events

If you need to support older browsers, you'll need to use one of the other answers!

7 Comments

I wasn’t sure if input[disabled] would also match elements disabled by JavaScript (element.disabled = true;) but it seems it does. Anyway, I find input:disabled cleaner.
This seems like a good solution, doesn't work for me in IE11 though! Also you say FF 38+ and Chrome 31+ but your caniuse link says FF 3.6+ and Chrome 4+?
@user764754 ...my mistake, I didn't realize I needed to click "Show All" on the caniuse page to get earlier browser versions! Have fixed that. As for IE11, I just tested it, and it works fine (see jsfiddle.net/7kkszq1c/1 for the code, though for some reason the jsFiddle site didn't work for me in IE11, I had to paste it into a .htm file instead)
Thanks for the update! In the meantime I also observed that it works on a website in IE11 but not with jsfiddle. Maybe because of the jsfiddle iframe...
@Protectorone :disabled is a pseudo-class since CSS 3: w3.org/TR/css3-selectors/#UIstates
|
86

Maybe you could make the field readonly and on submit disable all readonly fields

$(".myform").submit(function(e) { $("input[readonly]").prop("disabled", true); }); 

and the input (+ script) should be

<input type="text" readonly="readonly" name="test" value="test" /> 
$('input[readonly]').click(function () { $(this).removeAttr('readonly'); }); 

A live example:

$(".myform").submit(function(e) { $("input[readonly]").prop("disabled", true); e.preventDefault(); }); $('.reset').click(function () { $("input[readonly]").prop("disabled", false); }) $('input[readonly]').click(function () { $(this).removeAttr('readonly'); })
input[readonly] { color: gray; border-color: currentColor; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form class="myform"> <input readonly="readonly" value="test" /> <input readonly="readonly" value="test" /> <input readonly="readonly" value="test" /> <input readonly="readonly" value="test" /> <input readonly="readonly" value="test" /> <input readonly="readonly" value="test" /> <input readonly="readonly" value="test" /> <input readonly="readonly" value="test" /> <input readonly="readonly" value="test" /> <button>Submit</button> <button class="reset" type="button">Reset</button> </form>

4 Comments

+1, this is a decent alternative suggestion. The only downside is that the input box will not take on the disabled styling, which varies between browsers so it would be hard to make it look consistent with the user's expectations of a disabled input.
true. Perhaps this could be worked around with CSS? But yes it would not have the same look as normal diabled input fields
Excellent alternative solution. I like this one better because you can do any necessary styling with CSS (i.e. make it LOOK disabled) yet still have events available.
this is exactly what i needed!
16

I would suggest an alternative - use CSS:

input.disabled { user-select : none; -moz-user-select : none; -webkit-user-select : none; color: gray; cursor: pointer; } 

instead of the disabled attribute. Then, you can add your own CSS attributes to simulate a disabled input, but with more control.

2 Comments

only works with ie10, too many users have ie9 / 8. so not a reliable alternative.
This still causes the field to be posted when the form is submitted, which is undesirable in many cases.
8

Instead of disabled, you could consider using readonly. With some extra CSS you can style the input so it looks like an disabled field.

There is actually another problem. The event change only triggers when the element looses focus, which is not logic considering an disabled field. Probably you are pushing data into this field from another call. To make this work you can use the event 'bind'.

$('form').bind('change', 'input', function () { console.log('Do your thing.'); }); 

3 Comments

A readonly input will still be submitted with the form if I'm not mistaken
That's correct. It should then be combined with @npth anwsner.
Thanks, that was smart clean and optimous for my case.
7

$(function() { $("input:disabled").closest("div").click(function() { $(this).find("input:disabled").attr("disabled", false).focus(); }); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <div> <input type="text" disabled /> </div>

1 Comment

But this doesn't work on FireFox - and that was the whole point!
4

OR do this with jQuery and CSS!

$('input.disabled').attr('ignore','true').css({ 'pointer-events':'none', 'color': 'gray' }); 

This way you make the element look disabled and no pointer events will fire, yet it allows propagation and if submitted you can use the attribute 'ignore' to ignore it.

5 Comments

@Precastic, that's true, but it works for almost all other browsers at this point and you can use a polyfill for ie < 11. sidonaldson, why not use straight CSS to apply styles?
@KyleMit you could add a class rather than setting the styles, but that's not what this thread is about! I was only suggesting pointer events which is still a good and correct answer depending on browser matrix you are building for. And thanks for everyone who has marked this answer down that kinda sucks as nothing here is incorrect :/
@sidonaldson, It's a good answer so I also wish it was ranked higher as well. I'm not sure what the ignore attribute does. But my point about CSS was that I don't think we need jQuery to be the vehicle for applying CSS. You could just setup a CSS rule that targeted the same selector and also disabled pointer events. In this fiddle, the jQuery and CSS should be doing the same thing, but the CSS will be far more performant.
@KyleMit ah, well assuming the form is submitted you will have to somehow tell the backend to ignore that field if it contained a value (since we're spoofing disabled).
I agree CSS could be more powerful as you can use a selector based on an attribute! Check this demo where I've matched chromes own disabled field: jsfiddle.net/KyleMit/pxx8pk6v
2

There is no reason you can't simulate the disabled attribute using a combination of CSS and readonly:

Faux-Disabled: <input type="text" value="1" readonly="1" style="background-color:#F6F6F6;"><br> Real-Disabled: <input type="text" disabled="true" value="1"></input>

Note: This will not have the regular behavior of disabled in the <form>, which prevents the server from seeing the field. This is just in case you want to disable a field that doesn't matter server-side.

Comments

0

We had today a problem like this, but we didn't wanted to change the HTML. So we used mouseenter event to achieve that

var doThingsOnClick = function() { // your click function here }; $(document).on({ 'mouseenter': function () { $(this).removeAttr('disabled').bind('click', doThingsOnClick); }, 'mouseleave': function () { $(this).unbind('click', doThingsOnClick).attr('disabled', 'disabled'); }, }, 'input.disabled'); 

Comments

0

I did something very similar the Andy E; except I used a surrounding tag. However, I needed the 'name' so I changed it to an tag without the 'href'.

Comments

-1

I find another solution:

<input type="text" class="disabled" name="test" value="test" /> 

Class "disabled" immitate disabled element by opacity:

<style type="text/css"> input.disabled { opacity: 0.5; } </style> 

And then cancel the event if element is disabled and remove class:

$(document).on('click','input.disabled',function(event) { event.preventDefault(); $(this).removeClass('disabled'); }); 

1 Comment

The JavaScript part does not work for me. Apart from that, it does not answer the question, as it is about enabling a disabled input. In this example however it is not disabled at the start, and thus gets sent on submit.
-2

suggestion here looks like a good candidate for this question as well

Performing click event on a disabled element? Javascript jQuery

jQuery('input#submit').click(function(e) { if ( something ) { return false; } }); 

1 Comment

Click event will probably not happen on disabled attributes.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.