Python folium fetching csv data to the jinja macro template - javascript

I have the jinja macro template provided to my code, which executes the Leaflet circle creation.
I would like to include the .csv data in this template when possible
df = pd.read_csv("survey.csv")
class Circle(folium.ClickForMarker):
_template = Template(u"""
{% macro script(this, kwargs) %}
var circle_job = L.circle();
function newMarker(e){
circle_job.setLatLng(e.latlng).addTo({{this._parent.get_name()}});
circle_job.setRadius({{rad}});
circle_job.getPopup({{role}})
if {{role}} = "Contractor" {
color="red"
}else{
color="black"
}
circle_job.bringToFront()
parent.document.getElementById("latitude").value = lat;
parent.document.getElementById("longitude").value =lng;
};
{{this._parent.get_name()}}.on('click', newMarker);
{% endmacro %}
""") # noqa
def __init__(self, popup=None):
super(Circle, self).__init__(popup)
self._name = 'Circle'
job_range = Circle()
for i,row in df.iterrows():
lat =df.at[i, 'lat']
lng = df.at[i, 'lng']
sp = df.at[i, 'sp']
phone = df.at[i, 'phone']
role = df.at[i, 'role']
rad = int(df.at[i, 'radius'])
is it possible something like this?
A similar approach was here:
How add circle markers to a rendered folium map embedded in a QWebEngineView?
UPDATE I:
I tried recently something like this:
class Circle(MacroElement):
_template = Template(u"""
{% macro script(this, kwargs) %}
var {{this.get_name()}} = L.circle();
function newCircle(e){
{{this.get_name()}}.setLatLng(e.latlng)
.addTo({{this._parent.get_name()}});
{{this.get_name()}}.setRadius({{rad}});
{{this.get_name()}}.setStyle({
color: 'black',
fillcolor: 'black'
});
};
{{this._parent.get_name()}}.on('click', newCircle);
{% endmacro %}
""") # noqa
def __init__(self,
popup=None
):
super(Circle, self).__init__()
self._name = 'Circle'
for i,row in df.iterrows():
lat =df.at[i, 'lat']
lng = df.at[i, 'lng']
sp = df.at[i, 'sp']
phone = df.at[i, 'phone']
role = df.at[i, 'role']
rad = int(df.at[i, 'radius'])
popup = '<b>Phone: </b>' + str(df.at[i,'phone'])
work_range = os.path.join('survey_range.geojson')
job_range = Circle()
Now I lost some features, whereas the Js console says nothing. Is it possible to fetch data from df.iterrows directly to the Macroelement?
UPDATE II
I tried to fiddle with def__init__ section and now my code looks as follows:
class Circle(MacroElement):
def __init__(self,
popup=None,
draggable=False,
edit_options=None,
radius=rad
#lat,
#lng
):
super(Circle, self).__init__()
self._name = 'Circle',
self.radius = radius,
self._template = Template(u"""
{% macro script(this, kwargs) %}
var circle_job = L.circle();
function newCircle(e){
circle_job.setLatLng(e.latlng).addTo({{this._parent.get_name()}});
circle_job.setRadius(50000);
circle_job.setStyle({
color: 'black',
fillcolor: 'black'
});
};
{{this._parent.get_name()}}.on('click', newCircle);
{% endmacro %}
""") # noqa
for i,row in df.iterrows():
lat =df.at[i, 'lat']
lng = df.at[i, 'lng']
sp = df.at[i, 'sp']
phone = df.at[i, 'phone']
role = df.at[i, 'role']
rad = int(df.at[i, 'radius'])
and the error thrown is: The rad is not defined
Is there any way of including the stuff from inside of df.iterrows() in the jinja2 template via defining the def___init?

Related

Django-Javascript - materialcss breaks javascript code when adding new elements to the body of html template

Well this is making my head spin... When I run the following code in a test environment without material css loaded, I get the expected output, a dropdown menu with animals to select from. However, if I run this exact same code with material css loaded, it just displays the title and no dropdown is visible. Why does this happen?
html
{% extends 'base.html' %}
{% load materializecss %}
{% block content %}
<button id = 'id_graph_type'>Add Stuff</button>
{% endblock %}
javascript
graphInput.addEventListener('click', e=>{
var values = ["dog", "cat", "parrot", "rabbit"];
var select = document.createElement("select");
select.name = "pets";
select.id = "pets"
for (const val of values) {
var option = document.createElement("option");
option.value = val;
option.text = val.charAt(0).toUpperCase() + val.slice(1);
select.appendChild(option);
}
var label = document.createElement("label");
label.innerHTML = "Choose your pets: "
label.htmlFor = "pets";
document.body.appendChild(label).appendChild(select);
})

On click (image/button) store data in ... to render another html template live

I would like to retrieve the img.id or img.alt data when an image is clicked in my (x.html) template. The retrieved data will then be used to fill another template (dashboard.html). My only question is how to retrieve the data on an 'onclick' event. Once i have the data stored somewhere, I will be able to figure out how to fill another template based on that information. And does your answer change if i would add that the 'dashboard.html' should be a live stat dashboard.
I already have the following working js that returns the id of the clicked image. How do I use that data in views.py for example?
function ImgDetails(img){
var name = img.src;
var id = img.id;
console.log(id);
}
Below the html (x.html) in which i would like to add a onclick function on each image that is imported via views.
{% include 'navigation.html' %}
<div id="Content">
<div id="List-Content">
<!--- All_Test -->
{% for key, value_list in Drank.items %}
<div id ="Content-List">
<div id ="Title-Box">
<h1 class="hero_header">{{ key }}</h1>
</div>
{% for value in value_list %}
<div id ="Menu-Item">
<div id ="Menu-Item-Wrap">
<img style="margin: 0 auto;" id="{{ value }}" src="{{ value }}">
</div>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</body>
{% include 'footer.html' %}
And here my views.py:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
from django.template import loader
from django.db import models
from django.contrib.staticfiles.templatetags.staticfiles import static
import pandas as pd
import os
from os import walk
#C:\PythonProjects\DjangoApp\djangonautic
#C:/PythonProjects/DjangoApp/djangonautic
#Get dirs in imagefolder, files in dirs and create dictionairy for render
def smaakjes_list(request):
Temp_Directory_Path = []
#TempDic -> can later be replaced in the loop below, so that key values will be added as dir names
path_to_option_images = '/Users/kolinmac/AnacondaProjects/DjangoApp/djangonautic/smaakjes/static/options/'
#'/Users/kolinmac/AnacondaProjects/DjangoApp/djangonautic/smaakjes/static/options/'
super_dict = {}
#for each folder in options -> get all directory names
for (dirpath, dirnames, filenames) in walk(path_to_option_images):
Temp_Directory_Path.extend(dirnames)
print(Temp_Directory_Path)
break
#for each directory in the list with directories
for dir_name in Temp_Directory_Path:
#create path for file names - to iterate with walk()
Temp_Path = path_to_option_images + dir_name
#create title and dict - for later use
Dict1 = {dir_name : []}
super_dict_temp = {}
TempList = []
#for each image in path + dir_name
for (dirpath, dirnames, filenames) in walk(Temp_Path):
TempList.extend(filenames)
break
for values in TempList:
#currently only .png allowed
if values[-4:] == ".png":
value = "/static/options/" + dir_name + "/" + values
Dict1[dir_name].append(value)
super_dict_temp = Dict1.copy()
super_dict.update(super_dict_temp)
#print(super_dict)
return render(request, 'smaakjes/smaakjes.html', {'Drank': super_dict})
To retrieve the data you will :
HTML:
<p id="malek" onclick="getAttribute(this)" >malek</p>
JS:
function getAttribute(elem){
//get an attribute value of the element
idElement = elem.getAttribute('id');//src or howerver you want
}
//then you should submit it with ajax request
var xmlhttp = new XMLHttpRequest(); // new HttpRequest instance
xmlhttp.open("POST", "/YourRouteHere");//here you paste the route where u can receive data
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.send(JSON.stringify({src:idElement})); //And here ur data in Json Format
I found the solution in different posts. Also thanks to #Conan for pointing me in the right direction. The following json code worked for me:
function PostImageDetails(element) {
var imageSrc = element.src;
var imageId = element.id;
console.log(imageSrc);
console.log(imageId);
//String manipulate ID
imageId = imageId.split("/");
imageId = imageId[4];
imageId = imageId.split(".");
imageId = imageId[0];
imageId = imageId.replace(/[^a-zA-Z ]/g, "");
console.log(imageId);
//CREATE HTTP REQUEST
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "/api/users/", true);
xmlhttp.setRequestHeader("X-CSRFTOKEN", getCookie('csrftoken')); //HTTP_X_CSRFTOKEN
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.send(JSON.stringify({'url':imageSrc, 'username': imageId}))
//GET THE RESPONSE FROM THE SERVER
xmlhttp.onload = function(){
var csrftoken = getCookie('csrftoken');
console.log(csrftoken);
console.log(xmlhttp.status);
console.log(xmlhttp.statusText);
console.log(xmlhttp.responseText);
console.log(xmlhttp);
};
}
//Create Cookie/Token
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}

Using Django rendered lists in Javascript on the rendered html page

