Skip to content

Disable Directive

The v-disable directive can be used to disable or enable an element based on a binding value.

Usage

The v-disable directive can be used as follows:

vue
<template>
  <div class="space-x-2">
    <button v-disable>Disabled</button>
    <button>Enabled</button>
  </div>
</template>

Conditional Disable

The v-disable directive can be used to conditionally disable an element. This is useful when you want to disable an element only when a certain condition is met.

if count is odd, input will be disabled, otherwise it will be enabled, all the event will be disabled too

View Code
vue
<script setup>
import { ref } from "vue";
const count = ref(0);
</script>
<template>
  <div>
    <div class="space-y-2">
      <div>
        <p>
          if count is odd, input will be disabled, otherwise it will be enabled, all the event will be disabled too
        </p>
        <div>
          <input
            type="number"
            v-disable="count % 2 === 1"
            v-model="count"
            class="p-2 border w-full max-w-xs rounded-lg focus:outline-none ring-2 focus:ring-blue-600 focus:border-transparent"
            :placeholder="count % 2 === 1 ? 'Disabled' : 'Not disabled'"
          />
        </div>
      </div>
      <div class="w-full">
        <button
          @click="count++"
          class="px-2 py-1 w-full bg-blue-500 text-white rounded-lg max-w-xs"
        >
          count+
        </button>
      </div>
    </div>
  </div>
</template>
<style>
.disabled {
  @apply opacity-20 cursor-not-allowed pointer-events-none;
}
/* css */
/* 
.disable{
    opacity: 0.2;
    cursor: not-allowed;
    pointer-events: none;
}

*/
</style>

Arguments

The v-disable directive does not accept any arguments.

Modifiers

The v-disable directive does not accept any modifiers.

Source Code

js
export const vDisable = {
  mounted: (el, binding) => {
    const condition = binding.value !== undefined ? binding.value : true;
    updateState(el, condition);
    manageEvents(el, condition);
  },
  updated: (el, binding) => {
    const condition = binding.value !== undefined ? binding.value : true;
    updateState(el, condition);
    manageEvents(el, condition);
  },
};

function updateState(el, condition) {
  if (condition) {
    disableElement(el);
  } else {
    enableElement(el);
  }
}

function disableElement(el) {
  el.disabled = true;
  el.className += " disabled";
  el.style.pointerEvents = "none";
}

function enableElement(el) {
  el.disabled = false;
  el.className = el.className.replace(/\bdisabled\b/g, ''); // Remove "disabled" class
  el.style.pointerEvents = "auto";
}

function manageEvents(el, condition) {
  const eventList = ['click', 'mousedown', 'mouseup', 'mousemove', 'keydown', 'keyup', 'keypress', 'contextmenu', 'touchstart', 'touchend', 'touchmove', 'touchcancel'];

  if (condition) {
    eventList.forEach(event => {
      el.addEventListener(event, preventDefault, false);
    });
  } else {
    eventList.forEach(event => {
      el.removeEventListener(event, preventDefault, false);
    });
  }
}

function preventDefault(event) {
  event.preventDefault();
}