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?

4 Answers 4

14

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Also hint: you can prevent fieldset from breaking your grid layout (for example) by setting display: contents; style to it.
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;
      }
    });
  }
});

2 Comments

So pretty much what I said to do? Not sure why you didn’t just tick, but happy you got it sorted.
"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.
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>

5 Comments

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.
As I mentioned in the question, I'm aware of this solution, I was looking for a way to avoid it
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.
Won't this stop working if anything on the model changes because Vue will regenerate the UI?
"input" selector doesn't account for SELECT tags
2

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

5 Comments

v-form is not a Vuejs directive, but Vuetify component.
@Elmatou you are right. My bad! Is because I got used to Vuetify(my question, why would you not use Vuetify??)
Because you use Buefy ! just a matter of CSS framework
I can ensure you is not just a matter of CSS ;)
@pabloRN While this is not the correct answer to OP, it was the perfect solution for me since I use Vuetify too. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.