Django - Best way to refresh a div in a Template using Javascript? - javascript

I want to refresh the <div> that my google chart is embedded in every 30 seconds to display updates to the data in the model that it is using.
here is the template:
metrics.html
{% extends 'metrics/metrics_header.html' %}
{% block content %}
<h1>Metrics</h1>
<p>Submitted = {{ submitted }},
Conforming = {{ conforming }}
Transcoding = {{ transcoding }}
Complete = {{ complete }}
Error = {{ error }}
</p>
<script type="text/javascript">
google.charts.load("current", {packages:['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Job State', 'Jobs', { role: "style" }],
['Submitted', {{ submitted }},'blue'],
['Conforming', {{ conforming }},'purple'],
['Transcoding', {{ transcoding }},'yellow'],
['Complete', {{ complete }},'green'],
['Error', {{ error }},'red']
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2]);
var options = {
title: "Total Number of Jobs Processed",
bar: {groupWidth: "100%"},
legend: { position: "none" },
};
var chart = new google.visualization.ColumnChart(document.getElementById("columnchart_values"));
chart.draw(view, options);
}
</script>
<div id="columnchart_values" style="width: 100%; height:600px;"></div>
{% endblock %}
I have been using this to refresh the entire page: :
<script>
setTimeout(function(){
window.location.reload(true);
}, 5000);
</script>
As you can imagine it looks really bad when the entire page reloads every 5 seconds, is there a more ecstatically pleasing way to reload the <div>'s that contain jinja2 variables?

I solved my problem using Jquery .load().
setInterval(function () {
$("#div-you-want-to-reload").load("url-for-source-content");
}, 1000); // This reloads the <div> every 1 second.
I am using this with Django so I had to create a view to create the "url-for-source-content" and then reverence that in my url patterns for that app.

Related

Pass Django variables to javascripts

I am stuck into a problem, I want to pass django variable to javascripts but I can't.
views.py
def dashboard_view(request):
months_before = 5
now = datetime.utcnow()
from_datetime = now - relativedelta(months=months_before)
modified_from_datetime = from_datetime.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
month = Btdetail.objects.filter(DatePur__gte=modified_from_datetime).count()
return render(request, "dashboard.html", {'month': month})
I want to embed month value to javascripts data
my html script function is
<script>
var xValues = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
new Chart("myChart3", {
type: "line",
data: {
labels: xValues,
datasets: [{
data: [5,10,20,15,20,5,15,40,10,12,24,35],
borderColor: "red",
fill: false
}]
},
options: {
legend: {display: false}
}
});
</script>
actually I want to create a Area bar, all things are good but javascript functions cant get value from django database and if there is another way to do this please tell me
[1]: https://i.stack.imgur.com/9bJzE.jpg
on your anypage.html inside <body> </body> tag
<body>
<p> text for example </p>
<div> some divs </div>
<script type="text/javascript">
var month_count = {{ month }};
</script>
</body>
it will initiate month_count variable on your anypage.html and you could use it with javascripts inside this anypage.html
views.py
import json
def your_page(request):
context = {
"some_list": json.dumps([1,2,3]),
}
return render(request, "your_template.html", context)
javascript
<script>
const some_list = JSON.parse(`{{some_list|safe}}`);
</script>

How to show the default validation message in a multi select (selectpicker) with formvalidation.io and multiple languages

