Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

drewdan's avatar
Level 15

Livewire Jetstream Modal Unloading Incorrectly

Hi Guys,

I am having some weird behaviour with a modal and livewire. I have a modal which is a copy pasta of the jetstream modal, although jetstream isn't actually installed in this particular repo, I have copied a fair few of the components across. The modal looks like this:

<div>
		<x-jet.dialog-modal
			wire:model="updateStatusModal"
			wire:key="update-status-modal"
		>
			<x-slot name="title">
				Update Selected Order Status
			</x-slot>
			<x-slot name="content">
				<div class="flex flex-col gap-4">
					<div class="flex flex-col gap-2">
						<x-jet.label for="name" value="Name"/>
						<select
							wire:model="updateStatusValue"
							class="border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm"
						>
							@foreach($orderStatuses as $status)
								<option value="{{ $status->id }}">{{ $status->name }}</option>
							@endforeach
						</select>
						<x-jet.input-error for="award.name"/>
					</div>
					<div class="flex justify-between gap-2">
						<x-jet.label for="notify" value="Notify Customer"/>
						<div>
							<x-jet.checkbox
								class="z-20 relative"
								wire:model.defer="notifyCustomer"
								id="notify"
								wire:key="notify-customer"
							/>
						</div>
					</div>
					<x-jet.validation-errors/>
				</div>
			</x-slot>
			<x-slot name="footer">
				<x-jet.button
					wire:click="updateStatus"
				>
					Update Status
				</x-jet.button>
			</x-slot>
		</x-jet.dialog-modal>
	</div>

The underlying code for the jetstream modal has not changed and was copied from Jetstream 2.10.

The underlying class has these props:

class Dashboard extends Component {

	use WithPagination, TogglesModals, WithBannerNotifications;

	public array $deliveryMethods;
	public $orderStatuses;
	public $deliveryMethod;
	public $orderStatus;
	public array $selected = [];
	public int $updateStatusValue = 0;
	public bool $notifyCustomer = true;
	public bool $updateStatusModal = false;

When we load the modal, we get the form, with the checkbox already being ticked, as the value is true. When you untick the checkbox, Livewire is updating the props for both notifyCustomer and updateStatusModal to be false.

I have tried:

  • adding wire keys
  • wrapping extra divs around the modal and around the checkbox input
  • not typing the props as bools

No matter what I do, unticking the notifyCustomer checkbox always results in both props being updated to false.

I suspect I am overlooking something, or have made a silly error. If anyone can nudge me in the right directions, I'd be most grateful.

Thanks :)

0 likes
2 replies
drewdan's avatar
Level 15

OK, so plot thickens, or maybe this explains a little more.

Anything in the form being injected into the modal is triggering an update of the updateStatusModal value. So the selectbox I have is also updating the updateStatusModal value. I just did not notice before, as it was always a not null value, so it never closed the modal.

drewdan's avatar
drewdan
OP
Best Answer
Level 15

Transpires, at some point, I did a brain fart and did something stupid.

Putting the cause of the issue here, so if anyone ends up here via Google in the future (probably going to be me ending up back here), it might just help them too.

In the dialog-modal blade component, I seemingly misunderstood that the {{ $attrributes->merge()}} did and ended up with something like this:

@props(['id' => null, 'maxWidth' => null])

<x-jet.modal :id="$id" :maxWidth="$maxWidth" {{ $attributes }}>
    <div {{ $attributes->merge(['class' => 'px-6 py-4']) }}>
        <div class="text-lg">
            {{ $title }}
        </div>

        <div class="mt-4">
            {{ $content }}
        </div>
    </div>

    <div class="flex flex-row justify-end px-6 py-4 bg-gray-100 text-right">
        {{ $footer }}
    </div>
</x-jet.modal>

The extra attributes->merge() was also adding the wire model to this DIV, which was picking up the values of the inputs being passed into the content variable. I must have wanted to override the class of the div, in this case, I did a whole lot more.

Returning this to its original state:

@props(['id' => null, 'maxWidth' => null])

<x-jet.modal :id="$id" :maxWidth="$maxWidth" {{ $attributes }}>
    <div class="px-6 py-4">
        <div class="text-lg">
            {{ $title }}
        </div>

        <div class="mt-4">
            {{ $content }}
        </div>
    </div>

    <div class="flex flex-row justify-end px-6 py-4 bg-gray-100 text-right">
        {{ $footer }}
    </div>
</x-jet.modal>

Fixed the issue, as the wire:model was being set in the correct place.

Please or to participate in this conversation.