Q-tree with q-toggle



  • I want to build a ‘settings’ tree with toggles for each setting value. But I can’t figure out how to make the toggles actually do anything. The state of each toggle will be kept in a store module.
    Here’s a screen-shot of my test:
    tree toggle.png
    The top toggle works fine, but the one in the tree does not.

    Here’s the code:

    <!-- This toggle works fine -->
        <q-toggle v-model='labels'
          label="Show button labels"
        />
        <!-- But toggle in the tree doesn't work -->
        <q-tree
          :nodes="settings"
          node-key="label"
        >
          <template v-slot:header-toggle="prop">
            <q-toggle v-model="prop.node.model" :label="prop.node.label" />
          </template>
        </q-tree>
    
    <script>
    import ToolbarButton from '../widgets/ToolbarButton'
    import { mapActions, mapGetters } from 'vuex'
    
    export default {
      computed: {
        ...mapGetters('main', ['buttonLabels']),
    
        labels: {
          get () {
            return this.buttonLabels
          },
          set () {
            this.toggleButtonLabels()
          }
        }
      },
    
      methods: {
        ...mapActions('main', ['toggleButtonLabels'])
      },
    
      data () {
        return {
          settings: [
            {
              label: 'General settings',
              children: [
                {
                  header: 'toggle',
                  label: 'Show button labels',
                  body: 'toggle',
                  model: this.labels
                }
              ]
            }
          ]
        }
      }
    }
    </script>
    

    Any help will be appreciated.



  • @CWoodman

    I don’t think the second toggle has a proper v-model value.( because it’s now in Indeterminate state = null). model: this.labels ?

    codepen?



  • @dobbel Using vuex store, so can’t do a codepen. this.labels is a computed getter/setter as shown in the code.
    If I change the tree node ‘model’ to use a local data variable, it still doesn’t work. I must not be understanding how the ‘v-model=“prop.node.model”’ works.



  • @CWoodman vuex works in codepen. If youre having trouble setting it up, use codesandbox instead, fork the one from the docs and do your reproduction code there.



  • @metalsadman OK, I made a codepen (not using vuex)
    https://codepen.io/crawfordw/pen/poyRqqJ?editors=1111

    Shows what I’m trying to do, with a sample button - I want the user to be able to show/hide button labels with a toggle in a ‘settings tree’. But I’m not understanding how to control or respond to the toggle’s state when it’s in a tree.

    And while we’re at it, is there a better way to make a button’s label optional without repeating it’s code using v-if?



  • @CWoodman

    this example has a working toggle in the q-tree:

    https://quasar.dev/vue-components/tree#Example--Customizing-nodes



  • @dobbel Yes, that’s what I used as my template. But I don’t want the model to control disabled - I want it to toggle a data value and for some reason it doesn’t work for me, as you can see in my codepen.



  • @CWoodman

    I don’t understand v-model can contain anything, in the example it’s bound to disabled/enabled but it can be bound to anything.

    I suggest to build your code around a working example.

    working code:

      <template v-slot:body-toggle="prop">
            <p class="text-caption">{{ prop.node.caption }}</p>
            <q-toggle v-model="prop.node.whatever" />
          </template>
    

    your code:

      <template v-slot:header-toggle="prop">
            <q-toggle v-model="prop.node.model" :label="prop.node.label" />
          </template>
    

    for example your code uses a different slot



  • @dobbel The codepen works fine if you hard-code a value in the ‘model’ for the node. The question is 'how can the node’s model value be linked dynamically to another data value (or in my case a state value from the store). It seems I can’t just say:

    data: function () {
        return {
          showLabels: false,
          settings: [
            {
              label: 'General settings',
              children: [
                {
                  header: 'toggle',
                  label: 'Show button labels',
                  body: 'toggle',
                  model: this.showLabels
                }
              ]
            }
          ]
        }
    

    where the model prop is set to another data value (this.showLabels). How can this prop be bound dynamically with two-way connection to another data value??



  • This post is deleted!


  • @CWoodman

    dynamically linking won’t work like you tried.

    https://stackoverflow.com/questions/49614837/how-to-reference-data-variable-from-another-data-variable-in-vue-2

    This does work:

    data: function () {
            return {
                settings: [
                    {
                        label: 'General settings',
                        children: [
                            {
                                header: 'toggle',
                                label: 'Show button labels',
                                body: 'toggle',
                                model: false
                            }
                        ]
                    }
                ]
            }
        },
        computed: {
            showLabels () {
                return this.settings[0].children[0].model
            }
        }
    

    This is probably not what you want…
    I suggest you take a look at vuex-orm like suggested earlier.



  • @dobbel Thanks for your suggestions. I’ve decided to drop the toggle idea and just use the q-tree built-in check boxes. Works fine.



  • @CWoodman this tree implementation is VERY interesting - it has one of the cleanest and elegant implementation, it has PROPER dnd handling of middle nodes, and is generally easy to extend/modify:

    https://github.com/TinyWisp/twtree

    BEWARE - it is not optimized for large trees, I hope there will be commits soon from some good soul, correcting those few simple inefficiencies. If it will be corrected, this tree might be one of the best vue trees.


Log in to reply