I am working on a django app where I made a custom view that passes a queryset of elements to the rendered html page.
In the html page I want to have an option to select a word from a select list and If the selected word matches any element from the list I got from view, I should need to display it.
I tried using Java script to read these elements into array and then use that array on chnage in select box. but it didnt work as I required.
Here is what I have done so far.
View:
from .models import words as m
def test(request):
words = m.objects.all()
context = Context({
'words': words,
})
return render(request, 'newpage.html',context)
newpage.html:
<select id="sel" onChange="func();">
<option value="" selected="selected">--none--</option>
<option value="word1">word1</option>
....
<option value="wordn">wordn</option>
</select>
<script>
function func()
{
var e = document.getElementById("sel");
var str = e.options[e.selectedIndex].value;
'{% for each in words %}'
var a="{{ each.word }}";
if(str===a)
{
console.log('{{each.word }}')//or passing it to a div in html
}
{% endfor %}
}
</script>
what I require is If the selected element is "word1" and if the queryset "words" has "word1" in it, it should display the word in the page in any div
can any one help me understand the right way to use this queryset object in the html/js.
Fix your script like the following, this should work for you:
<script>
function func() {
var e = document.getElementById("sel");
var str = e.options[e.selectedIndex].value;
"{% for each in words %}"
var a = "{{ each.word }}";
if(str === a) {
console.log("{{ each.word }}")
}
"{% endfor %}"
}
</script>
Try something like this:
<script>
var words = [
{% for word in words %}
"{{ word }}",
{% endfor %}
];
function func() {
var e = document.getElementById("sel");
var str = e.options[e.selectedIndex].value;
for (var word = 0; word < words.length; word++) {
if (words[word] === str) {
console.log(words[word]);
}
}
}
</script>

Non defined array?

The code I'm writing is supossed to fetch a set of airports urls, and assign them to an array by code-url.
This is what I have so far:
<script>
var airport = new Array();
function CheckAirportCode(){
{% for x in linklists['airports'].links %}
var y = {{x.url}};
y = y.match(/\/([A-Za-z0-9]{3})\-/);
airport[y] = {{x.url}};
{% endfor %}
}
$(document).ready(CheckAirportCode());
</script>
but when I load the page and access the variable from the console browser, it says it is undefined. Any pointers ?

How to pass the datastore value to javascript? i need to get data from the gae datastore and need to pass javascript

am working with GAE using webapp2, python.
Now am working in google map using gae. Successfully done with multiple locations.
This is my JavaScript:
======================
<script type="text/javascript">
var USER_POSITION;
var DESTINATION_MARKER;
var ALL_MARKERS = [];
var coordinateArray = [
{coordinates: new google.maps.LatLng(12.9345494,77.6115174), id: "forum", title: "Forum", address_details: Bengaluru<br/>Karnataka-560095"},
{coordinates: new google.maps.LatLng(12.973584,77.611293), id: "central", title: "Central", address_details: Bengaluru<br/>Karnataka-560001"},
{coordinates: new google.maps.LatLng(12.956534,77.701239), id: "busstop", title: "Marathahalli", address_details: Bengaluru<br/>Karnataka-560037"}
];
</script>
Here am using hardcode values. But i need to pass my datastore values.
How do i pass those datastore values to my javascript.
This is my DBModel:
====================
class MapModel(db.Model):
Lattitude=db.StringProperty()
Landitude=db.StringProperty()
Id=db.StringProperty()
Title=db.StringProperty()
Address=db.StringProperty()
Kindly provide some example code.
My.js:
var mapProperty = new google.maps.Map(document.getElementById("example"), myOptions);
for(var i in coordinateArray ) {
var id = coordinateArray[i]['id'];
var title = coordinateArray[i]['title'];
var position = coordinateArray[i]['coordinates'];
var address_details = coordinateArray[i]['address_details'];
var boxText = [
'<div class="info_box">',
..info details..
'</div>'
].join(" ");
var markerOptions = {
animation: markerAnimation,
position: coordinateArray[i]['coordinates'],
icon: markerImage,
map: mapProperty,
html: boxText,
id: id
};
You can use webapp2 templates to pass the data to your HTML page.
Python Code:
coordinates = MapModel.all()
template_values = {
'coordinates': coordinates
}
path = os.path.join(os.path.dirname(__file__), 'YourFile.html')
self.response.out.write(template.render(path, template_values))
In HTML Page:
<script type="text/javascript">
var USER_POSITION;
var DESTINATION_MARKER;
var ALL_MARKERS = [];
var coordinateArray = [
{% for cord in coordinates %}
{coordinates: new google.maps.LatLng({{cord.Lattitude}},{{cord.Landitude}}), id: "{{cord.id}}", title: "{{cord.title}}", address_details: "{{cord.Address}}"},
{% endfor %}
];
</script>

Categories