Link_to tag to display map modal Rails 5

吃可爱长大的小学妹 提交于 2019-12-13 13:26:49

问题


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

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



回答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!




回答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.




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


来源:https://stackoverflow.com/questions/47735172/link-to-tag-to-display-map-modal-rails-5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!