I'm trying to make a Django form with dynamically pre-populated fields: that is, when one field (checkin_type
) gets selected from a drop-down menu, other fields get automatically pre-populated with corresponding data. To this end, I would like to send a POST request to the server as soon as a drop-down option is selected.
So far I've tried the following template (following https://docs.djangoproject.com/en/2.0/ref/csrf/):
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
<script>
$(document).ready(function(){
var csrftoken = Cookies.get('csrftoken');
$(".auto-submit").change(function() {
$.post({
url: "{% url 'get-checkin-type' %}",
data: $(".auto-submit option:selected").val(),
headers: {
X-CSRFToken: csrftoken
}
})
});
});
</script>
<form action="" method="post">{% csrf_token %}
{% for field in form %}
<div class="{% if field.name == 'checkin_type' %}auto-submit{% endif %}">
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
</div>
{% endfor %}
<input type="submit" value="Send message" />
</form>
However, when I select a drop-down option I get a
new:17 Uncaught SyntaxError: Unexpected token -
which emanates from the X-CSRFToken: csrftoken
line:
Can someone point out to me what is wrong with this code? (I tried looking it up from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Unexpected_token but so far couldn't figure it out).
By the way, it seems from jQuery add CSRF token to all $.post() requests' data that one can also add the CSRF token to the POST request's data
, but this doesn't seem like the most elegant approach to me, and the docs state that
For this reason, there is an alternative method: on each XMLHttpRequest, set a custom X-CSRFToken header to the value of the CSRF token.
You are missing single quote, Try like following.
$(".auto-submit").change(function() {
$.post({
url: "{% url 'get-checkin-type' %}",
data: $(".auto-submit option:selected").val(),
headers: {
'X-CSRFToken': csrftoken
}
})
});
PSK's solution works, but for the sake of completeness, here is the approach as outlined by the Django docs after reading a bit further (from https://docs.djangoproject.com/en/2.0/ref/csrf/#setting-the-token-on-the-ajax-request) which uses a .ajaxSetup
to cover all requests once and for all:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
<script>
$(document).ready(function(){
var csrftoken = Cookies.get('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
$(".auto-submit").change(function() {
$.post({
url: "{% url 'get-checkin-type' %}",
data: $(".auto-submit option:selected").val(),
})
});
});
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With