Unobtrusive Google Maps API Javascript in Rails View - google-maps-api-3

I have this javascript code inside my app/views/people/show.html.erb. It uses google maps api v3. But the thing is that this is very obtrusive. What I wanted is that I want the js codes to be inside the coffeescript. And that I should still be able to pass the longitude/latitude values to reflect them in the map.
<% unless #person.addresses.blank? %>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
function initialize() {
<%
if #person.addresses.first.latitude.blank? && #person.addresses.first.longitude.blank?
lat_long = #person.organization.latitude_longitude
else
address = #person.addresses.first
lat_long = [address.latitude, address.longitude]
end
lat = lat_long[0]
long = lat_long[1]
%>
var myLatlng = new google.maps.LatLng(<%= lat %>, <%= long %>);
var mapOptions = {
zoom: 17,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById('map_canvas_show'), mapOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Hello World!'
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<div id="map_canvas_show"></div>
<% end %>
<h1>
<%= #person.name %> <small><%= link_to(t('general.edit'), edit_person_path(#person)) %></small>
</h1>
<h3>
<%= #person.organization_names(current_organization) %>
</h3>
<div>
<%#= image_tag #person.fb_profile_pic_large %>
</div>
<div class="sfield field_group">
<div class="ls"><%= t('.addresses')%></div>
<% #person.addresses.each do |address| %>
<div class="rs"><%= address.address %></div>
<% end %>
</div>
<div class="sfield field_group">
<div class="ls"><%= t('.phone_numbers')%></div>
<% #person.phone_numbers.each do |phone_number| %>
<div class="rs field_group"><%= phone_number.phone_number %></div>
<% end %>
</div>
<div class="sfield field_group">
<div class="ls"><%= t('.offices')%></div>
<% #person.office_names.each do |office_name| %>
<div class="rs"><%= office_name %></div>
<% end %>
</div>

You can use HTML5 data-* attributes for this. See also the ujs section of rails guide.
<div id="map_canvas_show" data-lat="<%= lat %>"
data-long="<%= long %>" />
Then in jQuery you can use something like to get the coordinates:
var map_canvas = $('#map_canvas_show');
var lat = map_canvas.data('lat');
var lng = map_canvas.data('long');
var myLatlng = new google.maps.LatLng(lat, lng);

Related

Click event handler not working prepend parsed html

I have a element parsed from html template and i want to add a click event to it, it seems not working.
but when i add element like
$('#formatMe').click();
Here click is working but when
var formats = appAPI.resources.parseTemplate("formats.html",result);
$code=$(formats);
$('#vid_div').prepend($code);
But not on element from parseTemplate
I am writing click function in appAPI.ready like below
appAPI.ready(function($) {
$("#user-header").append("<div id='formatMe'>Download</div>");
$('#some-div-in-web-site').append("<div id='vid_div'></div>");
$('#formatMe').click(function(){
var url="myurl";
appAPI.request.get({
url: url,
onSuccess: function (data) {
var result=appAPI.JSON.parse(data);
var formats = appAPI.resources.parseTemplate("formats.html",result);
$('#vid_div').html('');
$code=$(formats);
$('#vid_div').prepend($code);
}
});
});
$('#close').click(function(){
alert("dont'click on me!!!");
});
});
Formats.html is like this
<div id="vid_formats">
<div id="close">×</div>
<div class="wrapper">
<h1>Download Links</h1>
<ul>
<% for (var i=0; i<vids.length; i++) { %>
<li>
<a id="format" href="<%=vids[i]['url'] %>"><%=vids[i]['type']%> <%=vids[i]['quality']%> - <%=vids[i]['size']%> </a>
</li>
<% } %>
</ul>
</div>
</div>
Still not able to fire click event, i am testing in firefox.
Foreword: Since the contents of the formats.html file and result array are not provided and it's also not clear from your example where the element with id close is defined, I created the scenario that I believe you are experiencing.
In the scenario I recreated, the click event handler worked as expected and I can see the alert. The following are the extension files I recreated and then tested in Chrome.
formats.html:
<div>
<ul>
<% for (var i=0; i<sites.length; i++) { %>
<li><%=sites[i].name%></li>
<% } %>
</ul>
</div>
<div id="close">Close</div>
extension.js:
appAPI.ready(function($) {
var result = {
sites:[
{url:' http://cnn.com ', name:'cnn'},
{url:' http://yahoo.com ', name:'yahoo'}
]
},
formats = appAPI.resources.parseTemplate("formats.html",result);
$('<div id="player"></div>').prependTo('body');
$code=$(formats);
$('#player').prepend($code);
$('#close').click(function(){
alert('clicked me');
});
});
[Disclosure: I am a Crossrider employee]

Add class for css in ejs by node

Please mind the environment of this Application. I'm using
Windows
NPM ,Express
MySQL
This is the code in ejs template. example.ejs
<% if (message) { %>
<p class="alert " id="errorMessage">
<%= message %>
</p>
<% } %>
I want to add class to p.
This is what I am doing but didn't work.
messages = "Password Successfully Changed";
jQuery('#errorMessage').addClass('successMessage');
res.render('profile',{page_title:"My Profile",data:rows,message: messages});
I got the answer.
var messageData = {
message : "Password Successfully Changed",
class : "successMessage"
};
res.render('profile',{page_title:"My Profile",data:rows,message: messageData });
then on template side.
<% if (globalMessage) { %>
<p class="alert <%= globalMessage.class %>" id="errorMessage">
<%= globalMessage.message %>
</p>
<% } %>

Autocomplete generate multiple markers

My goal is to have several input fields with Autocomplete functionality and each input will generate a marker on the map. I then need the map to zoom in to contain all of the markers. I have this working partially, without the Autocomplete functionality. I have tried adding the Google Maps API Places Autocomplete code to my for loop, but to no avail. It gives autocomplete functionality to all the input fields but only places a marker for the last input.
Any help/insight/guidance is appreciated.
Here is my code, the autocomplete is currently deleted since I couldn't get it to work.
<div class="container-fluid">
<div class="row-fluid">
<div class="span4 well">
<div id="locations">
<form>
<label>Location 0</label>
<input id="address0" type="text" size="50" >
<button id="clearField0">Clear</button>
<div class="panel">
<label>Location 1</label>
<input id="address1" type="text" size="50">
<button id="clearField0">Clear</button>
</div>
<div class="panel">
<label>Location 2</label>
<input id="address2" type="text" size="50">
<button id="clearField0">Clear</button>
</div>
</form>
</div>
<button id="addField">+</button>
<button id="deleteField">-</button>
<button id="submit">Submit form</button>
</div>
<div class="span8">
<div id="map-wrapper">
<div id="google-map"></div>
</div>
</div>
</div>
</div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCtNo_o0u8wYeqgiFF-KpvAtEy18T-PvAo&sensor=false&callback=createMap"></script>
<script type="text/javascript">
var inputFields = parseInt($('form input').size());
var markers = [];
var createMap = function() {
var latlngbounds = new google.maps.LatLngBounds();
var geocoder = new google.maps.Geocoder();
var myOptions = {
center : new google.maps.LatLng(35.9081, -78.8628), //center to RTP
zoom : 12,
zoomControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
},
map = new google.maps.Map(document.getElementById("google-map"), myOptions);
$("#submit").on("click", function() {
setAllMap(null);
markers.pop();
for (i=0; i<inputFields; i++) {
var location = $("#address" + i).val();
geocoder.geocode( {'address': location}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
latlngbounds.extend(results[0].geometry.location);
map.fitBounds(latlngbounds);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
};
});
function setAllMap(map) {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(map);
}
}
$('#addField').click(function(){ //add input field to bottom of form
$('form').append('<div class="panel"><label>Location '+ inputFields +'</label><input id="address'+ inputFields +'" type="text" size="50"><button id="clearField'+ inputFields +'">Clear</button></div>');
inputFields++;
});
$('#deleteField').click(function(){ //delete last input field
$('.panel').last().remove();
inputFields--;
});
};
</script>
My first problem was including the places library in the API reference. Following that, I simply needed two lines of code from Google's Places Autocomplete example page, as opposed to the entire script they offer:
var input = /** #type {HTMLInputElement} */(document.getElementById('searchTextField'));
var autocomplete = new google.maps.places.Autocomplete(input);
These two lines in my for loop solved the problem. Thanks again to Dr. Molle whose comment made me rethink what code I needed.

Foursquare Save Button not reading venue data

I tried, several times, to create a "save to foursquare button", but, maybe, there´s a problem with the script.
I tried this code, that works, from a website for the site venue:
<div class="locInfo vcard" style="display: none;">
<h4>
<a class="fn" href="">Flying Star Cafe - Menaul</a>
</h4>
<p class="adr">
<span class="street-address">8001 Menaul Blvd NE</span> <br> <span
class="locality">Albuquerque</span>, <span class="region">NM</span>
<span class="postal-code">87110-4607</span>
</p>
</div>
<a href="https://foursquare.com/intent/venue.html"
class="fourSq-widget">Save to foursquare</a>
<br />
<!-- Place this script somewhere after the anchor tag above. If you have multiple buttons, only include the script once. -->
<script type='text/javascript'>
(function() {
window.___fourSq = {
"uid" : "5166539"
};
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'http://platform.foursquare.com/js/widgets.js';
s.async = true;
var ph = document.getElementsByTagName('script')[0];
ph.parentNode.insertBefore(s, ph);
})();
</script>
It works nice, but if I use the same structure for this venue: https://pt.foursquare.com/v/centro-drag%C3%A3o-do-mar-de-arte-e-cultura/4be5f4802468c92887d30043
something goes wrong...
<div class="locInfo vcard" style="display: none;">
<h4>
<a class="fn" href="">Centro Dragão do Mar de Arte e Cultura</a>
</h4>
<p class="adr">
<span class="street-address">Rua Dragão do Mar, 81</span> <br> <span
class="locality">Fortaleza</span>, <span class="region">CE</span> <span class="postal-code">60060-390</span>
</p>
</div>
<a href="https://foursquare.com/intent/venue.html"
class="fourSq-widget">Save to foursquare</a>
<br />
<!-- Place this script somewhere after the anchor tag above. If you have multiple buttons, only include the script once. -->
<script type='text/javascript'>
(function() {
window.___fourSq = {
"uid" : "5166539"
};
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'http://platform.foursquare.com/js/widgets.js';
s.async = true;
var ph = document.getElementsByTagName('script')[0];
ph.parentNode.insertBefore(s, ph);
})();
</script>
Any clues?
I do not know if the problem is that the venue location is outside US... Is there an additional parameter that I should use for my venue?
I am using Google Chrome 18.0.1025.162 and running the code inside the Apache Tomcat 7.0.27
In order to determine the correct venue, you should give as much unique details of the venue as possible. In your case, it is sufficient to add the telephone number of the venue:
<div class="locInfo vcard" style="display: none;">
<h4>
<a class="fn" href="">Centro Dragão do Mar de Arte e Cultura</a>
</h4>
<p class="adr">
<span class="street-address">R. Dragão do Mar, 81</span> <br />
<span class="locality">Fortaleza</span>, <span class="region">CE</span>
<span class="postal-code">60060-390</span> <br />
<span class="tel">+55 85 3488-8600</span>
</p>
</div>
Save to foursquare
<br />
<script type='text/javascript'>
(function() {
window.___fourSq = {
"uid" : "5166539"
};
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'http://platform.foursquare.com/js/widgets.js';
s.async = true;
var ph = document.getElementsByTagName('script')[0];
ph.parentNode.insertBefore(s, ph);
})();
</script>
I had problems with that because I wrote a wrong locality (it was not exactly the same what I wrote on FS). Try to eliminate that class and give it a try...

JQuery Validate Plugin MS MVC: Won't validate

I'm trying out the jQuery Validation plugin
jQuery Docs
Here is the markup of my form:
<% using (Html.BeginForm("action", "contoller", null, FormMethod.Post, new { id = "sxform" })){%>
<div id="manifest">
Manifest Option:<br />
<%= Html.DropDownList("docid", ViewData["manifests"] as SelectList, new { #class = "required" })%>
</div>
<div id="release">
Release Version:<br />
<%= Html.TextBox("release", null, new { #class = "required" })%>
</div>
<div id="locale">
Localization:<br />
<%= Html.DropDownList("localization", ViewData["localizations"] as SelectList, new { #class = "required" })%>
</div>
<div id="label">
Label:<br />
<%= Html.TextBox("label", null, new { #class = "required" })%>
</div>
<div id="session">
Session ID (optional):<br />
<%= Html.TextBox("sessionInput", null, new { #class = "required" })%>
</div>
<div id="submit"><input type="submit" value="Build" /></div>
<% } %>
JS:
$(document).ready(function(){
$("#sxform").validate();
});
I am using MS MVC HTML Helpers to render this form. The resulting markup looks fine. IE each input and selection element contains the attribute 'class' with the value 'required'.
When I submit this form the validation does noting. Can someone familiar with this library help? It looks pretty widely used.
Thanks!
You code looks fine and should work. Make sure you have included the plugin:
<script type="text/javascript" src="http://dev.jquery.com/view/trunk/plugins/validate/jquery.validate.js"></script>
Also look for possible javascript errors in the FireBug console.

Resources