Wednesday, December 27, 2017

Link_to tag to display map modal Rails 5

Leave a Comment

When I click on a map marker a modal pops up as such:

map marker modal

I just implemented a search feature and am trying to get it when I click on a result a modal with all the information will pop up just like in the photo.

search results

Here is the code I am working with for that page:

MapsController:

class MapsController < ApplicationController   def index        @maps = Map.all       @hash = Gmaps4rails.build_markers(@maps) do |map, marker|       marker.lat map.latitude       marker.lng map.longitude        marker.json({:id => map.id,             :number => map.number,             :name => map.name,             :tabid => map.tabid,             :zipcode => map.zipcode,             :latitude => map.latitude,             :longitude => map.longitude                   })           end   end    def favorite      @map = Map.new(:number => 'Favorite Site')     @map.save     redirect_to :back     flash[:success] = "favorited"   end      def show    @maps = Map.find(params[:id])  end end 

SearchController:

class SearchController < ApplicationController   def index     if params[:query].present?      @maps = Map.search(params[:query]).with_pg_search_highlight      @count = @maps.pluck(:id).count        @hash = Gmaps4rails.build_markers(@maps) do |map, marker|       marker.lat map.latitude       marker.lng map.longitude        marker.json({:id => map.id,             :number => map.number,             :name => map.name,             :tabid => map.tabid,             :zipcode => map.zipcode,             :latitude => map.latitude,             :longitude => map.longitude                   })                   # marker.infowindow render_to_string(:partial => "/maps/info", :locals => { :object => map})        end     else        @maps = Map.all   end end end 

Here is my code for my search result page:

<% provide(:page_title, 'Search Results') %>  <script src="//maps.google.com/maps/api/js?key=AIzaSyAxwNVY12NVNEbrnPorhkHRe7V0_xU8xHM&libraries=places"></script>  <% content_for :scripts %> <%= javascript_include_tag 'creative/marker_cluster.js', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'creative/infobox_packed.js', 'data-turbolinks-track': 'reload' %>  <div class="main">  <div id="sideBar" class="pre-scrollable">       <h2><%= @count%> results found </h2>       <br>   <% @maps.each do |map| %>       <div>         <div class="" id="map_<%= map.id %>">          <h4>           <%= link_to map.number, controller: "maps", action: "show", id: map.id %>         </h4>           <hr>          </div>       </div>     <% end %>     <%= link_to 'Return to Main Map', maps_path %>  </div>   <div id="map_wrapper">     <div id="map" style='width: 100%; height: 100%;'></div>    </div>  </div>    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" >   <div class="modal-dialog">            <!--Basic Table-->           <div class="panel panel-green margin-bottom-40">             <div class="panel-heading">         <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>               <div class = "name"></div>             </div>             <div class="panel-body">                    <div id="map2" style='width: 568px; height: 365px;'>                    </div>                  <div class="row">     <div class="col-sm-12 text-center">                  </div>               </div>             </div>             <table class="table paneltb">               </table>            </div>           <!--End Basic Table-->   </div> </div>   <script type = "text/javascript"> var handler = Gmaps.build('Google', {          markers:             {clusterer: {               gridSize: 60,               maxZoom: 20,               styles: [ {                 textSize: 10,                 textColor: '#ff0000',                 url: 'assets/creative/m1.png',                 height: 60,                 width: 60 }               , {                 textSize: 14,                  textColor: '#ffff00',                 url:'assets/creative/m2.png',                 height: 60,                 width: 60 }               , {                textSize: 18,                 textColor: '#0000ff',                url: 'assets/creative/m3.png',                width: 60,                height: 60}               ]}}       });  var current; function initialize(){   handler.buildMap({ internal: {id: 'map'} }, function() {      markers_json = <%=raw @hash.to_json %>;     markers = _.map(markers_json, function(marker_json){       marker = handler.addMarker(marker_json);       handler.fitMapToBounds();       _.extend(marker, marker_json);       return marker;     });      getLocation();        markers.map(function(elem, index) {        google.maps.event.addListener(elem.getServiceObject(), "click", function(evt) {         var id = elem.id,             number = elem.number,             name = elem.name,             zipcode = elem.zipcode,             tabid = elem.tabid,             latitude = elem.latitude,             longitude = elem.longitude             $(".name").html("<h3 class='panel-title'><i class='fa fa-id-card'></i>"+number+"</h3>")          $(".paneltb").html("<thead><tr><th>Panel</th><th>Location</th><th>Tab ID</th><th>Zip Code</th><th>Latitude</th><th>Longitude</th></tr></thead><tbody><tr><td>"+number+"</td><td>"+ name + "</td><td>"+tabid+"</td><td>"+zipcode+"</td><td>"+latitude+"</td><td>"+longitude+"</td></tr></tbody>")           pos = new google.maps.LatLng( latitude, longitude );         var div = document.getElementById('map2');         var sv = new google.maps.StreetViewPanorama(div);            sv.setPosition( pos );         sv.setVisible( true );          // find the heading by looking from the google car pos to the venue pos         var service = new google.maps.StreetViewService();         service.getPanoramaByLocation( pos, 50, function(result, status) {             if (status == google.maps.StreetViewStatus.OK)              {                    carPos = result.location.latLng;                 heading = google.maps.geometry.spherical.computeHeading( carPos, pos );                 sv.setPov( { heading: heading, pitch: 0, zoom: 0 } );             }         })          $('#myModal').modal('show')            current = elem;        $("#myModal").on("shown.bs.modal", function () {     google.maps.event.trigger(sv, "resize"); });            });              })   });     // Create the search box and link it to the UI element.   } function getLocation(){   if(navigator.geolocation){     navigator.geolocation.getCurrentPosition(displayOnMap);   }   else{     navigator.geolocation.getCurrentPosition(displayOnMapError);   } }; function displayOnMap(position){    marker2 = handler.addMarker({     lat: position.coords.latitude,     lng: position.coords.longitude,     picture: {         url: "<%= asset_path 'creative/1499326997_Untitled-2-01.png' %>",         width:  48,         height: 48         },     infowindow:  "You are Here!"   });   handler.map.centerOn(marker2);   handler.getMap().setZoom(10); };  function displayOnMapError(position){    marker2 = handler.addMarker({     lat: 34.0522,     lng: -118.2437,     picture: {         url: "<%= asset_path 'creative/1499326997_Untitled-2-01.png' %>",         width:  48,         height: 48         }   });   handler.map.centerOn(marker2);   handler.getMap().setZoom(10); };     initialize();   </script> 

Right now when I click on a link I get redirected to the link with a map id which is nothing (see address) for example:

redirection

If someone can guide me it would be greatly appreciated.

Update 1

When I use the suggested answer I was given I do get a modal pop-up. The goal is to get the modal to give me the same information as if I clicked on a map marker (see first image). When I initially click on the search result number I get the following:

blank modal

However, when I click on a map marker and its modal pops up when I click on the results links each modal that pops up will show the information for the last map marker modal that popped up, meaning the modal looks correct as in the first image its just it is the same modal for each link in the search results.

Update 2

I think what my problem is, is that those links are not map markers thus the javascript written does not apply to them. How can I have the links act the same as the map markers so the information gets transferred over to the modal.

Update 3

I am trying as suggested to pull the function out and onclick to call it so far I have is this and its not working or me.

<%= link_to map.number, "#", data: {toggle: "modal", target: "#myModal"}, :html => {:onclick => 'initialize()' } %> 

4 Answers

Answers 1

Currently you have your link like this:

<%= link_to map.number, controller: "maps", action: "show", id: map.id %>

That's creating basic links that go to your /maps/{id} url.

To open a bootstrap modal with a link, do:

<%= link_to map.number, "#", data: {toggle: "modal", target: "#myModal"} %>


Update:

First, your initialize function already displays the modal with $('#myModal').modal('show') so you can get rid of the data: {toggle: "modal", target: "#myModal"} from the links.

Next, your initialize function needs the specific map marker element passed into it, so I suggest doing this:

<%= link_to map.number, "#", class: "map-marker-link", data: {elem: map} %>

Then in your javascript:

$(".map-marker-link").click(function (event) {     initialize($(this).data('elem'));     event.preventDefault(); }); 

Answers 2

If I got your question then the point is, you need to show map modal after clicking on the link right?

If yes then follow the steps

  1. Create a partial modal to any view folder better is in layout folder _modal.html.erb

    <div class="modal fade my-modal" id="modalOne" data-backdrop="static" data-keyboard="false" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">  <div class="modal-dialog" role="document">    <div class="modal-content">     <div class="modal-header">         <button type="button" class="close" data-dismiss="modal" aria-label="Close">             <span aria-hidden="true">&times;</span><span class="sr-only">Close</span>         </button>          <h4 class="modal-title" id="myModalLabel">Map</h4>     </div>     <div class="modal-body"></div>     </div>   </div> </div> 
  2. Inside your maps folder create partial _show.html.erb

    <div id="map_wrapper">    <div id="map" style='width: 100%; height: 100%;'></div> </div>  #=> with js script 
  3. Inside your maps folder create partial show.js.erb

    $modal = $('.modal'), $modalBody = $('.modal .modal-body'), $modalHeading = $('.modal .modal-title'); $modalHeading.html("Map"); $modalBody.html('<%= escape_javascript(render("show")) %>'); $modal.modal(); 
  4. Render the modal partial on your result page below

    <%= render partial: "../path/modal" %> 
  5. Create a link with remote true

    <%= link_to map.number, map_path(map_parameter1, map_parameter2), remote: true, id: map.id %> #=> pass your map parameter with link to the show modal 

Note: JS script you can able to use _show.html.erb or show.js.erb

Very carefully implement this

Hope to help!

Answers 3

I usually handle these using server-side Javascript. Try this out:

  1. Add a data-remote="true" to your link:

    <%= link_to map.number, controller: "maps", action: "show", id: map.id, data: { remote: true } %> 
  2. On your controller, add a JS response

    def show     @maps = Map.find(params[:id])     respond_to :js end 
  3. Create a new view file to be rendered. Should be called 'show.js.erb' and be located in the 'app/views/maps/' directory

    // Javascript code. // Whatever you write here will be executed  alert("You just clicked on Map <%= @maps.id %>"); 

The javascript that you write on the view file should be written out to populate the modal and show it. You'll be able to copy much of the JS code that you posted in your original question.

Answers 4

I have faced the same issue with map on modal,

Your map already there but you have to trigger resize the map when you open a modal like below:

google.maps.event.trigger(map, "resize") 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment