Reputation: 63
I need to disable Material Design Lite textfield via JS. I understand that I need to upgrade the element to MDL detects changes.
I expected that to be done like this:
$element.attr('disabled', 'disabled');
componentHandler.upgradeElement($element);
But that doesn't seem to work. I ended with this working solution:
$element.attr('disabled', 'disabled');
let inputWrap = $element.parent();
inputWrap.attr('data-upgraded', '');
inputWrap.attr('class', inputWrap.attr('class').replace(/is-upgraded/g, ''));
inputWrap.attr('class', inputWrap.attr('class').replace(/is-focused/g, ''));
componentHandler.upgradeElement(inputWrap[0]);
It did the trick but I can't shake the feeling that I am manually doing job for upgradeElement
function.
Is there a way to achieve this with less drastic approach? Any help would be much appreciated.
Upvotes: 6
Views: 1243
Reputation: 2050
Edit: See the other answer by Matthew, this answer is out of date in 2022.
MDL doesn't dynamically re-evaluate input elements when their values change programmatically and I haven't found a nice way to ask it to re-evaluate itself.
The good news is that you don't need to scrub the element and call componentHandler.upgradeElement() again, you just need to add or remove the appropriate classes to the element so the style changes correctly.
In your case you just need to add the 'is-disabled' class to disabled elements and remove it from ones that aren't disabled:
if (element.disabled) {
element.parentNode.classList.add("is-disabled");
} else {
element.parentNode.classList.remove("is-disabled");
}
There are other classes such as 'is-readonly' (for read only fields), 'is-checked' (for checkboxes), 'is-invalid' (for invalid inputs) and a handful of others.
For my projects using this library I made a small helper function that would scan for input fields under an element and re-evaluate the classes. After dynamically loading data I call the helper function and it takes care of fixing the styles for the form.
There may be a better way to do this, but I haven't found it.
Upvotes: -1
Reputation: 4339
Merely changing the classes will just change how it appears, it won't disable the button. Similarly, merely setting the disabled attribute will disable it but won't change how it looks. The correct method is to use the build-in disable
and enable
methods on MaterialCheckbox
. So if this is your checkbox
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-2">
<input type="checkbox" id="checkbox-2" class="mdl-checkbox__input">
<span class="mdl-checkbox__label">Checkbox</span>
</label>
then this is how you disable it
document.getElementById("checkbox-2").parentNode.MaterialCheckbox.disable();
and this is how you enable it
document.getElementById("checkbox-2").parentNode.MaterialCheckbox.enable();
Upvotes: 6