diff --git a/app/assets/javascripts/admin/communication/init.js b/app/assets/javascripts/admin/communication/init.js
index f584e2b9ca3af3d8b2c1467928f860587797b54c..965aba4c32f01247ac782f09728b7a16c89a92a3 100644
--- a/app/assets/javascripts/admin/communication/init.js
+++ b/app/assets/javascripts/admin/communication/init.js
@@ -1,5 +1,6 @@
 //= require_self
 //= require ./menu_items
+//= require ./posts
 //= require ./websites
 
 window.osuny.communication = {};
diff --git a/app/assets/javascripts/admin/communication/posts.js b/app/assets/javascripts/admin/communication/posts.js
new file mode 100644
index 0000000000000000000000000000000000000000..0077d825d72e8b27409f187b639aa5fcd13d8c63
--- /dev/null
+++ b/app/assets/javascripts/admin/communication/posts.js
@@ -0,0 +1,59 @@
+window.osuny.communication.posts = {
+    init: function () {
+        'use strict';
+        var i;
+
+        this.fieldset = document.querySelector('form fieldset.communication_website_post_categories');
+        if (this.fieldset === null) {
+            return;
+        }
+
+        this.checkboxes = this.fieldset.querySelectorAll('input[type="checkbox"]');
+        for (i = 0; i < this.checkboxes.length; i += 1) {
+            this.checkboxes[i].addEventListener('change', this.onCheckboxChange.bind(this));
+        }
+    },
+
+    onCheckboxChange: function (event) {
+        'use strict';
+        var checkbox = event.currentTarget,
+            parentId = checkbox.dataset.parent,
+            parentCheckbox;
+
+        if (!checkbox.checked || typeof parentId === 'undefined') {
+            return;
+        }
+
+        parentCheckbox = this.fieldset.querySelector('input[type="checkbox"][value="' + parentId + '"]');
+        if (parentCheckbox !== null) {
+            this.triggerCheck(parentCheckbox);
+        }
+    },
+
+    triggerCheck: function (checkbox) {
+        'use strict';
+        var evt;
+        checkbox.checked = true;
+        if (typeof document.createEvent !== 'undefined') {
+            evt = document.createEvent('HTMLEvents');
+            evt.initEvent('change', false, true);
+            checkbox.dispatchEvent(evt);
+        } else {
+            checkbox.fireEvent('onchange');
+        }
+    },
+
+    invoke: function () {
+        'use strict';
+        return {
+            init: this.init.bind(this)
+        };
+    }
+}.invoke();
+
+window.addEventListener('DOMContentLoaded', function () {
+    'use strict';
+    if (document.body.classList.contains('posts-new') || document.body.classList.contains('posts-edit')) {
+        window.osuny.communication.posts.init();
+    }
+});
diff --git a/app/models/concerns/with_tree.rb b/app/models/concerns/with_tree.rb
index eb0d0ff76459d32478f457410f55f049ec7c2e2f..7869bb8f0ec083d40fe67f5b618a78f65601227d 100644
--- a/app/models/concerns/with_tree.rb
+++ b/app/models/concerns/with_tree.rb
@@ -21,7 +21,7 @@ module WithTree
     def self_and_children(level)
       elements = []
       label = "&nbsp;&nbsp;&nbsp;" * level + self.to_s
-      elements << { label: label, id: self.id }
+      elements << { label: label, id: self.id, parent_id: self.parent_id }
       children.each do |child|
         elements.concat(child.self_and_children(level + 1))
       end
diff --git a/app/views/admin/communication/website/posts/_form.html.erb b/app/views/admin/communication/website/posts/_form.html.erb
index a430c84fc448583e69ce1a12e54ae80be886f60e..fb2f47dfe99a1ce57d8c6041585e462a7040be5f 100644
--- a/app/views/admin/communication/website/posts/_form.html.erb
+++ b/app/views/admin/communication/website/posts/_form.html.erb
@@ -29,9 +29,11 @@
           <%= f.association :author, collection: @website.authors.ordered if @website.authors.any? %>
           <%= f.association :categories,
                             as: :check_boxes,
-                            collection: @website.list_of_categories,
-                            label_method: ->(p) { sanitize p[:label] },
-                            value_method: ->(p) { p[:id] } if @website.categories.any? %>
+                            collection: @website.list_of_categories.map { |category| [
+                              sanitize(category[:label]),
+                              category[:id],
+                              { data: { parent: category[:parent_id] } }
+                            ] } if @website.categories.any? %>
         </div>
       </div>
       <div class="card flex-fill w-100">