In D2 ui-template can't get @update:modelValue to work in v-select

I am experimenting with widgets in D2 ui-template. I have a v-select and the docs suggests that @update:modelValue should be fired when the selected value changes, but I can't get this to work. @click does work. This is what I have so far. The code that changes the selection when an option is passed in msg.payload does work. Can anyone see what I am doing wrong?

<template>
  <div>
    <v-select
      :items="items"
      :model-value="value"
      @update:modelValue="mvchanged"
      @click="clicked"
    ></v-select>
  </div>
</template>

<script>
export default {
  data() {
    return {
        dropdownData: {options: ['Foo', 'Bar', 'Fizz', 'Buzz']}
    }
  },
  watch: {
      msg: function(){
          if (typeof this.msg.payload === "string" && this.dropdownData.options.includes(this.msg.payload)) {                  
              this.dropdownData.value = this.msg.payload
          }
          // prevent redraw on deploy
          //this.msg.payload = null
      }
  },
  methods:{
    mvchanged:function(){
      this.send({payload: "modelValue changed"});
    },
    clicked:function(){
      this.send({payload: "clicked"});
    },
  },
  computed : {
    items: function(){
      return this.dropdownData?.options ?? ""
    },
    value: function(){
      return this.dropdownData?.value ?? ""
    }
  }
}
</script>

[Clarification Edit] When I said that I can update the selection by passing in a message, that does change the selection but does not trigger the event.

I think it should be v-model="value" going by example

<v-rating hover :length="5" :size="32" v-model="value"
    active-color="primary" @update:modelValue="send({payload: value})"/>

Both work for me, possibly for compatibility with an older version of vue. Changing that does not make the update trigger work. The docs I linked to show model-value.
I also tried @change.

I noticed also that @update:modelValue didnt work,
when i was testing recently for another post that used v-select
After some research on the internet, what worked for me is to use @update:model-value="mvchanged" instead.

<template>
  <div>
    <v-select
      :items="items"
      v-model="value"
      @update:model-value="mvchanged"
    ></v-select>
  </div>
</template>

<script>
export default {
  data() {
    return {
        dropdownData: {options: ['Foo', 'Bar', 'Fizz', 'Buzz']},
        value: this.dropdownData?.value ?? ""
    }
  },
  watch: {
      msg: function(){
          if (typeof this.msg.payload === "string" && this.dropdownData.options.includes(this.msg.payload)) {                  
              this.dropdownData.value = this.msg.payload
          }
          // prevent redraw on deploy
          //this.msg.payload = null
      }
  },
  methods:{
    mvchanged:function(){
      this.send({payload: this.value});
    },
    clicked:function(){
      this.send({payload: "clicked"});
    },
  },
  computed : {
    items: function(){
      return this.dropdownData?.options ?? ""
    }
  }
}
</script>

Great, that works. Thanks.

Did you manage to access the new value? I can't work out how to do that. If, in the mvchanged function I put
this.send({payload: "model-value changed " + this["model-value"]})
then it just sends the value as undefined.

The only way I could get this to fire an event when a msg (via an inject node) is sent to the widget is this;

<template>
  <div>
    <v-select
      :items="items"
      v-model="value"
      @update:model-value="mvchanged"

    ></v-select>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dropdownData: {options: ['Foo', 'Bar', 'Fizz', 'Buzz']},
      value: ""

    }

  },

  watch: {
    value: function () {
      this.send({value: this.value})

    },

  },

  methods: {
    mvchanged: function() {
      this.send({payload: this.value})
  
    },

  },

  computed : {
    items: function() {
      return this.dropdownData?.options ?? ""

    },

  },

    mounted () {               
      this.$socket.on("msg-input:" + this.id, (msg) => {
      /**
      * 
      * topic:     ,
      * payload:   "<value>"
      * 
      */
        if (typeof msg.payload === "string" && this.dropdownData.options.includes(msg.payload)) {
          this.value = msg.payload

        }
  
      })

    },

}
</script>

mvchanged only fires when a selection is clicked on in the dropdown. With the code above the @update:model-value="mvchanged" (and therefor the mvchanged function) is not required. The send works both ways (selection & msg in)

All good with that solution. Thanks.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.