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 close child dialog dynamically

    Help
    2
    9
    3166
    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.
    • L
      lesourcil last edited by

      Hi, i have a parent component that creates a child dialog and I would like to close the dialog dynamically from the child. I have tried many things but it doesn’t work.

      Parent

      <template>
              <q-dialog
                v-model="signInDialog"
                @closeSignInDialog="signInDialog = false"
                persistent
                transition-show="flip-down"
                transition-hide="flip-up"
              >
                <login></login>
              </q-dialog>
      </template>
      <script lang="ts">
      import Login from 'components/Login.vue'
      import { defineComponent, ref } from '@vue/composition-api';
      
      export default defineComponent({
        name: 'MainLayout',
        data () {
          return {
            signInDialog: false
          }
        },
        components: { Login },
        setup() {
          const leftDrawerOpen = ref(false);
      
          return {leftDrawerOpen}
        }
      });
      </script>
      

      Child:

      methods: {
          async onSubmit () {
            await dispatchLogIn(this.$store, {username: this.email, password: this.password})
            if (readLoginError(this.$store)) {
              // fail
              this.$q.notify({
                color: 'negative',
                position: 'top',
                message: 'Incorrect email or password',
                icon: 'report_problem'
              })
            }else{
      ---->        this.$emit("closeSignInDialog")
            }
          }
        },
      });
      

      What am I doing wrong ?

      dobbel 1 Reply Last reply Reply Quote 0
      • dobbel
        dobbel @lesourcil last edited by

        @lesourcil

        What if you put the code from your login component directly in your q-dialog? Does it work then?

        If so maybe this will help:
        https://github.com/quasarframework/quasar/issues/5822

        1 Reply Last reply Reply Quote 0
        • L
          lesourcil last edited by

          @dobbel
          Im not sure I understand, if I copy my login component (child) directly into my q-dialog (parent) then i wont have a child/parent, only parent so it should work ?

          dobbel 1 Reply Last reply Reply Quote 0
          • dobbel
            dobbel @lesourcil last edited by

            @lesourcil

            Well yes because every thing( including the on submit code) is in 1 component so you don’t have to emit events. You can change signInDialog directly:

            async onSubmit () {
                  await dispatchLogIn(...)
                  if (readLoginError(this.$store)) {
                    // fail
                    this.$q.notify({
                      color: 'negative',
                      position: 'top',
                      message: 'Incorrect email or password',
                      icon: 'report_problem'
                    })
                  }else{
            ---->        this.signInDialog = false   <---
                  }
                }
            
            L 1 Reply Last reply Reply Quote 0
            • L
              lesourcil @dobbel last edited by

              @dobbel

              ok let me clarify. These are 2 different vue files. (im a noob in vue)

              Parent: pages/main.vue

              <template>
                      <q-dialog
                        v-model="signInDialog"
                        @closeSignInDialog="signInDialog = false"
                        persistent
                        transition-show="flip-down"
                        transition-hide="flip-up"
                      >
                        <login></login>
                      </q-dialog>
              </template>
              <script lang="ts">
              import Login from 'components/Login.vue'
              import { defineComponent, ref } from '@vue/composition-api';
              
              export default defineComponent({
                name: 'MainLayout',
                data () {
                  return {
                    signInDialog: false
                  }
                },
                components: { Login },
                setup() {
                  const leftDrawerOpen = ref(false);
              
                  return {leftDrawerOpen}
                }
              });
              </script>
              

              Child : components/Login.vue

              <template>
              ...
              </template>
              <script>
              ...
              
              methods: {
                  async onSubmit () {
                    await dispatchLogIn(this.$store, {username: this.email, password: this.password})
                    if (readLoginError(this.$store)) {
                      // fail
                      this.$q.notify({
                        color: 'negative',
                        position: 'top',
                        message: 'Incorrect email or password',
                        icon: 'report_problem'
                      })
                    }else{
              ---->        this.$emit("closeSignInDialog")
                    }
                  }
                },
              });
              </script>
              

              I don’t want to move my code from login.vue component to main.vue page.

              Does it makes sens ?

              dobbel 1 Reply Last reply Reply Quote 0
              • dobbel
                dobbel @lesourcil last edited by

                @lesourcil

                I don’t want to move my code from login.vue component to main.vue page.

                Ah I see.

                I personally use Vuex to solve these kind of problems. I am not a vue event expert, but using a q-dialog with custom components requires some extra work:

                https://github.com/quasarframework/quasar/issues/5822

                L 1 Reply Last reply Reply Quote 0
                • L
                  lesourcil @dobbel last edited by

                  @dobbel

                  I just figured it out because you made me think. You rock!

                  I ended moving my <dialog> into my login component itself and then adding a props “showDialog” that i can set from parent

                  Child : components/Login.vue

                  <template>
                    <q-dialog
                  --->    v-model="showDialog"
                      persistent
                      transition-show="flip-down"
                      transition-hide="flip-up"
                    >
                  
                  ...
                  
                  </template>
                  <script>
                  ...
                  
                  props: {
                  -->    showDialog: {
                        default: false,
                        type: Boolean,
                      },
                    },
                  
                  methods: {
                      async onSubmit () {
                        await dispatchLogIn(this.$store, {username: this.email, password: this.password})
                        if (readLoginError(this.$store)) {
                          // fail
                          this.$q.notify({
                            color: 'negative',
                            position: 'top',
                            message: 'Incorrect email or password',
                            icon: 'report_problem'
                          })
                        }else{
                  --->        this.showDialog = false
                        }
                  ...
                  </script>
                  

                  and then on parent : pages/main.vue

                  <template>
                    <login :showDialog="showSignInDialog"></login>
                  </template>
                  <script>
                  ...
                  
                  data () {
                      return {
                        showSignInDialog: false
                      }
                    },
                  
                  </script>
                  
                  
                  dobbel 1 Reply Last reply Reply Quote 0
                  • dobbel
                    dobbel @lesourcil last edited by

                    @lesourcil

                    Great! Yes that’s also a way to prevent using events.

                    I thought a little about it and I might know what the problem is in your original code. From Vue’s perspective the q-dialog is the parent of your custom login component.

                    Because your login component is emitting the event you should also let your login component expose the @closeSignInDialog instead of your q-dialog:(I might be totally wrong here)

                    <template>
                            <q-dialog
                              v-model="signInDialog"
                              persistent
                              transition-show="flip-down"
                              transition-hide="flip-up"
                            >
                              <login @closeSignInDialog="signInDialog = false"></login>
                            </q-dialog>
                    </template>
                    

                    A better name for the event would be ‘loginSucces’ or something since the login component is not aware of it’s parent q-dialog.

                    L 1 Reply Last reply Reply Quote 0
                    • L
                      lesourcil @dobbel last edited by

                      @dobbel

                      Yup it makes sense, but I think I prefer to have my dialog inside my component.

                      And I like your name suggestion for the event.

                      Thx again for your help.

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