I'm trying to do page with simple calculator. I made calculator in js, and now, when I click button I want to pass arguments from js to django. Count them there and print on redirect page.
I have problem with redirect page. When I dont put button in form, js script call calc view, but dont redirect page. I want redirect page and print a result there.
html code:
<form action="calc/" method="post">
{% csrf_token %}
<input id='btn' type="submit" value="CALC" onclick="change()">
</form>
javascript code:
function change(){
var foo = 1;
var foo1 = [1, "tralal", true, ''];
$.ajax({
url: 'calc/',
data : {
'foo': foo,
'foo1': foo1,
},
success: function (data) {
alert("it worked!");
}
}
)};
urls in django
path('calc/', views.calc, name='calc')
view in django
def calc(request):
foo = request.GET.get('foo')
print(foo)
foo1 = request.GET.getlist('foo1[]')
print(foo1)
context = {'data': foo1}
return render(request, 'calc.html', context)
If you want to redirect to another page, you have to do it explicitly from the javascript when the success callback is called. You can see here some answers on how to redirect the page from javascript. To do so, you will have to have another view for serving the result page.
The results of the calculation can be kept in the server (cached), or communicated from the client.
But, I wonder why you are using an Ajax request for that. Ajax requests are useful if you want to do some async http requests to the server without refreshing (or redirecting) the page. So I would say, don't use an Ajax request here, just simply submit the form. You can have a look for example here to see how forms work in javascript. You can also check this Django tutorial about using forms. Django has some tools for handling forms that can be quite convenient when for instance you want to update or create new instances in your database model. It can be a bit confusing at the beginning, but I think it is worth spending some time understanding Django forms.
I do something like this, it work, but I dont know is it correct.
views.py
def link(request):
global matrix
matrix = request.GET.getlist('foo1[]')
return HttpResponseRedirect('/calc/')
def calc(request):
if request.is_ajax:
global matrix
context = {'data': matrix}
return render(request, 'calc.html', context)
else:
return HttpResponseRedirect('/')
urls.py
path('link/', views.link, name='link'),
path('calc/', views.calc, name='calc'),
js function
$(document).ready(function() {
$("#btn").click(function(e) {
var foo = 1;
var foo1 = [1, "tralal", true, ''];
$.ajax({
url: 'link/',
data : {
'foo': foo,
'foo1': foo1,
},
success: function (data) {
window.location.href = "calc/"
}
});
});
});
html code
<input id='btn' type="submit" value="COUNT">
calc.html
{% for d in data %}
<p>"{{ d }}"</p>
{% endfor %}
Page redirect to calc/ and show correct not none matrix.
Result
What you get when using window.location.href = "127.0.0.1:8000/calc" is normal. You are just redirecting to the same page without any url query parameters.
So, you basically want to redirect to the same page?
Why then do you want to redirect? This does not make much sense to me. And again, if you wanna redirect, don't use AJAX, and follow the "normal" approach for submitting forms.
So what I think makes more sense, is to not redirect, but use the data you receive from the the AJAX request and show the information. You can still use some Django tempting en return some rendered HTML that you will then add dynamically with some Javascript code.
It could be something like that:
Javascript
$.ajax({
url: 'link/',
data : {
'foo': foo,
'foo1': foo1,
},
success: function (data) {
$('#result-container').html(data) // add the data in the div container
$("#your-form").trigger('reset'); //you should reset your form
}
});
Main HTML at "/" should contain
<div id="result-container"></div>
And you should just get rid of your link view and have the other somehow like that
def calc(request):
if request.is_ajax:
matrix = request.GET.getlist('foo1[]')
context = {'data': matrix}
return render(request, 'calc.html', context)
But I tell you again, you should use Django forms for what you are doing. See this tutorial for example.
I hope it helps.
Related
I have been trying to call a function in my Class Based View from an onclick event using javascript.
Please check my code below and let me know how i should approach the issue as i have been fairly new to python.
I followed following post : Django: How can I call a view function from template?
What i am really trying to do here is to dump the json data that i am getting in my javascript to a worker function in my django view. For that i followed this approach, i would appreciate if someone can help me with this, or if there is any norm or django way of doing this, then i would appreciate if someone can help me direct that way.
I will apologize in advance as i have started learning python since last may so it may be possible that i might doing some noob mistake here.
Javascript function
function request_access(){
var message = new Object();
message.platform_token = document.getElementById("id_platform_token").value;
message.platform_ui = document.getElementById("id_platform_uid").value;
var request_data= JSON.stringify(message);
alert(request_data);
$.ajax({
type: 'POST',
url: 'ui/seeds/<pk>/update',
data : { 'request_data': request_data},
success : function(json) {
$("#request-access").hide();
alert("requested access complete");
alert(data);
}
})
}
HTML button
<form action="" method="post">{% csrf_token %}
{{ form|crispy }}
<input type="submit" value="Update" onclick="request_access(this)" id="{{ data }}"/>
Django view under my Class based view
def request_access(self, request):
print("django view function")
m = request.POST.get('request_data')
z = request.POST.get('platform_uid')
print z
self.rabbit_worker(json.dumps(m))
return HttpResponse(json.dumps(m), content_type="application/json")
I want to be able to create a new Django object called 'Comment' in javascript.
(I understand that you can't simply declare a new object as you would do in a view method)
I need to allow the user to be able to reply to an existing comment.
I have done the bit where if user presses 'reply' button a comment, a form appears below and saves the id of the comment which the user wants to reply to in a js variable.
However, I am struggling to find a way to finally submit all this so that I can post a new sub-comment.
Is there a simple way to achieve this?
I would do that with ajax. If you are using jQuery you could work on something like that:
Lets say you have an template called home.html, which is where you are managing the comments and everything.
home.html
<ul class="comments">
<li data-id="1">This is a comment...</li>
</ul>
<textarea id="new_comment"></textarea>
<button type="button" id="send">Post comment!</button>
urls.py
url(r'^comment/$', 'core.views.comment', name='comment'),
views.py
def comment(request):
c = Comment()
c.text = request.GET.get('text')
c.save()
return render(request, 'core/partial_comment.html', { 'comment': c })
core/partial_comment.html
<li data-id="{{ comment.id }}">{{ comment.text }}</li>
Now you will need a jQuery snippet to send an async request to the server so you can create a new comment:
$(function () {
$("#send").click(function () {
$.ajax({
url: '/comment/',
data: { 'text': $("#new_comment").val() },
type: 'get',
cache: false,
success: function (data) {
$(".comments").append(data);
}
});
});
});
So let's understand what just happened here:
The user come and writes his comment on the textarea with id new_comment
The button with id "send" is listening to the click event
When the user clicks on this button it will send an ajax request to the server with this data which we called "text". Then you are on the server and you can create your Comment object. After saving it, you will return the response to the client. The "data" variable inside the ajax call will catch the result, which is "<li data-id="2">what ever he commented...</li>". Then you append it to the element where is storing your comments on the html view
I have looked at a number of answers and other websites, but none answer my specific question. I have a webpage with "+" and "-" buttons, which should increment a variable called "pieFact". This variable must be updated dynamically without having to refresh the page. It should then be passed to my Django view each time the value is changed. This will be used to update the size of pie charts in a web map. I have the following:
<button type="button" id=bttnMinus onclick="pieFact=pieFact*0.9">-</button>
<button type="button" id=bttnPlus onclick="pieFact=pieFact*1.1">+</button></td>
<script type="text.javascript">
var pieFact=0;
</script>
How can I pass the value of "pieFact" to Django? Based on my limited knowledge, I think I may have to use AJAX post/get.
In order to keep from refreshing the page, yes, you will need AJAX. I usually don't like to suggest libraries too much in answers, however, in the interest of being easily cross-browser compatible, I would suggest the use of jQuery.
With jQuery it would be as simple as
Inside of your django template
<html>
...
<head>
<script>
var URL = "{% url 'my_view_that_updates_pieFact' %}";
</script>
</head>
...
Later on...
You'll need to either POST or GET the data to the server via AJAX. To be more RESTful, whenever I need to send data to the server I use POST. jQuery provides the $.post() convenience function to AJAX data to a url via POST. The three parameters are the URL, the data to send (as a JavaScript object; think python dictionaries if you're not too familiar with JavaScript), and a callback function once the server sends back a response.
<script>
function updatePieFact(){
var data = {'pieFact': pieFact};
$.post(URL, data, function(response){
if(response === 'success'){ alert('Yay!'); }
else{ alert('Error! :('); }
});
}
The .click() functions are basically the same thing as specifying onlick in the html attribute. Both click events update pieFact as you would expect and then call updatePieFact() to send the value of pieFact to the server.
$(document).ready(function(){
$('#bttnMinus').click(function(){
pieFact *= 0.9;
updatePieFact();
});
$('#bttnPlus').click(function(){
pieFact *= 1.1;
updatePieFact();
});
});
</script>
In views.py
Since I've used the $.post() function in the JavaScript, the request that Django is going to receive is going to have a method of "POST", so I check to make sure that the method is indeed POST (this means that if someone visits the URL for this view with something like a GET request, they won't update anything). Once I see that the request is, in fact, a POST, I check to see if the key 'pieFact' is in the dict request.POST.
Remember when I set the variable data in the javascript to {'pieFact': pieFact}? That javascript just becomes the request.POST python dictionary. So, if in the javascript I had instead used var data = {'hello': pieFact};, then I would be checking if 'hello' in request.POST instead. Once I see that pieFact is in the request.POST dictionary, I can get its value and then do something with it. If everything is successful, I return an HttpResponse with the string 'success'. This correlates with the check in javascript: if(response === 'success').
def my_view_that_updates_pieFact(request):
if request.method == 'POST':
if 'pieFact' in request.POST:
pieFact = request.POST['pieFact']
# doSomething with pieFact here...
return HttpResponse('success') # if everything is OK
# nothing went well
return HttpRepsonse('FAIL!!!!!')
Hopefully that will get you pointed in the right direction.
Scenario:
I have written an MVC wizard that automatically uses ajax if javascript is enabled in the browser. Each step of the wizard is a PartialView (I'm using ASP.NET MVC 3).
All works fine.
The problem is refreshing the page if, for example, the user's status changes as a result of how she fills in the wizard. EG, if the wizard logs the user in, or registers them. As the wizard 'moves' from step to step by getting Partial Views via AJAX, the page doesn't get refreshed to reflect the change in the user's status (eg, an anonymous user is now registered).
What I want to do:
Essentially, when I need a full page refresh, I need to AUTOMATICALLY run the following on the client AFTER delivering the Partial View corresponding to the current step of the wizard via AJAX:
location.reload();
The Problem:
As the DOM has been modified via AJAX, I don't know how to make my javascript (location.reload();) run WITHOUT user intervention (eg, clicking a button).
Any suggestions? I have been off work for a while and am struggling to get back up to speed.
For now, I have solved my problem using the code in the following article:
Redirecting after AJAX call, when using ASP.NET MVC
I like the approach discussed in the article because it results in reusable code, in a very MVC way - I already have a base controller (AjaxController.cs) where I encapsulate all my AJAX aware code and this is a nice addition to it.
However, there are two issues with this approach:
I have to redirect away from my wizard, so it only works for the final step of the wizard. If the user's status changes half way through the wizard, I am still jiggered.
I would still like to know how to refresh my page after an AJAX call, rather than just redirecting like this.
So if anyone has the answer, I will gladly give them the biscuit.
I am not quite sure how your ajax calls are structured, but if you are using the MVC Ajax helper you can just call location.reload(); in the OnComplete method, like so:
#using (Ajax.BeginForm(new AjaxOptions{OnComplete = "javascriptfunction"}))
{
//Data and submit button
}
<script>
function javascriptfunction(){
location.reload();
}
</script>
// C# code
public ActionResult Foo(Bar bar)
{
// code here
return Json(new
{
Success = true,
Value = this.RenderPartialViewToString("PartialViewName", bar),
Callback = "window.location.href = 'http://yourdomainurl.com/';"
});
}
// jQuery Ajax
$.ajax({
type: "POST",
url: "/urlWhereToPost",
data: ("form#id").serialize(),
dataType: 'json',
async: false,
beforeSend: function() {
// some instruction
},
error: function(e) {
alert(e.responseText);
},
success: function(data) {
if (data.Success) {
if (data.Callback != null) {
if (data.Callback.length > 0) {
jQuery.globalEval(data.Callback);
}
}
}
else {
// do something
}
}
});
I am writing a django app where the user wants to click a button and have a partial page change. Data needs passed from the server to the web page without a needing a complete page refresh. That task sounded like a job for ajax. However, I can't make Ajax work in my app.
I cannot get the call into my server-side function. Below is the code the subject matter is regarding missed calls. My intent is to get the server side to return a list of missed calls and display it to the user without having to refresh the page.
When I click the button, I get a popup that says "Something goes wrong" using firebug, I traced this to a DAJAXICE_EXCEPTION but I don't know anything else about it.
What's going on here? How do I make this work? Also if there's an easier way to do this that doesn't require the Dajax library please advise. And any step-by-step examples would be very helpful.
Server side function
-------- /jim/ajax.py---------
#dajaxice_register
def missedCalls(request, user):
print "Ajax:missedCalls" #never prints...
missedCalls = ScheduledCall.objects.filter(status__exact='Missed')
render = render_to_string('examples/pagination_page.html', { 'missedCalls': missedCalls })
dajax = Dajax()
dajax.assign('#calls','innerHTML', render)
return dajax.json()
-------page.html---------
<script type='text/javascript'>
function missed_calls_callback(data){
# The dajax library wants a function as a return call.
# Have no idea what I'm supposed to do with this part of the function.
# what is supposed to go here?
alert(data.message);
}
</script>
<!-- Button -->
<input type="button" name="calltest" value="JQuery Test"
id="calltest" onclick="Dajaxice.jim.missedCalls(missed_calls_callback, {'user':{{ user }}})">
<div id="calls">
{% include "calls.html" %}
</div>
--------calls.html--------
<h2> Missed Calls</h2>
<ul>
{% for i in missedCalls.object_list %}
<li>{{ i }}</li>
{% endfor %}
</ul>
Before you start using a library, if might be helpful to do manually (to see what's going on).
An ajax request is a HTTP request like any other except that it happens asynchronously (i.e. outside the normal request/response cycle) and it usually returns json or xml (although you can return html if you like).
This means that to accept an AJAX request you just create an url and view as you would normally.
urls.py
...
url(r"^/my/ajax/path/$", myapp.views.ajax_view, name="do-something-ajaxy"),
...
views.py
def ajax_view(self, request):
# Django's Request objects have a method is_ajax()*
# which checks the header to see if it's an 'ajax' request
if request.is_ajax():
raise Http404
missedCalls = ScheduledCall.objects.filter(status__exact='Missed')
# You can return a dictionary-like json object which can be manipulated by the javascript when it receives it
return HttpResponse(simplejson.dumps(missedCalls), mimetype='application/javascript')
https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.is_ajax
And using jquery to carry out the ajax request:
(function($){
$.ajax({
type: 'GET',
url: '/my/ajax/path/',
success: function(data){
for call in data:
/* Do something with each missed call */
},
});
});