How to save and show Mapbox directions? - django

I am using Mapbox and Leaflet.
I have a create view, where I create walking directions.
But I also need detail view, where I can show created directions.
Now I save only originMarker and destinationMarker coordinates into database;
This way I try to show routing:
<script>
var start = JSON.parse($('#start_field').val());
var finish = JSON.parse($('#finish_field').val());
L.mapbox.accessToken = 'qwerty';
var map = L.mapbox.map('map', 'mapbox.streets', {
zoomControl: false
}).setView([42.8580536, 74.6224754], 12);
L.Routing.control({
waypoints: [
L.latLng(start.lat, start.lng),
L.latLng(finish.lat, finish.lng)
]
}).addTo(map);
var start_marker = L.marker([start.lat, start.lng], {
draggable: false
}).addTo(map);
var finish_marker = L.marker([finish.lat, finish.lng], {
draggable: false
}).addTo(map);
</script>
But browser gives me an error:
Uncaught TypeError: Cannot read property 'control' of undefined

Without the full code it's kind of hard to answer but my first guess is that you didn't load the routing plugin's assets or not in the proper order (first the Leaflet script then the routing plugin, the other way around doesn't work):
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<link rel="stylesheet" href="leaflet-routing-machine.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="leaflet-routing-machine.js"></script>

Related

Trying to get a Google maps to display in Django

