I use the latest versions of Django, python, bootstrap3, and crispy forms for this project.
To maintain user inputted checkboxes on multiple pages, I must use POST. But, pagination only uses GET. So, a hack on pagination is to wrap the Next/Previous buttons in a sub-form and POST using the buttons. This works for pagination, but then my normal "I'm done, submit this session and process the updates" button - my submit button - does nothing: no GET, no POST, nothing.
How can I enable pagination, multiple screen data accumulation across pages, and final submission of the session when complete?
Just FYI - for me, session data and hidden forms haven't worked because the data doesn't come back to the Django server. So, request.POST.get('CAT') returns NULL even though the web page has a value in the tag 'CAT'. Session data doesn't work because I can't get the data to the server.
Here are sub-sections of my code. The "hidden" fields (cat and crd) are visible during my testing. They are filled with the IDs of any/all selected categories (cat) or flashcards (crd) - comma separated.
Views.py:
class CardsCreate(TemplateView):
template_name = 'sel_cards_add.html'
model = FlashCard
def dispatch(self, request, *args, **kwargs):
print('DISPATCH:')
student_id = kwargs.get('student_id')
try:
flashcards = FlashCard.objects.all().order_by('category', 'front')
except FlashCard.DoesNotExist:
flashcards = None
except Exception as e:
print('type=%s args=%s (%s)' % (type(e), e.args, e))
raise Http404
flashcard_paginator = paginator.Paginator(flashcards, 2)
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
try:
flashcards = flashcard_paginator.page(page)
except (paginator.EmptyPage, paginator.InvalidPage):
flashcards = flashcard_paginator.page(flashcard_paginator.num_pages)
context = {'flashcards': flashcards, 'id': student_id, 'title': 'Available Flashcards By Category'}
print('End of DISPATCH:')
return render(request, self.template_name, context)
Template (sel_cards_add.html):
{% extends 'base.html' %}
{% load crispy_forms_tags %}
<form id="myForm" action="{% url 'add_cards' id %}" method="POST">
{% block content %}
{% csrf_token %}
<div class = "row">
<div class="col-sm-8 col-sm-offset-1">
<h1>{{ title }}</h1>
{% for flashcard in flashcards %}
{% ifchanged flashcard.category %}
</table>
<h3><input type="checkbox" onchange="chkcat(this)" name="chkcat{{ flashcard.category_id }}" /> Category: {{ flashcard.category }}</h3>
<table>
<tr>
<th>Select?</th>
<th>Flashcard</th>
<th>Answer</th>
<th>Easy Factor</th>
</tr>
{% endifchanged %}
<tr>
<td><input type="checkbox" onchange="chkid(this)" name="chkid{{ flashcard.id }}" /></td>
<td>{{ flashcard.front }}</td>
<td>{{ flashcard.answer }}</td>
<td>{{ flashcard.easy_factor }}</td>
</tr>
{% empty %}
<tr><td align="center" colspan="4">No flashcards to select yet.</td></tr>
{% endfor %}
</table>
<br>
<input type="text" id="cat" name="CATS" value="{{ CATS }}" />
<input type="text" id="crd" name="CRDS" value="{{ CRDS }}" />
<br>
<div class="pagination">
<span class="step-links">
<table class="pagination" style="border: none;"><tr style="border: none;"><td style="border: none;">
{% if flashcards.has_previous %}
<span>
<form action="?page={{ flashcards.previous_page_number }}" method="POST">
{% csrf_token %}
<button type="submit">Previous</button>
</form></span>
{% endif %}
</td><td style="border: none;">
<span>Page {{ flashcards.number }} of {{ flashcards.paginator.num_pages }}</span>
</td><td style="border: none;">
{% if flashcards.has_next %}
<span>
<form action="?page={{ flashcards.next_page_number }}" method="POST">
{% csrf_token %}
<button type="submit">Next</button>
</form></span>
{% endif %}
</td></tr></table>
</span>
</div>
<br>
<button type="submit" class="btn btn-default">Add Selections to User</button>
<a href="{% url 'home' %}" class="btn btn-primary" role="button" padding="15px">Cancel</a>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
function chkcat(element) {
var x = $(element).attr('name');
var num = x.substring(6,12);
var categorys = document.getElementById("cat").value;
var array = strToArray(categorys);
var checked = document.getElementsByName(x)[0].checked;
if (checked) {
if ((array.indexOf(num)) == -1) {
array.push(num.concat(","));
}
}
else {
array = valueRemove(num,array);
}
document.getElementById("cat").value = array;
}
function chkid(element) {
var x = $(element).attr('name');
var num = x.substring(5,11);
var cards = document.getElementById("crd").value;
var array = strToArray(cards);
var checked = document.getElementsByName(x)[0].checked;
if (checked) {
if ((array.indexOf(num)) == -1) {
array.push(num.concat(","));
}
}
else {
array = valueRemove(num,array);
}
document.getElementById("crd").value = array;
}
function valueRemove(obj, array) {
var hold = [];
var objLoc = array.indexOf(obj);
if (objLoc == -1) {
return array;
}
else {
for (var i=(array.length-1); i >= 0; i--) {
if (i == a) {
array.pop();
}
else {
hold.push(array.pop());
}
}
return hold;
}
}
function strToArray(txt) {
var array = [];
var i = 0;
var j = 0;
var len = txt.length;
for (i=0; i < len; i++) {
if (txt[i] == ",") {
array.push(txt.substring(j, i));
j = i+1;
}
}
return array;
}
</script>
{% endblock content %}
</form>
Thanks for any help with this issue. Is there a much better approach using Django?
Jim Illback
No comments:
Post a Comment