need quasar form components to emit on change/input



  • The input and select components emit an undocumented 'input" when their state/value changes but option group does not and maybe other form components. Option group only has focus and blur (at least documented)

    If a form component has no way to tell me that a user has changed a value/state/choices (in option group for example) then I have not way to mange those changes with for example server updates, automatic validatioin etc.

    I writing a generic form generator component made of quasar form components using a render function (below) and there and you can see the listener for ‘input’ which remits ‘changed’ to the parent which then the parent can process as it wants. This works fine for both qinput and qselect components as they emit ‘input’ with state. This I assume must be because the quasar component is an extension of a vue component that does emit ‘input’

    @rstoenescu
    Can this functionality be added? I suppose ‘input’ is as good as anything to emit but all quasar form components should emit this along with the state/value of the form field compoenent. In particular my current need is for the qOptionsGroup to emit when user changes/checks/unchecks an option

    <script>
    
    // import makeFieldProps from '../helpers/makeFieldProps.js'
    
    export default {
      data () {
        return {
        }
      },
      render (element) {
        return element('div', {}, this.makeForm(element))
      },
      props: ['values', 'schema'],
      methods: {
        makeForm (element) {
          let form = []
          // console.log('values', this.values)
          for (let key in this.schema) {
            // console.log('form schema key on render', key)
            if (this.schema[key].fieldType !== 'hidden') {
              let field =
              element('q-field', {
                props: {
                  label: this.schema[key].fieldProps.label
                }
              }, [
                element(this.schema[key].fieldType ? `q-${this.schema[key].fieldType}` : 'q-input', {
                  props: this.fieldProps(this.values[key], this.schema[key]),
                  on: {
                    input: (value) => {
                      this.$emit('changed', { name: key, value: value })
                    }
                  }
                }),
                this.tooltip(this.schema[key].fieldProps.tip, element)
              ]
              )// end field element
              form.push(field)
            } // skip for hidden
            // console.log('field', key, field)
          }// end form field loop
          // console.log('the form object', form)
          return form
        },
        fieldProps (value, field) {
          let props = field.fieldProps // quasar compenent props here
          // let props = makeFieldProps[ field.fieldType ? field.fieldType : 'input' ](field)
          // console.log('props after processing', props)
          props.value = value
          return props
        },
        tooltip (tip, e) {
          if (tip) {
            return e('q-tooltip', {}, [ tip ])
          }
          else {
            return null
          }
        }
      },
      mounted () {
      }
    }
    </script>
    
    <style lang="stylus">
    
    @import '~variables'
    
    </style>
    


  • @dgk Wonder why do you still want to think in “events”? Vue/Quasar is not jQuery :-) It’s easier to just watch for changes in data model (from VUE docs):

    #watch
    
    Type: { [key: string]: string | Function | Object }
    
    Details:
    
    An object where keys are expressions to watch and values are the corresponding callbacks. The value can also be a string of a method name, or an Object that contains additional options. The Vue instance will call $watch() for each entry in the object at instantiation.
    
    Example:
    
    var vm = new Vue({
      data: {
        a: 1,
        b: 2,
        c: 3
      },
      watch: {
        a: function (val, oldVal) {
          console.log('new: %s, old: %s', val, oldVal)
        },
        // string method name
        b: 'someMethod',
        // deep watcher
        c: {
          handler: function (val, oldVal) { /* ... */ },
          deep: true
        }
      }
    })
    vm.a = 2 // => new: 2, old: 1
    
    Note that you should not use an arrow function to define a watcher (e.g. searchQuery: newValue => this.updateAutocomplete(newValue)). The reason is arrow functions bind the parent context, so this will not be the Vue instance as you expect and this.updateAutocomplete will be undefined.


  • This post is deleted!


  • @qyloxe

    I’m only a month new to both quasar and vue so didn’t occur to me to use them.

    BUT as I look at my use case I am wondering if they apply because I am binding a prop in my child compoenet (above) and not local data. My understanding is that if you pass a prop then for the prop to change you must emit an event that the parent can listen for that has the changes made in child, then you set those in the parent and they get sent back to child via the prop. You can’t change a prop directly within the same component and and thus you can’t watch a prop as a way of ddeterming a change that can be emitted to the parent. Is that so?

    The only way I can think of to use watchers in my case is to make a copy of my values prop to local data and bind that to my form elements, watch that and emit my change for the parent

    Makes me wonder what the quasar form components themselve do? They obviously emit events but how do they change the bound object if that object was prop in the parent. ’


  • Admin

    Use @change event (applies to almost all form components). This is triggered whenever the model changes, whatever the model is (String, Array, Object, etc).
    Just added this event to the Option Group docs page (will get live in a few days) – missing this prop was a docs glitch.



  • @rstoenescu said in need quasar form components to emit on change/input:

    triggered whenever the model changes

    One thing that is driving me a little crazy with Quasar is the @change is triggered differently than traditional Vue.

    see this jsfiddle
    https://jsfiddle.net/daveline/dr5fzcrr/

    notice how the input is triggered as you type
    notice how the change is triggered as you click off the component (even if the model has changed)

    if you replace the input with an q-input, the input AND change will be triggered as you type.


  • Admin

    @daveline A general rule of thumb when dealing with Quasar: @input is used solely for managing state with Vue in order to generate as few re-renders as possible, while @change ensures it is triggered each time the model changes, as soon as it changes.


Log in to reply
 

Looks like your connection to Quasar Framework was lost, please wait while we try to reconnect.