How to Ajax replaceWith(Django form's {% csrf_token %}) - javascript

I'm trying to replace a 'reply' button with a form in my Django app.
Here's my Javascript code:
$(document).on('click', '.comment-reply-link', function(e) {
$(this).replaceWith("<form method='post'>{% csrf_token %}<div class='form-group'><label for='comment'>Comment:</label><textarea class='form-control' id='comment' rows='5' maxlength='300' minlength='1' name='comment' placeholder='Tell us how you loved this product :D'></textarea></div><button type='submit' name='post_comment' value='True'>Comment</button></form>");});
// The replacing line should contain no whitespace.
// Otherwise it will raise Uncaught SyntaxError: Unexpected token ILLEGAL
I get the form element but the problem is that {% csrf_token %} is processed as just unicode in replaceWith(). {% csrf_token %} is necessary in Django to submit a form. Any kind of help and advice will be thankful :)
Edit:
I assume that {% %} means that Django needs to be involved to retrieve the right value. So I thought I should render an html page with form and update that form with 'reply' button. Here's my logic.
view.html
<div class="reply">
<a class='comment-reply-link' href='{% url "rango:reply_form" %}'aria-label='Reply to Araujo'>Reply</a>
</div>
reply.js
function ajax_get_update(item){
$.get(url, function(results){
//get the parts of the result you want to update. Just select the needed parts of the response
// var reply_form = $("#reply_form", results);
var reply_form = $(".head", results);
console.log(reply_form);
//console.log(results);
//update the ajax_table_result with the return value
$(item).html(reply_form);
}, "html");
}
$(document).on('click', '.reply', function(e) {
console.log("Debuggin...");
e.preventDefault();
url = ($( '.comment-reply-link' )[0].href);
console.log(url);
ajax_get_update(this);
});
reply_form.html
<!DOCTYPE html>
... code omitted ....
<form id="reply_form" method="post">
{% csrf_token %}
<div class="form-group">
<label for="comment">Reply:</label>
<textarea class="form-control" id="comment" rows="5" maxlength="300" minlength="1" name="comment" placeholder="Tell us how you loved this product :D"></textarea>
</div>
<button type="submit" name="post_comment" value="True">Reply</button>
</form>
</body>
</html>
When I click the reply button, the button disappears but nothing updates. The html page variable results gets the correct html page data but it seems like
$(item).html(reply_form);
is not working right. Because when I do
$(item).html('<p>button disappears</p>');
the paragraph will appear. Any thoughts?

