Tuesday, December 30, 2008

jQuery: How to disable form element, link, etc.

In this post you will learn how to disable and enable different HTML elements (input, textarea, links, etc.) using jQuery. First, let's categorize the diffent types of elements that can be disabled using jQuery. We can categorize them into 3 general categories. Method of disabling items in each category is different.

If I missed some other element that does not fall under any of those 3 categories please leave a comment. The idea behind any method is very simple though. Usually all you have to do is to change element's attribute. See example below to get an idea.


Here are the three categories that we mentioned:

  1. Form elements - input fields, textarea, buttons, select boxes, radio buttons, etc.
  2. Anchor links - make text links non clickable.
  3. Bound jQuery events - for example bound click event on a <div>.

1. Disable form elements

Consider you have a form and you need to disable some element on it. All you have to do to disable it is to add disabled property to that element (input, textarea, select, button). Let's see an example:

<form action="url" method="post">
  <input type="text" class="input-field" value=".input-field">
  <input type="button" class="button-field" value=".input-field">
  <input type="radio" class="radio-button" value=".input-radio">
  <select class="select-box">
    <option value="1">One</option>
  <select class="select-box">
</form>

jQuery code to disable form elements and enable them back:

// jQuery code to disable
$('.input-field').prop('disabled', true);
$('.button-field').prop('disabled', true);
$('.radio-button').prop('disabled', true);
$('.select-box').prop('disabled', true);

// To enable an element you need to either
// remove the disabled attribute or set it to "false"
// For jQuery versions earlier than 1.6, replace .prop() with .attr()
$('.input-field').prop('disabled', false);
$('.button-field').removeAttr('disabled');
$('.radio-button').prop('disabled', null);
$('.select-box').prop('disabled', false);

Caveats & notes

Setting form element's disabled attirbute causes browsers not to sent that element to the server on form submit. In other words, your server script will not receive that form element's value. The workaround to that problem is to sent readonly attribute instead of disabled. This will make your fields non editable, but browser will still send the data to the server.

2. Disable anchor link (<a href="" ...>)

Now, let's see how to disable a link on your page, so that when user clicks on it browser does not follow it. There 2 methods to do that:

  1. Catch click event and prevent default bahaviour;
  2. Replace link's href property to "#".

I personaly prefer the first method, but you may have different needs. Let's see both methods in action.

<!-- Consider we have this HTML -->
<a href="aboutus.html" class="internal">some internal link<a>
<a href="http://www.google.com" class="external">external link<a>
// Bind "onclick" event
$('.internal').on("click", function(e){
  e.preventDefault();
  return false;
});

// Replace link's "href" attribute
$('.external').prop('href', '#');

Caveats & notes

In the onclick example above we added e.preventDefault() method which would stop event propagation. If you have other events relying on it on parent elements, please remove that method call. Also, when setting link's new href attribute, you can save the initial value with .data() method in order to set it back later.

// Removing e.preventDefault();
$('.internal').on("click", function(e){
  return false;
});

// Recording link's "href" attribute for later use
$('.external').data('original-href', $('.external').attr('href'));
$('.external').prop('href', '#');

// Setting it back
$('.external').prop('href', $('.external').data('original-href'));

3. Unbinding bound jQuery events

Last but not least is unbinding previously bound events. This is probably the easiest of the batch. All you have to do is to use jQuery's .unbind() method. Let's see an example:

<div class="some-elem">
  Click me
</div>
// Bind "click" event
$('.some-elem').on('click', function(){
  alert("Div is clicked!");
});

// Unbind "click" event
$('.some-elem').unbind('click');

Caveats & notes

Unbinding click event will unbind all click events that were bound to that element. So, if you want to unbind only your click event, without affecting others you have 2 options:

  1. Namespace your events;
    // Namespacing events
    $('.some-elem').on('click.my_event', function(){
      alert("Div is clicked!");
    });
    
    // Unbind namespaced event
    $('.some-elem').unbind('click.my_event');
  2. Use function reference when binding and unbinding.
    // User function reference
    var my_func = function(){
      alert("Div is clicked!");
    };
    
    // Bind using function reference
    $('.some-elem').on('click', my_func);
    
    // Unbind namespaced event
    $('.some-elem').unbind('click', my_func);

