Calling Django Function from JS Ajax not working - javascript

I am trying to call a python function that calculates and converts some number input from a user form.
I have an onclick button event to call the following JS function
$.ajax({
type: "POST",
url:"/calc_ha_range/",
dataType: 'json',
data: {'ra_deg' : ra_deg, 'dec_deg': dec_deg, 'glon_deg': glon_deg, 'glat_deg': glat_deg},
success: function(data) {
jsonData = JSON.parse(data);
ha_start.setAttribute('min', jsonData.min);
ha_start.setAttribute('max', jsonData.max);
ha_end.setAttribute('min', jsonData.min);
ha_end.setAttribute('max', jsonData.max); // data.min = minimum val for HA range
}
})
I then have a django url mapping in the form of
import home.views, sensitivity_radec_astro.views,sensitivity_radec_astro_show.views, sensitivity_map.views, sensitivity_map_show.views, sensitivity_radec_vs_freq.views, sensitivity_radec_vs_freq_show.views, sensitivity_radec_vs_lst.views, sensitivity_radec_vs_lst_show.views, sensitivity_vs_freq.views, sensitivity_vs_freq_show.views, sensitivity_vs_lst.views, sensitivity_vs_lst_show.views, utils.sensitivity_db
urlpatterns = [
path('', home.views.load),
path('sensitivity_radec_astro/', sensitivity_radec_astro.views.load),
path('sensitivity_radec_astro_show/', sensitivity_radec_astro_show.views.sensitivity_radec_astro_show),
path('sensitivity_map/', sensitivity_map.views.load),
path('sensitivity_map_show/', sensitivity_map_show.views.sensitivity_map_show),
path('sensitivity_radec_vs_freq/', sensitivity_radec_vs_freq.views.load),
path('sensitivity_radec_vs_freq_show/', sensitivity_radec_vs_freq_show.views.sensitivity_radec_vs_freq_show),
path('sensitivity_radec_vs_lst/', sensitivity_radec_vs_lst.views.load),
path('sensitivity_radec_vs_lst_show/', sensitivity_radec_vs_lst_show.views.sensitivity_radec_vs_lst_show),
path('sensitivity_vs_freq/', sensitivity_vs_freq.views.load),
path('sensitivity_vs_freq_show/', sensitivity_vs_freq_show.views.sensitivity_vs_freq_show),
path('sensitivity_vs_lst/', sensitivity_vs_lst.views.load),
path('sensitivity_vs_lst_show/', sensitivity_vs_lst_show.views.sensitivity_vs_lst_show),
path('calc_ha_range/', utils.sensitivity_db.calc_hour_angle_range)
]
which refers to the following python function
def calc_hour_angle_range( request ):
geo_lat = EarthLocation.from_geodetic(lon="XXXX",lat="XXXX",height=XXXX).lat.value
if request.method == "POST":
ra_deg, dec_deg, glon_deg, glat_deg = request.POST["ra_deg"], request.POST["dec_deg"], request.POST["glon_deg"], request.POST["glat_deg"]
tan_geo_lat = math.tan( geo_lat*(math.pi/180.00) )
tan_dec = math.tan( dec_deg*(math.pi/180.00) )
cos_ha = -tan_dec * tan_geo_lat
ha_rad = math.acos( cos_ha )
ha_deg = ha_rad*(180.00/math.pi)
ha_h = ha_deg/15.00
output = {'min': -math.fabs(ha_h), 'max': +math.fabs(ha_h)}
My issue is when the ajax call takes place in the onClick function I get an error in the console saying 404: mysite.com/calc_ha_range/ not found
I have taken over this project from another amateur developer so my understanding of ajax and django is quite fragmented

Related

Bad request error in Flask while request names generated with javascript

I'm creating an app to calculate a projection of the transit given the years and some other values, first I created a script in javascript where depending on if the user decide to add a new type of vehicle a new div is created with unique ids and names and ofcourse the data the user introduced, for showing the final result i'm using ajax, the problem comes when i tried to access the data via flask, i'm getting a bad request from the names of each vehicle like if they did not exist, but the page is actually displaying them (hope you understand my english and my problem :) )
I've tried giving a specific name (a1) an then tried to take the value in flask but i still can#t make it work.
Python
#app.route("/pavimentos/calculoTransito" , methods=['POST'])
def calculoTransito():
direc = float(request.form["direc"])
zr = float(request.form["zr"])
years = float(request.form["years"])
tc = float(request.form["direc"])
vehicles = int(request.form["vehicles"])
car1 = request.form.get("a1", None)
if car1==None:
print("No funciona")
else:
print("Funciona")
always get "No funciona"
Javascript
countClicks = 0
lista_vehiculos = []
function addVehicle(){
countClicks += 1;
//var automovil = document.getElementById("automovil").value
var fd = document.getElementById("damage_factor").value
var currentType = document.getElementById("vehicleType")
if(currentType.value == 1){
var icon = "<h2 class='pt-4'><i class='fas fa-car text-secondary'></i></h2>";
var tipoVehiculo = "Automóvil";
}
... More code for select the currentType ...
var vehicleStyle = "<div><input id=a" + countClicks + "name=a" + countClicks + "value=" + fd + "></div>"
lista_vehiculos.push(vehicleStyle)
var vehicle = document.getElementById("vehiclesContainer").innerHTML += lista_vehiculos[countClicks-1]
document.getElementById("vehicles").value = countClicks
}
AJAX part
$(document).ready(function(){
$('form').on('submit', function(event){
$.ajax({
data:{
direc: $('#direc').val(),
zr: $('#zr').val(),
years: $('#years').val(),
tc: $('#growingRate').val(),
vehicles: $('#vehicles').val(),
car1: $('#a1').val()
},
type: 'POST',
url: '/pavimentos/calculoTransito'
})
.done(function(data){
if (data.resultado){
$('#resultado').text(data.resultado).show()
}
})
event.preventDefault();
});
});
You're not submitting a form, you're sending JSON. The initial event might be the submission of a form, but your AJAX uses event.preventDefault() and does not end up submitting a traditional serialized form. You can't use car1 = request.form.get("a1", None) here.
Firstly, you should correct your AJAX to add a contentType:
$(document).ready(function(){
$('form').on('submit', function(event){
$.ajax({
data: JSON.stringify({
direc: $('#direc').val(),
zr: $('#zr').val(),
years: $('#years').val(),
tc: $('#growingRate').val(),
vehicles: $('#vehicles').val(),
car1: $('#a1').val()
}),
type: 'POST',
contentType: 'application/json; charset=utf-8',
url: '/pavimentos/calculoTransito'
})
.done(function(data){
if (data.resultado){
$('#resultado').text(data.resultado).show()
}
})
event.preventDefault();
});
});
And then you need to change your Flask method from request.form to request.json. So the Flask side would look something like:
#app.route("/pavimentos/calculoTransito" , methods=['POST'])
def calculoTransito():
req = request.json
direc = float(req["direc"])
zr = float(req["zr"])
...
car1 = req.get("a1", None)
if car1 is None: # None is a singleton, you shouldn't use == here
print("No funciona")
else:
print("Funciona")
LATE EDIT
This can't work because calculoTransito does not actually return anything, so Flask will throw an error from that alone. Your view function actually has to return something other than an implicit None.

ajax call based on the value of 2 input fields to populate jquery autocomplete

I have been stuck with this problem for a while. I would like to pass 2 arguments (the value of 2 input fields of one form) in my ajax call to be used for a jquery autocomplete (the search is based on a mysql query using the values of input1 and input2). I had a few suggestions but so far i have no luck:
here my ajax call trying to pass the 2 arguments input1 and input2. there is no code error showing up but the autocomplete does not work. it is working if i am using only one argument.
function fillbox2(){
$('#input2').autocomplete({
source: function(request, response ){
var frmStr={
input1:$('#input1').val(),
input2:$('#input2').val()
requestTerm: request.term
};
$.ajax({
url: './cgi_temp3.cgi',
dataType: 'json',
data:{data: frmStr},
contentType: "application/json; charset=utf-8",
success: function (data) {
response ($.map( data.matches, function(item){
return {
value: item.info2,
}
}));
}
});
},
minLength: 2,
select: function(event, ui){
$("#prod_term").val(ui.item.value);
return false;
}
});
and here my cgi script that process the MYSQL query
#!/usr/local/bin/python3
import cgi, json
import os
import mysql.connector
def main():
print("Content-Type: application/json\n\n")
form = cgi.FieldStorage()
term2 = form.getvalue('input2')
term1=form.getvalue('input1')
conn = mysql.connector.connect(user='***', password='***', host='localhost', database='***')
cursor = conn.cursor()
qry = """
SELECT name2, info2
FROM table2
join table1 ON
info2_id=information2_id
WHERE name2 LIKE %s AND info2_id=%s
"""
cursor.execute(qry, ('%' + term2 + '%',term1))
where could be the problem?
At first glance I'd say it's possibly a timing issue. The source function isn't going to wait for your ajax call to complete, so you're essentially giving it a blank value. Try initiating the autocomplete inside the ajax success function.
function fillbox2(){
$.ajax({
...
success: function (data) {
...
$('#input2').autocomplete(...);
});
}

ajax failing getting data from pre element after it gets filled

The thing is that i have an embedded python interpreter and after a user presses "Run", the output from interpreter gets transferred to a pre element. I want to take that data from pre element and send it to django server through AJAX. The problem is that even after assigning of that data to a variable, django gets nothing. Also i can start interpreter and AJAX script only after pressing "Run", both work work with onclick. I am using POST request.
`$(document).ready(function(){
$('#run').click(function(){
var input_string = String(document.getElementById("output").innerHTML);
alert(input_string);
$.ajax({
url: '/courses/python3/lesson_validate/{{ lesson_number }}/',
data: {"text": input_string, csrfmiddlewaretoken: '{{ csrf_token }}'},
dataType: "json",
type:"POST",
success: function(data, textStatus){
alert('get_response');
alert(data);
},
error : function(xhr,errmsg,err) {
alert(xhr.status + ": " + xhr.responseText);
}
});
});
});
`
So that code works perfectly
var input_string = String(document.getElementById("output").innerHTML);
alert(input_string);
but when i try to use that variable in ajax, server fails to get it.
I tried using async: false, it doesn't change anything.
This is view code:
`def lesson_validate(request,lesson_number):
args = {}
args.update(csrf(request))
out_compare = Lessons.objects.get(id=lesson_number).lesson_output
if request.method == "POST" and request.POST.get('text') == out_compare:
text = "they are equal"
return HttpResponse(json.dumps(text), content_type='application/javascript')
else:
args['testtest']=request.POST.get('text')
return render_to_response('course_lesson.html', args, context_instance=RequestContext(request))`
After i check request.POST.get('text') it is empty
The question is how can i get data from ajax, from a variable assigned before, not just from a sting?
It looks like you're sending JSON to the server in that request, so to get the variables in Django you'd need to do:
def lesson_validate(request,lesson_number):
import json
data = json.loads(request.body)
text = data.get('text')
# Do stuff.

JQuery $.ajax not posting multiple vars

Hi Guys I have the following function that is called on a link:onclick(), but for some reason the $.ajax does nothing at all - have even stripped my php code to only dump the $_POST var but I still get no feedback from the function - all i get is the alert msg - which is also just there for test purposes...
called there:
Save
function saveMyGame(){
var usern = $('#usern').attr('value');
var usrPoints = $('#userPoints').attr('value');
var usrLevel = $('#userlevel').attr('value');
var saveState = this.imgPath;
alert('Saving your game: '+usern+' Points: '+usrPoints+' Level: '+usrLevel+' state phase: '+saveState);
e.preventDefault();
var svGame = {act:'saveGame',user:usern, Points:usrPoints, Level:usrLevel, saveGState:saveState} ;
$.ajax({
url: "game/lib/updateGame.php",
type: "POST",
cache: false,
data: svGame,
dataType: "html",
success: function(svGame) {
$(".traget").html(svGame).fadeIn('slow');
}
});
}
the PHP code is suppose to check act, then verify that all required info is passed, than process the request or display an error msg...
<?php
if(isset($_POST['act']) && $_POST['act'] == 'saveGame') {
//Process save game request
/*if(isset($_POST['user']) && isset($_POST['userPoints']) && isset($_POST['userLevel']) && isset($_POST['saveGState']) ) {
$Game->saveGame();
echo'<br>....'.$_POST['user'];
} else {
echo 'Please provide correct information for saving...';
}
*/
echo var_dump($_POST);
}
Url in your ajax request has relative path url: "game/lib/updateGame.php", without slash in the beginning of the url like url: "/game/lib/updateGame.php",.
So maybe if your page adress differ from root (for example http://yourdomain.com/games/), full path will be http://yourdomain.com/games/game/lib/updateGame.php and therefore the server method is not performed.

Using Ajax with cakephp doesnt work

I have a page like this:
Basically, I pick 2 dates and hit the button, then the data below will change without refreshing this page.
Here is the code in controller:
if( $this->request->is('ajax') ) {
$this->autoRender = false;
//if ($this->request->isPost()) {
print_r($this->request->data);
// get values here
echo $from=( $this->request->data('start_time'));
echo $to= $this->request->data('end_time');
Debugger::dump($from);
Debugger::dump($to);
//$this->layout = 'customer-backend';
$this->Order->recursive=-1;
$this->Order->virtualFields['benefit']='SUM(Product.product_price - Discount.product_discount)';
$this->Order->virtualFields['number']='COUNT(Order.order_id)';
$option['joins'] = array(
array('table'=>'discounts',
'alias'=>'Discount',
'type'=>'INNER',
'conditions'=>array(
'Order.discount_id = Discount.discount_id',
)
),
array('table'=>'products',
'alias'=>'Product',
'type'=>'INNER',
'conditions'=>array(
'Discount.product_id = Product.product_id'
)
)
);
$option['fields']= array('Discount.product_id','Product.product_name','benefit','number');
$option['conditions']=array('Discount.start_time >='=>$from);
$option['group'] = array('Discount.product_id','Product.product_name');
//$option['limit']=20;
$products = $this->Order->find('all',$option);
//Debugger::dump($products);
$this->set('products',$products);
//}
}
else
{
$from='27 November 2012';
//$this->layout = 'customer-backend';
$this->Order->recursive=-1;
$this->Order->virtualFields['benefit']='SUM(Product.product_price - Discount.product_discount)';
$this->Order->virtualFields['number']='COUNT(Order.order_id)';
$option['joins'] = array(
array('table'=>'discounts',
'alias'=>'Discount',
'type'=>'INNER',
'conditions'=>array(
'Order.discount_id = Discount.discount_id',
)
),
array('table'=>'products',
'alias'=>'Product',
'type'=>'INNER',
'conditions'=>array(
'Discount.product_id = Product.product_id'
)
)
);
$option['fields']= array('Discount.product_id','Product.product_name','benefit','number');
$option['conditions']=array('Discount.start_time >='=>$from);
$option['group'] = array('Discount.product_id','Product.product_name');
//$option['limit']=20;
$products = $this->Order->find('all',$option);
$this->set('products',$products);
}
If the request is ajax, it gets 2 values $from and $to from the POST and pass them to the SQL query. If the request is not ajax (mean the access this page for the first time when the dates havent picked yet), $from and $to are assigned default values.
Here is my ajax in view:
<script>
$(function(){
$('#btnSubmit').click(function() {
var from = $('#from').val();
var to = $('#to').val();
alert(from+" "+to);
$.ajax({
url: "/project/cakephp/orders/hottest_products",
type: 'POST',
data: {"start_time": from, "end_time": to },
success: function(data){
alert("success");
}
});
});
});
it gets data from 2 date picker then send it to the controller as a POST method.
My problem is that after I choose 2 dates and hit the button, nothing happens. the data doesnt change according to the dates.
Any thoughts about this. Thanks in advance.
When opening your page and running the following in the console:
$(".tab_container").html("loaded from ajax");
The products table now only shows "loaded from ajax". If the content of the products table is generated by it's own template you can have cakephp render that template only when it's an ajax call: http://book.cakephp.org/2.0/en/controllers.html
$this->render('/Path/To/ProductTable/');
If your cakephp will output only the product table when an ajax call is made you could try to run the following code:
var from = "2000-01-01";
var to = "2014-01-01";
$.ajax({
url: "/project/cakephp/orders/hottest_products",
type: 'POST',
data: {"start_time": from, "end_time": to }
}).then(
function(result){
$(".tab_container").html(result);
},function(){
console.log("fail",arguments);
}
);

Categories