README update for latest SDK; misc small cleanup
[gae-samples.git] / search / product_search_python / templates / product.html
blob9309ba51417c30e4f71d55b24bf9e7816837ec4c
1 {% extends "base.html" %}
2 {% block head %}
3 <title>Product Information for {{pname}}</title>
4 <script type="text/javascript" src="https://www.google.com/jsapi"></script>
5 <script type="text/javascript">google.load("jquery", "1"); google.load("jqueryui", "1");</script>
6 <script
7 src="https://maps.googleapis.com/maps/api/js?sensor=false"
8 type="text/javascript"></script>
9 <script type="text/javascript" src="/static/js/StyledMarker.js"></script>
12 {% endblock %}
15 {% block content %}
17 <script type="text/javascript">
19 // Geolocation with HTML 5 and Google Maps API based on example from
20 // maxheapsize: http://maxheapsize.com/2009/04/11/getting-the-browsers-geolocation-with-html-5/
21 // This script is based in part on one from http://merged.ca/
23 var map;
24 var mapCenter;
26 var hostname_ = "{{app_url}}"
29 function getStoreLocations(squery, lat, lon, dist) {
31 ajax_data = {
32 location_query: squery,
33 latitude: lat,
34 longitude: lon,
35 distance: dist
38 $.ajax({
39 url: hostname_ + "get_store_locations",
40 success: function (data) {
41 // alert('location search results: ' + data[0].addr + ': ' + data[0].lat + ', ' + data[0].lon);
42 mapServiceProvider(lat, lon, dist, data);
44 data: ajax_data,
45 dataType: "jsonp"
46 });
49 function mapLocations(latitude, longitude) {
50 // Did we get the position correctly?
51 // alert (position.coords.latitude+', '+position.coords.longitude);
52 // show the map
53 $('#map').css({ 'display': 'block'});
54 var d = parseFloat($("#distance").val());
55 var distance;
56 if ($("#units").val() == "miles") {
57 distance = d * 1.609344 * 1000;
58 } else {
59 distance = d * 1000;
61 var squery = 'distance(store_location, geopoint(' + latitude + ', ' + longitude + ')) < ' + distance
62 // submit search query
63 getStoreLocations(squery, latitude, longitude, distance);
66 function findLocation() {
68 if (navigator.geolocation) {
69 navigator.geolocation.getCurrentPosition( function (position) {
71 mapLocations(position.coords.latitude, position.coords.longitude);
73 }, // next function is the error callback
74 function (error)
76 switch(error.code)
78 case error.TIMEOUT:
79 alert ('Timeout');
80 break;
81 case error.POSITION_UNAVAILABLE:
82 alert ('Position unavailable; using fake data (37.60, -122). If you are running from localhost, note that geosearch is not currently fully supported on the dev app server.');
83 mapLocations(37.60, -122);
84 break;
85 case error.PERMISSION_DENIED:
86 alert ('Permission denied; using fake data.(-33.873038, 151.20563). If you are running from localhost, note that geosearch is not currently fully supported on the dev app server.');
87 mapLocations(-33.873038, 151.20563);
88 break;
89 case error.UNKNOWN_ERROR:
90 alert ('Unknown error');
91 break;
96 else {
97 alert("Geolocation services are not supported by your browser or you do not have a GPS device in your computer. Using fake data.");
98 mapLocations(-33, 151);
103 function createMarker(map, point, title, text) {
105 var marker = new google.maps.Marker({
106 position: point,
107 map: map,
108 title: title,
110 var infowindow = new google.maps.InfoWindow({
111 content: text
113 google.maps.event.addListener(marker, "click", function() {
114 infowindow.open(map, marker);
116 return marker;
120 function mapServiceProvider(latitude,longitude, distance, data) {
121 var userloc = new google.maps.LatLng(latitude,longitude);
122 var mapOptions = {
123 zoom: 4,
124 center: userloc,
125 mapTypeId: google.maps.MapTypeId.ROADMAP,
127 var map = new google.maps.Map(document.getElementById("map"),
128 mapOptions);
129 var latlngbounds = new google.maps.LatLngBounds();
130 latlngbounds.extend(userloc);
131 for (var i = 0; i < data.length; i++) {
132 var p = new google.maps.LatLng(data[i].lat, data[i].lon);
133 latlngbounds.extend(p);
134 var storename = data[i].storename;
135 var addr = data[i].addr;
136 var store_info = storename + ', ' + addr;
137 var marker = createMarker(map, p, storename, store_info);
138 marker.setMap(map);
140 // build blue-colored point for the user's location.
141 var styleIconClass = new StyledIcon(StyledIconTypes.CLASS,{color:"#016DCF"});
142 var youarehere = new StyledMarker({styleIcon:new StyledIcon(StyledIconTypes.MARKER,{},styleIconClass),position:userloc, map:map, title: 'you'});
143 map.fitBounds(latlngbounds);
147 </script>
149 <h2>Product Information for {{pname}}</h2>
151 <!-- For expository purposes, all document fields are listed below with their actual names; -->
152 <!-- a real customer-facing app would expose this information differently. -->
154 <div id="mapbox" style="padding: 20px;border: 1px dotted #666;">
156 <div id="map" style="display: none; margin: 0 0 20px 20px;width: 650px; height: 300px;border: 1px solid #6666dd;">
157 </div>
159 <div>
160 <div class="clearfix">
161 <label for="rating">distance: </label>
162 <div class="input">
163 <input type="text" id="distance" name="distance" /> &nbsp; units:
164 <select id="units" name="units">
165 <option value="km">km</option>
166 <option value="miles">miles</option>
167 </select>
168 </div>
169 </div>
170 <div class="actions">
171 <input class="btn primary" id="locate" name="locate" type="submit"
172 value="Find stores near me" onclick="findLocation();"/>
173 </div>
174 <div id="loc_results">
175 </div>
176 </div>
177 </div>
180 <p><br/>
181 {% for field in prod_doc.fields %}
182 <b>{{field.name}}</b>:&nbsp;{{field.value}} <br/>
183 {% endfor %}
184 <br/><a href="{{review_link}}">Reviews for {{pname}}</a>
185 </p>
188 <h4>Create a Review for {{pname}}</h4>
190 <form action="/create_review" method="post">
191 <input type="hidden" name="pid" value="{{pid}}" />
192 <input type="hidden" name="category" value="{{category}}" />
193 <input type="hidden" name="pname" value="{{pname}}" />
194 <div class="clearfix">
195 <label for="comment">review comment:</label>
196 <div class="input">
197 <textarea name="comment" rows="3" cols="80">{{comment}}</textarea>
198 </div>
199 </div>
201 <div class="clearfix">
202 <label for="rating">rating (1-5):</label>
203 <div class="input">
204 <input type="text" id="rating" name="rating" value="{{rating}}"/>
205 </div>
206 </div>
208 <div class="actions">
209 <input class="btn primary" id="subreview" name="subreview" type="submit" value="Review"/>
210 <input type="reset" class="btn primary" name="reviewreset" value="Clear"/>
211 </div>
212 </form>
214 {% if user_is_admin %}
215 <p>Delete this product and its reviews; no undo (admin).</p>
216 <form action="/admin/delete_product" method="post">
217 <input type="hidden" name="pid" value="{{pid}}" />
218 <div class="actions">
219 <input class="btn primary" id="delete_prod" name="delete_prod" type="submit" value="Delete Product"/>
220 </div>
221 </form>
222 {% endif %}
224 {% endblock %}