How to use the K-Dialog component

Hello,

can somebody tell me whats wrong with my k-dialog component ^^ - I tried using the Lab but the examples and documentation is not helping :smiley:

      <k-dialog :visible="showCustomerDialog" size="medium" @close="closeCustomerDialog" @cancel="closeCustomerDialog">
        <template #default>
          <k-dialog-body>
            <k-headline class="h5">{{ $t('embed_footer_control.edit_customer') || 'Kunde bearbeiten' }}</k-headline>
            <div class="stack">
              <k-text-field :label="$t('embed_footer_control.customer_name') || 'Name des Kunden'"
                v-model="customerForm.clientName" disabled />
              <k-text-field :label="$t('embed_footer_control.customer_domain') || 'Domain'"
                v-model="customerForm.clientDomain" />
              <k-toggle-field :label="$t('embed_footer_control.customer_enabled') || 'Aktiv'"
                :text="[$t('embed_footer_control.disabled'), $t('embed_footer_control.enabled')]"
                :value="customerForm.enabled" @input="customerForm.enabled = $event" />
              <k-toggle-field :label="$t('embed_footer_control.customer_locked') || 'Gesperrt'"
                :text="[$t('embed_footer_control.disabled'), $t('embed_footer_control.enabled')]"
                :value="customerForm.locked" @input="customerForm.locked = $event" />
            </div>
          </k-dialog-body>
          <k-dialog-buttons :cancel-button="true" :submit-button="true" :disabled="isSavingCustomer"
            @submit="saveCustomer">
            <template #submit>
              <k-button theme="positive" icon="check" :disabled="isSavingCustomer" @click="saveCustomer">
                {{ $t('embed_footer_control.save_short') || 'Speichern' }}
              </k-button>
            </template>
          </k-dialog-buttons>
        </template>
      </k-dialog>

even if :visible is set to true it is not visible :frowning:

Thanky for the help ^^

How are you opening your custom dialog in code?

It is a simple bool inside my data() function

data() {
    return {
      current_tab: "overview",
      tab_list: [
        { name: "overview", label: this.$t('embed_footer_control.overview'), badge: 0 },
        { name: "settings", label: this.$t('embed_footer_control.settings'), badge: 0 },
      ],
      showAddCustomer: false,
      sites: this.sites,
      isLoadingSites: false,
      isSavingCustomer: false,
      showCustomerDialog: false,
[...]

this variable is set by another function which is triggered by a button (the console.log call works)

openCustomer(site) {
      console.log("Open customer " + site.clientName);
      this.selectedCustomer = site;
      this.customerForm = {
        kunde: site.kunde,
        clientName: site.clientName,
        clientDomain: site.clientDomain,
        enabled: site.enabled,
        locked: site.locked ?? false,
      };
      this.showCustomerDialog = true;
    },

That won’t work. Defining your dialog component and opening the dialog are two separate things. So you can define your custom dialog and register it as component

panel.plugin("your/plugin", {
  components: {
    "my-custom-dialog": {
      // ...
    }
  }
})

And then to open the dialog you have to use this.$panel.dialog.open(), e.g. as done here: kirby/panel/src/components/Forms/Blocks/Block.vue at main ¡ getkirby/kirby ¡ GitHub

EDIT: To give some background why just setting :visible doesn’t work: k-dialog portals/teleports its elements to the dialog overly in the document. This is however only rendered if the $panel.dialog is aware of the dialog, e.g. by using this.$panel.dialog.open().

Ah nice, thank you :slight_smile:

If somebody else needs the solution a bit more clear →

In index.js a new component needs to be defined:

import MissionControl from "./components/MissionControl.vue";
import CustomerDialog from "./components/CustomerDialog.vue";

panel.plugin("nodework/embed-footer-control", {
  components: {
    missioncontrol: MissionControl,
    customerDialog: CustomerDialog,
  },
});

In my example the “customerDialog”.

The customer Dialog is a normal component that only defines the k-dialog component:

<template>
  <k-dialog
    v-bind="$props"
    @submit.prevent="handleSubmit"
    @cancel="$emit('cancel')"
    @close="$emit('close')"
  >
    <k-dialog-body>
      <k-headline class="h3">{{ title }}</k-headline>
      <br/>
      <div class="stack">
        <k-text-field
          :label="labels.name"
          v-model="value.clientName"
        />
        <k-text-field
          :label="labels.domain"
          v-model="form.clientDomain"
        />
        <k-toggle-field
          :label="labels.enabled"
          :text="toggleText"
          :value="form.enabled"
          @input="form.enabled = $event"
        />
        <k-toggle-field
          :label="labels.locked"
          :text="toggleText"
          :value="form.locked"
          @input="form.locked = $event"
        />
      </div>
    </k-dialog-body>

  </k-dialog>
</template>

<script>

export default {
  props: {
    size: {type: String},
    title: {type: String},
    submitLabel: { type: String},
    toggleText: { type: Array},
    labels: {type: Object},
    value: {type: Object}
  },
  data() {
    return {
      title: this.title,
      form: { ...this.value },
    };
  },
  watch: {
    value: {
      deep: true,
      handler(newVal) {
        this.form = { ...newVal };
      },
    },
  },
methods: {
    handleSubmit() {
      this.$emit("submit", { ...this.form });
    },
  },
};

And this component can be called inside the main component:

    openCustomer(site) {
      this.selectedCustomer = site;

      this.$panel.dialog.open({
        component: "customer-dialog",
        props: {
          size: "huge",
          title: this.$t("embed_footer_control.customer.edit_customer") || "Kunde bearbeiten",
          submitLabel: this.$t("embed_footer_control.save_short") || "Speichern",
          toggleText: [
            this.$t("embed_footer_control.disabled"),
            this.$t("embed_footer_control.enabled"),
          ],
          labels: {
            name: this.$t("embed_footer_control.customer_name") || "Name des Kunden",
            domain: this.$t("embed_footer_control.customer_domain") || "Domain",
            enabled: this.$t("embed_footer_control.customer_enabled") || "Aktiv",
            locked: this.$t("embed_footer_control.customer_locked") || "Gesperrt",
          },
          value: {
            clientName: site.clientName,
            clientDomain: site.clientDomain,
            enabled: site.enabled,
            locked: site.locked ?? false,
          },
        },
        on: {
          submit: (values) => this.saveCustomer(values),
          cancel: () => this.$panel.dialog.close(),
          close: () => this.$panel.dialog.close(),
        },
      });
    },

Hope if somebody is a starter like me this will help figuring it out a bit faster :smiley: