No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    need quasar form components to emit on change/input

    Help
    4
    7
    7047
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • D
      dgk last edited by

      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>
      
      qyloxe 1 Reply Last reply Reply Quote 0
      • qyloxe
        qyloxe @dgk last edited by

        @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.
        D 1 Reply Last reply Reply Quote 0
        • D
          dgk last edited by

          This post is deleted!
          1 Reply Last reply Reply Quote 0
          • D
            dgk @qyloxe last edited by

            @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. ’

            1 Reply Last reply Reply Quote 0
            • rstoenescu
              rstoenescu Admin last edited by

              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.

              D 1 Reply Last reply Reply Quote 0
              • D
                daveline @rstoenescu last edited by

                @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.

                1 Reply Last reply Reply Quote 0
                • rstoenescu
                  rstoenescu Admin last edited by

                  @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.

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post