Google maps not being displayed in django template - django

I am trying to display a google map for a django site. I have a template, roughly,
{% extends "base.html" %}
{% load staticfiles %}
{% block content %}
...
<div class="col-md-6">
<div id="map_canvas" style="width:100%;height:400px;background-color:#CCC;"></div>
</div>
...
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script>
function initialize() {
var mapCanvas = document.getElementById('map_canvas');
var mapOptions = {
center: new google.maps.LatLng(44.5403, -78.5463),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(map_canvas, map_options);
}
</script>
{% endblock%}
When I reload the webpage, I can see that a request is being made for Google's map url's , but I see no map, just a plain gray background.

i have the same problem in html code I delete <!DOCTYPE html> and it work

You just need to add the line before closing your script tag:
google.maps.event.addDomListener(window, 'load', initialize);
You can see it in the Documentation

Related

Django ChoiceField RadioSelect widget in form, test whitch element selected in template

I have 2 radio buttons in a ChoiceField and I would like to display some parts of the template, depending of witch radio button is selected.
Following :
form.py
class CtdForm(forms.Form):
protocol_name = forms.CharField(max_length=100)
rb = forms.BooleanField(required=False, label='RB')
mr = forms.BooleanField(required=False, label='MR')
CHOICES = [('rb' ,'RB'), ('mr', 'MR')]
analyse_type = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect)
template html
...
{{ form.analyse_type }}
Here I would like to test which button is selected and display the template depending of the selection
something like : {% if form.analyse_type.? == true %}
...
I test a lot of syntaxe with form.analyse_type.? like form.analyse_type.field.widget.choices to have each choices in a loop ect. , but I do not found the right one returning the selected radiobutton...
Maybe this way is not the right one to do what I want.
If you have any idea, solution thank you ;)
Edit for user2497126
Thanks for all tips :) !
I have an error Uncaught Error: GET_ELEMENTS: -> form[data-sb-form-api-token] seems to be in link with the object analyse_type
As requested, following a print screen with the html element.I tired different synthaxe like
let radioValue =$("input[name='analyse_type']:checked").value();
I also put my HTML code in case
{% extends "index.html" %}
{% load static %}
{% block content %}
<div style="padding-left: 30%;" class="col-lg-6 col-xl-6"
<h2 class="h4 fw-bolder">
Analyse Type
</h2>
<br>
{{ form.analyse_type }}
<br> </div>
<div id="template-one" style="display:none;">
<div style="padding-right: 30%;" class="col-lg-6 col-xl-6">
<h2 class="h4 fw-bolder">
TEST
</h2>
</div>
</div>
{% endblock %}
{% block javascript %}
<script type="text/javascript">
$(document).ready(function () {
$(".custom-control-input").change(function () {
let radioValue = $("input[name='analyse_type']:checked").value();
let templateOne = document.getElementById('template-one')
if (radioValue == "rb") {
$("#template-one").show();
} else {
$("#template-one").hide();
}
});
});
</script>
{% endblock javascript %}
EDIT
if I do a
console.log($("input[name='analyse_type']:checked").val())
in the debugger of chrome I have a return of rb.
But the error is still there with no result.
I also change the html, include the template-one in the same div of the form like your example
The problem seems here
$(".custom-control-input").change(function () {
I replace .custom by select or select#id_analyse_type, based on some forum answers, but I have no result
Thanks for your time and your help :)
EDIT
Here the solution :
{% block javascript %}
<script type="text/javascript">
$(document).ready(function () {
let radioValue = $("input[name='analyse_type']:checked").val();
if (radioValue == "rb") {
$("#template-one").show();
} else {
$("#template-one").hide();
}
$('#id_analyse_type').change(function () {
let radioValue = $("input[name='analyse_type']:checked").val();
if (radioValue == "rb") {
$("#template-one").show();
} else {
$("#template-one").hide();
}
});
});
</script>
{% endblock javascript %}
Thank you for your help !
Here is an edited answer which I have tried to adapt to your question
For the change function (i.e when selecting the radio) inspect and replace the class value with the one in your radio input. Also ensure you supply the correct name when instantiating the variable radioValue, I have used 'analyze_type' for the sake of the example but inspect and confirm the correct name value of the radio input.
You can achieve it using JS like this in your template
{% extends "base.html" %}
{% block title %}Form title{% endblock title %}
{% block content %}
<!-- page content -->
<div class="x_content">
{{ form.analyse_type}}
<div id="template-one" style="display:none;">
Template one
</div>
<div id="template-two" style="display:none;">
Template two
</div>
</div>
<!-- /page content -->
{% endblock %}
{% block javascript %}
<script>
$(document).ready(function(){
$(".custom-control-input").change(function(){
let radioValue = $("input[name='analyse_type']:checked").val();
let templateOne = document.getElementById('template-one')
if(radioValue == "RB"){
$("#template-one").show();
$("#template-two").hide();
}
else {
$("#template-two").show();
$("#template-one").hide();
}
});
});
</script>
{% endblock javascript %}

How can I make chart day to day objects count in Django?

My question is I need to make a dashboard page. In that, I need to make a chart on day to day created objects by the specific user in Django like the image below.
Also, I need to know how to save data for this like charts.
There are lots of options if you want to create charts. Most of them are JS and/or Ajax which you can include in the template page. Try this Google Charts which I believe is the simplest way to get things up and running,
https://developers.google.com/chart/interactive/docs/gallery/piechart
You can use the parameters from the context dictionary to generate a dynamic graph.
1 From views.py Send the Value of the data (ie the number of Problems solved) through the context Dictionary.
ex: views.py
def index(request):
context = {"problems_solved" : calculated_value}
return render(request, "results.html", context)
in the Template HTML do the following ,
results.html:
{% extends "base.htm" %}
{% load static %}
{% block title %}
results
{% endblock %}
{% block head %}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
var solved = {{problems_solved}};
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['day', 'problems solved'],
['prob solved', solved ]
]);
var options = {
title: 'Profile progress Report: '
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
</script>
{% endblock %}
{% block body %}
<div id="piechart" style="width: 600px; height: 500px;">
{% endblock %}
If you are looking it to be generated everyday dynamically then you need to append values based with date to the context dictionary and execute the form generation everytime the page gets loaded

Django template block from within template tag template

I have a template called base.html. This template contains a block called pagescripts at the bottom after jQuery has been loaded, like this:
<div class="container-fluid">
{% block content %}
{% endblock %}
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
<script defer src="https://use.fontawesome.com/releases/v5.0.10/js/all.js" integrity="sha384-slN8GvtUJGnv6ca26v8EzVaR9DC58QEwsIk9q1QXdCU8Yu8ck/tL/5szYlBbqmS+" crossorigin="anonymous"></script>
{% block pagescripts %}
{% endblock %}
Next, I have a template tag that is an inclusion tag for displaying a fancy-looking boostrap 4 card for a particular news article, like this:
#register.inclusion_tag('long_article_card.html', takes_context=True)
def show_long_card(context, article):
try:
contextForm = context['form']
except KeyError:
contextForm = None
return {'article':article, 'form': contextForm}
Now, within that long_article_card.html, I want to add a script to the pagescripts block from base.html. So, in long_article_card.html, I have this:
<div class="target">TARGET HERE</div>
<a class="dropdown-item" id="lean-vote-xl" href="#">Extreme Left</a>
{% block pagescripts %}
<script>
$(document).ready(function(){
$("#lean-vote-xl").on('click', function(){
$.ajax({
url:'/webproxy/v/?i=a&pk={{article.id}}&t=1&v=3',
type:'get',
dataType:'html',
crossDomain:true,
success:function(data)
{
var outputCard = "<div class=\"target\"><br><h2>That worked</h2></div>";
$(".target").html(outputCard);
},
error: function(data) {
var outputCard = "<div class=\"target\"><br><h2>Load Error</h2></div>";
$(".target").html(outputCard);
}
});
}); // end id_url_text
});
</script>
{% endblock %}
That template tag is then called from an article detail template called article/detail.html, which extends base.html.
{% extends 'base/base.html' %}
<div class="row">
{% show_long_card article %}
</div>
But that results in the javascript in long_article_card.html being rendered at the end of long_article_card.html, which means it is rendered before jQuery is loaded at the bottom of the page, therefore the script doesn't work because $ is not defined yet. What I need to happen is for the block pagescripts from long_article_card.html to be rendered at the very bottom of the page, essentially at the bottom of base.html. I need django to take the block pagescripts from long_article_card.html, pass it up to article/detail.html, and then article/detail.html to pass it up to base.html, then base.html includes it in its pagescripts block that is at the very bottom of base.html after jQuery is loaded.
I can't have long_article_card.html extend the article/detail.html because it causes a recursion error. Is there any way for long_article_card.html to add things to base.html's pagescripts block?
Thank you.
django-sekizai was built for this use case. It may be of use to you

Why doesn't the curly braces work for a Vue app within a Django template?

Basically, Im trying to integrate Vue with Django. I have the following template:
<!DOCTYPE html>
<html>
<head>
<title>Django Vue</title>
</head>
<body>
{% verbatim %}
<div id="components-demo">
<button-counter></button-counter>
</div>
{% endverbatim %}
<!-- Vuejs -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- App -->
<script>
// Define a new component called button-counter
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: `
<button v-on:click="count++">You clicked me {{ count }} times.</button>
`
});
// App definition
new Vue({ el: '#components-demo' });
</script>
</body>
</html>
Everything is very simple, CDNs are used, not webpack. The component shows up, but the count does not. In other words, the curly braces are not functioning properly within my template. Why is that? I have the verbatim tag up and running.
It looks like this:
Any help?
You didnt wrap the {{count}} with a {% verbatim %} tag, which means {{count}} is being interpreted by Django, not by Vue (you should be able to see that this is the case if you inspect the template that is being rendered).
This should work:
<!-- App -->
{% verbatim %}
<script>
// Define a new component called button-counter
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: `
<button v-on:click="count++">You clicked me {{ count }} times.</button>
`
});
// App definition
new Vue({ el: '#components-demo' });
</script>
{% endverbatim %}
The {% verbatim %} tag you used is not really necessary, because the reason you want to use it (in this case) is because both Django and Vue use the same mustache {{}} syntax, which is causing the conflict. This means you should use {% verbatim %} only if there would otherwise be a conflict of syntax (for example, the mustache syntax).

