Update form with select option not selecting the current value

Hello

I’m playing around a bit with livewire and ran into a problem with a form which uses a select dropdown option.
It works fine when I add a new item to the database, but when I try to update an existing record, the dropdown menu is not selecting the current item.

the view:




{{ __(‘Create’) }}

{{-- The data table --}}
<div class="flex flex-col">
	<div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
		<div class="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
			<div class="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
				<table class="min-w-full divide-y divide-gray-200">
					<thead>
						<tr>
							<th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">Asn</th>
							<th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">Organization</th>
							<th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">Sync with PeeringDB</th>
							<th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">As-set</th>
							<th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">Max IPv4 prefixes</th>
							<th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">Max IPv6 prefixes</th>
							<th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider"></th>
						</tr>
					</thead>
					<tbody class="bg-white divide-y divide-gray-200">
						@if ($data->count())
							@foreach ($data as $item)
								<tr>
									<td class="px-6 py-4 text-sm whitespace-no-wrap">{{ $item->asn }}</td>
									<td class="px-6 py-4 text-sm whitespace-no-wrap">{{ $item->organization->name }}</td>
									<td class="px-6 py-4 text-sm whitespace-no-wrap">
										@if($item->sync_with_peeringdb)
											<svg class="h-6 w-6 text-gray-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 27 27" fill="currentColor">
												<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
											</svg>

										@endif
									</td>
									<td class="px-6 py-4 text-sm whitespace-no-wrap">{{ $item->as_set }}</td>
									<td class="px-6 py-4 text-sm whitespace-no-wrap">{{ $item->ipv4_max_prefixes }}</td>
									<td class="px-6 py-4 text-sm whitespace-no-wrap">{{ $item->ipv6_max_prefixes }}</td>
									<td class="px-6 py-4 text-right text-sm">
										<x-jet-button wire:click="updateShowModal({{ $item->id }})">
											{{ __('Update') }}
										</x-jet-button>
										<x-jet-danger-button wire:click="deleteShowModal({{ $item->id }})">
											{{ __('Delete') }}
										</x-jet-danger-button>
									</td>
								</tr>
							@endforeach
						@else
								<tr>
									<td class="px-6 py-4 text-sm whitespace-no-wrap" colspan="6">No results found</td>
								</tr>
						@endif
					</tbody>
				</table>
			</div>
		</div>
	</div>
</div>

<br />

{{ $data->links() }}

{{-- Modal Form --}}
<x-jet-dialog-modal wire:model="modalFormVisible">
	<x-slot name="title">
		{{ __('Save Network') }}
	</x-slot>

	<x-slot name="content">
		<div class="mt-4">
			<x-jet-label for="asn" value="{{ __('asn') }}" />
			<x-jet-input id="asn" class="block mt-1 w-full" type="text" wire:model.debounce.800ms="asn" />
			@error('asn') <span class="error">{{ $message }}</span> @enderror
		</div>
		<div class="mt-4">
			<x-jet-label for="organization" value="{{ __('organization') }}" />
			<select name="organization_id" id="organization_id" class="border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm block mt-1 w-full" wire:model.debounce.800ms="organization">
				<option value="">Select Organization</option>
				@foreach ($organizations as $organization)
					<option value="{{ $organization->id }}">{{ $organization->name }}</option>
				@endforeach
			</select>
			@error('organization_id') <span class="error">{{ $message }}</span> @enderror
		</div>
		<div class="mt-4">
			<x-jet-label for="sync_with_peeringdb" value="{{ __('Sync with PeeringDB') }}" />
			<x-jet-input id="sync_with_peeringdb" class="block mt-1" type="checkbox" wire:model.debounce.800ms="sync_with_peeringdb" />
			@error('sync_with_peeringdb') <span class="error">{{ $message }}</span> @enderror
		</div>
		<div class="mt-4">
			<x-jet-label for="as_set" value="{{ __('as-set') }}" />
			<x-jet-input id="as_set" class="block mt-1 w-full" type="text" wire:model.debounce.800ms="as_set" />
			@error('as_set') <span class="error">{{ $message }}</span> @enderror
		</div>
		<div class="mt-4">
			<x-jet-label for="ipv4_max_prefixes" value="{{ __('ipv4 max prefixes') }}" />
			<x-jet-input id="ipv4_max_prefixes" class="block mt-1 w-full" type="text" wire:model.debounce.800ms="ipv4_max_prefixes" />
			@error('ipv4_max_prefixes') <span class="error">{{ $message }}</span> @enderror
		</div>
		<div class="mt-4">
			<x-jet-label for="ipv6_max_prefixes" value="{{ __('ipv6 max prefixes') }}" />
			<x-jet-input id="ipv6_max_prefixes" class="block mt-1 w-full" type="text" wire:model.debounce.800ms="ipv6_max_prefixes" />
			@error('ipv6_max_prefixes') <span class="error">{{ $message }}</span> @enderror
		</div>
	</x-slot>

	<x-slot name="footer">
		<x-jet-secondary-button wire:click="$toggle('modalFormVisible')" wire:loading.attr="disabled">
			{{ __('Nevermind') }}
		</x-jet-secondary-button>

		@if ($modelId)
			<x-jet-button class="ml-2" wire:click="update" wire:loading.attr="disabled">
				{{ __('Update') }}
			</x-jet-button>
		@else
			<x-jet-button class="ml-2" wire:click="create" wire:loading.attr="disabled">
				{{ __('Create') }}
			</x-jet-button>
		@endif
	</x-slot>
