sherpaurgen
sherpaurgen

Reputation: 3274

How to save POST data with multiple checkboxes using Django ?

Django version=1.10.2 and python 2.7 Im learning django and trying to clone to-do list item like this Here is the models file for todo:-

class Todo(models.Model):
    title = models.CharField(max_length=200)
    # text = models.TextField()
    completed = models.BooleanField(null=False,default=False)

    created_at = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return self.title   #this makes djangoadmin page show title inthe list

The views file

from django.shortcuts import render
from models import Todo
def index(request):
    todos = Todo.objects.all()
    context = {
        'todos':todos
    }
    if request.method == 'POST':
        title = request.POST['title']
        todo = Todo(title=title)
        todo.save()
        return render(request,'index.html',context)
    else:
        return render(request,'index.html',context)

def show_completed(request): #show completed task only
    todos = Todo.objects.filter(completed=True)
    context = {
        'todos': todos
    }
    return render(request, 'index.html', context)

def show_active(request):   #show active task list
    todos = Todo.objects.filter(completed=False)
    context = {
        'todos': todos
    }
    return render(request, 'index.html', context)
def clear_completed(request):    #Delete the completed tasks
    Todo.objects.filter(completed=True).delete()
    todos = Todo.objects.all()
    context = {
        'todos': todos
    }
    return render(request, 'index.html', context)

def save_state(request):
     pass

The template file "index.html"

<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<h3>Todo List:</h3><hr>

<form method="post" action="{% url 'index' %}">
    {% csrf_token %}
    <input type="text" name="title" id="title"/>
    <input type="submit" value="submit" />
</form>
<hr><br>
<form method="post" action="{% url 'save_state'%}">
{% csrf_token %}
<ul>{% for todo in todos %}
    <li>  <input type="checkbox" name="completed" value="True" {% if todo.completed is True %} checked = "checked" {% endif %} >{{ todo.title }}   </li>
{% endfor %}
</ul>
 <input type="submit" value="Submit">
</form>
<a href="/todos/">All</a>
<a href="/todos/active">Active</a>
<a href="/todos/completed">Completed</a>
<a href="/todos/clear_completed">ClearCompleted</a>
</body>
</html>

I want to know how to get the checkbox's of todo items and save it if the checkbox is checked by passing those to view called "save_state"

Upvotes: 2

Views: 4374

Answers (2)

sherpaurgen
sherpaurgen

Reputation: 3274

using jquery and ajax TemplateFile: index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
    <title>Todo Indexpage</title>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
<div class="container">
  <div class="row">
    <div class="col-sm-4">
<h3>Todo List:</h3><hr>

{% if not request.user.is_authenticated  %}
    Please login to view the content <hr>
click <a href="/accounts/login">here</a> to login <br>
click <a href="/signup">here</a> to signup
{% endif %}

{% if request.user.is_authenticated and not user.is_superuser %}
    <h3> {{request.user.username}} is logged in <hr></h3>
<form method="post" action="{% url 'index' %}">
    {% csrf_token %}
    <input type="text" name="title" id="title" placeholder="What needs to be done?"/>
    <input type="hidden" name="author" id="author" value="{{request.user.username}}">
    <input type="submit" value="submit" hidden="hidden" />
</form>
<hr>
<br>

<ul>

{% for todo in todos %}
<li>
    <input class="todoBox" type="checkbox" id="{{ todo.title }}" name="{{ todo.title }}" value=""
         {% if todo.completed is True %} checked = "checked"
         {% endif %} >   {{ todo.title }}
</li>
{% endfor %}
</ul>

<a href="/todos/">All </a>|
<a href="/todos/active">Active </a>|
<a href="/todos/completed">Completed </a>|
<a href="/todos/clear_completed"> ClearCompleted</a>
<hr>
click <a href="/accounts/logout/">here</a> to logout
{% endif %}
<!-- for admin viewpage -->
{% if request.user.is_authenticated and user.is_superuser %}
    <h3> {{request.user.username}} is logged in (Administrator User)<hr></h3>
<form method="post" action="{% url 'index' %}">
    {% csrf_token %}
    <input type="text" name="title" id="title" placeholder="What needs to be done?"/>
    <input type="hidden" name="author" id="author" value="{{request.user.username}}">
    <input type="submit" value="submit" hidden="hidden" />
</form>
<hr>
<br>

<table>
  <tr>
    <th>Task</th>
    <th>Author</th>
  </tr>
{% for todo in todos %}
<tr > <td class="pull-left">
    <input class="todoBox" type="checkbox" id="{{ todo.title }}" name="{{ todo.title }}" value=""
         {% if todo.completed is True %} checked = "checked"
         {% endif %} >   {{ todo.title }}</td> <td class="text-right">{{ todo.author }}</td>

</tr>
{% endfor %}


<a href="/todos/">All </a>|
<a href="/todos/active">Active </a>|
<a href="/todos/completed">Completed </a>|
<a href="/todos/clear_completed"> ClearCompleted</a>
<hr>
click <a href="/accounts/logout/">here</a> to logout
{% endif %}

<script>
    $(document).ready(function()
    {
        var data = [];
        $('.todoBox').click(function()
        {
            var check = $(this).is(':checked');
            var todo_title =  $(this).attr('name');
            $.ajax
            ({
                url: "{% url 'save_state'%}",
                type: 'post',
                data: {check: check, todo_title: todo_title, csrfmiddlewaretoken: "{{ csrf_token }}"},
                success: function(html)
                {
                    console.log(html);
                }
            });
        });
    });
</script>
</body>
</html>

views.py

def save_state(request):
    print request.POST
    if request.method == 'POST':
        uname  = request.session.get('uname')
        check  = request.POST['check'] # post value either true or false
        titles = request.POST['todo_title']# post value i.e. name of title
    for title in Todo.objects.filter(title=titles):
        # return HttpResponse(title.title)
            title.completed = check.title() # title() capitalizes first letter of string
            title.save()
    return HttpResponse('data is saved')

Upvotes: 0

Bestasttung
Bestasttung

Reputation: 2458

Well just use javascript to call your url that you have to define, sending the todo.title. Something like :

urls.py

... # other patterns
url(r'^save_state/$', save_state, name='save_state')

whatever.js

$('input[name="completed"]').click(function(){
  data['checked'] = $(this).value()
  data['todo_title'] =  $(this).text()
  $.ajax({
    url: 'path/to/save_state',
    type: 'POST',
    data: data
  });
});

views.py

def save_state(request):
    if request.method == 'POST':
        title = request.POST.get('todo_title', '')
        checked = request.POST.get('checked', '')
        todo = Todo.objects.get(title=title)
        todo.completed = checked
        todo.save()

Please note that's a big help but not a copy paste solution : you need to adapt this js to get the actual good value, and see if the checked value is stored as string ('0' or '1') when you get it back in the save_state view.

Use click event cause it's triggered after the value changed.

EDIT If you want to use only django, you need to change your html like this:

<ul>{% for todo in todos %}
    <li>  <input type="checkbox" id="{{ todo.title }}"name="completed" value="" {% if todo.completed is True %} checked = "checked" {% endif %} >{{ todo.title }}   </li>
{% endfor %}
</ul>

And then you can get all the input in your request.POST and update. request.POST.getlists('completed') you'll get all the fields with name completed

Upvotes: 1

Related Questions