192

I’ve read that you can disable (make physically unclickable) an HTML button simply by appending disable to its tag, but not as an attribute, as follows:

<input type="button" name=myButton value="disable" disabled>

Since this setting is not an attribute, how can I add this in dynamically via JavaScript to disable a button that was previously enabled?

Sebastian Simon
  • 14,320
  • 6
  • 42
  • 61
Jack Roscoe
  • 4,063
  • 10
  • 34
  • 45

9 Answers9

278

Since this setting is not an attribute

It is an attribute.

Some attributes are defined as boolean, which means you can specify their value and leave everything else out. i.e. Instead of disabled="disabled", you include only the bold part. In HTML 4, you should include only the bold part as the full version is marked as a feature with limited support (although that is less true now then when the spec was written).

As of HTML 5, the rules have changed and now you include only the name and not the value. This makes no practical difference because the name and the value are the same.

The DOM property is also called disabled and is a boolean that takes true or false.

foo.disabled = true;

In theory you can also foo.setAttribute('disabled', 'disabled'); and foo.removeAttribute("disabled"), but I wouldn't trust this with older versions of Internet Explorer (which are notoriously buggy when it comes to setAttribute).

Quentin
  • 800,325
  • 104
  • 1,079
  • 1,205
  • Would it make sense to do both, change the property and set the attribute or is it just an overkill? – v010dya Nov 18 '14 at 12:28
  • What's `foo` in `foo.disabled = true;`? Is it the id of that button? – stack Jun 27 '16 at 21:03
  • @stack — A variable holding a reference to the element collected through whatever means you like (e.g. querySelector) – Quentin Jun 27 '16 at 21:04
154

to disable

document.getElementById("btnPlaceOrder").disabled = true; 

to enable

document.getElementById("btnPlaceOrder").disabled = false; 
Andro Selva
  • 51,960
  • 51
  • 189
  • 237
kaushar
  • 1,541
  • 1
  • 9
  • 2
22

It is an attribute, but a boolean one (so it doesn't need a name, just a value -- I know, it's weird). You can set the property equivalent in Javascript:

document.getElementsByName("myButton")[0].disabled = true;
Andy E
  • 311,406
  • 78
  • 462
  • 440
  • 2
    It does need a value, it is the name that it doesn't need. (Strange, but true). – Quentin Jun 10 '10 at 13:18
  • 1
    @David: I remember reading that before, fixed. It is strange indeed and would probably make more sense if syntax highlighters honoured it correctly :-) – Andy E Jun 10 '10 at 13:22
10

Try the following:

document.getElementById("id").setAttribute("disabled", "disabled");
royhowie
  • 10,605
  • 14
  • 45
  • 66
Maksim Kondratyuk
  • 1,369
  • 15
  • 26
  • 4
    As [David Dorward mentioned](http://stackoverflow.com/questions/3014649/how-to-disable-html-button-using-javascript/3014678#3014678), this cannot be relied upon properly cross-browser and the property equivalent should be used instead. – Andy E Jun 10 '10 at 13:20
9

The official way to set the disabled attribute on an HTMLInputElement is this:

var input = document.querySelector('[name="myButton"]');
// Without querySelector API
// var input = document.getElementsByName('myButton').item(0);

// disable
input.setAttribute('disabled', true);
// enable
input.removeAttribute('disabled');

While @kaushar's answer is sufficient for enabling and disabling an HTMLInputElement, and is probably preferable for cross-browser compatibility due to IE's historically buggy setAttribute, it only works because Element properties shadow Element attributes. If a property is set, then the DOM uses the value of the property by default rather than the value of the equivalent attribute.

There is a very important difference between properties and attributes. An example of a true HTMLInputElement property is input.value, and below demonstrates how shadowing works:

var input = document.querySelector('#test');

// the attribute works as expected
console.log('old attribute:', input.getAttribute('value'));
// the property is equal to the attribute when the property is not explicitly set
console.log('old property:', input.value);

// change the input's value property
input.value = "My New Value";

// the attribute remains there because it still exists in the DOM markup
console.log('new attribute:', input.getAttribute('value'));
// but the property is equal to the set value due to the shadowing effect
console.log('new property:', input.value);
<input id="test" type="text" value="Hello World" />

That is what it means to say that properties shadow attributes. This concept also applies to inherited properties on the prototype chain:

function Parent() {
  this.property = 'ParentInstance';
}

Parent.prototype.property = 'ParentPrototype';

// ES5 inheritance
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

function Child() {
  // ES5 super()
  Parent.call(this);

  this.property = 'ChildInstance';
}

Child.prototype.property = 'ChildPrototype';

logChain('new Parent()');

log('-------------------------------');
logChain('Object.create(Parent.prototype)');

log('-----------');
logChain('new Child()');

log('------------------------------');
logChain('Object.create(Child.prototype)');

// below is for demonstration purposes
// don't ever actually use document.write(), eval(), or access __proto__
function log(value) {
  document.write(`<pre>${value}</pre>`);
}

function logChain(code) {
  log(code);

  var object = eval(code);

  do {
    log(`${object.constructor.name} ${object instanceof object.constructor ? 'instance' : 'prototype'} property: ${JSON.stringify(object.property)}`);
    
    object = object.__proto__;
  } while (object !== null);
}

I hope this clarifies any confusion about the difference between properties and attributes.

Community
  • 1
  • 1
Patrick Roberts
  • 40,065
  • 5
  • 74
  • 116
5

It's still an attribute. Setting it to:

<input type="button" name=myButton value="disable" disabled="disabled">

... is valid.

Oli
  • 215,718
  • 61
  • 207
  • 286
  • 1
    Valid, but the spec says that syntax should be avoided: http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.3 – Quentin Jun 10 '10 at 13:19
  • 2
    All browsers look for disabled="disabled", i know the spec say to avoid it, but i have never had any problems setting disabled="disabled" or checked="checked" or selected="selected"...Just don't do disabled="true"...only some browsers will recognize that – Bob Fincheimer Jun 10 '10 at 13:25
  • Clearly not all browsers support it — the spec wouldn't be so explicit if they didn't. They just aren't in common usage any more. – Quentin Jun 10 '10 at 13:28
  • 1
    BTW, the question says "how can I add this in dynamically via JavaScript" – Quentin Jun 10 '10 at 13:28
  • Sure but the question goes on to talk about disabled not being an attribute. My answer is about dispelling that and saying you can use it as an attribute. You *can* also use the DOM property. – Oli Jun 10 '10 at 13:45
4

If you have the button object, called b: b.disabled=false;

dplass
  • 1,393
  • 9
  • 20
3

I think the best way could be:

$("#ctl00_ContentPlaceHolder1_btnPlaceOrder").attr('disabled', true);

It works fine cross-browser.

Kenly
  • 16,220
  • 5
  • 36
  • 52
Benito
  • 115
  • 1
0
<button disabled=true>text here</button>

You can still use an attribute. Just use the 'disabled' attribute instead of 'value'.

anonymous
  • 67
  • 1
  • 1
  • It’s `disabled="disabled"` or just `disabled`. Any string value is equivalent to `"disabled"`, including `disabled="true"` and `disabled="false"`. – Sebastian Simon Sep 07 '18 at 14:37