Add Events to a Mapbox map via PHP
 
                Adding a map to your application is very easy to do these days. You might use the more popular google maps, but Mapbox makes this process really simple. In order to create a map, you will use Javascript, but to save and provide data for the map we will use php.
Video Guide:
Source Code:
GitHub - mbouldo/mapbox-events-php: Add events to a map via mapbox & retrieve data async via JS and PHP
Add events to a map via mapbox & retrieve data async via JS and PHP - GitHub - mbouldo/mapbox-events-php: Add events to a map via mapbox & retrieve data async via JS and PHP
Helpful Links:
Maps | Mapbox
Unparalleled speed and customization to visualize your world.

Documentation
Examples, tutorials, and API references to help you start building with Mapbox.

Installation | Mapbox GL JS
Get started with Mapbox GL JS.

Written Guide:
Basic Pages, and styles
Basic HTML
<div class="flex font-sans">
    <!-- SIDEBAR -->
    <div class="w-1/5 bg-gray-900 h-screen">
        <!-- LOGO -->
        <div class="flex justify-center pt-8 pb-8 border-b border-b-white">
            <img src="../dist/mapbox-logo-white.svg" class="h-14" />
        </div>
        <!-- HEADING -->
        <h3 class="text-white font-bold  text-center text-3xl mt-8 flex items-center w-full justify-center">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"
                stroke-width="2">
                <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
            </svg>
            Add an Event
        </h3>
        <!-- ADD EVENT FORM -->
        <div class="mb-6 w-5/6 mx-auto mt-12">
            <label for="eventName" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">Event Name</label>
            <input type="text" id="eventName" class="input-field" placeholder="DC Event" required>
        </div>
        <div class="mb-6 w-5/6 mx-auto mt-6">
            <label for="eventDescription" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">Event
                Description</label>
            <input type="text" id="eventDescription" class="input-field" placeholder="There will be very cool refreshments"
                required>
        </div>
        
        <div class="mb-6 w-5/6 mx-auto mt-6">
            <label for="geocoder" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">Event Address</label>
            <div id="geocoder"></div>
        </div>
        
        <div class="w-5/6 mx-auto flex justify-end">
            <button type="button" class="submit-button" onclick="addEvent()">Add Event</button>
        </div>
    </div>
    <!-- MAP -->
    <div class="h-screen w-full" id="map"></div>
</div>Styles
mapbox-events-php/output.css at main · mbouldo/mapbox-events-php
Add events to a map via mapbox & retrieve data async via JS and PHP - mapbox-events-php/output.css at main · mbouldo/mapbox-events-php
Header Dependencies
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=Poppins:wght@400;500;600;700;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v5.0.0/mapbox-gl-geocoder.css" type="text/css">
<link href="../dist/output.css" rel="stylesheet">Mapbox, JQuery Dependencies
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src='https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.css' rel='stylesheet' />
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v5.0.0/mapbox-gl-geocoder.min.js"></script>Initialize Your Map (In a script tag)
mapboxgl.accessToken = 'YOUR_MAPBOX_TOKEN_HERE';
var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v11',
    center: [-77.04, 38.907],
    zoom: 11.15
});Get Events Data & Add to Map
Load an icons layer onto your map
map.on('load', function () {
    //place object we will add our events to
    map.addSource('places',{
        'type': 'geojson',
        'data': {
            'type': 'FeatureCollection',
            'features': []
        }
    });
    //add place object to map
    map.addLayer({
        'id': 'places',
        'type': 'symbol',
        'source': 'places',
        'layout': {
            'icon-image': '{icon}',
            'icon-allow-overlap': true
        }
    });
    //Handle popups
    map.on('click', 'places', (e) => {
        const coordinates = e.features[0].geometry.coordinates.slice();
        const description = e.features[0].properties.description;
        while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
            coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
    }
    new mapboxgl.Popup()
        .setLngLat(coordinates)
        .setHTML(description)
        .addTo(map);
    });
    //Handle pointer styles
    map.on('mouseenter', 'places', () => {
        map.getCanvas().style.cursor = 'pointer';
    });
    map.on('mouseleave', 'places', () => {
        map.getCanvas().style.cursor = '';
    });
    //get our data from php function
    //getAllEvents();
});Async get events data from PHP
function getAllEvents(){
    $.ajax({
        url: "../api/getAllEvents.php",
        contentType: "application/json",
        dataType: "json",
        success: function (eventData) {
            console.log(eventData)
            map.getSource('places').setData({
                    'type': 'FeatureCollection',
                    'features': eventData
            });
        },
        error: function (e) {
            console.log(e);
        }
    });
}Create a new database

