Vue: need to disable all inputs on page
Asked Answered
D

4

12

I'm developing an app that has different license types, and according to the license we need to disable/enable inputs.

One way is to put a conditional :disabled for each input but that's a lot of work and error prone, since we might forget to put it on some inputs.

I thought of using a directive like v-disable-all that searches for all inputs under the container and adds disabled to them.

I was wandering if there is a better solution or if there is already a solution like this?

Diphenylhydantoin answered 29/4, 2019 at 14:4 Comment(0)
D
13

I ended up creating this directive:

import Vue from "vue";

Vue.directive("disable-all", {
  // When all the children of the parent component have been updated
  componentUpdated: function(el, binding) {
    if (!binding.value) return;
    const tags = ["input", "button", "textarea", "select"];
    tags.forEach(tagName => {
      const nodes = el.getElementsByTagName(tagName);
      for (let i = 0; i < nodes.length; i++) {
        nodes[i].disabled = true;
        nodes[i].tabIndex = -1;
      }
    });
  }
});
Diphenylhydantoin answered 30/4, 2019 at 7:7 Comment(2)
So pretty much what I said to do? Not sure why you didn’t just tick, but happy you got it sorted.Saddler
"I thought of using a directive like v-disable-all that searches for all inputs under the container and adds disabled to them." this is a quote from my question, and then i asked if there is another , better, way. you just told me to do what i wanted to do in the first place. Also you wrote it in simple JS and not as a Vue directive, so i gave you a thumbs up for the effort but you didn't really answer my question.Diphenylhydantoin
C
13

I'am coming a bit late, but there is an attribute on the HTML element called "disabled", which ... disable every input in the tree.

<fieldset :disabled="!canEdit">
  ...
</fieldset>

canEdit could be a computed property or anything you want.

Conrad answered 20/6, 2020 at 17:5 Comment(1)
Also hint: you can prevent fieldset from breaking your grid layout (for example) by setting display: contents; style to it.Hyperopia
S
6

You can do something like this:

let elems = document.getElementById('parentDiv').getElementsByTagName('input');

This will give you all the inputs inside a parent, then you can run a simple for loop to loop over them and set each one to disabled.

Something like this:

for(let i = 0; i < elems.length; i++) {
    elems[i].disabled = true;
}

Hope this helps set you on the right path.

let elems = document.getElementById('someid').getElementsByTagName('input');

console.log(elems);

for(let i = 0; i < elems.length; i++) {
  elems[i].disabled = true;
}
<html>
  <body>
    <div id="someid">
      <input type="text">
      <input type="text">
      <input type="text">
      <input type="text">
      <input type="text">
    </div>
  </body>
</html>
Saddler answered 29/4, 2019 at 14:10 Comment(5)
He could write a directive and append it to each input or the parent that does exactly as shown above. "One way is to put a conditional :disabled for each input but that's a lot of work and error prone, since we might forget to put it on some inputs." This covers all inputs inside a parent.Saddler
As I mentioned in the question, I'm aware of this solution, I was looking for a way to avoid itDiphenylhydantoin
You could write a watch function that has an array of licenses and the inputs that should be available when a license is selected and on change. But again, you would have to add each input to the array. I can't think of anything else off the top of my head.Saddler
Won't this stop working if anything on the model changes because Vue will regenerate the UI?Paleozoology
"input" selector doesn't account for SELECT tagsNigrescent
M
2

Now you just need to wrap your fields inside <v-form :disabled="variable"></v-form>

Monto answered 10/8, 2020 at 1:57 Comment(5)
v-form is not a Vuejs directive, but Vuetify component.Conrad
@Conrad you are right. My bad! Is because I got used to Vuetify(my question, why would you not use Vuetify??)Monto
Because you use Buefy ! just a matter of CSS frameworkConrad
I can ensure you is not just a matter of CSS ;)Monto
@Monto While this is not the correct answer to OP, it was the perfect solution for me since I use Vuetify too. Thanks!Mississippian

© 2022 - 2024 — McMap. All rights reserved.