motla / vue-file-toolbar-menu

:desktop_computer: UI file/toolbar menus for Vue apps
https://motla.github.io/vue-file-toolbar-menu
MIT License
150 stars 31 forks source link

Disable item dynamically #18

Closed bobhablutzel closed 2 years ago

bobhablutzel commented 2 years ago

Love the framework, but can't figure out how to disable an item on the fly. I'm a Vue newbie, so apologize if it should be obvious.

For example, I only want the Copy item enabled if text is selected...

bobhablutzel commented 2 years ago

I managed to make it work with setting the id and using

  document.getElementById('copyItem').className = isNothingSelected ? 'bar-menu-item disabled' : 'bar-menu-item'

but that seems kludgy... is there a better way

motla commented 2 years ago

Yes, all the purpose of Vue is to avoid to access the DOM directly (document.getElementById). Instead you can make reactive variables, and when you update them the DOM updates like magic, this library included.

So create your variable in data to make it reactive:

<template>
  <div> <vue-file-toolbar-menu :content="my_menu" /> </div>
</template>

<script>
import VueFileToolbarMenu from 'vue-file-toolbar-menu'

export default {
  components: { VueFileToolbarMenu },

  data () {
    return {
      isNothingSelected: false
    }
  },

  computed: {
    my_menu () {
      return [
        { text: "Edit", menu: [{
            text: "Copy",
            disabled: this.isNothingSelected,
            click: () => document.execCommand("copy")
          }]
        }
      ]
    }
  }
}
</script>

Then you can set isNothingSelected and the menu will update. You can get and set it using this.isNothingSelected in any function of your Vue component, including Lifecycle Hooks if you want to bind it with javascript's addEventListener.

Good luck!

bobhablutzel commented 2 years ago

Romain - Thank you for this. It wasn't exactly the problem, but it pointed me toward what I'd done right.

Because of the complexity of my menu I'd moved the definition function into a separate JS module. That broken the auto-wiring from the SFC compiler. I put it back into my main .vue file, and introduced some custom IDE code folding comments in order to make the code more readable and it's back to working again.

Thanks for the quick response, though, because it pulled me out of the rabbit hole I was in.


      //region MenuItems
      const separator = { is: "separator" }
      const newItem = { text: "New", id: 'newItem', click: this.new_item }
      const saveItem = { text: "Save", id: 'saveItem' }
      const printItem = { text: "Print", id: 'printItem' }
      const closeItem = { text: "Close", id: 'closeItem', click: this.close }

      const cutItem = { text: "Cut", id: 'cutItem', disabled: this.noItemsSelected}
      const copyItem = { text: "Copy", id: 'copyItem', disabled: this.noItemsSelected }
      const pasteItem = { text: "Paste", id: 'pasteItem' }
      //endregion MenuItems

      return [
        [
          {
            text: "File",
            id: "FileMenu",
            menu: [newItem, saveItem, separator, printItem, separator, closeItem]
          },
          {
            text: "Edit",
            menu: [cutItem, copyItem, pasteItem]
          },
...