url should not change on submitting a form - django

i have this Django application in which when user request for "localhost:8000/time/ ,it is shown html form input.html.
<head>
<!-- paste this in your footer -->
<script type="text/javascript">
$(document).ready(function() {
$('#myForm').submit(function() { // catch the form's submit event
$.ajax({ // create an AJAX call...
data: $(this).serialize(),
type: $(this).attr('POST'), // "post"
url: $(this).attr('/poi/'), // "/poi/"
success: function(response) {
// do something here
}
});
return false;
});
});
</script>
<!-- add jquery or it won't work -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
</head>
<body>
<form action="/poi/" method = "post">
<!---------
first name :<input type ="text" name ="fname">
last name:<input type ="text" name ="lname">
------>
enter a days :<input type ="text" name ="days">
<br>
<input type=submit name="submit" onclick="submit_function(); return false;">
</form>
</body>
when form is submitted user sees response.html page and URL is changed to "localhost:8000/poi/ is shown having
urls.py
urlpatterns = patterns('',
(r'^hello/$', hello),
('^time/$', current_datetime),
('^poi/$', next_datetime),
)
views.py
def current_datetime(request):
return render_to_response('input.html')
def next_datetime(request):
now = datetime.datetime.now()
now_day = now.day
now_month = now.month
now_year = now.year
return render_to_response('response.html', {'now_day': now_day, 'now_month'}}
now i have to do same thing but the url should not change from "localhost:8000/time/ to "localhost:8000/poi/
but it should be "localhost:8000/time/
how to accomplish that?

You have to use ajax to accomplish this
With jquery it would look something like
<form id="myForm"> ... </form> <!-- add an id to your form -->
<!-- paste this in your footer -->
<script type="text/javascript">
$(document).ready(function() {
$('#myForm').submit(function() { // catch the form's submit event
$.ajax({ // create an AJAX call...
data: $(this).serialize(),
type: $(this).attr('method'), // "post"
url: $(this).attr('action'), // "/poi/"
success: function(response) {
// do something here
}
});
return false;
});
});
</script>
<!-- add jquery or it won't work -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
and it should work out of the box
this is with an anonymous function, but you can put the code inside a named one and then add it to the button:
<input type="submit" onclick="submit_function(); return false;" />
it's basically the same

Related

Ajax Triggered request doesn't update Django View

I tried to break this problem down into the simplest example. When the request is ajax, rendering the page with an updated context doesn't produce the expected result.
index.html:
<html>
<body>
{% if templateVariable %}
<h1>{{ templateVariable }}</h1>
{% endif %}
<button id="testBtn">TEST</button>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$(function() {
$('#testBtn').click(function(event) {
$.ajax({
type: "POST",
url: "./",
data: {
'x' : 'x',
'csrfmiddlewaretoken' : '{{ csrf_token }}'
}
});
});
});
});
</script>
</body>
</html>
views.py
def index(request):
context = {}
if 'x' in request.POST:
context['templateVariable'] = 'I was updated via ajax'
print('ajax ran')
return render(request, 'index.html', context)
context['templateVariable'] = 'I was not updated via ajax'
print('ajax was not run')
return render(request, 'index.html', context)
When I first load the page, 'ajax was not run' is printed, templateVariable is 'I was not updated via ajax', and the page renders with that in the h1 tag as expected.
When I click the testBtn, I expect the ajax request to trigger the if statement, update the context, and render the page with 'I was updated by ajax' in the h1 tag.
Instead, 'ajax ran' is printed but templateVariable remains 'I was not updated by ajax' when the page is rendered. 'ajax was not run' only is printed once when the page is loaded initially.
Why would I not be getting the expected result?
EDIT: It seems everyone agrees that you cannot return a render and update context variables with an ajax request but I'm still having trouble with this as I believe this is possible. Here's some alternate code:
index2.html:
<html>
<body>
{% if templateVariable %}
<h1>{{ templateVariable }}</h1>
{% endif %}
<h1 id="placeHolder"></h1>
<button id="testBtn">TEST</button>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$(function() {
$('#testBtn').click(function(event) {
$.ajax({
type: "POST",
url: "./",
data: {
'x' : 'x',
'csrfmiddlewaretoken' : '{{ csrf_token }}'
},
success: function (data) {
$('#placeHolder').html(data);
},
dataType: 'html'
});
});
});
});
</script>
</body>
</html>
views2.py
def index2(request):
context = {}
if 'x' in request.POST:
context['templateVariable'] = 'I was updated via ajax'
print('ajax ran')
return render_to_response('notIndex.html', context)
context['templateVariable'] = 'I was not updated via ajax'
print('ajax was not run')
return render(request, 'index.html', context)
notIndex.html:
{% if templateVariable %}
{{ templateVariable }}
{% endif %}
In this example, the page is initially loaded with templateVariable in the context as 'I was not updated via ajax'.
When testBtn is clicked, the ajax request triggers the if block in the view. This renders notIndex.html with the updated context.
The success function of the ajax call sets the generated html from notIndex.html to the h1 tag.
So why is it only possible to trigger a page render with ajax if the page is not the same one that the ajax call came from?
You can't return renders or redirects from AJAX, that's how it works
If you want to update your UI based on something that happens on the server say you have a cart and you'd like to implement 'add to cart' without refreshing the page, the 'add to cart' button must request an endpoint you provided in your urls.py & that url must return true if object is added, or false if it wasn't, but it won't update it on the UI, you need to manually change the cart items count with Javascript.
If you try to redirect or return a render to ajax, it will get the HTML or the redirect/render, nothing else.
if you want to redirect, you'll want to do that with JS but with no context variables from django.
see this ref