To use django template language in javascript you should encapsulate your code in a Verbatim tag.
example :
{% verbatim %}
var hello = {% if some_condition %} 'World' {% else %} 'foobar' {% endif %};
{% endverbatim %}
From the docs :
Stops the template engine from rendering the contents of this block tag.
A common use is to allow a JavaScript template layer that collides with Django’s syntax
In your case :
<script>
{% verbatim %}
$(document).on('click', '.comment-reply-link', function(e) {
$(this).replaceWith("<form method='post'> {% csrf_token %} </form>")
};
{% endverbatim %}
</script>

Related

Unable to change input field text content with javascript

I'm trying to change the text inside an input field to username.
The id for the field is is_username.
And in my Javascript file I've tried
document.getElementById("id_username").innerHTML = "Username";
document.getElementById("id_username").value = "Username";
document.querySelector(".id_username").textContent = "Username";
None are working... This site runs on django.
I know with html you can use placeholder to achieve this but these fields are created using django tags.
Any ideas?
I did try using these methods on a normal html input field and also had no luck.
htmlpage:
{% extends 'display_words.html' %}
{% block content %}
<div class="flex-container">
<div class="content">
<div class="display-box">
<!-- <p>Please login to see this page.</p> -->
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
{% if next %}
{% if user.is_authenticated %}
<p>Your account doesn't have access to this page. To proceed,
please login with an account that has access.</p>
{% else %}
<p>Please login to see this page.</p>
{% endif %}
{% endif %}
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<table>
<tr>
<!-- <td>{{ form.username.label_tag }}</td> -->
<td>{{ form.username }}</td>
</tr>
<tr>
<!-- <td>{{ form.password.label_tag }}</td> -->
<td>{{ form.password }}</td>
</tr>
</table>
<input id="login-button" class="button" type="submit" value="login">
<input type="hidden" name="next" value="{{ next }}">
</form>
{# Assumes you setup the password_reset view in your URLconf #}
<p id="lost-password-link">Lost password?</p>
</div>
</div>
</div>
{% endblock %}
I created a test html file and it also doesn't work: code below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Words & Phrases</title>
</head>
<body>
<input type="text" id=“id_username”>
<script>
document.querySelector('#id_username').textContent = 'username';
</script>
</body>
You can try with this:
document.querySelector('input[name="id_username"]').value = 'Username';
<input type="text" name="id_username" id="id_username" placeholder="Your text">
Would like to point out that when you tried your queryselector. You used ".id_username", this selects a class that is called that, not the id.
You can try to store the selected element in a variable then, run the innerHTML/textcontent.
const stubbornInput = document.getElementById("id_username");
stubbornInput.innerHTML = 'Whatever you want';
Ive had cases where this worked but, going straight for the thing didnt. Not sure if it helps or why it worked for me before but, worth a shot :)
your text input has the ID username, in your javascript it says id_username try this input and the javascript.
document.getElementById("username").value = "your_value_here";
<input type="text" name="username" id="username">
If that doesn't work, try using JQuery.
$("input[name=username]").val("hello_world")
ok below is the correct answer:
my main js file was causing an issue which is why it didn't work for me earlier. After i created a empty js file for this purpose it worked.
document.querySelector('#id_username').value = 'username' ;
document.querySelector('#id_username').addEventListener('click', function () {
document.querySelector('#id_username').value = '';
})
Found an easier was to do this:
document.querySelector('#id_username').setAttribute('placeholder', 'Username');

jQuery Scirpt not begin called- Flask app

im trying to send requests without refreshing the pae using ajax requests.
Watching the google event listerner when i i click the submit button my script is not begin called.
script.js
$("#new_app_b").click(function(event) {
//prevent submit
event.preventDefault();
//do things on submit
$.ajax({
data : {
data_app : $('#data_app').val(),
time_app : $('#time_app').val(),
id : $('#id').val()
},
type: "POST",
url: "/update",
beforeSend: function(){
//before send data
},
success: function(data){
// the data
console.log(data);
}
});
});
in layout.html i call this in the
in page html the part with the form is like this it has the {% extends 'layout.html' %} and the form is the the blockcontent and is begin displayed correctly it has 300+ lines so i wont post it all.
<form action="/update" method='POST' id="new_app">
<input name="id" id="id" type="hidden" value="{{ pratica[0][1] }}">
</input>
{% for cell in pratica %}
{% if cell[0] == 'data_app' %}
<td><input name="data_app" id="data_int" class="form-control form-control-sm"
type="text" value="{{ cell[1] }}"/></td>
{% elif cell[0] == 'time_app' %}
<td><input name="time_app" id="ora_app" class="form-control form-control-sm"
type="text" value="{{ cell[1] }}"/></td>
{% endif %}
{% endfor %}
<td>
<button id="new_app_b" type="submit" class="btn btn-success">
<i class="fa fa-check"></i>
</button>
</td>
</form>
while the /update controller is just like:
#app.route("/update", methods=['GET','POST'])
def update():
print("request: ")
print("id: " + request.form['id_pratica'])
print("data_app: " + request.form['data_app'])
print("time_app: " + request.form['time_app'])
return ''
So ive found the solution and this is what i did:
I moved the into the child template, using a block block like so:
{% block scripts %}
{{ super() }}
<script type="text/javascript" src="{{ url_for('static',filename='js/script.js') }}"></script>
{% endblock %}
and put that block on top of the content block, and then i call the block in the layout.html file like so
{% block scripts %}{% endblock %}
in the tag, and now is begin loaded and called when it needs to.

How to pass parameters on onChange of html select with flask-wtf

The following flask code creates a select .. option dropdown menu:
model:
class SelectForm(Form):
country = SelectField('Country', choices=[
('us','USA'),('gb','Great Britain'),('ru','Russia')])
flask app:
#app.route('/new')
def new():
form = SelectForm()
return render_template('new.html', form = form )
html file:
<form method=post action="/register">
{{ render_field(form.country) }}
<p><input type=submit value=Register>
</form>
macro file the defines render_field:
{% macro render_field(field) %}
<dt>{{ field.label }}
<dd>{{ field(**kwargs)|safe }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</dd>
{% endmacro %}
What is the best way to have onchange submit the results automatically without the user having to press the submit button? Is there a way to change the macro or what's the most elegant way?
thanks
It can be done by add javascript onchange function as attribute
<form method=post action="/register">
{{ render_field(form.country(**{"onchange":"this.form.submit()"})) }}
<input type=submit value=Register>
</form>

Problems displaying django syntax in html when using ajax request

I have an article where i allow people to comment.
When the user clicks on the reply button in a submitted comment an ajax request is being sent to retrieve html from a file to add a new element to the DOM that contains the reply form.
I'm using this code:
function handle_ajax_request(event) {
if ( request.readyState === 4) {
if (request.status === 200 || request.status === 304) {
console.log("AJAX request from get_reply_form was received successfully from the server.");
parentElement = document.getElementById("reply_comment");
reply_form_element = document.createElement("div");
reply_form_element.id = "reply_comment_form";
parentElement.appendChild(reply_form_element);
reply_form_element.innerHTML = request.responseText;
} else {
console.log("Error: AJAX request from get_reply_form failed!");
}
}
}
function get_reply_form(event) {
event.preventDefault();
reply = document.getElementById("reply_comment");
request = new XMLHttpRequest();
if (! request) {
console.log("Error: Unable to create AJAX request.")
}
console.log("Created ajax request, checking for state.");
request.onreadystatechange = handle_ajax_request;
request.open("GET", "http://localhost:8000/static/html/experience/comment_reply_form.html", true);
request.send(null)
}
I fetch this file with the ajax request:
{% load comments %}
{% get_comment_form for article_details as form %}
<form action="{% comment_form_target %}" method="post">{% csrf_token %}
{{ form.object_pk }}
{{ form.content_type }}
{{ form.timestamp }}
{{ form.security_hash }}
{% if node.id %}
<div class="form-group">
<input type="hidden" class="form-control" name="parent" id="parent_id" value="{{ node.id }}" />
</div>
{% endif %}
{{ form.comment }}
<div class="col-md-4">
<div class="form-group">
<input type="hidden" class="form-control" name="next" value="/article/display/{{ article_details.id }}" />
<input type="submit" class="form-control" value="Reply">
</div>
</div>
</form>
As you can see there is some django template syntax code in that html.
When i add this html to a div on the page it works except from that the django syntax is not being interpreted by django for some reason and i dont understand why its not being interpreted normally.
I literally get this displayed:
Posted by an anonymous user 4 days, 20 hours ago
test
Reply
{% get_comment_form for article_details as form %}
{% csrf_token %} {{ form.object_pk }} {{ form.content_type }} {{ form.timestamp }} {{ form.security_hash }} {% if node.id %}
{% endif %} {{ form.comment }}
The django syntax is being display literally and should not be visable at all if it was interpreted by django. Why doesnt this work ?
In the html code a " is inserted before the django syntax for some reason, i dont know why and a " is added at the end. Also, its seem that every time a { is encountered a " is put in front of it and a " is put at the end and i dont know why.
I'm not using jquery since im currently learning about javascript and i like to learn the plain version as welll and not just frameworks.
You're making a get request against a static HTML template. You should be making the request against a URL that calls a view, like any other Django page.

Jquery in Django

I am trying to learn using Jquery in django application.My code looks like this
views.py
from django.shortcuts import render
from django.http import HttpResponse
from airapp.models import Travel
def search_form(request):
return render(request, 'search_form.html')
def search(request):
if 'f' in request.GET and request.GET['f']:
q = request.GET['f']
books = Travel.objects.filter(froms__icontains=q)
return render(request, 'search_results.html',
{'books': books, 'query': q})
else:
return HttpResponse('Please submit a search term.')
urls.py
from django.conf.urls import patterns, include, url
from air import views
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^search-form/$', views.search_form),
url(r'^search/$', views.search),
)
search_form.html
<html>
<head>
<title>Search</title>
</head>
<body>
<form action="/search/" method="get">
FROM<input type="text" name="f"><br>
TO<input type="text" name="t"><br>
CLASS<input type="text" name="c"><br>
<input type="submit" value="Search">
</form>
</body>
</html>
search_results.html
<p>You searched for: <strong>{{ query }}</strong></p>
{% if books %}
<p>Found {{ books|length }} book{{ books|pluralize }}.</p>
<ul>
{% for book in books %}
<li>{{ book.froms }}</li>
<li>{{ book.to}}</li>
<li>{{ book.classs }}</li>
<li>{{ book.details }}</li>
{% endfor %}
</ul>
{% else %}
<p>No books matched your search criteria.</p>
{% endif %}
When the search result displays it will be on a new html page(search_results.html).I want to display search results on the same html page where form is created(search_form.html) when I click search button.Can I display it using jquery? Can anybody help me write the code.
Also anybody suggest me good tutorial for learning ajax and jquery & how can I use it django
application development.
Here is an working sample. Just need to modify search_form.html:
<html>
<head>
<title>Search</title>
<script language="JavaScript" type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script language="JavaScript" type="text/javascript">
$(function() {
$("#search-form").submit(function() {
var from = $("#search-form :input[name='f']").val();
$.get("/search/", { f : from })
.done(function(data) {
$("#search-result").html(data);
$("#search-result").show();
});
return false;
})});
</script>
</head>
<body>
<form id="search-form">
FROM<input type="text" name="f"><br>
TO<input type="text" name="t"><br>
CLASS<input type="text" name="c"><br>
<input type="submit" value="Search">
</form>
<div id="search-result" style="display:none">
</div>
</body>
</html>
Basically, what it does:
include jQuery in head
in the script, replace 'submit' behaviour of 'search-form': use $.get to send a GET request to server, and directly show response in 'search-result' div. (you may modify the codes to make it more robust)
in body, create a 'search-result' div for displaying response. Make it invisible by default (may do it in a CSS file)
For Ajax, you may refer to: http://api.jquery.com/jquery.ajax/. $.get is a shortcut based on $.ajax: http://api.jquery.com/jquery.get/

Categories

Resources