Add an events table

Create your id, event, lat, lng columns, name, and description

Your table should look like this:

Connect your PHP file that handles events to your DB
<?php
$db = "mapboxevents";
$host = "localhost";
$user = 'USERNAME';
$pass = 'PASSWORD';
//PDO Connection
try {
    $pdo = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    //echo "Connected successfully";
}
catch(PDOException $e){
    //echo "Connection failed: " . $e->getMessage();
}
function p($arr){
    echo "<pre>";
        print_r($arr);
    echo "</pre>";
}Get event data from your events table
$sql = "SELECT * FROM events";
try {
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
    die($e);
}Morph your $data from mySQL Into json Mapbox can use
foreach ($data as $key => $eventData) {
    $returnData[] = [
        'type' => 'Feature'.$eventData['id'],
        'properties' => [
            'description' => '<strong>'.$eventData['name'].'</strong><p>'.$eventData['description'].'</p>',
            'icon' => 'rocket-15'
        ],
        'geometry' => [
            'type' => 'Point',
            'coordinates' => [$eventData['lat'], $eventData['lng']]
        ]
    ];
}Set your headers to support json, and echo out your json
//top of file
header('Content-Type: application/json; charset=utf-8');
include('db.php');
//bottom of file
echo json_encode($returnData);Test your first event, by adding it into your mySQL
INSERT INTO `events` (`id`, `name`, `description`, `lat`, `lng`) VALUES (NULL, 'Manual mySQL', 'Test mySQL event', '-77.0877945', '38.937867');
Add events to your database:
Your php file will contain a simple PDO sql statement that will insert all of the posted variables, including name, description, lat, and lng
PHP Process File that will add to DB
<?php
// api/createEvent.php
include('db.php');
if(isset($_POST['name'])){
    $sql = "INSERT into events (name,description,lat,lng) VALUES (:name,:description,:lat,:lng)";
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            'name'=>$_POST['name'],
            'description'=>$_POST['description'],
            'lat'=>$_POST['lat'],
            'lng'=>$_POST['lng'],
        ]);
        echo json_encode('success');
    
    } catch (Exception $e) {
        die($e);
    }
}
Async JavaScript file to call your API file
function addEvent(){
    $.ajax({
        url: "../api/createEvent.php",
        type:'POST',
        data:postObj,
        dataType: "json",
        success: function (resp) {
            
        },
        error: function (e) {
            console.log(e);
        }
    });
}Initialize Your Geocoder to get lat, lng data
const geocoder = new MapboxGeocoder({
    accessToken: mapboxgl.accessToken,
});
geocoder.addTo('#geocoder');
var geocoderResult = {};
geocoder.on('result', (e) => {
    geocoderResult = e.result, null, 2;
});
// Clear results container when search is cleared.
geocoder.on('clear', () => {
    geocoderResult = {};
});
Validate if geocoder is set & set postData
    if(geocoderResult=={}){
        return false;
    }
    var postObj = {
        name:$("#eventName").val(),
        description:$("#eventDescription").val(),
        lat:geocoderResult.center[0],
        lng:geocoderResult.center[1],
    }Handle success when event is created
//reset form & get new data
$("#eventName").val('');
$("#eventDescription").val('');
geocoder.clear();
getAllEvents(); 
        

