Using Quill.js for Inline Post Editing in Django with the Bubble Theme

How to use Quill editor for editing in place of Django forms
December 11, 2024 by
Using Quill.js for Inline Post Editing in Django with the Bubble Theme
Hamed Mohammadi
| No comments yet

Integrating a modern, elegant text editor into your Django project can significantly enhance the user experience. Among the many options, Quill.js stands out for its simplicity, rich formatting features, and flexibility. In this post, I’ll walk you through how to use Quill.js with the Bubble theme for inline editing of a Post model in Django—without relying on Django-specific Quill modules. Instead, we'll manually integrate Quill.js into our forms and templates for maximum control.

Why Quill.js?

Quill.js is an open-source WYSIWYG (What You See Is What You Get) editor that offers:

  • A customizable toolbar.
  • Multiple themes, including Snow and Bubble.
  • Easy integration with front-end frameworks.
  • Clean, lightweight HTML output.

The Bubble theme is ideal for inline editing, displaying a floating toolbar only when the user interacts with the content.

Step 1: Setting Up the Django Post Model

Here’s a simple Post model to work with:

# models.py
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()  # This will be edited with Quill.js
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

Step 2: Adding Quill.js to Your Project

Download the necessary Quill.js files or include them via a CDN in your base HTML template. For this example, we'll use a CDN.

<!-- base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}Quill.js Demo{% endblock %}</title>
    <!-- Quill.js -->
    <link href="https://cdn.quilljs.com/1.3.7/quill.bubble.css" rel="stylesheet">
</head>
<body>
    {% block content %}{% endblock %}
    <!-- Quill.js -->
    <script src="https://cdn.quilljs.com/1.3.7/quill.min.js"></script>
</body>
</html>

Step 3: Customizing the Django Form

We'll create a form for the Post model but won't render the content field directly. Instead, we’ll use a <div> as the editor and handle its data manually.

# forms.py
from django import forms
from .models import Post

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['title', 'content']
        widgets = {
            'title': forms.TextInput(attrs={'class': 'form-control'}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['content'].widget = forms.HiddenInput()  # Hide the default textarea

Step 4: Updating the Template for Quill.js

Here’s how to create a form template for editing posts:

<!-- templates/post_edit.html -->
{% extends "base.html" %}

{% block content %}
<h1>Edit Post</h1>
<form method="post" action="">
    {% csrf_token %}
    <div class="form-group">
        <label for="id_title">Title:</label>
        {{ form.title }}
    </div>

    <div id="quill-editor" style="min-height: 200px;">{{ form.instance.content|safe }}</div>

    <input type="hidden" name="content" id="content">

    <button type="submit" class="btn btn-primary">Save</button>
</form>

<script>
    // Initialize Quill editor
    var quill = new Quill('#quill-editor', {
        theme: 'bubble'  // Use Bubble theme
    });

    // Sync content with hidden input on form submission
    document.querySelector('form').onsubmit = function () {
        document.querySelector('#content').value = quill.root.innerHTML;
    };
</script>
{% endblock %}

Step 5: Adding the View

Create a view to handle both the GET and POST requests for editing a post.

# views.py
from django.shortcuts import render, get_object_or_404, redirect
from .models import Post
from .forms import PostForm

def edit_post(request, pk):
    post = get_object_or_404(Post, pk=pk)
    if request.method == "POST":
        form = PostForm(request.POST, instance=post)
        if form.is_valid():
            form.save()
            return redirect('post_detail', pk=post.pk)
    else:
        form = PostForm(instance=post)
    return render(request, 'post_edit.html', {'form': form, 'post': post})

Step 6: Adding a URL Pattern

Update your urls.py to include the edit view.

# urls.py
from django.urls import path
from .views import edit_post

urlpatterns = [
    path('post/<int:pk>/edit/', edit_post, name='edit_post'),
]

Step 7: Styling the Editor (Optional)

If needed, you can add some custom CSS for the editor container:

/* static/css/custom.css */
#quill-editor {
    border: 1px solid #ddd;
    padding: 10px;
    border-radius: 4px;
}

Testing It Out

Navigate to the edit page of a post (e.g., /post/1/edit/), and you'll see the Quill.js editor in action. The content field will automatically populate with the existing content, and any changes you make will sync back to the server upon form submission.

Final Thoughts

By manually integrating Quill.js, you gain full control over its behavior and appearance, without being tied to a specific Django module. The Bubble theme makes inline editing intuitive and visually appealing, perfect for modern web applications. With just a few lines of JavaScript, you’ve added a polished, interactive editor to your Django project.

Have you used Quill.js in your projects? Let me know in the comments below!

Using Quill.js for Inline Post Editing in Django with the Bubble Theme
Hamed Mohammadi December 11, 2024
Share this post
Tags
Archive

Please visit our blog at:

https://zehabsd.com/blog

A platform for Flash Stories:

https://readflashy.com

A platform for Persian Literature Lovers:

https://sarayesokhan.com

Sign in to leave a comment