owlondrugsmobile's avatar

How make crud page with modals?

How to make modal windows based on inertia v2 correctly? I tried making them with an ajax request. I also tried to use the philosophy of inertia and return all the page data through the passes, using the same page for rendering. But I still can't figure out how to simplify this process.

0 likes
7 replies
LaryAI's avatar
Level 58

Certainly! Here’s a suggested solution for handling CRUD pages with modals in Inertia.js v2 (commonly with Laravel + Vue/React/Svelte). The recommended “Inertia way” is to treat modals as part of your page state, not separate requests or views. This makes navigation (including opening modals via links) possible and works seamlessly with browser navigation.

Below is a general approach (using Vue as an example):


1. Modal State via Query Strings

When a user triggers a modal (Create/Edit/etc), update the browser URL (with Inertia.visit) to include something like ?modal=create or ?modal=edit&id=1.

2. Controller Handles Modal Data

In your controller, detect if a modal is requested (look for those query params), then pass the necessary data (e.g., record to edit) to the Inertia page props.

Example Controller:

public function index(Request $request)
{
    $items = Item::all(); // Or paginate

    $modal = $request->query('modal');
    $modalData = null;

    if ($modal === 'edit' && $request->has('id')) {
        $modalData = Item::findOrFail($request->input('id'));
    }

    return Inertia::render('Items/Index', [
        'items' => $items,
        'modal' => $modal,
        'modalData' => $modalData,
    ]);
}

3. Page Handles Modal Rendering

In your Vue component, reactively watch the modal prop and render the modal accordingly.

<template>
  <div>
    <ItemTable :items="items" @edit="openEdit" />
    <Modal v-if="modal === 'edit'" @close="closeModal">
      <EditItemForm :item="modalData" @saved="closeModal" />
    </Modal>
  </div>
</template>

<script>
export default {
  props: {
    items: Array,
    modal: String,
    modalData: Object,
  },
  methods: {
    openEdit(item) {
      this.$inertia.visit(route('items.index', { modal: 'edit', id: item.id }), { preserveScroll: true, preserveState: true })
    },
    closeModal() {
      this.$inertia.visit(route('items.index'), { preserveScroll: true, preserveState: true })
    }
  }
}
</script>

4. No AJAX, No Extra Pages

No need for separate AJAX requests or additional page files. Everything flows through Inertia and is managed as page state.


Benefits:

  • Browser back/forward just works (modals open/close as expected).
  • SEO and shareable links (you can share a link to items?modal=edit&id=1).
  • Keeps to “Inertia Philosophy”: server returns full page state, not partials/fragments.

Summary:

  1. Use query params to represent modal state.
  2. Handle modal data fetching server-side in your controller.
  3. Render modals in your client page based on Inertia props.
  4. Use Inertia navigation for opening/closing modals.

Let me know if you want a more detailed code example with Create/Update/Delete flows!

owlondrugsmobile's avatar

Yes, I need a more detailed explanation. I use it. Select you have users, you have roles (space). I need dictionaries with roles to be loaded to the main page via the controller for subsequent filtering. Using the create/edit route, I load either an empty modal or a modal with props embedded in it by sending Inertia::render to the same page with additional modal array data. How to do all these routes correctly and how to organize the architecture and code correctly? I noticed that when loading the create/edit pages, if we upload all the data again, there is a delay.

JussiMannisto's avatar

A modal is just a UI component on a page. It doesn't require any special architecture. You can implement normal CRUD routes while controlling the modal state in the UI code.

How to do all these routes correctly and how to organize the architecture and code correctly?

You're asking for someone to design the feature for you without seeing any of your code. If you want pointers, you're more likely to get help if you post your current solution.

I noticed that when loading the create/edit pages, if we upload all the data again, there is a delay.

What do you mean by this? There's always some delay when submitting data or loading pages over the internet.

owlondrugsmobile's avatar

My controller:

Vue page:

This works, but this approach reloads the page, and if the table is complex or has a lot of data, it takes significantly longer to load.

As I mentioned above, I tried using Ajax requests, but then the application starts using two approaches: one is Ajax, the other is Inertia.

This works, but this approach reloads the page and if the table is complex or there is a lot of data, it takes a noticeable amount of time to load.

I have also tried loading additional data using only[] and preserveUrl, but when validation errors occur, the page breaks instantly due to Laravel's back() function.

owlondrugsmobile's avatar

It looks interesting. But how can I make vue open the page as a modal? Using additional resolve?

Tray2's avatar

You can always give Filament a try, it includes modal support out of the box, you basically just need to remove one line of code to make it a modal.

https://filamentphp.com/

Please or to participate in this conversation.