I wondered if anyone has managed to get Google maps working within a Django project and if so, could they tell me what I may be doing wrong.
In base.html, I have the following scripts at the end of the body in base.html :
<script src="{% static '/js/script.js' %}" ></script>
<script src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js"></script>
<script async defer src=https://maps.googleapis.com/maps/api/js?key=”API_KEY”&callback=initMap"></script>
<script src="{% static '/js/maps.js' %}" ></script>
Script.js is working fine and map.js is executing but after map.js runs the div element doesn’t display.
In maps.js, I have:
function initMap() {
var map = new google.maps.Map(document.getElementById("map"), {
//zoom: 3,
zoom: 10,
center: {
lat: 46.619261, lng: -33.134766
}
});
var labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var locations = [
{ lat: 40.785091, lng: -73.968285},
{ lat: 41.084045, lng: -73.874245},
{ lat: 40.754932, lng: -73.984016}
];
var markers = locations.map(function(location, i){
return new google.maps.Marker({
position: location,
label: labels[i % labels.length]
});
});
var markerCluster = new MarkerClusterer( map, markers, {imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m' } );
}
I do not seem to have any Google API key issues. However I have a div in the index.html with the following element and the map is not being displayed:
<div class="row">
<!-- Map -->
<div id="map" class="col-12"></div>
<div class="col-12 mt-2 request-page">
<h2>Map Will Go Above Here </h2>
</div>
</div>
I can get the map to display if I load static in index.html and place the scripts in index.html but ideally I think I am meant to do this in base.html.
I have not changed settings.py, views.py or urls.py to accommodate Google maps, is that where my error is?
Thanks in advance.
if there is a blank gap create a CSS file and add#map {height:500px;width: 100%;}
do not forget to link it to html.
This is probably because the div element #map does not have a defined height. Try adding style="height: 300px" to it.

Power BI Premium - embed using Power BI API and javascript not working like previous way

Earlier I used to use 'loadReport' from javascript which is not working with new PBI Premium, e.g. the below is not working anymore & it always says "This content isn't available". BTW this is still working for PBI embedded reports.
<html>
<body>
<iframe id="iFrameEmbedReport"></iframe>
</body>
<script type="text/javascript">
window.onload = function () {
var iframe = document.getElementById('iFrameEmbedReport');
iframe.src = 'https://app.powerbi.com/reportEmbed?reportId=******-088f-4967-***-279bd5a**df&groupId=*****-****-4033-862d-1cd4f4fa72c1';
iframe.onload = function()
{
var m = {
action: 'loadReport',
accessToken: 'H4s*****'
};
message = JSON.stringify(m);
iframe = document.getElementById('iFrameEmbedReport');
iframe.contentWindow.postMessage(message, "*");
};
};
</script>
</html>
But if we use powerbi.js with the same configs its working fine (below)
<html>
<body>
<div id="reportContainer"></div>
</body>
<script src="https://microsoft.github.io/PowerBI-JavaScript/demo/node_modules/jquery/dist/jquery.js"></script>
<script src="https://microsoft.github.io/PowerBI-JavaScript/demo/node_modules/powerbi-client/dist/powerbi.js"></script>
<script type="text/javascript">
window.onload = function () {
var accessToken = '******************';
var embedUrl = 'https://app.powerbi.com/reportEmbed?reportId=**********&groupId=**********';
var embedReportId = '*****-088f-****-aa2d-279bd5a662df';
var models = window['powerbi-client'].models;
var config = {
type: 'report',
tokenType: models.TokenType.Embed,
accessToken: accessToken,
embedUrl: embedUrl,
id: embedReportId,
permissions: models.Permissions.All,
settings: {
filterPaneEnabled: true,
navContentPaneEnabled: true
}
};
var reportContainer = $('#reportContainer')[0];
var report = powerbi.embed(reportContainer, config);
}
</script>
</html>
Not able to figure out what has changed. I really don't want to include powerbi.js in my application if not needed. I know I have a working copy but really need to understand what has changed and if there is any way I can avoid powerbi.js. End goal is to use the first approach in UWP App.
Thanks
The main thing that's changed in the 2 approaches is the property TokenType.Embed which is not available in the 'old way', i.e. 'loadReport' message format.
This is a deprecated way of communicating with embedded entities from Power BI, and all users are encouraged to write their code against the new and maintained Javascript SDK: https://microsoft.github.io/PowerBI-JavaScript/
The 'loadReport' way work for backward compatibility concerns but you won't be able to write new code in new methods using this way.

Canvas not shown on page using Raphael.js in web2py

Goal: use Raphael.js to draw data chart/lines in web2py framework.
What I have learned from http://raphaeljs.com/ is that, I just need to include the JS into the HTML page and then I can use the APIs. But here is what I have done:
(1) First, I copied both raphael.js and raphael-min.js to myapp\static\js folder.
(2) Then I wrote these in the HTML file:
<script type="text/javascript" src="{{=URL('static','js/raphael.js')}}">
window.onload = function() {
var paper = new Raphael(0, 0, 100, 100);
var circle = paper.circle(50, 50, 50);
circle.attr("fill", "#f00");
circle.attr("stroke", "#fff");
}
</script>
This file is periodically loaded to a div in the index.html.
I expected a circle could be shown but nope, though I was very sure this page was periodically loaded.
Did I do anything wrong here (of course I did)? Thanks for your help!
Try using separate script tags to load the library and then run your code:
<script type="text/javascript" src="{{=URL('static','js/raphael.js')}}"></script>
<script>
window.onload = function() {
var paper = new Raphael(0, 0, 100, 100);
var circle = paper.circle(50, 50, 50);
circle.attr("fill", "#f00");
circle.attr("stroke", "#fff");
}
</script>
I'm not sure if this is exactly your question but instead of importing just one and then writing the other in the file, you can do it all in one src assigning like so:
<script type="text/javascript" src="{{=URL('static','js/raphael.js')}} {{=URL('static', 'other_function.whatever_extension}}">
This will import both scripts. You can add as many as you wish and even change the paths.

Backbone Collection

I was trying to make a Backbone Application with Django at its backend. I was following a Backbone tutorial. I used the following code:
Code
<!doctype html>
<html lang = "en">
<meta charset = "utf-8">
<title>IstreetApp</title>
<link rel="stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Book Manager</h1>
<hr />
<div class="page"></div>
</div>
<script type = "text/template" id = "booklist.template">
</script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.10/backbone-min.js"></script>
<script>
$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
options.url = 'http://backbonejs-beginner.herokuapp.com' + options.url;
});
var Books = Backbone.Collection.extend({
url: '/books'
});
var BookList = Backbone.View.extend({
el: '.page',
render: function () {
var that = this;
var books = new Books();
books.fetch({
success: function(books) {
var template = _.template($('#booklist.template').html(), {books: books.models});
that.$el.html(template);
}
})
}
});
var Router = Backbone.Router.extend({
routes: {
'': 'home'
}
})
var bookList = new BookList();
var router = new Router();
router.on('route:home', function () {
bookList.render();
});
Backbone.history.start();
</script>
</body>
</html>
Since the collection is not defined, the success code doesn't execute. I suppose the collection data should come from the server through Django but I am not sure how and in what form. Kindly help. I am pretty much new to backbone and Django.
When you call fetch on your collection, it makes an AJAX request to:
http://backbonejs-beginner.herokuapp.com/books
However, there is no API set up there. Either one of two things needs to happen:
1) you need to modify your code to point to a different URL, one that does have an existing API (perhaps whatever tutorial you are using has such an API)
2) you need to create such an API yourself on yoursever.com (and then make your Backbone code point to that API's URL instead)
Without a server to support it, operations like save and fetch and such in Backbone simply cannot function.
As a side note, Django is a web site framework. While you can use it to create server-side APIs, that's not really Django's focus. Because of this, several good third party libraries exist for doing RESTful APIs (ie. the kind that Backbone likes) in Django; personally I'd recommend either Django REST Framework (I use it and it works great) or TastyPie (never used it, but it's very popular).
When using a backbone collection you need to return a json array of objects from your api url (http://backbonejs-beginner.herokuapp.com/books)
Example
{[{"name":"bookname", "publisher": "penguin"}, {"name":"bookname", "publisher":"penguin"}]}
You'll also want a model for your collection. A model would look like this
Example:
var Book = Backbone.Model.extend({
defaults: {
"name": "",
"publisher": ""
}
});
The way that the collection works is by parsing the json array and turning each object in the array in to a model that you specific (in this instant an individual book with values for the name and publisher).
When you make a .fetch() on your model you are making a GET request, so make sure that your http://backbonejs-beginner.herokuapp.com/books url is prepared to receive GET requests and respond with the json data in the format I specified up top.

document.getElementById to include href

<script type="text/javascript">
document.getElementById("IDOFELEMENT");
</script>
What is the correct way to turn this into a link?
Can I write
<script type="text/javascript">
document.getElementById("IDOFELEMENT").href("http://www.address.com");
</script>
Many thanks.
javascript:
// this changes the href value<br>
document.getElementById("IDOFELEMENT").href = "http://www.address.com";
and the html:
<a href="www.toBeChanged.com" id="IDOFELEMENT">To Website< /a>
You should specify what kind of element is IDOFELEMENT. But you can't convert it to a link by just adding a href attribute, it only works if IDOFELEMENT
is an hyperlink like <a id="IDOFELEMENT">stuff</a>
Simplest way is to add an onclick event to the element that changes the url to desired address:
<script type="text/javascript">
var element = document.getElementById("IDOFELEMENT");
element.setAttribute('onclick', 'window.location.href=\'http://address.com\'');
</script>
Or if you wanna wrap it with a hyperlink:
<script type="text/javascript">
var element = document.getElementById("IDOFELEMENT");
var parent = element.parentNode;
var link = document.createElement('a');
link.href = 'http://www.address.com';
link.appendChild(element.cloneNode(true));
parent.replaceChild(link, element);
</script>
I hope this helps you.
I came accross the issue - Javascript error: Cannot read property 'parentNode' of null.
I discovered this was due to executing this code while the DOM is not ready.
window.onload solved the issue for me.
<script>
window.onload = function() {
var element = document.getElementById("IDOFELEMENT");
var parent = element.parentNode;
var link = document.createElement('a');
link.href = 'http://www.google.com';
link.appendChild(element.cloneNode(true));
parent.replaceChild(link, element);
};
</script>
You just need to wrap your element in an anchor tag as follows...
<a href="http://www.address.com">
<div id="IDOFELEMENT">
... content ...
</div>
</a>