Django and Ajax refreshing a div

I am very new to JS/Ajax and a relative novice to Django. I am testing to see how I can get information back and forth from an Ajax call to my view, and back to Ajax to replace a header string as a simple test.
I can receive information back to my view (h1, which is "AJAX TEST"). What I can't seem to get is the h2text to change to "HEADER CHANGED".
Any help is appreciated as I don't know if it's my Django return function or my Ajax function.
Here is my ajax_test.html:
<div class="content">
<div class="center">
<h1 id="h1">AJAX TEST</h1>
<div>
<button id="btn">PRESS ME</button>
</div>
</div>
<div id="update_div">
{% include "ProdPlat/ajax_test_div.html" %}
</div>
</div>
<script type="text/javascript" src="{% static 'ProdPlat\js\ajax_test.js' %}"></script>
{% endblock %}
My ajax_test_div.html (which I'm trying to refresh):
<div class="content">
<div class="center">
<h2 id="h2">{{h2text.h2text}}</h2>
</div>
</div>
My views_test.py:
def test_ajax(request):
h2text = {'h2text': "INITIAL HEADER"}
if request.method == 'POST':
logger.debug('POST request')
text = request.POST.get('text')
logger.debug('text = {}'.format(text))
h2text = "HEADER CHANGED"
dict = {
'h2text': h2text,
}
# return JsonResponse(dict)
# return render(request, 'ProdPlat/ajax_test_div.html', {'h2text': h2text})
return render_to_response('ProdPlat/ajax_test_div.html', dict)
return render(request, 'ProdPlat/ajax_test.html', {'h2text': h2text})
And finally my Ajax call:
$(document).on('click', 'button', function(){
var csrftoken = getCookie('csrftoken');
console.log('Button Clicked!');
var text = $('h1').text()
console.log('h1 text = ' + text);
$.ajax({
type : 'POST',
url : "/ProdPlat/Ajax_Test/",
dataType: 'json',
data: {'text' : text,
'csrfmiddlewaretoken': csrftoken,
},
success: function(data) {
console.log('data = ' + data);
console.log('data.h2text = ' + data.h2text);
$('#update_div').load(' #update_div')
console.log('Success!');
},
failure: function(data) {
console.log('Failed!');
console.log('data = ' + data);
},
})
})

typeahead autocomplete for Django

base.html
<html lang=en>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link type="text/css" rel="stylesheet" href="/media/js/autocomplete.css">
<script type="text/javascript" src="/media/js/jquery-1.2.1.js"></script>
<script type="text/javascript" src="/media/js/dimensions.js"></script>
<script type="text/javascript" src="/media/js/autocomplete.js"></script>
{% block extra_css %}{% endblock extra_css %}
<title>{% block title %}books are social{% endblock title %}</title>
</head>
<body>
{% block body %}
{% endblock body %}
</body>
</html>
and the smaller template:
<script type="text/javascript" >
$(function(){
setAutoComplete("bookSearchField", "bookResults", "/lookup/?query=");
});
</script>
<label for="bookSearchField">Book: </label>
<input type="text" id="bookSearchField" name="bookSearchField">
urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('project.app.views',
(r'^/lookup/$', 'book_lookup'),
)
models.py
class Book(models.Model):
name = models.CharField(max_length=200)
views.py
from django.utils import simplejson
from django.http import HttpResponse
from project.app.models import Book
def book_lookup(request):
# Default return list
results = []
if request.method == "GET":
if request.GET.has_key(u'query'):
value = request.GET[u'query']
# Ignore queries shorter than length 3
if len(value) > 2:
model_results = Book.objects.filter(name__icontains=value)
results = [ {x.id :x.name,} for x in model_results ]
json = simplejson.dumps(results)
return HttpResponse(json, mimetype='application/json')
so is there any tutorial/solution to create bootstrap typeahead for elagent and responsive .
<input id="book_lookup" class="search-query typeahead" data-items="4" type="text"
placeholder="Select here....">
Edited:
<script type="text/javascript">
var typeahead_data = [];
function get_client_names() {
$.ajax({
url: "/lookup/?query=",
success: function (data) {
$.each(data, function (key, value) {
typeahead_data.push(value.toString());
});
// assign the array to my typeahead tag
$('.typeahead').typeahead({
source: typeahead_data,
});
}
});
}
$(function () {
get_client_names();
});
</script>
need something like
$("#book_lookup").tokenInput([{"id": 1, "name": "ddddd"},{"id": 2, "name": "ddffddd"}],{preventDuplicates: true,
hintText: "Type book name here...",
validateInputAjax: true,
validateInputObjectType: "book name",
validateInputNewObjectLink: function (value) {
$('#book_lookup').tokenInput(
'add', {'id': value, 'name': value});
return true;
},
validateInput: function (value) {
$.post("/lookup/", {validate_field_name: value},
function(data){
if (data.valid) {
$("#book_lookup").tokenInput('valid', value);
} else {
$("#book_lookup").tokenInput('invalid', value, 'is not a valid Book name');
};
});
}});
});
how to change data-source to book_lookup json view ?
I have used Bootstrap's typeahead before and what I did was create a method to get the dictionary via Ajax like this:
<script type="text/javascript">
var typeahead_data = [];
function get_client_names() {
$.ajax({
url: "/lookup",
success: function (data) {
$.each(data, function (key, value) {
typeahead_data.push(value.toString());
});
// assign the array to my typeahead tag
$('.typeahead').typeahead({
source: typeahead_data,
});
}
});
}
$(function () {
get_client_names();
});
</script>
The tag element is like this:
<input id="book_lookup" class="search-query typeahead" data-items="4" type="text"
placeholder="Select here....">
And basically the rest of your code is ok.
Note that here you're doing an ajax request (this requeires jquery) to the /lookup/ view which in turn returns a json object, that should look like this: [name1,name2,name3...]. You can test if the view is working ok by just accessing the view through the explorer like this: /lookup/ and if you see the dictionary displaying correctly there, the server side is ok.
Hope this works for you!
In Paulo's answer, he just has a static list of items to search from, that is why he calls the ajax on load, and gets the list and adds it to the source.
In your case, I think, you need to query whatever the user types, and send it to the server. This can be done by adding the function param in data-source, which gets 2 arguments, query and a callback.
Check here

