I have been trying to implement a form in a bootstrap modal, using django-crispy forms. I am using class based views. I know that I would require some Ajax, but I didn't understand all the examples I have been seeing. I tried django-bootstrap-modal-forms - this works with the modal, but sadly, it dosen't support bootstrap styling, and I couldn't find any way to add it. When I tried to add bootstrap sytling to django-bootstrap-modal-forms using bootstraps form class, form-control, the form dosen't submit, and gives no errors. So now, I want to fall back to django-crispy-forms.
So my question is:
How do I implement a bootstrap modal form with django-crispy-forms
How do I implement validation with ajax, to avoid page reload - The errors should also have the same error styling as django-crispy-forms
- Also, how to I also implement a success message using an alert, when the object has been successfully added into the database.
My code is shown below:
my_template.html
This currently contains the CSS classes for django-bootstrap-modal-forms. Check out https://pypi.org/project/django-bootstrap-modal-forms/
You can replace the text in the modal-body with {{ form | crispy }} to use django-crispy-forms
<form method="post" action="">
{% csrf_token %}
<div class="modal-header">
<h5 class="modal-title">Create new Task</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{% for field in form %}
<div class="form-group{% if field.errors %} invalid{% endif %}">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
{% for error in field.errors %}
<p class="help-block invalid-feedback"><strong>{{ error }}</strong></p>
{% endfor %}
</div>
{% endfor %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="submit-btn btn btn-primary">Add Task</button>
</div>
</form>
javascript
$(document).ready(function() {
$(".create-task").modalForm({
formURL: "{% url 'create_task' %}"
});
});
forms.py
from .models import Task, Categories
from bootstrap_datepicker_plus import DateTimePickerInput
from django import forms
from django.db.models import Q
from bootstrap_modal_forms.forms import BSModalForm
from django.contrib.auth import get_user_model
class TaskForm(BSModalForm):
# Get al the categories from the database
categories_queryset = Categories.objects.all()
task_title = forms.CharField(max_length=100)
task_description = forms.CharField(widget=forms.Textarea)
due_date = forms.DateTimeField(
widget = DateTimePickerInput(format='%Y-%m-%d %H:%M')
)
is_completed = forms.BooleanField()
categories = forms.ModelChoiceField(categories_queryset, empty_label="---None---")
#parent = forms.ModelChoiceField()
#task_title.widget.attrs.update({'class': 'form-control'})
class Meta:
model = Task
fields = ['task_title', 'task_description', 'due_date', 'is_completed', 'categories', 'parent']
def __init__(self, *args, **kwargs):
super(TaskForm, self).__init__(*args, **kwargs)
# I have errors using the Queryset to find entities with Categories.user_id == null, and Categories.user_id=get_user_model() -- It gives an error about unpacking boolean.
#self.fields['categories_queryset'] = Categories.objects.filter(Categories.user_id=get_user_model())
# Q(Categories.user_id__isnull==True) |
# User.objects.filter(username=username).exists():
models.py
from django.db import models
from django.db.models import Q
from users.models import CustomUser
from django.urls import reverse
from django.contrib.auth import get_user_model
class Categories(models.Model):
category_type = models.CharField(max_length=50)
user = models.ForeignKey(CustomUser, null = True, on_delete=models.CASCADE)
def __str__(self):
return '%s ' % (self.category_type)
def get_absolute_url(self):
return reverse('task_list')
class Task(models.Model):
task_title = models.CharField(max_length=100)
task_description = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
due_date = models.DateTimeField()
is_completed = models.BooleanField(default=False)
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
categories = models.ForeignKey(Categories, on_delete=models.CASCADE)
parent = models.ForeignKey("self", on_delete=models.CASCADE)
class Meta:
verbose_name = "Task"
verbose_name_plural = "Tasks"
def __str__(self):
return '%s ID: %s' % (self.task_title, self.last_name)
def get_absolute_url(self):
return reverse('task_detail')
Thanks...