I'm totally new to all this python things, I've searched on my problem but withiout results, so I count on your help guys :)
I have a template file with button:
<button class="btn" value="{{invoice.number}}">Send</button>
In different file I have a class which runs function from another file:
class ReminderManual(webapp2.RequestHandler):
...
for inv in invoices:
is_send = reminder.send(inv)
And I'd like to:
run this class when the button is pushed
display is_send value
Any ideas how I can do that?
If you don't want to reload the complete page to get the result, you could to the following using JQuery and Ajax:
In HTML, you have
<button class="btn" value="{{invoice.number}}" id="myButton">Send</button>
and later in the file (before the closing </body> tag):
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function() {
$('#myButton').on('click', function (e) {
var invoice_number = $('#myButton').val();
var data = { invoice_number:invoice_number };
var args = { dataType: "json", type:"POST", url:"/my_ajax_url/",
data:data, complete:ajax_call_complete };
$.ajax(args);
});
});
var ajax_call_complete = function(res, status) {
data = jQuery.parseJSON(res.responseText);
// use data as a json response object here and
// do something with the response data
}
</script>
In Javascript, the /my_ajax_url/ would be the URL on which your request handler on the server runs. It is called via Ajax, the parameters are provided as POST parameters (in the code example, the value of the button is send as parameter invoice_number).
I typically set up my server Ajax requests to return JSON, which is then handled by the callback method (in the example, ajax_call_complete). Here you can check for errors and indicating the result to the user by displaying a message, modifying certain HTML elements, etc.
If you want to submit the complete page instead of using Ajax, you should use the Django forms mechanism:
https://docs.djangoproject.com/en/1.6/topics/forms/
The button needs an onclick handler, so it knows what to do. The onclick handler is a javascript function that sends a new request via a url. So, your app needs to handle that url, and execute the Class when a request comes to the url.
With jquery, you could easily make the onclick handler process an Ajax request to the url, and respond back with the value of is_send. Still need a url handler in the app, which calls the class.
I see you added django as a tag. With django, you could make the button part of a form, and use django's form handling to execute the class, and push back the value of is_send.
Related
I'm fairly new to Django rest and angularjs. I'm trying to create a Django view which will have a function and this function has to be called via a button in angular js. Can anyone please help me out?
Thanks
This might help:
Django - Angular Tutorial
General answer would be:
1) Using for example Django REST expose your method (endpoint)
2) From Angular application send request to the previously exposed endpoint.
say this is your Django/python api end point (assume controller file to be random.py)
def getRandomInfo(request):
try:
result = database.getRandomInfo()
return JsonResponse(result, content_type="application/json", safe=False)
except Exception as e:
import traceback
traceback.print_exc(e)
return JsonResponse({error:'sorry'}, content_type="application/json", safe=False)
Via angular, provided you have resolved all the dependencies and have a functioning angular app and/or controller set up in your html/js
you can call the api using below code
app.controller("appControllerName", function ($scope, $http) {
$http.get("{% url 'getRandomInfo' %}")
.success(function (response, status) {
response_data = response
$scope.data = response_data;
}).error(function (response, status) {
$scope.status = status;
});
}
if you notice the {% url 'getRandomInfo' %} , this is defined in your urls.py , u'll have to add a line like this over there where getRandomInfo will have to be the 'name' of the url
url(r'^random/getRandomInfo/$',random.getRandomInfo, name='getRandomInfo'),
Over here you controller name is random and a function within that controller is def getRandomInfo, so django allows two ways to access this endpoint, either via the url r'^random/getRandomInfo/$ (yes regex is allowed here) or via the name as stated in the example here.
Best of Luck :)
What i am trying to ask is, i have a website which takes the user profile and generates some kind of user specific reports in pdf. Pdf is generated at back end. So when user clicks on "generate" button, it should show blocking message and once the file is generated blocking message is removed and file is displayed with tag.
I am able to do this with help of socket.io and to be very Frank I copied this solution from one blog without understanding much. So my stack is Python and socket.io is on node. While it worked perfectly on my dev machine but on server its keep on throwing connection error message in JavaScript and post message fails on back end. So I am currently having issues with front and back end. And thanks to my blindly copy paste thing I am kind of clueless about the fix.
Is there any alternative to this approach? I can think of using Python based socket io (this time I will read and implement ) but something similar can be achieved by any other approach? I am using this to only send the generated pad back to client there is no other communication b/w client and server.
Adding code
It works like, client opens the download/generate page and gets the ID assigned, once generate button is clicked ID is sent to back-end, now celery generates the PDF (converts to base64) and then posts that on nodejs/notify with ID. Now the socket.io is already listening on /notify url, so once the data is posted its displayed in browser.
Browser -> sock (register) -> AJAX -> Celery (task) -> on nodejs/notify -> browser sockio client displays the data
Here is the code,
Client / Browser code
// func called on generate btn press
$client.on('notify', function(result) {
$.unblockUI();
// alert('In Receiving function...');
var $obj = $('#dynamic-pdf');
$obj.hide();
$obj.attr('data', result);
$obj.show();
$('button#view-again').removeClass('disabled');
$('#previe').modal('show');
});
blockWithMsg("Generating PDF, Please Wait...");
$.ajax({
url: $url,
data: {clientId: $clientId},
method: 'POST',
cache: false,
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'},
});
// func finished
<!-- register client on page load -->
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
var $client = io('http://localhost:3000'),
$clientId = null;
$client.on('register', function(id) {
$clientId = id;
});
</script>
Node js code
var app = require('express')(),
server = require('http').Server(app),
io = require('socket.io')(server),
bodyParser = require('body-parser');
// Accept URL-encoded body in POST request.
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true, parameterLimit: 50000}));
app.use(require('morgan')('dev'));
// Echo the client's ID back to them when they connect.
io.on('connection', function(client) {
client.emit('register', client.id);
});
// Forward task results to the clients who initiated them.
app.post('/notify', function(request, response) {
var client = io.sockets.connected[request.body.clientId];
client.emit('notify', request.body.result);
response.type('text/plain');
response.send('Result broadcast to client.');
});
server.listen(3000);
I am getting emit on undefined value error
(Posted on behalf of the OP).
The error was I started site on different domain than one mentioned in the socket.io connection (which was still localhost) in browser JavaScript.
I got an URL like: http://localhost:4284/?session_expired=true
Now I'm sending and AJAX-Request for something and the return should be a HTTPFound with 'http://localhost:4284/'.
Cutting the URL is not the problem, but either Pyramid or the Browser are ignoring the changes, so the keep the parameter session_expired in the window location :(
Thanks
AJAX requests do not affect the window location (I suppose you want the browser to go to a completely new page as a result of the AJAX request, so the address in browser's address bar changes).
You can do this manually in JavaScript when handling the response of the AJAX request:
$.ajax(
...
}.done(function (data) {
if (data.redirect_to) {
window.location = data.redirect_to;
}
});
In the example above the server returned 200 Ok status with a JSON response which looks something like {"redirect_to": "http://localhost:4284/"}. You may prefer to return a different HTTP status and handle it in the error handler instead.
If you are returning an HTTPFound-Object, do not parse it as JSON, but rather parse is as HTML!
I have confusion on how the servers(here app engine) respond to AJAX GET and POST requests. I want send a GET request to my server and get some JSON data back.
Here is the AJAX GET request
function syncRestoreLinks(e) {
var request = new XMLHttpRequest();
var url = "/sync"
request.open("GET", url);
request.setRequestHeader("Content-Type", "application/json");
request.onreadystatechange = function() {
if (request.readyState === 4) {
console.log(request.responseText);
}
}
request.send(null);
console.log("Getting links from db");
}
Handler on the server side
class SyncHandler(Handler):
def get(self):
response_data = {"loggedIn":False, "linkData":None, "success":False}
json_txt = json.dumps(response_data)
self.response.headers['Content-Type'] = 'application/json; charset=UTF-8'
self.response.out.write(json_txt)
def post(self):
response_data = {"loggedIn":False, "linkData":None, "success":False}
json_txt = json.dumps(response_data)
self.response.headers['Content-Type'] = 'application/json; charset=UTF-8'
self.response.out.write(json_txt)
This handler writes my response data out to the screen where as I want it to send it back and let JS handle it. (I am able to use server redirects here.)
If I make a POST request instead, the code works the way I intend it to. But here, I cannot make server redirects or render pages and only the script making request has that control.
Is this how GET/POST responses work or I am doing something stupid in my code?
Is there any way for GET response not to be written on the page and be sent to JS? In the code above the responseText is an empty string but, the json is printed on screen.
I'm doing AJAX Get requests successfully with app engine right now.
Your sync handler looks correct. Are you sure it is being called? Add a logging.info() statement there to make sure. If it is being called, then I suspect the error is on the front end. I use jQuery and not XMLHttpRequest so I can't you help you with that. My jQuery call looks like this:
$.get(url, callback_function, 'json');
You can add a POST handler to your SyncHandler like this:
def post(self):
...
self.response.out.write(json_txt)
The strange part is that your POST request should not be working without this code to handle the request. You only show a get() method in your code.
I am trying to make a web application that accepts button clicks. The button clicked then sends a specific device, and operation code to the python application which then calls a irsend command using Lirc. This is based off of the source code/instructions from here:
https://github.com/slimjim777/web-irsend
http://randomtutor.blogspot.com/2013/01/web-based-ir-remote-on-raspberry-pi.html
The html for the button is simple and is in "Xbox.html"
<button onclick="clickedOp('Xbox', 'OnOff');"> Power </button>
This launches the js function:
<script>
function clickedOp(device_name, op) {
$.ajax({url:'/' + device_name + '/clicked/' + op});
}
I know that the function is firing on a click event because if i put an alert command in the clickedOp function the alert command runs
the python/flask app looks like this:
from flask import Flask
from flask import render_template
from flask import request, redirect, url_for
BASE_URL = ''
app = Flask(__name__)
#app.route("/")
def menu():
return render_template('menu.html')
#app.route("/<device_name>")
def remote(device_name):
if device_name == "Xbox":
return render_template('Xbox.html')
#app.route("/<device_name>/clicked/<op>")
def clicked(device_id=None, op=None):
return render_template('test.html')
if __name__ == "__main__":
app.run('0.0.0.0', port=80, debug=True)
All of the code up to the ajax request works. going to "/" loads the menu.html template and presents links to different devices, for instance
Xbox
will route to
"/<device_name>"
in the python program and "Xbox.html" is loaded.
Then the button loads and clicking it fires the "clickedOp(device_name, op)" function.
This is where it breaks down. Even though the ajax request routes to
"/<device_name>/clicked/<op>"
the "test.html" page is not loaded
This is the case even though the Flask debugger says that there was a successful GET request(it returns 200) to "/Xbox/clicked/OnOff" (filling in the variables for the example above)
so any ideas why test.html is not being loaded from the ajax request, when it seems that in the source code/tutorial I provided he uses the same ajax method?
You can simply do this with help of AJAX... Here is a example which calls a python function which prints hello without redirecting or refreshing the page.
In app.py put below code segment.
//rendering the HTML page which has the button
#app.route('/json')
def json():
return render_template('json.html')
//background process happening without any refreshing
#app.route('/background_process_test')
def background_process_test():
print "Hello"
return "nothing"
And your json.html page should look like below.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type=text/javascript>
$(function() {
$('a#test').on('click', function(e) {
e.preventDefault()
$.getJSON('/background_process_test',
function(data) {
console.log(data)
});
});
});
</script>
//button
<div class='container'>
<h3>Test</h3>
<form>
<a href=# id=test><button class='btn btn-default'>Test</button></a>
</form>
</div>
Here when you press the button Test simple in the console you can see "Hello" is displaying without any refreshing.
In the code the template will render and be returned to the jquery Ajax object, which will do nothing with it - it won't render it in the browser. Have you used your browser's developer tools to see if a response is received by the browser - again, if Flask logs HTTP 200 OK then I would imagine the request is being handled correctly. You should also be able to put print statements in your Flask method and see them logged too (I think).