Goal
Show the default error message for a multi select field (styled with selectpicker) in various languages.
Description
I have a multi step wizard and want to validate a multi select dropdown with the formvalidation.io JS plugin. I don't know, how to make it work, that the default message from the appropriate language file (en_US.js, de_DE.js) is shown.
The thing i don't get is how to use the default error message for a choice validation from formvalidation.io. Docs for single lang are here but i can't figure out how to make it work with multiple languages.
JS code
var _initValidation = function () {
let language = window.uh.localeIso
const plugins = () => {
return {
trigger: new FormValidation.plugins.Trigger(),
bootstrap: new FormValidation.plugins.Bootstrap(),
}
}
if (language === 'en_GB') { language = 'en_US'}
// Step 1
_validations.push(FormValidation.formValidation(
_formEl,
{
locale: language,
localization: FormValidation.locales[language],
fields: {
company: {
validators: {
notEmpty: {}, // <---- this works with multiple languages
},
}
// and so on...
},
plugins: plugins(),
},
))
// Step 2
_validations.push(FormValidation.formValidation(
_formEl,
{
fields: {
'job_ad_visible_country[]': {
validators: {
choice: {
min: 1,
max: 3,
message: {} // <--- what here for the default validation message in multiple languages?
}
},
},
},
plugins: plugins(),
},
))
}
HTML Code
...
<div class="col-xl-6">
<div class="form-group">
<label>{{ "job.wizard.two.country" | trans }}</label>
<select class="form-control form-control-lg selectpicker"
name="job_ad_visible_country[]"
title="{{ "job.wizard.nothing-selected" | trans }}"
multiple="multiple"
data-depend-select="true"
data-dependent="country_region">
{% for country in countries %}
<option value="{{ country.getCountryId() }}" selected="selected">
{{ country.getName() | trans }}
</option>
{% endfor %}
</select>
<span class="form-text text-dark-40">
{{ "job.wizard.two.country.subtitle" | trans }}
</span>
</div>
</div>
...
... and at the bottom of course the JS scripts
<script type="text/javascript" src="{{ '/assets/wizard.js' | asset }}"></script>
<script type="text/javascript" src="/assets/translations/validation/{% if locale_iso() == 'en_GB' %}en_US{% else %}{{ locale_iso() }}{% endif %}.js"></script>
Solution:
In step 2 the language was missing. So it has to look like this (to see how i get the language code, look at my question):
_validations.push(FormValidation.formValidation(
_formEl,
{
locale: language,
localization: FormValidation.locales[language],
fields: {
'job_ad_visible_country[]': {
validators: {
choice: {
min: 1,
max: 3,
}
},
},
},
plugins: plugins(),
},
))

Chart.js does not get the updated value from Flask

Working on a project here where I take values from an API, using Flask. And then adding it to a chart using chart.js
I got it to work somewhat, issue I am having is that the variable I use to add the value to the chart with, but it does not change the variable, I add to the chart, whenever the value changes in the API.
Meaning:
Sell Price: 10.3
sell price change to 10.4
Sell Price: 10.3 <-- It does not change to 10.4
Here is my python code for it:
#app.route('/product/<product>')
def productPage(product):
price = []
data = requests.get(
'https://api.hypixel.net/skyblock/bazaar?key=').json()
sell = data['products'][product]['sell_summary']
for x in sell:
price.append(x['pricePerUnit'])
currentSell = data['products'][product]['sell_summary'][0]['pricePerUnit']
return render_template('product.html', product=product, price=price, currentSell=currentSell)
#app.route('/graph_update/<product>', methods=['GET', 'POST'])
def graph_update(product):
data = requests.get(
'https://api.hypixel.net/skyblock/bazaar?key=').json()
currentSell = data['products'][product]['sell_summary'][0]['pricePerUnit']
return jsonify('', render_template('graph_update.html', currentSell=currentSell))
And here HTML/JS:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<div class="container" style="position: relative; height: 40vh; width: 80vw">
<canvas style="width: 25%" id="myChart"></canvas>
</div>
<input
type="button"
value="add data"
style="margin-top: 25%"
onclick="addData()"
/>
<h1 style="padding-top: 25%">{{product}}</h1>
{% for sell in price %}
<p id="sellprice">{{ sell }}</p>
{% endfor %}
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<script>
var sellprice = JSON.parse("{{ currentSell | tojson | safe }}");
var product = "{{ product }}";
let myChart = document.getElementById("myChart").getContext("2d");
let priceChart = new Chart(myChart, {
type: "line", // bar, horizontalBar, pie, line, doughnut, radar, polarArea
data: {
labels: [],
datasets: [
{
label: "Sell Price",
},
],
},
options: {},
});
var getData = function () {
$.ajax({
url: "/graph_update/" + product,
success: function (data) {
// process your data to pull out what you plan to use to update the chart
// e.g. new label and a new data point
// add new label and data point to chart's underlying data structures
var sellprice = JSON.parse("{{ currentSell | tojson | safe }}");
priceChart.data.labels.push(sellprice);
priceChart.data.datasets[0].data.push(sellprice);
// re-render the chart
priceChart.update();
},
});
};
// get new data every 3 seconds
setInterval(getData, 10000);
</script>
Thanks!
The issue is that your python code at the endpoint /graph_update/<product> should return data as JSON and currently it is doing the following:
return jsonify('', render_template('graph_update.html', currentSell=currentSell))
You need to return something like
return jsonify(data) # or subset of data that you need to pass

