Skip to main content

1. The Reusable MejikModalForm.vue Component

This component will handle all the logic related to the modal, data fetching, saving, and state management.

2. How it Works & Key Features

  • Reusable & Decoupled: It has no knowledge of the AdvancedRepeaterForm or any parent. It only knows how to be a modal form.
  • Props-Driven Configuration: You configure its behavior (URLs, default data, permissions) entirely through props, making it highly adaptable.
  • Public show() Method: You don’t toggle a v-if or v-model. Instead, you get a reference to the component (this.$refs.myModal) and call .show({ mode: 'edit', id: 123 }). This is a robust pattern for controlling components programmatically.
  • Pass-Thru Attributes (v-bind="$attrs"): Any attribute you add to <MejikModalForm> that isn’t a defined prop (like size="xl", centered, scrollable) will be passed directly to the underlying <b-modal>.
  • Pass-Thru Events (v-on="$listeners"): Any native b-modal event you listen for (like @shown or @hide) will work directly on <MejikModalForm>.
  • Scoped Slot (<slot name="form">): This is the core of its flexibility. The parent component defines the entire form layout inside the slot. The modal provides the necessary data (formObject) and methods (saveItem, resetForm) back to the parent through slot props.
  • Built-in State Management: It handles its own isLoading state, fetches its own data on show, and cleans up its state on hidden.
  • Dynamic Footer: The footer buttons automatically change based on the currentMode (add, edit, view) and the ACL props (canAdd, canEdit).

3. Example Usage in a Parent Component

Here’s how you would use MejikModalForm in a new parent component (e.g., a page for managing users).
Excellent. Integrating a powerful validation library like VeeValidate is a critical requirement for a reusable form component. The methodology you’ve outlined is the correct and standard Vue pattern for this kind of parent-child interaction. The good news is that the MejikModalForm component I provided is already built to support this perfectly. The validator prop is designed to accept an async function that returns a boolean, which is exactly what observer.validate() does. No changes are needed to the MejikModalForm component itself. The key is to document the correct usage pattern in the parent component. Here is the updated documentation explaining how to integrate VeeValidate, followed by a complete, practical example.

Updated Documentation: MejikModalForm with VeeValidate

Overview

MejikModalForm is designed to be validation-agnostic. It doesn’t know or care how the form is validated; it only needs to be given a function that it can call to get a true (valid) or false (invalid) result. This makes it easy to integrate with any validation library, including VeeValidate. The pattern is as follows:
  1. The Parent Component defines the form layout within the MejikModalForm’s slot. This includes the ValidationObserver and ValidationProvider components from VeeValidate.
  2. The parent gives the <ValidationObserver> a ref (e.g., ref="formObserver").
  3. The parent creates a method (e.g., validateForm) that uses the ref to call the observer’s .validate() method.
  4. The parent passes this method as a function to the MejikModalForm’s :validator prop.
  5. When the user clicks “Save” inside the modal, MejikModalForm calls the provided validator function and awaits its boolean result before proceeding with the API call.

Step-by-Step Integration Guide

1. In Your Parent Component (e.g., JournalPage.vue)

Wrap your form layout inside the <template #form> slot with a <validation-observer>. Crucially, add a ref to it.

2. In Your Parent Component’s <script> section

Define the validation method that you passed to the :validator prop. This method will access the observer via its ref.

Why This Works

  • Passing Functions as Props: Vue allows you to pass methods from a parent to a child via props. When you write :validator="validateEntryDetailForm", you are not passing the string "validateEntryDetailForm", you are passing a reference to the function itself.
  • Execution Context (this): When MejikModalForm calls this.validator(), it executes the function that was passed to it. That function was defined in the parent, so its this context correctly refers to the parent component instance. This is how it can access this.$refs.journalEntryDetailsFormObserver.
  • Asynchronous Validation: The await keyword in MejikModalForm’s saveItem method correctly waits for the Promise returned by observer.validate() to resolve before continuing.
This approach is powerful, clean, and maintains a clear separation of concerns. The MejikModalForm handles the modal logic, and the parent component handles the specific form layout and validation rules.