Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Implement Leaflet on rails with stimulus
Ankit Pariyar
Ankit Pariyar

Posted on

     

Implement Leaflet on rails with stimulus

Set up basic rails app

  • we will use database PostgreSQL, esbuild to bundle the project's JavaScript, and TailwindCSS for its CSS. We'll also skip installing a test framework by passing the -T flag.
rails new leaflet_map-T-d postgresql--css=tailwind--javascript=esbuildcdleaflet_maprails db:create
Enter fullscreen modeExit fullscreen mode
  • Configure Tailwind: Inapplication.tailwind.css replace the@tailwinddirectives with@import
@import"tailwindcss/base";@import"tailwindcss/components";@import"tailwindcss/utilities";
Enter fullscreen modeExit fullscreen mode

Create basic MVC

  • createPlace model which will have longitude, latitude and name attributes
rails g model Place name:string longitude:float latitude:floatrails db:migrate
Enter fullscreen modeExit fullscreen mode
  • add simple validation for name, longitude and latitude onPlace model
classPlace<ApplicationRecordvalidates:name,presence:truevalidates:latitude,numericality:{greater_than_or_equal_to:-90,less_than_or_equal_to:90}validates:longitude,numericality:{greater_than_or_equal_to:-180,less_than_or_equal_to:180}end
Enter fullscreen modeExit fullscreen mode
  • updateseed.rb file to create some data for places
Place.create(name:'Place-1',longitude:-70.06,latitude:39.35)Place.create(name:'Place-2',longitude:-55.30,latitude:35.20)Place.create(name:'Place-3',longitude:-80.20,latitude:25.20)Place.create(name:'Place-4',longitude:-90.20,latitude:15.20)
Enter fullscreen modeExit fullscreen mode
  • Runrails db:seed to seed data

  • CreatePlacesController

rails g controller Places index
Enter fullscreen modeExit fullscreen mode

it will createPlacesController with index action as well as view files for index

  • UpdatePlacesController to show list of places
classPlacesController<ApplicationControllerdefindex@places=Place.allendend
Enter fullscreen modeExit fullscreen mode
  • Also, updateroute.rb to make that index, home page
Rails.application.routes.drawdoroot'places#index'end
Enter fullscreen modeExit fullscreen mode

To test that every thing is working so far, run rails server withbin/rails and go tolocalhost
You can see default view provided byviews/places/index.html.erb

Create basic map with leaflet

  • install leaflet
yarn add leaflet
Enter fullscreen modeExit fullscreen mode
  • updateviews/layouts/index.html.erb
<!DOCTYPE html><html><head><title>LeafletMap</title><metaname="viewport"content="width=device-width,initial-scale=1"><%=csrf_meta_tags%><%=csp_meta_tag%><%=stylesheet_link_tag"application","data-turbo-track":"reload"%><%=javascript_include_tag"application","data-turbo-track":"reload",defer:true%></head><body><mainclass="container mx-auto mt-28 px-5"><%=yield%></main></body></html>
Enter fullscreen modeExit fullscreen mode

We just wrap main content that is<%= yield %> with<main> just to give it a little bit style

  • Updateviews/places/index.html.erb this is place where we will display our map
<divclass="w-full"><h1class="font-bold text-4xl mb-2">Places</h1><divdata-controller="maps"><divdata-maps-target="container"class="h-[75vh] w-auto"></div></div></div>
Enter fullscreen modeExit fullscreen mode

The main things you need to focus here isdata-controller="map" indicates stimulus controller anddata-map-target="container" this allow us to definecontainerTarget on our map stimulus controller

  • Generate map stimulus controller
rails g stimulus map
Enter fullscreen modeExit fullscreen mode
  • updatemap_controller.js
import{Controller}from"@hotwired/stimulus"importLfrom"leaflet"exportdefaultclassextendsController{statictargets=["container"]connect(){this.createMap()this.map.setView([27.700769,85.300140],12);}createMap(){this.map=L.map(this.containerTarget)L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png',{maxZoom:19,attribution:'&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'}).addTo(this.map);}disconnect(){this.map.remove();}}
Enter fullscreen modeExit fullscreen mode

Here, first we import L from leaflet.when our element with attributedata-controller = "map" enters DOMconnect will be called in which we usecreateMap function to create map.

With linestatic targets = ["container"] we add container target which we defined in our HTML withdata-map-target="container" now that element can be access withthis.containerTarget

Inside ofcreateMap() function with linethis.map = L.map(this.containerTarget) we initialize empty map insidecontainerTarget element and we added tile layer to our map withL.tileLayer

After creating map and adding tile, we set map's view to Kathmandu, Nepal with linethis.map.setView([27.700769, 85.300140], 12)

  • Add<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI=" crossorigin=""/> inside head section ofapplication.html.erb file for styling map
<!DOCTYPE html><html><head><title>LeafletMap</title><metaname="viewport"content="width=device-width,initial-scale=1"><%=csrf_meta_tags%><%=csp_meta_tag%><%=stylesheet_link_tag"application","data-turbo-track":"reload"%><linkrel="stylesheet"href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css"integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI="crossorigin=""/><%=javascript_include_tag"application","data-turbo-track":"reload",defer:true%></head><body><mainclass="container mx-auto mt-28 px-5"><%=yield%></main></body></html>
Enter fullscreen modeExit fullscreen mode

Now, restart rails server you can see map of Kathmandu,Nepal

map of Kathmandu, Nepal

Showing our list of places on map

  • Updateindex.html.erb
<divclass="w-full"><h1class="font-bold text-4xl mb-2">Places</h1><divdata-controller="map"data-map-latlong-value="<%=@places.pluck(:latitude, :longitude)%>"><divdata-map-target="container"class="h-[75vh] w-auto"></div></div></div>
Enter fullscreen modeExit fullscreen mode

Here, we adddata-map-latlong-value="<%=@places.pluck(:latitude, :longitude)%>" which we can access withthis.latlongValue from ourmap_controller.js

  • Updatemap_controller.js
import{Controller}from"@hotwired/stimulus"importLfrom"leaflet"exportdefaultclassextendsController{statictargets=["container"]staticvalues={latlong:Array}connect(){this.createMap()this.map.fitBounds(this.latlongValue)this.latlongValue.forEach(place=>this.addMarker(place))}createMap(){this.map=L.map(this.containerTarget)L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png',{maxZoom:20,attribution:'&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'}).addTo(this.map);}addMarker(place){const[latitude,longitude]=place;L.marker([latitude,longitude]).addTo(this.map).bindPopup(`<div>latitude:${latitude}</div><div>longitude:${longitude}</div>`)}disconnect(){this.map.remove();}}
Enter fullscreen modeExit fullscreen mode

Linestatic values = { latlong: Array } add value latlong which datatype will be array and now we can access this value which we defined inindex.html.erb withthis.latlongValue

Instead of showing map of Kathmandu, Nepal withsetView() function we usefitBounds() which take list of latitude and longitude and map will be adjusted to fit all of provided latitude and longitude

And for each latitude and longitude value we call functionaddMarker. OuraddMarker function is responsible for adding marker to provided longitude and latitude and we also add popup showing it's latitude and longitude which will appear while clicking on marker withbindPopup

Now our map is look like this

Map showing list of places

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

  • Work
    Ruby on Rails developer
  • Joined

More fromAnkit Pariyar

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp