diff --git a/app/controllers/admin/courses.php b/app/controllers/admin/courses.php
index 99b2943c6d83a75b28cf8af05c42dcfded692bda..7bdeaae2ee387c4811e9288feb479fd396d9b230 100644
--- a/app/controllers/admin/courses.php
+++ b/app/controllers/admin/courses.php
@@ -884,7 +884,10 @@ class Admin_CoursesController extends AuthenticatedController
         $course->store();
 
         if (Request::isXhr()) {
-            $this->render_json((int)$course->completion);
+            $this->render_json([
+                'state' => (int)$course->completion,
+                'label' => $course->getCompetionLabel(),
+            ]);
         } else {
             $this->redirect('admin/courses/index#course-' . $course_id);
         }
diff --git a/app/views/admin/courses/_course.php b/app/views/admin/courses/_course.php
index 87491fd152ae1657210a71566488a8e869a82789..645b06e7443e0763ac888430a95354e20f215b3b 100644
--- a/app/views/admin/courses/_course.php
+++ b/app/views/admin/courses/_course.php
@@ -25,10 +25,11 @@ if (!$values['parent_course'] || !in_array($values['parent_course'], array_keys(
         <td>
         <? if (Config::get()->ADMIN_COURSES_SHOW_COMPLETE): ?>
             <? if ($GLOBALS['perm']->have_studip_perm('tutor', $semid)) : ?>
-                <a href="<?= $controller->url_for('admin/courses/toggle_complete/' . $semid) ?>"
+                <a href="<?= $controller->toggle_complete($course) ?>"
                    class="course-completion"
                    data-course-completion="<?= $values['completion'] ?>"
-                   title="<?= _('Bearbeitungsstatus ändern') ?>">
+                   title="<?= htmlReady($course->getCompetionLabel()) ?>"
+                   aria-label="<?= _('Bearbeitungsstatus ändern') ?>">
                     <?= _('Bearbeitungsstatus ändern') ?>
                 </a>
             <? else : ?>
diff --git a/lib/models/Course.class.php b/lib/models/Course.class.php
index 5df3e3e3e681cec1d7d00d6c1ad00c2e29a88735..429bb1b8459776549d1062a4d9074d7604cf9ebe 100644
--- a/lib/models/Course.class.php
+++ b/lib/models/Course.class.php
@@ -754,6 +754,20 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe
         return Icon::create('radiobutton-checked', $role);
     }
 
+    /**
+     * Returns the appropriate label for the completion status.
+     *
+     * @return string
+     */
+    public function getCompetionLabel(): string
+    {
+        return [
+            0 => _('unvollständig'),
+            1 => _('in Bearbeitung'),
+            2 => _('fertig'),
+        ][$this->completion] ?? _('undefiniert');
+    }
+
     /**
      * Generates a general log entry if the course were changed.
      * Furthermore, this method emits notifications when the
diff --git a/resources/assets/javascripts/bootstrap/application.js b/resources/assets/javascripts/bootstrap/application.js
index 4802091dbf74054bee7d874522f618bda5a8ff0e..f97dd90e04897dd0bd8b034c0cea57c7f2f48644 100644
--- a/resources/assets/javascripts/bootstrap/application.js
+++ b/resources/assets/javascripts/bootstrap/application.js
@@ -334,10 +334,13 @@ jQuery(document).on('click', '.course-admin td .course-completion', function ()
             $(this).addClass('ajaxing');
         }.bind(this), 300);
 
-    $.getJSON(href).done(function (completion) {
+    $.getJSON(href).done(function (response) {
         clearTimeout(timeout);
 
-        $(this).removeClass('ajaxing').attr('data-course-completion', completion);
+        $(this).removeClass('ajaxing').attr({
+            'data-course-completion': response.state,
+            title: response.label
+        });
     }.bind(this));
 
     return false;