webdevpuneet.com

Leaflet Location Picker (Click to Set Coordinates) — Free Snippet

Leaflet Location Picker (Click to Set Coordinates) · Forms · Plain HTML, CSS & JS · Live preview

CategoryForms

Copy & paste

Source Code

<div class="lp-wrap">
  <div class="lp-form">
    <h1>Set Pickup Location</h1>
    <label class="lp-field">Latitude
      <input type="text" id="lpLat" placeholder="Click the map">
    </label>
    <label class="lp-field">Longitude
      <input type="text" id="lpLng" placeholder="Click the map">
    </label>
    <label class="lp-field">Address (search)
      <input type="text" id="lpSearch" placeholder="Type an address or place...">
      <div class="lp-suggestions" id="lpSuggestions"></div>
    </label>
    <p class="lp-hint" id="lpHint">Click anywhere on the map, drag the pin, or search an address above.</p>
    <button class="lp-confirm" id="lpConfirm" type="button" disabled>Confirm Location</button>
  </div>
  <div class="lp-map" id="lpMap"></div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Four synced input paths
Click, drag, type, or search — one function updates all state.
Validated manual entry
Typed coordinates are range-checked before moving anything.
Local place-search demo
Same UX pattern a real geocoding API integration would use.
Outside-click dismissal
Suggestions close like a real autocomplete, not just on select.
Bidirectional pin and form
Moving either one always updates the other.
Free OpenStreetMap tiles
No API key or paid map provider required.

About this UI Snippet

Leaflet Location Picker — Four Inputs, One Coordinate, No Way to Disagree

Screenshot of the Leaflet Location Picker (Click to Set Coordinates) snippet rendered live

A location picker that only supports clicking the map is missing half its users — some already know the exact coordinates, some know an address, and some just want to drag a pin to fine-tune a rough guess. This snippet supports all four paths (map click, pin drag, typed coordinates, and place search) by routing every one of them through a single setLocation(lat, lng, pan) function, so no path can produce a state the others don't recognize.

One function, four callers

Clicking the map, finishing a drag, selecting a search suggestion, and typing valid coordinates all eventually call setLocation — it's the only place that updates the latitude/longitude inputs, moves or creates the marker, and enables the confirm button. That's what guarantees the form fields and the map pin can never show two different locations at once, regardless of which interaction the user chose.

Manual coordinate entry is validated before it moves anything

Typing into the latitude or longitude field doesn't move the pin on every keystroke — it validates on change (when the field loses focus or Enter is pressed), checking both that the values parse as numbers and that they fall within real coordinate ranges (-90 to 90, -180 to 180) before calling setLocation. An invalid or incomplete entry simply doesn't move anything, rather than crashing or panning to NaN, NaN.

The place search is a local filter, not a live geocoding call

To keep the demo self-contained and free of network dependencies inside the sandboxed preview, search matches against a small fixed list of named places rather than a real geocoding API — the interaction pattern (type, see suggestions, click one, pin moves and map flies there) is exactly what a real fetch-based geocoder integration would look like, with the local array standing in for the API response.

Suggestions close on outside click, not just on selection

A document-level click listener closes the suggestions dropdown whenever a click lands outside the search field's container — the kind of small interaction detail (matching what every real autocomplete does) that's easy to skip and immediately feels unfinished without it.

Reusing it

Swap the local PLACES array for a real geocoding API call (Nominatim, Mapbox, Google) inside the same input handler, keep the rest of the four-way sync exactly as is, and this becomes a production-ready address picker for checkout flows, pickup/dropoff selection, or any form that needs a precise geographic point.

Step by step

How to Use

  1. 1
    Add the Leaflet CDNLoad leaflet.css and leaflet.js before the snippet's JS runs.
  2. 2
    Paste HTML, CSS, and JSA form and map render side by side, both empty.
  3. 3
    Click anywhere on the mapA pin drops and the coordinate fields fill in.
  4. 4
    Drag the pinThe coordinate fields update live as you move it.
  5. 5
    Type coordinates directlyTab or click away to move the pin to that exact point.
  6. 6
    Search a place namePick a suggestion to fly the map there and drop the pin.

Real-world uses

Common Use Cases

Delivery address refinement
Let a customer fine-tune a delivery pin by clicking the map, dragging the marker, typing coordinates or searching for a place name.
Ride-share pickup points
Offer a map and form entry for pickup spots, with all four input paths calling a single function that updates every piece of state.
Property listing coordinates
Place a property accurately in an admin tool, range-checking typed latitude and longitude before the marker moves anywhere.
Event and venue setup
Let an organiser set a venue location, with a place-search demo that follows the pattern a real geocoding API integration would use.
Geofence configuration
Pair with the Leaflet draw radius selector so a point is chosen first and a service area is drawn around it.

Got questions?

Frequently Asked Questions

Every interaction path — clicking the map, dragging the pin, selecting a search result, or typing valid coordinates — ultimately calls the same setLocation function, which is the only code that updates the latitude/longitude input values, moves or creates the marker, and enables the confirm button. Because there is exactly one function responsible for that state, no interaction path can leave the form and the map pin showing different locations.

The manual-entry handler runs on the field's change event and checks that both values parse as real numbers and fall within valid coordinate ranges (latitude between -90 and 90, longitude between -180 and 180) before calling setLocation. If the check fails — an empty field, non-numeric text, or an out-of-range value — nothing happens: the pin stays where it was rather than jumping to an invalid or NaN position.

No — to keep this snippet self-contained and free of network calls inside a sandboxed preview, it searches against a small fixed local array of named places. The interaction it demonstrates (type, see filtered suggestions, click one, the map flies there and the pin drops) is exactly the pattern you would wire up to a real geocoding API's search endpoint, with the local array simply standing in for that API's response.

The marker's drag event (which fires continuously throughout the gesture) reads the marker's current position on every frame of the drag and writes it straight into the latitude and longitude fields. Using dragend instead would leave the form fields stale and out of sync with the pin's actual position for the entire duration of the drag, which reads as a bug even if it self-corrects at the end.

Replace the local PLACES.filter() logic inside the search input's handler with a fetch call to a real geocoding API (Nominatim, Mapbox Geocoding, Google Places), map its response results into the same { label, lat, lng } shape the suggestions list already expects, and everything downstream — rendering suggestions, selecting one, flying the map, dropping the pin — needs no other changes.