gem MapkickJS for beautiful JavaScript maps with one line of Ruby

superails

Yaroslav Shmarov

Posted on February 2, 2023

gem MapkickJS for beautiful JavaScript maps with one line of Ruby

MapkickJS is a javascript adapter to display coordinates on Mapbox maps. It requires a Mapbox API key.

mapkick-rb is a Ruby on Rails adapter for MapkickJS. It allows you to easily feed a JSON with coordinates and display a map within your Rails app.

To display a marker on a map, you need to know latitude and longitude GPS coordinates. gem Geocoder allows you to get coordinates based on an address (house, street, city, state, country).

Basic usage

After installing the gem, initialize your Mapkick API key.

# echo > config/initializers/mapbox.rb
# config/initializers/mapbox.rb
ENV["MAPBOX_ACCESS_TOKEN"] = "pk.eyJ1..."
# ENV["MAPBOX_ACCESS_TOKEN"] = Rails.application.credentials.dig(:mapkick_api_key)
Enter fullscreen mode Exit fullscreen mode

Basic map with multiple options:

<%= js_map [{latitude: 37.7829,
             longitude: -122.4190,
             label: 'My home',
             tooltip: 'Hello!'
            }],
            id: "cities-map",
            width: "800px",
            height: "500px",
            markers: {color: "#00FF00"},
            tooltips: { hover: false, html: true},
            style: "mapbox://styles/mapbox/outdoors-v12",
            zoom: 15,
            controls: true,
            refresh: 60 %>
Enter fullscreen mode Exit fullscreen mode

Result:

mapbox-map-all-params

HTML tooltips

Map with clickable links to locations:

mapbox-map-clickable-link

Create a helper with a link:

# app/helpers/locations_helper.rb
module LocationsHelper
  def html_link_to_location(location)
    link_to location.name,
            location_url(location),
            target: '_blank',
            style: 'font-weight: bold; color: green'
  end
end
Enter fullscreen mode Exit fullscreen mode

To be able to click on the tooltip, use the option { hover: false, html: true}.

Render the helper method in the tooltip param:

<%= js_map [{latitude: location.latitude,
             longitude: location.longitude,
             label: location.name,
             tooltip: html_link_to_location(location)}],
             tooltips: { hover: false, html: true} %>
Enter fullscreen mode Exit fullscreen mode

Display multiple locations on the map, JSON

For this, the best way will be to render /locations.json:

<%= js_map locations_path(format: :json) %>
Enter fullscreen mode Exit fullscreen mode

Customize the JSON:

// app/views/locations/_location.json.jbuilder
json.extract! location, :latitude, :longitude
json.label location.name
json.tooltip html_link_to_location(location)
// json.tooltip "#{html_link_to_location(location)} <br> #{location.address}"
Enter fullscreen mode Exit fullscreen mode

Result:

mapbox-map-multiple-locations

With search params

In this final example, we will factor in having a search form for place and distance. The maps’ zoom will be smaller/higher based on the maximum search distance:

# app/controllers/locations_controller.rb
class LocationsController < ApplicationController
  before_action :set_location, only: %i[show edit update destroy]

  # GET /locations or /locations.json
  def index
    if params[:place].present?
      @locations = Location.near(params[:place], params[:distance] || 10, order: :distance)
      # this!
      @zoom = params[:distance].eql?('10') ? 13 : 10
    else
      @locations = Location.all
    end
    respond_to do |format|
      format.html
      format.json
    end
  end
Enter fullscreen mode Exit fullscreen mode

Be sure to add the query params to the path in the view:

<%= js_map locations_path(format: :json, place: params[:place], distance: params[:distance]), zoom: @zoom %>
Enter fullscreen mode Exit fullscreen mode

Result - smaller/bigger map zoom based on search params:

geocoder-search-zoom

That’s it! Now you can build your own AIRNBN search frontend!

💖 💪 🙅 🚩
superails
Yaroslav Shmarov

Posted on February 2, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related