Map

Devisto provides the built-in <x-map />, <x-map-marker /> and <x-places-autocomplete /> components that you can use in your views and Livewire components to build map functionalities.

First thing you must know: a map without a height or aspect ratio won't render anything:

{{-- ❌ Won't show anything --}}
<x-map>...</x-map>

{{-- ✅ You must give it an explicit height or aspect ratio --}}
<x-map class="h-96">...</x-map>
<x-map class="aspect-w-4 aspect-h-3">...</x-map>

A simple map to show your location can be built like this:

<x-map class="aspect-w-4 aspect-h-3">
    <x-map-marker location="6th Avenue, New York">
        Here is our shop!
    </x-map-marker>
</x-map>

If you have a table with locations, make sure you have a Geo field with the coordinates of the locations. Then you can make a map and use a loop for the markers:

<x-map class="aspect-w-4 aspect-h-3">
    @foreach (table('locations')->get() as $location)
        <x-map-marker :location="$location->coordinates">
            {{ $location->title }}
        </x-map-marker>
    @endforeach
</x-map>

If you want to add search functionality, you'll have to create a Livewire component:

<div>
    <div class="bg-gray-200 aspect-w-4 aspect-h-3 mb-4">
        @if ($dealers->isNotEmpty())
            <x-map>
                @foreach ($dealers as $dealer)
                    <x-map-marker :location="$dealer->coordinates">
                        <strong>{{ $dealer->name }}</strong><br>
                        {{ $dealer->address }}<br>
                        {{ $dealer->zip }} {{ $dealer->city }}
                    </x-map-marker>
                @endforeach
            </x-map>
        @else
            <div class="flex items-center justify-center">
                No dealers found.
            </div>
        @endif
    </div>

    <form wire:submit.prevent="$refresh" class="flex space-x-4">
        <x-places-autocomplete country="us" wire:model.defer="location" class="form-input flex-1" placeholder="Enter a location" />

        <select wire:model="radius" class="form-select">
            <option value="10">10 km</option>
            <option value="20">20 km</option>
            <option value="50">50 km</option>
        </select>

        <button type="primary" wire:loading.class="opacity-50">
            Search
        </button>
    </form>
</div>

<?php

class DealerFinder extends Component
{
    public $location = '';
    public $radius = 10;

    protected $queryString = ['location', 'radius'];

    // Add this listener to listen to changes in the <x-places-autocomplete /> component
    protected $listeners = ['placeChanged'];

    public function placeChanged($location)
    {
        $this->location = $location;
    }

    public function renderData()
    {
        return [
            'dealers' => table('dealers')->near($this->location, $this->radius)->get(),
        ];
    }
}
Previous topic
← Breadcrumbs
Next topic
Contact Form →