I'm encountering a major issue with checkboxes while developing a ToDo-style application. I aim to have the changes (item_done = False or True) saved when the checkbox is clicked.
To achieve this, I've incorporated a JavaScript script using jQuery for a smoother user experience. However, an error keeps cropping up: clicking on the first item works fine, but upon clicking on the second, the change occurs on the opposite item instead.
I'm struggling to identify where I might be going wrong.
Below is the code snippet:
HTML alongside Django, displaying a list of tasks and items:
{% extends 'base.html' %}
{% block content %}
<br/><br/><br/>
<div class="container">
<div class="col-md-6 offset-md-3">
<div class="row">
<div class="card border-primary mb-3 text-center" style="max-width: 60rem;">
<div class="card-header bg-transparent ">{{ task.date }}</div>
{% if task.image %}
<img src="{{ task.image.url }}" class="card-img-top" alt="">
{% endif %}
<div class="card-body">
<h3 class="card-header bg-transparent">{{ task.title }}</h3>
<p class="card-text">{{ task.description }}</p>
</div>
<div class="card-header bg-transparent" ><h3>To-do list</h3></div>
<div class="text-start">
<br/>
<ul class="list-group">
{% if list_items %}
{% for item in list_items %}
{% if item.item_done %}
<li class="list-group-item">
<input class="form-check-input" type="checkbox" checked="checked" value="{{ item.id }}" id="un-check-box">
{{ item.title }}
</li>
{% else %}
<li class="list-group-item">
<input class="form-check-input" type="checkbox" value="{{ item.id }}" id="check-box">
{{ item.title }}
</li>
{% endif %}
{% endfor %}
{% else %}
<p class="text-center">the task list is empty</p>
{% endif %}
</ul>
</div>
<div>
<br/>
<button type="button" class="btn btn-primary">Add new item</button>
</div>
<div class="card-header bg-transparent">
<h3>Notes</h3>
</div>
<form>
<br/>
<div class="mb-3">
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"
placeholder="type something">
</textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<div class="card-body">
<a href="#" class="card-link">Card link</a>
<a href="#" class="card-link">Another link</a>
</div>
</div>
</div>
</div>
</div>
<br/><br/><br/>
<script>
// Check if checkbox pressed
$(document).on('click', '#check-box', function(e){
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url 'check_boxes' %}',
data: {
item_id: $('#check-box').val(),
csrfmiddlewaretoken: '{{ csrf_token }}',
action: 'post'
},
success: function(json){
console.log(json)
document.getElementById("check-box").checked = true;
location.reload();
},
error: function(xhr, errmsg, err){
}
});
});
// Uncheck boxes
$(document).on('click', '#un-check-box', function(e){
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url 'uncheck_boxes' %}',
data: {
item_id: $('#un-check-box').val(),
csrfmiddlewaretoken: '{{ csrf_token }}',
action: 'post'
},
success: function(json){
console.log(json)
document.getElementById("un-check-box").checked = false;
location.reload();
},
error: function(xhr, errmsg, err){
}
});
});
</script>
{% endblock %}
JavaScript code:
<script>
// Check if checkbox pressed
$(document).on('click', '#check-box', function(e){
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url 'check_boxes' %}',
data: {
item_id: $('#check-box').val(),
csrfmiddlewaretoken: '{{ csrf_token }}',
action: 'post'
},
success: function(json){
console.log(json)
document.getElementById("check-box").checked = true;
location.reload();
},
error: function(xhr, errmsg, err){
}
});
});
// Uncheck boxes
$(document).on('click', '#un-check-box', function(e){
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url 'uncheck_boxes' %}',
data: {
item_id: $('#un-check-box').val(),
csrfmiddlewaretoken: '{{ csrf_token }}',
action: 'post'
},
success: function(json){
console.log(json)
document.getElementById("un-check-box").checked = false;
location.reload();
},
error: function(xhr, errmsg, err){
}
});
});
</script>
Python views:
def check_boxes(request):
if request.POST.get('action') == 'post':
item_id = int(request.POST.get('item_id'))
item = get_object_or_404(ToDoItem, id=item_id)
item.item_done = True
item.save()
response = JsonResponse({'item': item.item_done,
'item_id' : item_id
})
return response
def uncheck_boxes(request):
if request.POST.get('action') == 'post':
item_id = int(request.POST.get('item_id'))
item = get_object_or_404(ToDoItem, id=item_id)
item.item_done = False
item.save()
print(item.item_done)
response = JsonResponse({'item': item.item_done,
'item_id': item_id
})
return response
Task display along with "to do list." Each item has its own unique identifier.
def view_task(request, pk):
if request.user.is_authenticated:
task = Task.objects.get(id=pk)
list_items = ToDoItem.objects.filter(task=task.id)
if request.user.id == task.task_user.id:
return render(request, 'view_task.html', {
'task': task,
'list_items': list_items
})
else:
messages.success(request, ("No authorisation!"))
return redirect('home')
else:
messages.success(request, ("You have to be logged in!"))
return redirect('login')
Models for Task and ToDoItems to aid in deciphering the remaining code.
class Task(models.Model):
task_user = models.ForeignKey(AppUser, on_delete=models.CASCADE)
title = models.CharField(max_length=50)
description = models.TextField(max_length=1000)
date = models.DateField(default=datetime.datetime.today)
image = models.ImageField(upload_to='uploads/task/', blank=True)
is_done = models.BooleanField(default=False)
def __str_(self):
""" return object name"""
return self.title
class ToDoItem(models.Model):
title = models.CharField(max_length=100)
task = models.ForeignKey(Task, on_delete=models.CASCADE)
item_done = models.BooleanField(default=False)
def __str__(self):
"""return object name"""
return self.title
Your guidance is greatly appreciated as I strive to understand my mistakes and find solutions.