Django TinyMCE issues

All the textareas are inline, StackedInline
All textareas works fine in this model change_view. BUT, when I add a new row the last row is not editiable in the textarea.
If I remove the mode:"textareas" in the tunyMCE Init, it abviasly removes the wsgi editor but then the textareas work when adding new ones. So I guess its tinyMCE that breaks it.
But I haved copied this tinyMCE files form another project where it works. So I dont know wtf!
I have my tinymce setup like this:
media/js/tinymce
then I have in templates:
templates/admin/app_name/model_name/change_form.html
and this is my change_form.html
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block extrahead %}{{ block.super }}
{% url 'admin:jsi18n' as jsi18nurl %}
<script type="text/javascript" src="{{ jsi18nurl|default:"../../../jsi18n/" }}"></script>
{{ media }}
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript">
function CustomFileBrowser(field_name, url, type, win) {
var cmsURL = "/admin/filebrowser/browse/?pop=2";
cmsURL = cmsURL + "&type=" + type;
tinyMCE.activeEditor.windowManager.open({
file: cmsURL,
width: 850, // Your dimensions may differ - toy around with them!
height: 650,
resizable: "yes",
scrollbars: "yes",
inline: "no", // This parameter only has an effect if you use the inlinepopups plugin!
close_previous: "no",
}, {
window: win,
input: field_name,
editor_id: tinyMCE.selectedInstance.editorId,
});
return false;
};
tinyMCE.init({
// add these two lines for absolute urls
remove_script_host : false,
convert_urls : false,
// General options
mode : "textareas",
theme : "advanced",
plugins : "safari,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media",
file_browser_callback: 'CustomFileBrowser',
// Theme options
theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|styleselect,formatselect,|,undo,redo,|,link,unlink,image,code",
theme_advanced_buttons3 : "",
theme_advanced_buttons4 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
// theme_advanced_statusbar_location : "bottom",
theme_advanced_resizing : false,
width:300,
height:300,
});
</script>
{% endblock %}
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
<li>{% trans "History" %}</li>
{% if has_absolute_url %}
<li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink">
{% trans "View on site" %}</a>
</li>
<li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/html/" class="viewsitelink">
{% trans "View source" %}</a>
</li>
{% endif%}
</ul>
{% endif %}{% endif %}
{% endblock %}
Even If I do this in textareas.js and include that in the chnage_form.html extrahead block it does the same.
Well, I figured out what was wrong. Maybee someone runs into the same problem
The problem is thart when adding a new row, that texarea is not initiated by tinymce, bacause it only does that once, when the pages loads. Makses perfect sence, so you need to add functionality to the textarea again after adding anew row.
This is how I did it:
change_form.html, added this to the bottom of the file
$(".add-row a").click(function () {
// this is the span that the current wsgi editor is in, so I remove it
$($(this).parent().prev().prev().find("span")[2]s).remove();
// Now I display the original textarea
$(this).parent().prev().prev().find("textarea").show();
// and Finaly lets add MCE control to this area.
tinyMCE.execCommand(
'mceAddControl',
false,
$(this).parent().prev().prev().find("textarea").attr('id')
);
});