Having trouble submitting my form using Dojo

I am using Django 1.5 and Dojo 1.8. I am trying to get Dojo to submit a form back to a Django view when I click a button.
Here is my Django view:
def report(request, report_id, report_url=None, template='report_parameters.html'):
if request.method == 'POST':
form = ReportParametersForm(request.POST)
if form.is_valid():
report_params = form.save()
html = "Success!"
return HttpResponse(html)
else:
form = ReportParametersForm()
return render(request,template, {
'form': form,
'report_url': report_url,
'report_id': report_id,
})
Here is the html page:
<div id="report_body">
<form data-dojo-type="dijit/form/Form" id="parameters_form" data-dojo-id="parameters_form">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<p><button id="submit_parameters" dojoType="dijit.form.Button" type="submit">Submit</button></p>
</form>
</div>
<script type="dojo/on" data-dojo-event="submit" data-dojo-args="e">
e.preventDefault();
require(["dojo/dom", "dojo/request", "dojo/dom-form"], function(dom, request, domForm){
on(dom.byId("submit_parameters"), "click", function() {
console.log("Dojo Post");
request.xhr("/report_parameters/report_id/report_url/", {
method: "post",
handleAs: "json",
data: domForm.toJson("parameters_form"),
}).then(
function(response){
alert(response);
dom.byId("report_body").innerHTML = "Report!";
},
function(error){
dom.byId("report_body").innerHTML = "<div class=\"error\">"+error+"<div>";
}
);
});
});
</script>
When I click the Submit button, I want to send a POST request to the url passing the data I have in my form. However, right now when I click Submit, the page reloads with a url looking something like this: /?csrfmiddlewaretoken=Y9gaNMFRWZNXMbJ2L3Ev7A5iKPGTuWeF&param_1=0&param2=0/report_parameters/report_id/report_url/.
I don't see the Dojo Post that should be appearing in my console.
How do I get my form to submit?
This fiddle seems to do what you want.
The major differences seem to be:
The <form> is actually a <div>. The Dojo documentation for Form links to reasons why this is done for IE.
All the related event script is inside the form <div>.
Remove the on(dom.byId("submit_parameters")... code, as there's already a declarative submit event handler.
HTML code:
<div id="report_body"></div>
<div data-dojo-type="dijit/form/Form" id="parameters_form" data-dojo-id="parameters_form" encType="multipart/form-data" action="" method="">
<input name="dummy" value="dummy">
<script type="dojo/on" data-dojo-event="submit" data-dojo-args="e">
console.log("submit");
e.preventDefault();
require(["dojo/dom", "dojo/request/xhr", "dojo/dom-form"], function(dom, xhr, domForm) {
console.log("Dojo Post");
var url = "/report_parameters/report_id/report_url/";
var data = domForm.toJson("parameters_form");
// overwrite url and data for jsfiddle
url = "/echo/json/";
data = {
json: data
};
xhr(url, {
method: "post",
handleAs: "json",
data: data,
}).then(function(response) {
alert(JSON.stringify(response, null, 2));
dom.byId("report_body").innerHTML = "Report!";
}, function(error) {
dom.byId("report_body").innerHTML = "<div class=\"error\">" + error + "<div>";
});
});
</script>
<button data-dojo-type="dijit/form/Button" id="submit_button" type="submit" name="submitButton" value="Submit">Submit</button>
</div>
JS code:
require(["dojo/parser", "dijit/registry", "dijit/form/Form", "dijit/form/Button", "dijit/form/ValidationTextBox", "dijit/form/DateTextBox", "dojo/domReady!"], function (parser, registry) {
parser.parse().then(function () {
console.log("parsed");
console.log(registry.byId("parameters_form"));
console.log(registry.byId("submit_button"));
});
});
I had to modify the above slightly. This is what eventually worked for me:
<div id="report_body"></div>
<form data-dojo-type="dijit/form/Form" id="parameters_form" data-dojo-id="parameters_form" encType="multipart/form-data" action="" method="POST">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<script type="dojo/on" data-dojo-event="submit" data-dojo-args="e">
e.preventDefault();
require(["dojo/dom", "dojo/request/xhr", "dojo/dom-form"], function(dom, xhr, domForm){
var url = "/report_parameters/report_id/report_url/"
var data = domForm.toObject("parameters_form")
xhr(url, {
method: "post",
data: data,
}).then(
function(response){
alert(response);
dom.byId("report_body").innerHTML = "Report!";
},
function(error){
dom.byId("report_body").innerHTML = error;
}
);
});
</script>
<p><button id="submit_parameters" dojoType="dijit/form/Button" type="submit" name="submitButton" value="Submit">Submit</button></p>
</form>
Using either the <div> or <form> tags to wrap the whole thing worked for me.

sent image data using jquery ajax won't be saved using ModelForm

I'm going to edit an ImageField using jquery ajax,so I've used jquery form plugin,this is the code:
<form id='form_upload' action="." method="POST" enctype="multipart/form-data">
<input type='file' id='id_HeadImage' name='id_HeadImage' />
</form>
<script typr="text/javascript">
var options = {
dataType: 'xml',
url: '{% url DrHub.views.editNews param1,param2 %}',
}
$('#form_upload').ajaxSubmit(options);
</script>
in <head>:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script>
<script src="http://malsup.github.com/jquery.form.js"></script>
and in server side :
if ('id_HeadImage' in request.FILES) and (request.FILES['id_HeadImage']):
gForm=GalleryForm(request.POST,request.FILES,instance=newsInstance.gallery_ptr)
if gForm.is_valid():
gForm.save()
as U can see I'm going to edit ImageField of a model named Gallery.
How can I do this?
this is Gallery Model:
class Gallery(models.Model):
HeadImage = models.ImageField(upload_to="gallery",blank=True,null=True)
While gForm.is_valid() returns True,but It won't be saved and Image of HeadImage Field won't be changed.
Note : I've checked this in firebug and I'm sure that data is sent and request.FILES has value.
what's wrong here?
EDIT : I've worked based on this article: http://www.laurentluce.com/posts/upload-to-django-with-progress-bar-using-ajax-and-jquery/
Try ajaxForm in place of ajaxSubmit:
`
<form id='form_upload' action="." method="POST" enctype="multipart/form-data">
<input type='file' id='id_HeadImage' name='id_HeadImage' />
</form>
<div id="empty">
</div>
<script type="text/javascript">
function handleResult(responseText, statusText, xhr, $form) {
//do stuff here
};
jQuery(document).ready(function() {
var options = {
target: '#empty',
// Not sure if you should use xml here, I would suggest json . ,
dataType: 'xml',
url: '{% url DrHub.views.editNews param1,param2 %}',
success: handleResult,
}
$('#form_upload').ajaxForm(options);
});
</script>`