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

    How to use a parent (Dialog) component

    Help
    2
    5
    2620
    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.
    • O
      olaf last edited by olaf

      Hi,

      I would like to create a default parent component from a QDialog. I have created a component/DefaultDialog.vue:

      <template>
        <q-dialog ref="defaultDialog" @hide="onDialogHide">
          <q-card>
            <q-card-section class="row text-white bg-primary q-pa-sm">
              <div class="text-h6 q-pl-sm">{{title}}</div>
              <q-space/>
              <q-btn v-close-popup flat round dense icon="close"/>
            </q-card-section>
      
            <form @submit.prevent="saveForm">
              <q-card-section>
                <!-- dynamic section.. I want to use slots to fill this section -->
                <slot></slot>
              </q-card-section>
      
              <q-card-actions align="right" class="inset-shadow q-pr-md">
                <q-btn label="Save" color="primary" type="submit"/>
              </q-card-actions>
            </form>
          </q-card>
        </q-dialog>
      </template>
      
      <script>
      export default {
        name: 'DefaultDialog',
      
        props: ['title'],
      
        methods: {
          show() {
            this.$refs.defaultDialog.show()
          },
          hide() {
            this.$refs.defaultDialog.hide()
          },
          onDialogHide() {
            this.$emit('hide')
          },
          saveForm() {
            this.$emit('saveForm')
          }
        }
      }
      </script>
      

      Now I want to use it and tried this ‘components/UserDialog2.vue’:

      <template>
        <default-dialog>
          <q-input outlined label="Name"/>
        </default-dialog>
      </template>
      
      <script>
      import DefaultDialog from 'components/DefaultDialog'
      
      export default {
        mixins: [DefaultDialog],
        components: {
          DefaultDialog
        }
      }
      </script>
      
      

      I want to open the dialog using:

      this.$q.dialog({
         component: UserDialog2,
         parent: this
      })
      

      When its opened the input is not shown.
      I have created a full codesandbox app: https://codesandbox.io/s/reusable-dialog-component-nkdfn
      Here you can find: components/UserDialog.vue

      I want to split the dialog part so I can reuse it.
      Therefore I have create components/UserDialog2.vue. this uses components/DefaultDialog.vue
      I think I am almost there but something went wrong. There comes an error: ‘Error in mounted hook: “TypeError: this.$refs.defaultDialog is undefined”’

      Does anybody have got a idea?
      Thanks!

      1 Reply Last reply Reply Quote 0
      • J
        jraez last edited by jraez

        From my understanding, you are mixing 2 distinct things. Using slots mean that you’ll your component into the template. But you want to call it from the plugins.

        On my projects, I use pug for that purpose (https://pugjs.org/).
        You can split the code from the template, write a DefaultDialog component, a DefaultDialog template. Then, create your UserDialog2 than extends DefaultDialog component and DefaultDialog template.

        // DefaultDialog.pug
        q-dialog(ref="dialog" @hide="onDialogHide" :persistent="true")
          q-card
              block title
               q-card-section.row.text-white.bg-primary.q-pa-sm
                .text-h6.q-pl-sm {{title}}
                q-space
                q-btn(v-close-popup flat round dense icon="close")
              form @submit.prevent="saveForm"
                q-card-section
                 block content
              q-card-actions(align="right").inset-shadow.q-pr-md
                q-btn(label="Save" color="primary" type="submit")
        

        for DefaultDialog.vue refer to the plugin: https://quasar.dev/quasar-plugins/dialog#Invoking-custom-component but without a template:

        then for UserDialog2:

        <template lang="pug">
          extends DefaultDialog
            block content
              div your-content-here
        </template>
        <script>
        import DefaultDialog from 'DefaultDialog'
        export default {
          name: 'UserDialog2',
          extends: DefaultDialog
        }
        </script>
        

        As it’s a extends, you can overload methods, etc. to perform whatever you never on Ok, Cancel, etc.

        1 Reply Last reply Reply Quote 0
        • O
          olaf last edited by

          Hi,

          Thanks for you idea’s. I have tried to implement it by adding a new UserDialog3.vue in the codesandbox https://codesandbox.io/s/reusable-dialog-component-nkdfn

          This generates an error: Component template requires a root element, rather than just text.
          Googling about this error I find out pug might be installed. So I have tried to install it following this document: https://quasar.dev/quasar-cli/cli-documentation/handling-webpack#Pug
          I have runed the command yarn add --dev pug pug-plain-loader

          and changed the build section in quasar.conf.js :

              build: {
                scopeHoisting: true,
                vueRouterMode: 'history',
                extendWebpack (cfg) {
                  cfg.module.rules.push({
                    test: /\.pug$/,
                    loader: 'pug-plain-loader'
                  }),
                  chainWebpack (chain) {
                    chain.module.rule('pug')
                      .test(/\.pug$/)
                      .use('pug-plain-loader')
                        .loader('pug-plain-loader')
                  }        
                }      
              },
          

          Now I keep getting a 502 error: 502 Bad Gateway. We had trouble connecting to the server, try restarting it or check the logs to see what happened.
          I have tried to remove the pug settings from the quasar.conf.js, but this does not work. I cannot find the log either.

          Any idea’s?

          1 Reply Last reply Reply Quote 0
          • J
            jraez last edited by

            I guess you don’t need both rules.

             extendWebpack (cfg) {
                    cfg.module.rules.push({
                      test: /\.pug$/,
                      loader: 'pug-plain-loader'
                    })
            }
            

            should be enough

            1 Reply Last reply Reply Quote 0
            • O
              olaf last edited by

              Hi @jraez ,

              Thanks for your help! I have tried it, but it is still broken.
              I didn’t like the dialog plugin approach, so have recreated a similar topic with a different approach: https://forum.quasar-framework.org/topic/5541/how-to-extend-a-dialog

              Perhaps you can look into this?

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