Pass ajax response to django template - javascript

I am learning to use javascript, ajax, python and django together.
In my project, a user selects a language from a drop-down list. Then the selected is sent back to the server. Then the server sends the response back to the django template. This is done by javascript. In the django template, I need the response, for example, German, to update the html code. How to pass the response to the html code. The response can be seen in the range of ....
How to do it without reload the html page?
Thanks.

You could use jquery to send the ajax request and server could send the response with html content.
For example,
Server: When server receives the ajax request. This would return the html content i.e. a template which could be rendered to the client via ajax
def update_html_on_client(request):
language = request.GET.get('language', None)
#for selected language do something
cal_1 = ...
return render_to_response('my_template.html', {'cal':cal_1}, content_instance = template.RequestContent(request))
Template: This is example of ajax function you would use to generate ajax request. You can select the div in which you can populate the html response returned by the server.
function getServerResponse(){
$.ajax({
url: 'your_url_here',
data: {language:'German'},
dataType:'html'
success : function(data, status, xhr){
$('#server_response').html(data);
}
});
}

Because your templates are rendered on the server, your best bet is to simply reload the page (which re-renders the page with your newly selected language).
An alternative to using ajax would be to store the language in a cookie, that way you don't have to maintain state on the client. Either way, the reload is still necessary.
You could investigate client side templating. Handlebars is a good choice.

Related

Returning HTML View vs. JSON Object with HTML using Flask & AJAX

I'm developing a single page Flask app using AJAX to navigate through my routes. For example, when a user clicks on a nav-link, a GET request is made with AJAX that calls a route like "/profile", which returns a JSON including the HTML to be replaced on the screen.
If I type an existing route in the browser without calling an AJAX request, the HTML will be returned as expected as a JSON and simply pasted as text on the screen. I would like to give users the ability to type routes in the address bar and have the page load instead of just pasting the JSON with the HTML. What is the proper way to instead return a view instead of simply the JSON from my Flask end-point if no AJAX request was made (someone just types in "/profile" in the browser without clicking the profile nav-link)?
My first thought is to pass some type of parameter as part of every AJAX request and have the backend check if the parameter exists upon being called, where I would return a view instead of the JSON. That seems very inefficient and would make the code more complex by adding many more if statements. Additionally, I would have to create 2 HTML files for each route.
What is the proper way to go about this?
If you are making an ajax request, you can add this into your route.
_xhr_key = request.headers.get('X-Requested-With')
if _xhr_key and _xhr_key == 'XMLHttpRequest': # if true this means that its an AJAX call
#return data for AJAX function
else:
#return data for regular request
#render HTML template to the user over here since its a regular request
Ajax Requests make an XMLHttpRequest object
So if XMLHttpRequest object is present in the header then it means that it is an AJAX request. This is how you can load a webpage when a use normally loads it thus, you are able to render page using AJAX and when someone normally types the link in the browser

Alternative render of JSON response in Django depending on request origination

I'm trying to find a way how to return JsonResponse which would be either interpreted as JSON when received by Ajax success function, or will be rendered to 404 (or any other page) if will be called directly via URL.
The reason I'm looking for this is because on my website I have few places where I am using empty modal view (pop-up) which is later populated with proper HTML content by server based on Ajax request.
In return JSON to my Ajax success function I have only HTML responsible for the modal content. So, when displayed as standalone (by typing GET request url directly in browser) it is JSON object.
What I'd like to achieve is display some page in such case (directly typed url for GET request), which will inform user that he's in wrong place, but at the same time will be properly understood by Ajax.
So far I've considered two approaches:
Use POST request - this is ok, until I need to render form in modal which is then sent back, also as a POST request, to server to be somehow processed. It requires some ugly workarounds to figure out if request is to render form and send HTML back, or to process form. In this approach I can return 404 page simply using http_method_not_allowed function.
Render JSON response using return render(request, 'mytemplate', {'form_html': form_from_string}) - this requires change of Ajax request to use text dataType and some extra workarounds on JS side to extract form_html.
Is there any 3rd option to get it working as I've imagined it will work?
I'm not sure to fully understand your question, but you can use request.is_ajax() to determine if the request was made using Ajax.
It uses the header X-Requested-With to determine if the request was made from ajax context.
Example:
class MyView(View):
def dispatch(self, request, *args, **kwargs):
if not request.is_ajax():
raise Http404
return super().dispatch(request, *args, **kwargs)

Is it possible to insert or delete a database record using Javascript?

I'm new to Javascript and I couldn't find this information so far.
I'd like to create a button which, when clicked, creates a new entry in my database, and another one which removes a specific entry when clicked. The reason I don't want to use PHP is because I don't want the page to reload when the button is clicked.
Where can I find information on how to achieve this?
EDIT
Okay I found this:
<script type="text/javascript">
$(document).on('click','#save',function(e) {
var data = $("#save-form").serialize();
$.ajax({
data: data,
type: "post",
url: "save.php",
success: function(data){
alert("Data Save: " + data);
}
});
});
</script>
My HTML:
<form id="save-form" method="post">
<input id="save" type="submit" value="Save" name="save-submit" />
</form>
My PHP file (save.php), which creates a new record in my database, works, but only if my form's action is action="save.php". What should I put in my form's action to trigger the script?
Also, it seems like the submit button still reloads the page (even if my form has no action).
You cannot directly communicate with Database from your javascript. What you can do is like use Ajax to communicate with your server side language(It can be anything like PHP,.net,Java etc..) and with the help of server side language communicate with Database
If you are using Ajax then you can make the way asynchronous.
If you really want use JavaScript to communicate with Database then you can go for Node.js(There you can use javascript syntax) but still it is a server side language based on Javascript and its not related to your browser
Why you cannot connect database from client side ??
The main reason is Security. You're not granting DB access to anyone but web server/app user.
The other few reason are
DB load reduction
Scalability Issues
Encapsulation Issues
Ability for fault tolerance
See there are ways to insert into db with using PHP and without doing a postback.
But specific to your question you can find answer in below link
Insert Record in Database Using Textboxes in JavaScript
Not only in PHP but also in any other programming language(e.g: asp.net,java etc) you can create an entry and remove a specific entry without loading the page.
You need to use the plugin of jquery which is called 'ajax'.
Using 'ajax' you can send data to the server without loading the page. And after having your data in server side, you can do whatever you want to do.
You will find ajax documentation here: http://api.jquery.com/jquery.ajax/
Same kind of question answered here: Delete record without refresh page using php
If you having any problem,let me know.
Here is an example of a simple client server communication model. Client codes are executed at the browser which is JavaScript. The Server side codes are PHP, Nodejs, java, python etc) Which resides on server only. Client sends a request to the server for a resource. And server and back a response with an HTTP status. Which represents the status of a response. The client side JavaScript cannot communicate directly with the server database. What it does is sending a request to the server which will eventually trigger the actual code in server which inserts the data into the server.
The one you mentioned is the ajax method which sends an HTTP request without actually reloading a page. You can also use a form to post data into the server without ajax which will reload the page.
You must validate the user inputs in server side even though you will be validating it in the client side.
You can use the event.preventDefault() to prevent the form submit and then insert it via ajax.
$(document).ready(function() {
$('#save-form').on('submit', function(e){
e.preventDefault();
var data = $("#save-form").serialize();
$.ajax({
data: data,
type: "post",
url: "save.php",
success: function(data){
alert("Data Save: " + data);
}
});
});
});

How to interface JQuery with Flask?

I'm writing a Google Chrome extension that uses a jQuery.post() call to send data to an external website. The external website handles the data using a Flask endpoint and generates a result. Unfortunately I am not sure how to transfer the result back to the client. How can I do this?
I've tried using a render_template call within Flask, like so:
app.route("/my_endpoint", methods = ['POST'])
def my_endpoint():
print ('hi') # this statement prints
results = ...
if request.method == 'POST':
# want to eventually replace this with
# return render_template("results.html", results=results)
return render_template("test.html")
But this doesn't actually load the page test.html.
I've also tried transferring the data back to the Chrome extension using a callback (which I would prefer not to do if possible), as in
post_results = function(input_data) {
jQuery.post("my_flask_endpoint",
input_data,
function (data, textStatus, jqXHR) {
...
}
But I'm not sure what to put in the callback function, because it seems like "data" is a bunch of HTML, and I don't know how to load pages given only an HTML string (as opposed to the URL).
It's good that data is a bunch of HTML, because that's exactly what you sent it! render_template is the Jinja2 function you use to show a given page to a user, and in the end, all that is is HTML. What you are doing is returning the HTML rendering of test.html as the data.
What (I think) you are trying to do, is either return the "results" object, or trigger a redirect to /results after POSTing to /my_endpoint?
Depending on what you plan to do with the data, you could go either way.
If you are wanting to return the data to the users current page/the jQuery callback, try just returning results as JSON (assuming results is a dictionary). A more detailed explanation of jsonify can be found here
return flask.jsonify(**results)
Alternatively, if you plan to navigate to a different page to show the results, you need to decide whether you want Flask to perform the redirection and render the data using results.html as a template, or pass the results to the client and have it navigate and transfer the received data itself.

jquery.post(): how do i honor a redirect from the server?

I'm trying my hand at unobtrusive JS, using JQuery in my Ruby On Rails app.
After the user fills out a form, the client-side JQuery code calls:
$.post("/premises", ui.form)
I can see the POST hit the server, and I can see the server emit a redirect notice to http://localhost:3000/users/42 complete with the data to be displayed.
But the browser page doesn't change. This doesn't really surprise me -- the whole point of client-side javascript is to control what gets updated -- I get that. But in this case, I'd like to honor whatever the server replies with.
I tried extending the call to post() based on How to manage a redirect request after a jQuery Ajax call:
$.post("/premises",
ui.item,
function(data, textStatus) {
if (data.redirect) {
// data.redirect contains the string URL to redirect to
window.location.href = data.redirect;
} else {
// data.form contains the HTML for the replacement form
$("#myform").replaceWith(data.form);
}
});
... but (among other problems) data.redirect is undefined. I suspect the real answer is simple, right? Looking forward to it!
The post you refer to uses JSON as return value and it is constructing that json on server side. it means if there is redirect your data object would look like
{redirect:'redirecturl.html'}
and if it is not redirect then data object would be like
{form:html-string-for-form}
now job is to construct json object accordingly on server side
The server is saying that the data you want to process with JavaScript is available at a different URL, not that the browser should load a new document into the top level frame. Sending the browser to the URL where it was told the data it was requesting with JS is wouldn't be honouring the redirect.
If you want to do that, then the server should respond with data (in the body of the response) that the JavaScript interprets as a reason to assign a new value to location.
data.redirect is probably undefined because you're not specifying it on the server side. In the answer you linked to the point was to have the server always respond with 200 regardless of the outcome, and then the JSON body it sends back determines how the client reacts. So, on the server side you'd want to respond with {"redirect" : "/where/to/go"}

Categories

Resources