I'm trying get user input from a HTML form and use that value to populate a ChartJS graph in my Django app called DisplayData which has a template called Display.html. I have an API set up to pass data into ChartJS called display/api/chart/data/ which I use to get two lists to populate the Chart with. In order make the Chart, I am getting data from my models and graphing the data value (integer) against the timestamp of when the value of recorded. This is one of the queries that gets the data:
all_entries = models.Entries.objects.all().filter(parent=2)
Right now, I have it hardcoded to one time of data value (as seen above, to the integer 2), but I would like the user to have a form where they can input a number and submit it, generating the chart by using that integer as a filter. The user input integer would be placed inside the parent= portion of the code above.
I have the following urls set up.
urls.py
urlpatterns=[
url(r'^$',views.DisplayView, name='DisplayView'),
url(r'^api/data/$', views.get_data, name='api-data'),
url(r'^display/api/chart/data/$', views.ChartData.as_view()),
url(r'^logs/', views.LogDisplay, name='Display-Logs'),
]
In order to achieve this, I have added a form in my Display.html file above the code for ChartJs as follows.
Display.html
{% block content %}
<div class="row">
<h4>Enter measurable number:</h4>
<form method="POST">
{% csrf_token %}
<input type="number" name="textfield">
<button type="submit">Submit</button>
</form>
</div>
<div class='padded'>
<div class='col-sm-12' url-endpoint='{% url "api-data" %}'>
<h1>Graph Data</h1>
<canvas id="myChart" width="400" height="400"></canvas>
</div>
</div>
<script>
{% block jquery %}
var endpoint = 'display/api/chart/data/'
var defaultData = []
var defaultLabels = [];
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
defaultLabels = data.labels
defaultData = data.default
console.log(data)
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: defaultLabels,
datasets: [{
label: '# Measurable',
data: defaultData,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
},
error: function(error_data){
console.log("error")
console.log(error_data)
}
})
{% endblock %}
</script>
{% endblock %}
The first part of the code is the form to get data from the user, the second part is the code to generate the graph which we can ignore right now since the graph works (when I hardcode the value).
In my views file, I have the following code to get the input from the user and then place it in the required place for the query.
views.py
class ChartData(APIView):
authentication_classes = []
permission_classes = []
def post(self, request, format=None):
display_id = self.request.POST.get("textfield")
print(request.data)
try:
display_id = int(display_id)
except ValueError:
display_id = 2
return display_id
def get(self, request, format=None):
display_id = self.request.POST.get("textfield")
print('value of display_id ')
print(display_id)
#insert value from form into parent= below
all_entries = models.Entries.objects.all().filter(parent=display_id)
all_measurables = models.Measurables.objects.all().filter(user_id=request.user.id) #change to current user
all_times = [m.timestamp for m in all_entries]
all_data = []
for m in all_entries:
data = m.data
json_data = json.loads(data)
value = json_data['value']
all_data.append(value)
data = {
"labels": all_times,
"default": all_data,
}
return Response(data)
However, when I run this program, upon entering a number into the textfield and hitting submit the value of display_id seems to be None. Where am I going wrong and how can I achieve what I am trying to do?
Related
i wrote a program using django to retrieve all checked checkbox without submit button by using AJAX , it is not throwing any error , but it displays "NO Value " . Can anyone check and tell me what is the mistake i did .
AJAX :
<script>
$('.form-check-input').change(function(){ // checkbox1 change event
var checked_lists = [];
$(".form-check-input:checked").each(function() {
checked_list.push(this.value);
});
var formdata = new FormData();
$.ajax({
formdata.append('checked_list',checked_list)
formdata.append('csrfmiddlewaretoken',$('input[type=hidden]').val());
$.ajax({
url:"secondtableonDashboard", //replace with you url
method:'POST',
data:formdata,
enctype: 'application/x-www-form-urlencoded',
processData:false,
contentType:false,
success:function(data){
alert("Display return data"+data)
},
error:function(error){
alert(error.error)
}
});
});
});
</script>
Views.py
def secondtableonDashboard(request):
conn = pyodbc.connect('Driver={SQL Server};'
'Server=ABC\SQLEXPRESS;'
'Database=WebstartUI;'
'Trusted_Connection=yes;')
cursor = conn.cursor()
cursor.execute("select * from CustomerServer")
result = cursor.fetchall()
if request.method=='POST':
user_list = request.getlist('checked_list')
print(user_list)
else:
print("No Values")
html :
<td>
<div class="form-check form-switch">
<input class="form-check-input" name="Servers[]" value="{{datas.ServerName}}" type="checkbox" id="flexSwitchCheckDefault">
<label class="form-check-label" for="flexSwitchCheckDefault">
</div>
</td>
So here i use my views.py, same function to keep data in checkbox and to get POST values.
UI:
I am trying to create an E-Commerce Website. So, I am trying to add filters like Price: Low - to High and vice versa. I know how to filter the price but I don't know how to apply the filter on select value getting changed.
Here is HTML Code
<div class="d-flex flex-row-reverse" style="margin-right: 20px; margin-bottom: 20px;">
<label>
<select class="bg-dark" name="price" id="priceFilter">
<option value="normal">Sort by Price</option>
<option value="low">Low-to-High</option>
<option value="high">High-to-Low</option>
</select>
</label>
</div>
Django Code
def index(request):
fil = request.GET('price')
if fil == "low":
products = Product.objects.all().order_by('productDiscountedPrice')
elif fil == "high":
products = Product.objects.all().order_by('-productDiscountedPrice')
else:
products = Product.objects.all()
context = {
'products': products
}
return render(request, "Amazon/index.html", context)
So, How to sort products when select tag value gets changed?
You need to use ajax if you don't want to reload the page. Here is the ajax tutorial link.
Include this jquery link in the main html page head tag.
<script>
$('#priceFilter').on('change', 'input, select', function(event){
// id = this.id; // you can use this.id to get the corresponding id.
var word = $("#priceFilter").val();
$.ajax({
type: 'GET',
url: '{% url <YOUR DJANGO INDEX VIEW URL NAME> %}',
data: {
word: word,
},
success: function (response) {
console.log(response); // print response.content and response.data to see the data in the console. And later you can use those data in template using javascript.
},
error: function (error_data) {
console.log(error_data)
}
});
}
</script>
And in the views.py, write modify your view like this:
from django.shortcuts import render
from django.http import JsonResponse
def index(request):
fil = request.GET('price')
if fil:
if fil == "low":
products = Product.objects.all().order_by('productDiscountedPrice')
elif fil == "high":
products = Product.objects.all().order_by('-productDiscountedPrice')
else:
products = Product.objects.all()
context = {
'products': products
}
return JsonResponse(context)
else:
context = {}
return render(request, "Amazon/index.html", context)
I am trying to fetch data from postgres table by clicking a button in the django template page and the fetched data from db should be populated into another div.
For the same, I am using Ajax get call to fetch the data from DB, but I am facing problem that the value is shown as undefined.
With the Ajax call if I populate the target div with the below, it is working.
$('#childContainer').html(10 + Math.floor(Math.random()*91));
But when I try to fetch the data from table, I am getting undefined.
Here is the code which I have written:-
views.py:-
def index(request):
distinctenvapp = Env_app.objects.values('environment_name').distinct()
return render(request, 'envconfigmgmt/index.html', {'distinctenvapp' : distinctenvapp});
def get(self,request, *args, **kwargs):
if self.request.is_ajax():
return self.ajax(request)
def ajax(self, request):
response_dict= {
'success': True,
}
action = request.GET.get('action','')
if action == 'get_appnames':
env_id = request.GET.get('id','')
if hasattr(self, action):
response_dict = getattr(self, action)(request)
envappname = Env_app.objects.get(environment_name='env_id')
response_dict = {
'application_name':envappname.application_name
}
return HttpResponse(simplejson.dumps(response_dict),
mimetype='application/json')
index.html:-
<div><center><table id="t1"><tr>
{% for obj in distinctenvapp %}
<td>
<button id="{{ obj.environment_name }}">
{{ obj.environment_name }}
</button>
</td>
{% endfor %}
</tr></table></center></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("button").click(function(){
$env_id = $(this).attr('id')
$.ajax({
type: "GET",
data: { action: "get_appnames", id: $env_id },
success: function(data){
$("#childContainer").html("<strong>"+data.application_name+"</strong>");
console.log(data);
}
});
//$('#childContainer').html(10 + Math.floor(Math.random()*91));
});
});
</script>
<div id="childContainer"></div>
I expect the data to be fetched in the target child div.
It should show application names like App1, App2 etc, but it is showing undefined.
IF your ajax request returning JSON content then you have to define datatype in Ajax parameter
$.ajax({
type: "GET",
data: { action: "get_appnames", id: $env_id },
dataType: 'json',
success: function(data){
$("#childContainer").html("<strong>"+data.application_name+"</strong>");
console.log(data);
}
});
For more refere this https://api.jquery.com/jquery.ajax/
I think your ajax request doesnt have url so ajax called current page again
current page is a string and doesnt have application_name
be aware that the mimetype argument was removed in Django 1.7. Use content_type instead.
I am trying to pass the variable ,I am obtaining from view to the template but it is showing in the preview of the web-browser(chrome) but not on actual screen.
Following is my view file:
analyzer=SentimentIntensityAnalyzer()
data={}
with open('today_5th_oct_new.csv','r',newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
data[row[0]]=float(row[1])
analyzer.lexicon.update(data)
def index(request):
return render(request, "gui/index.html")
#csrf_exempt
def output(request):
sentences = request.POST.get('name',None)
senti = analyzer.polarity_scores(sentences)
context_dict = {'sentiment': senti}
return render(request,"gui/index.html", context = context_dict)
Following is my template-
<!doctype html>
<html>
<head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script></head>
<body>
<form action>
Enter Sentence:<input id = "name" type = "text" name = "EnterSentence" encoding = "utf-8"><br>
<input onclick = "testfunction()" type = "button" value = "Submit" >
</form>
<div><strong>Score is {{ sentiment }}</strong></div>
</body>
<script>
var testfunction = () => {
var test = document.getElementById("name").value
console.log(test)
$.ajax({
type: "POST",
dataType: "json",
url: 'output/',
data:{
csrfmiddlewaretoken: '{{ csrf_token }}',
'name': test
},
success: function(response) {
console.log("Succesful return firm ajax call");
},
error: function(result){
console.log("Failure");
}
});
}
</script>
I am observing the desired output in preview but not on actual page.
How to resolve that ?
You're getting the response via Ajax but you're not doing anything with it. Your success function needs to insert the content into the page somehow.
To be honest, I don't see why you use Ajax here at all; if you removed the JS code and just let your form do a POST directly it would work fine.
I am using django 1.5, python 2.7 and jquery 1.9. I have a form which has precisely 2 fields i.e. title and document. When I press submit I want the users chosen document to be present in the request.FILES as shown in the view.
When I submit the regular form (without ajax), this works fine, but with ajax I do not get the file field in my request. Any suggestions on how to upload a file using ajax.
HTML:
<form enctype="multipart/form-data" action="{% url 'upload_document' %}" method="post" id="uploadForm">
{% csrf_token %}
<ul>
<li>
<div>Title</div>
<input id="title" type="text" maxlength="200"/>
<div class="error"></div>
</li>
<li>
<div>Upload File</div>
<input id="document" type="file" size="15" />
<div class="error"></div>
</li>
</ul>
<input type="submit" value="submit"/></p>
</form>
FORMS.PY:
class UploadForm( forms.Form ):
document = forms.FileField()
title = forms.CharField(max_length = 200)
def clean(self):
cleaned_data = super(UploadForm, self).clean()
return cleaned_data
def save(self, *args, **kwargs):
title = self.cleaned_data['title']
doc = self.cleaned_data['document']
document = Document(title = title, document = doc)
document.save()
return document
SCRIPT:
<script type="text/javascript">
$("#uploadForm").submit(function(event){
event.preventDefault();
$.ajax({
url : "{% url 'upload_document' %}",
type: "POST",
data : {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
title: document.getElementById('title').value,
//document: document: document.getElementById('document'),
},
dataType : "json",
success: function( response ){
if(response == "True"){
// success
}
else {
//append errors
}
}
});
});
</script>
VIEWs.PY
def upload_document(request):
print request.POST
print request.FILES
if request.is_ajax():
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES, user = request.user)
if form.is_valid():
form.save()
return HttpResponse(simplejson.dumps('True'), mimetype = 'application/json' )
else:
errors = form.errors
return HttpResponse(simplejson.dumps(errors), mimetype = 'application/json' )
The answer to that question is not that simple. First of all if you intend to support old browsers then indeed it gets nasty. You have to deal with hidden iframes and some JavaScript tricks. I do advice using some well-known scripts for that like jQuery-File-Upload.
But the world is evolving and new technologies arise including HTML5. There's a new File API which is available in most modern browsers ( IE10+, FireFox3.6+, Chrome13+, see: http://caniuse.com/fileapi ) which can be used for that. First you need some HTML:
<input type="file" id="file-select" />
Then you can bind to (for example) change event:
$('#file-select').change( handleFileSelect );
and finally the handler itself:
var data = {};
function createReaderHandler(name) {
return function(ev) {
data[name] = ev.target.result;
};
}
function handleFileSelect(ev) {
var files = ev.target.files; // FileList object
// Loop through the FileList
for (var i = 0; i < files.length; i++) {
var file = files[i],
name = file.name || file.fileName,
reader = new FileReader();
reader.onload = createReaderHandler(name);
reader.readAsText(file);
}
}
Once the data is loaded into JavaScript memory (note that the operation is asynchronous) you can send it via AJAX like any other data. There are more options: depending on your file you can read it as a binary data using .readAsBinaryString and so on. Google is your friend. :)
Also I think there already are good scripts for uploading files with a fallback to old methods. This one can be interesting (haven't tried it):
http://www.plupload.com/
I think the issue is in the submit button, change it into normal button
ie, <button type='button' id='submit'>submit</button>(by default all buttons in form are submit)
and the ajax as
$('#submit').on('click',function(){
frm = $(this).parents('form')
$.ajax({
type: frm.attr('method'),
dataType:'json',
url: frm.attr('action'),
data: frm.serialize(),
async: false,
success: function (data) {
console.log('success')
},
error: function(data) {
console.log("Something went wrong!");
}
})
All others will be same
Just try it will work