Sending JSON Data from Python to Javascript and accessing them. - javascript

I have a python file that gets the data from database and returns them in the form of JSON.
import pymysql;
import json;
from flask import Flask, render_template, request, redirect, Response
app = Flask(__name__)
#app.route('/test', methods=["POST", "GET"])
def getMySQlData():
tableData = []
connection = pymysql.connect(host='db-auto-performancetesting',
user='DBUser',
password='*******',
database='DbPerformanceTesting',
port=3302,
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
try:
with connection.cursor() as cursor:
sql = "SELECT TestcaseName, AverageExecutionTimeInSeconds FROM PASPerformanceData WHERE BuildVersion='38.1a141'"
cursor.execute(sql)
while True:
row = cursor.fetchone()
if row == None:
break
tableData.append(row)
tableDataInJson = json.dumps(tableData, indent=2)
print tableDataInJson
return tableDataInJson
finally:
connection.close()
if __name__ == "__main__":
app.run()
I need help in collecting this JSON data into HTML & Javascript and use them as the chart data.
I am new to Javascript and ajax. Can someone help me in writing ajax call to python file from Javascript and retrieve the JSON data returned.
<!DOCTYPE HTML>
<html style="height:100%;">
<head>
<style type="text/css">
body {
overflow:hidden;
}
</style>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript">
window.onload = function () {
var chart1 = new CanvasJS.Chart("chartContainer1", {
title:{
text: "Launch Application"
},
axisY:{
title: "Average Execution Time(seconds)"
},
axisX:{
title: "Software Version",
labelAngle: 180
},
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
indexLabelFontSize: 16,
labelFontSize: 16,
type: "column",
dataPoints: [
{ label: "ReleaseVersion \n (20.1a121)", y: "**Data recieved from JSON, indexLabel**": "6.0 s" },
{ label: "PreviousVersion \n (38.1a140)", y: "**Data recieved from JSON**", indexLabel: "5.0 s" },
{ label: "CurrentVersion \n (38.1a.141)", y: "**Data recieved from JSON**", indexLabel: "5.4 s" }
]
}
]
});
Thanks

So let me give you quick overview of how might AJAX and flask work together.
Lets say you have some data that you get from database which is something like this
items=[{"id":123,"name":"abc","lastname":"xyz"}]
And you could store something like this with a small piece of code which would be something like this
result = cursor.fetchall()
links = []
num = 0
for item in result:
if links.__len__()-1 != num:
links.append({})
links[num]['id'] = item[0]
links[num]['name'] = item[1]
links[num]['lastname'] = item[2]
#links.append({}) extra append should be created
num += 1
Now the interesting AJAX part
Lets say you have a simple form that you would want to submit.
<form id="searchForm" action="/" method="POST">
<input type="text" id="search" name="search" placeholder="Search">
<input type="submit" value="Search">
</form>
To stop default action for submit you can have a script which would be something like this
$(document).ready(function() {
//#addLinkForm is nothing but the id of the form (works well if you have multiple forms in your page)
$('#addLinkForm').on('submit',function(event){
//This is where the data is sent
$.ajax({
url: '/adminAJAX',
type: 'POST',
data: $('#addLink'),
})
//this is done when the response is received
.done(function(data) {
console.log("success " + data);
});
event.preventDefault();
});
});
The response would be in your browser console. The data received can be used as you see fit
For this to work you would also need
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
in your HTML code
One last thing. For all of this to work you would also need your server side which i guess would be flask for you
#app.route('/adminAJAX',methods=['POST'])
def adminAJAX():
#your processing logic
items=[{"id":123,"name":"abc","lastname":"xyz"}] #just an example
return json.dumps(items)

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 access Queryset returned to template by AJAX response - Django

I want to return a queryset to a template using ajax.
this is my ajax function in a seperate js file:
$(document).ready(function(){
$("#data_to_plot_button").click(function(){
var serialized_data = $("#data_to_plot_form").serialize();
$.ajax({
url: $("data_to_plot_form").data('url'),
data: serialized_data,
type: 'post',
success: function(response){
$("#graph").append('<p>data returned successfuly</p>'); //this line is printed correctly.
$.each(response, function(i, val) {
$('graph').empty().append(
$('<li>').addClass('list-group-item list-group-item-success').text(val)
)
}); // this block adds nothing to the #graph div
}
})
});
});
and my views.py:
def my_products(request):
queryset_list_intro_products = Intro_products.objects.all().order_by('title')
products = 0
if request.method == 'POST':
products_checkbox = request.POST.get('products')
if products_checkbox:
products = serializers.serialize('json', list(queryset_list_intro_products))
context = {
'products': products,
}
return JsonResponse(context, status=200)
return render(request, 'users/basket/my_products.html')
based on an answer to this question, I try to access the returned products which is in response. but the js code adds nothing to the #graph div.
in XHR section of network tab of inspects in chrome, the ajax call's status is 200 and in the preview section I can see the products as following:
products: "[{"model": "products.intro_products", "pk": 5, "fields": {"products_intro": false, "ip_sensor_intro": false, "control_valve_intro": false, "water_quality_sensor_intro": false, "accessories_intro": true, "cover_intro": "photos/products/intro_cover/solutions.png", "title": "Accessories", "subtitle": "", "description": "description", "detailed_description": "", "video_link": "", "is_published": true, "image_left": "", "title_left": "", "description_left": "", "image_right": "", "title_right": "", "description_right": ""}},
How to access the fields of an ajax response knowing its a queryset?
You need to do something like this;
from django.template.loader import render_to_string
if request.is_ajax():
html = render_to_string(
template_name="your seperate template where you want to display the queryset",
context=dict_of_items_to_be_passed_to_above_temp.
)
data_dict = {"html_from_view": html}
return JsonResponse(data=data_dict, safe=False)

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.

What is the proper way to get the data for Highcharts in Rails

My Rails website display a simple table about name and age of students.
name age
Lily 25
Tom 27
Chris 19
...
So I have #names = Student.pluck(:name), #ages = Student.pluck(:age). Now I would like to generate a line chart by using Highcharts:
HTML: <div id='students-chart'></div>
JavaScript:
$(function() {
Highcharts.chart('students_chart', {
...
};
};
Now I should provide the name and age to the chart as the xAxis and yAxis. The simplest way is to include the JavaScript in the html.erb file and provide the data by <%= #names %> and <%= #ages %>. However, it's not recommended, and I want to put the JavaScript code in the assets/javascripts/students.js file.
A very common way to fetch the data in the JavaScript file is using the Ajax, however, my data is already in the page so I don't want to add an extra action in the controller to send the data.
So what's the best practice to get the data for the Highcharts? data- attribute?
No front-end frameworks in the project, only jQuery. I know some gems could help me like Chartkick or LazyHighCharts, but I would like to know the basic strategy.
This is one way to show the chart, just jQuery getting data from the controller.
In controller fetch the data, adjust and convert to json. Customise respect to on your models. Here is an example with an array of hashes (data are passed as arrays):
#series = [ {name: 'Lily', data: [25]}, {name: 'Tom', data: [27]}, {name: 'Chris', data: [19]} ].to_json
For example, if your User model includes the age column, you can adjust like this:
#series = User.all.map{ |user| {name: user.name, data: [user.age]} }.to_json
In view (customise as you will), passing the variable here:
<div id='students_chart'></div>
<script>
$(function () {
var myChart = Highcharts.chart('students_chart', {
chart: {
type: 'column'
},
title: {
text: 'User ages'
},
xAxis: {
categories: ['Users']
},
yAxis: {
title: {
text: 'Age'
}
},
series: <%= raw #series %>
});
});
</script>
Edit - get data from server
Instead of sending data to view, render as json (no need to add e new action):
respond_to do |format|
format.html
format.json { render json: #series }
end
Then place the javascript in a file and get json data using jQuery.getJSON():
$.getJSON(window.location.href, function(json) {
var highChartData = json;
console.log(json)
var myChart = Highcharts.chart('students_chart', {
chart: {
type: 'column'
},
title: {
text: 'User ages'
},
xAxis: {
categories: ['Users']
},
yAxis: {
title: {
text: 'Age'
}
},
series: highChartData
});
});

Displaying Data in Dojogrid using dojo.xhrget() method

I want to display a set of data which i am retrieving by an asynchronous call to the server using dojo.xhrget() method. I am retrieving data through a URL and i want that everytime a user clicks in content pane a new set of values gets displayed in grid without refreshing whole page. The problem is that data is not getting displayed in Grid. I am receiving an error by xhrget() error method.
The code for my script is ::
<script>
function populateGrid(){
dojo.xhrGet({
url: "http://localhost:8080/2_8_2012/jsp/GetJson.jsp",
load: fillGrid,
error:handleError,
preventCache:true
});
}
function fillGrid(data, ioArgs)
{
alert(data);
var newData = {
identifier: "ID",
items: data
};
var dataStore = new dojo.data.ItemFileReadStore({data: newData, id:"dataStoreId"});
var gridStructure =[[
{ field: "ID",
name: "ID_Emp",
width: "20%",
classes:"firstName"
},
{
field: "Names",
name: "Name",
width: "20%",
classes: "firstName"
},
{ field: "Email",
name: "Mail",
width: "20%",
classes:"firstName"
}
]
];
var grid = dijit.byId("grid.DataGrid");
grid.setStore(dataStore);
grid.startup();
}
function handleError() {
alert("An error occurred while invoking the service.");
}
</script>
Now , here the output of alert(data) and http://localhost:8080/2_8_2012/jsp/GetJson.jsp is same i.e ::
[{"ID":1,"Names":"Shantanu","Email":"shantanu.tomar#gmail.com"},{"ID":2,"Names":"Mayur","Email":"mayur.sharma#gmail.com"},{"ID":26,"Names":"Rohit"}]
My xhr.get function is working fine in terms of data retrieval. i.e when i update the values in a database. I do get the alert(data) output with that updated value without refreshing the whole page again. But data is not displayed in Data grid.
I am receiving an alert
An error occurred while invoking the service.
The code for http://localhost:8080/2_8_2012/jsp/GetJson.jsp is ::
<%# page language="java" contentType="application/json; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# page import="MyPackage.PopulateTextbox" %>
<%
String temp1;
PopulateTextbox obj = new PopulateTextbox();
temp1 = obj.method();
%>
<%=temp1 %>
The markup code is ::
<div id="grid.DataGrid" data-dojo-type="dojox.grid.DataGrid" title="Simple Grid" data-dojo-props= "autoWidth:true, structure: gridStructure" style="width:900px; height:200px;"></div>
<div id="contentpaneid" dojoType="dijit.layout.ContentPane" title="Pending Activities" style="background-image: url('http://localhost:8080/2_8_2012/images/17.png');" onclick="populateGrid">
I am not getting what's the problem. Can u please help me out on why am i getting an error alert. thanks.
Pratik Chandra rightly alluded to the issue - the datagrid is being populated without any store being set. I suggest changing your datagrid to be populated programmatically
So your declaration:
<div id="grid.DataGrid" data-dojo-type="dojox.grid.DataGrid"
neeeds to be changed to:
<div id="mygrid" ></div>
and then change the line:
var grid = dijit.byId("grid.DataGrid");
to:
var grid = new dojox.grid.DataGrid({
id: "grid",
jsid: "grid",
store: dataStore,
structure: gridStructure,
style: 'width:900px;height:300px;'
}, dojo.byId("mygrid"));
grid.startup();
Also note that whenever you want to refresh the data in the grid, you do not need to repopulate the grid, you can just update the datastore with new values and the datagrid will automatically refresh with new data :-) Dojo takes care of that part.
To clean existing data in the datastore and populate it with new data, set the clearOnClose property on your IFRS. See: Updating Dojo Dijit FilteringSelect's store with asynchonous data to learn about clearOnClose

Categories