39 comments:

  1. Thank you its working

    ReplyDelete
  2. when i disable one of my sliders, it is almost completly transparent... is there a way to not have it transparent, and keep it disabled???

    ReplyDelete
  3. Thanks for the post. Just what I was looking for

    ReplyDelete
  4. @Tony, do you have a demo page? Not really getting what you mean...

    ReplyDelete
  5. thanks man..

    it helped me instantly...

    keep up the good work

    ReplyDelete
  6. Can't you just set the disabled property to true or false? I find this easier, because that way I can toggle the state of the element and not need to mess with the removeAttr call.

    For example, I have a function which returns the state of a checkbox on the page; I can just have the following:

    $('.someElement').attr('disabled', isDisabled());

    ReplyDelete
  7. Thank you very much. It helped me a lot :-)

    ReplyDelete
  8. My 2-cents: This also works...

    // To disable
    $('.someElement').attr('disabled', true);
    // To enable
    $('.someElement').attr('disabled', false);

    ReplyDelete
  9. Thank's for the advice...

    Really helpful.

    ReplyDelete
  10. Thanks for this.

    ReplyDelete
  11. Actually there are much easy ways of doing this now. Not sure these were available back in 2008

    $('input').disable(); //disables
    $('input').enable(); //enables
    $('input').toggleDisabled(); //toggles
    $('input').toggleEnabled(); //toggles
    $('input').toggleDisabled(true); //disables
    $('input').toggleEnabled(true); //enables

    ReplyDelete
  12. THANK YOU! THANK YOU! THANK YOU! THANK YOU! THANK YOU! THANK YOU!

    ReplyDelete
  13. thank u its worked

    ReplyDelete
  14. $('.someElement').attr('disabled', ''); doesn't seem to work in jQuery 1.6.x so I recommend to use removeAttr('disabled') instead.

    ReplyDelete
  15. Thanks, works great!

    ReplyDelete
  16. Thank you, just what I was looking for.

    ReplyDelete
  17. The example only shows:
    // To disable
    $('.someElement').attr('disabl

    It get's cut off due to the huge amount of ads. Fix the layout

    ReplyDelete
  18. thanks man..it worked..

    ReplyDelete
  19. This no longer works with the latest jQuery. Don't set to empty string, set to true/false or remove/add attribute.

    ReplyDelete
  20. Thanks... It works..

    ReplyDelete
  21. Thanks for this.
    // To disable
    $('.someElement').attr('disabled', true);
    // To enable
    $('.someElement').attr('disabled', false);

    ReplyDelete
  22. In a drop down the same is not working.
    i used $(this).attr('disabled','disabled') which worked fine and the enabling part - $(this).removeattr('disabled') is not working. please help

    ReplyDelete
  23. please try to display contents more than advt on site .
    answers are hide to read most often due to advt.

    ReplyDelete
  24. Warning: I found that .attr('disabled','') does NOT work to enable in JQuery 1.7.2, just like <input type="text" disabled="" /> still means the input is disabled (tested IE9 and chrome)

    ReplyDelete
  25. Good post mate.

    It saves my time!

    ReplyDelete
  26. Thanks, it solved my issues.
    Regards.
    Federico

    ReplyDelete
  27. thanks, short and simple

    ReplyDelete
  28. Thanks for the post Jon. I found that

    $('.someElement').attr('disabled', '');

    doesn't work to enable a control on my machine (OS X / Chrome). I had to use the first alternative:

    $('.someElement').removeAttr('disabled');

    ReplyDelete
  29. Does not work with the latest version of jquery. Use false instead of empty string, or better yet, use element.disabled = false;

    ReplyDelete
  30. For people coming from Google: Note that this post is out of date. You should use the .prop method in 1.6+:

    $('element').prop('disabled', true);
    $('element').prop('disabled', false);

    ReplyDelete
  31. Since jQuery 1.6 this should be done through the prop method:
    $('.someElement').prop('disabled', true);
    $('.someElement').prop('disabled', false);

    ReplyDelete