FYI - development site, work in progress.
I am using Django on a page with a form. However, I am also using a javascript tab function on this same page which highlights the tab with the correct on-page link / hash.
The default page = http://learntango.webfactional.com/video/35863752#section=comment
The contact-us page = http://learntango.webfactional.com/video/35863752#section=contact
When the form is not valid, the page is returned (good). However, it is the base page which is returned: http://learntango.webfactional.com/video/35863752
After that, the javascript then defaults this to the comment page.
How do I return the same page, with the "contact" on-page link active, so they can see their form errors and realize that the form did not submit?
Thanks!
David
def video(request, url_vimeo_id):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
send_mail(
'This is an e-mail from the website',
cd['message'],
cd.get('email', 'noreply#example.com'),
['dwyliu#gmail.com'],
)
return HttpResponseRedirect('http://www.learntodancetango.com')
return render_to_response('video.html',{'video': video,'next':next, 'form': form}, context_instance=RequestContext(request))
else:
form = ContactForm()
return render_to_response('video.html',{'video': video,'next':next, 'form': form}, context_instance=RequestContext(request))
Set form's action as http://learntango.webfactional.com/video/35863752#section=contact
Related
I have a login form displayed always at the top right of my website. When an invalid username/password combination is found, a hidden form is generated based on the server response and submitted in order to redirect to a larger login (i.e. login.php)... When I submit my new attempt to login on the login.php login form after being redirected via the hidden form, the browsers warns "To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier." Wierdly enough, this message is only displayed on successful logins ( correct username/password as per database ).
Here is the Javascript function that handles the servers response when attempting to login
handleLoginXML: function(xml){
var loginValue = xml.getElementsByTagName('info')[0].firstChild.nodeValue;
if(loginValue === "success"){
location.reload();
}
if(loginValue === "failed") {
this.post('?page=login', { login_error : 'Invalid Email/Password'});
}
},
Also, here is the post function that submits the hidden form on failed login
post: function(path, params, method='POST'){
const form = document.createElement('form');
form.method = method;
form.action = path;
for(const key in params) {
if(params.hasOwnProperty(key)){
const hiddenField = document.createElement('input');
hiddenField.type = 'hidden';
hiddenField.name = key;
hiddenField.value = params[key];
form.appendChild(hiddenField);
}
}
document.body.appendChild(form);
form.submit();
}
How can I prevent the form on ?page=login from resending the hidden form data? Is it the way i'm dealing with successful logins that is the problem? Thanks
This is the problem right here location.reload();, it is reloading the page like hitting the refresh button.
An easy alternative is: window.location.href = window.location.href; That should redirect the user back to the same URL without resubmitting of the form.
you can also reset the form: document.getElementById("myForm").reset();
I am deploying a website using Django. There is an application called 'forum', supporting a discussion forum on my website.
The url of the discussion forum is 'XXX.com/forum/roomY'. I want to refresh a div id = ''chat'', which includes a message list, on this page when users click a refresh button. I want to use AJAX to do that.
But I find that I could not call the function updatestatementlist(request) to retrieve the updated message list so it can be passed to the on this page.
/forum/views.py def updatestatementlist(request):
log.debug("call statementlist function")
statements = Statement.objects.filter(discussion=discussion)
return render(request, 'forum/statementlist.html', {
'statements': statements
})
I cannot see the log info so I think by clicking the button I fail to call this function.
The main html page of the discussion forum is /forum/discussion.html, which is under the template folder. I extract the html code within the div id = "chat" to a separate html /forum/statementlist.html as suggested here and several other SO posts.
/forum/discussion.html
<button id = "Refresh"> Refresh </button>
<div id="chat">
{% include 'forum/statementlist.html' %}
</div>
/forum/statementlist.html
{% load mptt_tags %}
{% recursetree statements %}
// display each statement
{% endrecursetree %}
forum.js
//When users click the refresh button
$("#Refresh").on("click", function(event){
alert("Refresh clicked")
$.ajax({
url: '',
type: "GET",
success: function(data) {
alert("success")
var html = $(data).filter('#chat').html();
$('#chat').html(html);
}
});
});
I also tried a few other url in this AJAX request: {% url updatestatementlist %}, {% url 'updatestatementlist' %}. But then I think it should be set to empty because I don't want to be redirected to another url. The discussion forum has a url of 'XXX.com/forum/roomY', by clicking the refresh button on this page I only want to refresh the div and fetch an updated statement list from the server.
BTW, I can see the two alerts after I click the button.
/forum/urls.py
urlpatterns = [
...
url(r'^(?P<label>[\w-]{,50})/$', views.discussion_forum, name='discussion_forum'),
url(r'^(?P<label>[\w-]{,50})/$', views.statementlist, name='statementlist'),
]
/forum/views.py def discussion_forum() is used to load all the information when the user first arrives at this forum.
I guess my problem might be that 1) the AJAX is wrong; 2) the url is wrong so that the updatestatementlist() can not be called.
Can anyone help me with that? Thanks a lot! Let me know if you need any other information!
Packages related:
Django==1.9.3
django-mptt==0.8.7
On the client side, Set your request header to X-Requested-With to XMLHttpRequest, Django use this specific header to determine whether it is a Ajax Request:
Here is the a snippet from Django source code:
https://docs.djangoproject.com/en/2.2/_modules/django/http/request/#HttpRequest.is_ajax
def is_ajax(self):
return self.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
After defining this header, you need to add one logic layer into your view function.
def your_view_func(request, *args, **kwargs):
if request.is_ajax():
...
return render(request, <your_ajax_template>)
return render(request, <your_normal_template>)
Updated:
I prefer the raw XMLHttpRequest API, if you use Jquery, add the berforeSend property.
$.ajax({
type: "GET",
beforeSend: function(request) {
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
},
...
});
Why X-Requested-With but not HTTP_X_REQUESTED_WITH?
HTTP headers in the request are converted to META keys by converting all characters to uppercase, replacing any hyphens with underscores and adding an HTTP_ prefix to the name.
https://docs.djangoproject.com/en/2.2/ref/request-response/#django.http.HttpRequest.META
I'm new to Django and Python so bear with me.
I'm trying to submit a form (in test.html page) And once the form is submitted I want to load a new page(test.html/web1.html) and then the page will display continuous updates on tasks running.
This currently works on a single page, where I submit the form I get the updates on the same page using AJAX. I want to implement this on a new page. Below is my code.
test.js
$('#Submit_button').on('submit',function(event){
event.preventDefault();
console.log("form submitted!")
call_func();
});
function call_func() {
$.ajax({
url : "start_task/", // the endpoint
data:{...,'init':call_func.i}, // call_func.i to iterate 2 times
headers: {Accept: "application/json"},
success : function(json) {
if(call_func.i==0){
call_func.i=1;
call_func();
}
else ...
views.py
def start_task(request):
if request.method == 'POST':
init = request.POST.get('init')
print('init =',init)
if init==0:
return render(request, 'my_app/web1.html')
elif init==1:
# work on updates
return HttpResponse(
json.dumps(response_data),
content_type="application/json"
)
html
<form action="/test.html/start_task/" method="POST" id="Submit_button">
How do I use AJAX only for the latter part (to update the new page) and just load the page first after submit?
I think you need something like HttpResponseRedirect instead of HttpResponse:
if form.is_valid(): # validation
# Process your data
# ...
return HttpResponseRedirect('/new_page_url/')
I have a the following view that works ok and displays the results just fine in the template.
def PTR(request):
if request.method == 'POST':
form = PTRForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
results = data_groups.setup_ptr(cd)
t = loader.get_template('ptr_records.html')
c = RequestContext(request, {'results': results})
return HttpResponse(t.render(c))
else:
form = PTRForm()
return render_to_response('ptr_form.html', {'form': form})
However, I'd prefer the results display in a bootstrap modal. I'm sure I can figure it out if I new where to start. Should I do the following.... Add jQuery to the form and have jQuery/javascript handle the post and get the results to put in a modal that is defined on the form itself. That is, the modal won't be displayed until success is returned to the AJAX call?
Yes you should do that, use Ajax to call the server then return the data as json then use jquery and bootstrap to display the modal
I need some advise handling a form submit and page redirect. I have two pages, where the first is a landing page with a simple form, when user select a criteria and submits it, he is redirected to page2 that displays tabular data and some query related info.
When Submiting Page1 Form, data is passed in the url :
for ( var key in dataArray )
{
if ( dataArray[key] )
{
if (queryStr != "")
{
queryStr += "&" ;
}
queryStr += key + "=" + dataArray[key];
}
}
var url = "page2.html?" + queryStr;
window.location.href = url;
On the other hand, I am handling this POST using $_GET['xxx']), then build a query accordingly.The issue is not handling POST & GET requests but handling errors..
I dont like is that if the user types something in the url www.site.com/page2.html?Q1=red -> www.site.com/page2.html?Q1=red545454 it will logically not pass the server side validation and therefore just display an empty page template without data, which kind o bothers me.. Also if the user tries to load page2.html without any posted data(querystring).
I would like upon page2.html load event, check if there are any posted values, if not redirect back.. Is this the correct way of handling it? Thanks
You doesn't submit form through POST method because "on submitting" you usewindow.location.href (redirect) with param Q1 in query string.
If you want see only url like www.site.com/page2.html do next: set action to your form as action="www.site.com/page2.html",instead adding variable to QUERY_STRING dynamically insert Q1 in any hidden element like:
document.getElementById('Q1_ID').value = dataArray[key];
After call like document.forms[0].submit();. Now variable Q1 in $_POST['Q1'] and url look as www.site.com/page2.html.
An elegant way to handle this would be to submit your form using Ajax and respond with validation errors or success message. In case of errors, show them on the current page otherwise redirect user to whatever page you want.