javascriptmaterial-design-lite

Dynamically disable MDL textbox via JavaScript


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.


Solution

  • 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.