How to modify shopify reorder to cart to add custom line item properties

I am trying to add a reorder button to my customer's order history pages to automatically reorder items they've already purchased. This would send them back to the cart with items already prefilled and ready for checkout. Each product item has custom properties attached to it. Everything seems to work fine, except that when I add the items back into the cart, I cannot get the custom line item properties to display.
I'm using the order-to-cart.liquid snippet.
On line 18, it seems the custom properties are being called:
properties: {{ line_item.properties | json }}
I've tried to modify the code to add them:
request.send(JSON.stringify({
'quantity':order.items[0].quantity,
'id':order.items[0].variant_id,
'properties':order.items[0].properties
}));
But this does not work.
Based on the comment below, I tried to loop through the item properties:
request.send(JSON.stringify({
'quantity':order.items[0].quantity,
'id':order.items[0].variant_id,
'properties': {
{% for line_item in order.line_items %}
{% for property in line_item.properties %}
'{{ property.first }}': '{{ property.last }}'{% unless forloop.last %},{% endunless %}
{% endfor %}
{% endfor %}
}
}));
But I get syntax error:
SyntaxError: missing } after property list
note: { opened at line 403, column 26
Which seems to reference the property list of request.send
The outputted example json is:
/* Setup the order object. Extend this as needed. */
var order = {
items:[
{
variant_id: 16320547225634,
product_id: 1782978904098,
properties: [["Arrangement Type",""],["Enclosed Card",""],["Occasion \u0026amp; Comments","Condolescens"],["Delivery Date","Mar 29, 2019"]],
available: true
},
{
variant_id: null,
product_id: 1776316743714,
properties: [["Arrangement Type",""],["Enclosed Card",""],["Occasion \u0026amp; Comments",""],["Delivery Date","Mar 24, 2019"]],
available: null
},
{
variant_id: 16319970017314,
product_id: 1782916808738,
properties: [["Arrangement Type","Seasonal"],["Enclosed Card","Love and best wishes"],["Occasion \u0026amp; Comments","Just Because"],["Delivery Date","Mar 25, 2019"]],
available: true
},
{
variant_id: 16311468687394,
product_id: 1780877819938,
properties: [["Arrangement Type","Large vase with orchids"],["Enclosed Card","Steal the warm chair right after you get up when owners are asleep, cry for no apparent reason sleeps on my head."],["Occasion \u0026amp; Comments","Birthday so make extra special!"],["Delivery Date","Apr 10, 2019"]],
available: true
}
]
};
request.send(JSON.stringify({
'quantity':order.items[0].quantity,
'id':order.items[0].variant_id,
'properties': {
'Arrangement Type': '',
'Enclosed Card': '',
'Occasion & Comments': 'Condolescens',
'Delivery Date': 'Mar 29, 2019'
'Arrangement Type': '',
'Enclosed Card': '',
'Occasion & Comments': '',
'Delivery Date': 'Mar 24, 2019'
'Arrangement Type': 'Seasonal',
'Enclosed Card': 'Love and best wishes',
'Occasion & Comments': 'Just Because',
'Delivery Date': 'Mar 25, 2019'
'Arrangement Type': 'Large vase with orchids',
'Enclosed Card': 'Steal the warm chair right after you get up when owners are asleep, cry for no apparent reason sleeps on my head.',
'Occasion & Comments': 'Birthday so make extra special!',
'Delivery Date': 'Apr 10, 2019'
}
}));
My cart.liquid file calls the custom properties like so:
{% if property_size > 0 %}
{% for p in item.properties %}
{% assign first_character_in_key = p.first | truncate: 1, '' %}
{% unless p.last == blank or first_character_in_key == '_' %}
<div class="label-info">{{ p.first }}:
<strong class="input-info">{{ p.last }}</strong>
</div>
{% endunless %}
{% endfor %}
{% endif %}
But I'm not sure if I need to modify this to accommodate any properties already created.
The custom line item properties need to show up when added back to the cart, otherwise the reorder function won't really be a time saver as it will force customers to go back to each product page to re-add info into the custom fields.
I'm not that versed in liquid so not quite sure what needs to be done to modify the snippet or cart templates. Any help you could provide would be greatly appreciated!
Many thanks,
Mark
The reason 'properties':order.items[0].properties does not work is because it contains an array with the name and value of the line item property.
To set this up we will need to turn the array into and object and then pass that into the request.send function.
A function I found that achieves this can be seen in this post. You can copy and paste this function into the orderItems function.
Once that is added we then create the properties variable, passing in order.items[0].properties as an argument to turn this into an object.
This variable is added along with the 'quantity' and 'id' in request.send.
Here is how the orderItems function will look once everything is added:
/* Simple function add to cart */
var orderItems = function(){
if(!order.items.length){ return }
if(!order.items[0].available){
checkQueue();
}
function objectify(array) {
return array.reduce(function(p, c) {
p[c[0]] = c[1];
return p;
}, {});
}
var properties = objectify(order.items[0].properties);
var request = new XMLHttpRequest();
request.open('post', '/cart/add.js', true);
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.onload = function() {
var resp = request.responseText;
if (request.status >= 200 && request.status < 400) {
checkQueue();
} else { /* add your error handling in here */ }
};
request.onerror = function() {
/* add your error handling in here */
};
request.send(JSON.stringify({
'quantity':order.items[0].quantity,
'id':order.items[0].variant_id,
properties
}));
};
Hope that helps!

Django template tag, making my list empty or I'm not pass anything

Thanks for reading my post
okay, I'm currently working on Django project that displays data in a dashboard; I manage to display and draw charts with Chart JS, great but now I need to limited number data in Django database to be displayed on charts and display the most recent data put into the database.
I use Django built-in tag to display the most recently is "last" and limiting the display data, the tag is "length_is"(Solve).
Here are my HTML codes for using the "last" tag and index page
<div class = "containor">
<div class = "float-right my-4 chartjs-render-monitor" id="chartContainerPH" style="width: 49%; height: 400px;display: inline-block; background-color:#FDFDFD;">
<center>
<a class="title-link" href="{%url 'ph' %}">PH:</a>
<p>{% for tank_system in tank %} {{tank_system.ph|last}} {%endfor%}</p>
</center>
{%include 'FrounterWeb/includes/PHchart.html'%}
</div>
This is the result I get Last Tag result in my index
(Solve)
Here' my code for chart HTML which I use the length_is tag
{%block PHchart%}
<canvas class = "my-4 chartjs-render-monitor" id="PHchart" ></canvas>
<script>
var ctx = document.getElementById("PHchart");
var PHchart = new Chart(ctx, {
type: 'line',
data: {
labels: [ {%for tank_system in tank%} "{{tank_system.datetime}}", {%endfor%} ], //x-Axis
datasets: [{ //y-Axis
label: 'PH1',
data: [ {%for tank_system in tank%} {{tank_system.PH|length_is:"3"}}, {%endfor%} ],
backgroundColor: "rgb(249, 24, 24,0.2)",
borderColor: "rgb(249, 24, 24,0.2)",
fill: true,
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:false
}
}]
}
}
});
</script>
</div>{%endblock%}
and the result Length_is on chart
Summary: I can't get the built-in "filter" and "length_is"(Solve) Django tags to work. Could you please share an example or tutorial with me? The Django documentation didn't write many examples.
and here my views codes;
#login_required(login_url='/accounts/login/')
def index(request):
tank = tank_system.objects.all()
args = {'tank':tank}
return render(request,'FrounterWeb/extends/includes.html',args)
and my models' codes;
class tank_system(models.Model):
PH = models.DecimalField(max_digits=3, decimal_places=1)
EC = models.DecimalField(max_digits=3, decimal_places=1)
WaterLevel = models.IntegerField(default=100)
TempWater = models.IntegerField(default=0)
TempRoom = models.IntegerField(default=0)
datetime = models.DateTimeField(default=timezone.now())
Both of these filters are well documented in the django docs. The last filter gets you the last element of a list, and the length_is filter returns True if the list is that length, or False otherwise.
This likely means that there is an issue in your understanding of your code. You'll want to verify the type and the values of tank_system.PH or tank_system.ph (you have both) and the case will matter. One way to debug this is to simply output the value of tank_system.ph to the web page and verify the result.

Categories