</x-jet-dialog-modal>

{{-- The Delete Modal --}}
<x-jet-dialog-modal wire:model="modalConfirmDeleteVisible">
	<x-slot name="title">
		{{ __('Delete Network') }}
	</x-slot>

	<x-slot name="content">
		{{ __('Are you sure you want to delete this network? Once the network is deleted, all of its resources and data will be permanently deleted') }}
	</x-slot>

	<x-slot name="footer">
		<x-jet-secondary-button wire:click="$toggle('modalConfirmDeleteVisible')" wire:loading.attr="disabled">
			{{ __('Nevermind') }}
		</x-jet-secondary-button>

		<x-jet-danger-button class="ml-2" wire:click="delete" wire:loading.attr="disabled">
			{{ __('Delete Network') }}
		</x-jet-danger-button>
	</x-slot>
</x-jet-dialog-modal>

the component:
<?php

namespace App\Http\Livewire;

use App\Models\Network;
use App\Models\Organization;
use App\Jobs\updateNetwork;

use Illuminate\Validation\Rule;
use Livewire\Component;
use Livewire\WithPagination;

class Networks extends Component
{
use WithPagination;
public $modalFormVisible = false;
public $modalConfirmDeleteVisible = false;
public $modelId;
public $organization;
public $organization_id;
public $asn;
public $sync_with_peeringdb;
public $as_set;
public $ipv4_max_prefixes;
public $ipv6_max_prefixes;

public $organizations = [];

public function rules()
{
	return [
		'asn' => ['required', Rule::unique('networks', 'asn')->ignore($this->modelId)],
	];
}

public function mount()
{
	$this->organizations = Organization::all()->sortBy("name");
	$this->resetPage();
}

public function create()
{
	$this->validate();
	Network::create($this->modelData());
	$this->modalFormVisible = false;
	$this->resetVars();
}

public function read()
{
	return Network::paginate(10);
}

public function update()
{
	$this->validate();
	Network::find($this->modelId)->update($this->modelData());
	$this->modalFormVisible = false;
}

public function delete()
{
	Network::destroy($this->modelId);
	$this->modalConfirmDeleteVisible = false;
	$this->resetPage();
}

public function createShowModal()
{
	$this->resetValidation();
	$this->resetVars();
	$this->modalFormVisible = true;
}

public function updateShowModal($id)
{
	$this->resetValidation();
	$this->resetVars();
	$this->modelId = $id;
	$this->modalFormVisible = true;
	$this->loadModel();
}

public function deleteShowModal($id)
{
	$this->modelId = $id;
	$this->modalConfirmDeleteVisible = true;
}

public function loadModel()
{
	$data = Network::find($this->modelId);
	$this->asn = $data->asn;
	$this->organization_id = $data->organization_id;
	$this->sync_with_peeringdb = $data->sync_with_peeringdb;
	$this->as_set = $data->as_set;
	$this->ipv4_max_prefixes = $data->ipv4_max_prefixes;
	$this->ipv6_max_prefixes = $data->ipv6_max_prefixes;
}

public function modelData()
{
	return [
		'asn' => $this->asn,
		'organization_id' => intVal($this->organization),
		'sync_with_peeringdb' => $this->sync_with_peeringdb,
		'as_set' => $this->as_set,
		'ipv4_max_prefixes' => $this->ipv4_max_prefixes,
		'ipv6_max_prefixes' => $this->ipv6_max_prefixes,
	];
}

public function resetVars()
{
	$this->modelId = null;
	$this->asn = null;
	$this->organization_id = null;
	$this->organization = null;
	$this->sync_with_peeringdb = null;
	$this->as_set = null;
	$this->ipv4_max_prefixes = null;
	$this->ipv6_max_prefixes = null;
}

public function render()
{
    return view('livewire.networks', [
    	'data' => $this->read(),
    ]);
}

}

Any idea on how I could fix this?

greetings
Roel

In the blade you are binding the select to “organization” property that is an Elocuent collection. You have to bind it like “organization_id” that is loaded when you are in editing modal

I updated my blade to:

		<div class="mt-4">
			<x-jet-label for="organization" value="{{ __('organization') }}" />
			<select name="organization_id" id="organization_id" class="border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm block mt-1 w-full" wire:model.debounce.800ms="organization_id">
				<option value="">Select Organization</option>
				@foreach ($organizations as $organization)
					<option value="{{ $organization->id }}">{{ $organization->name }}</option>
				@endforeach
			</select>
			@error('organization_id') <span class="error">{{ $message }}</span> @enderror
		</div>

This now shows the selected organization, but when pressing the save button it’s throwing an exception because it tries to update the id to 0.

Check on update method what data is going to be updated when call $this->modelData()…I mean, make a dd and check what is happening in

'organization_id' => intVal($this->organization),

Thanks! I got it fixed by changing this->organization to $this->organization_id

1 Like

I’m glad you fix your issue. :blush: If you can, make this post solved. :ok_hand: