简体   繁体   中英

Link_to tag to display map modal Rails 5

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

地图标记模态

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.

搜索结果

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:

重定向

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:

空白模态

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()' } %>

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();
});

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!

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.

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")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM