diff --git a/soitool/modules/module_base.py b/soitool/modules/module_base.py
index 630cdaeb4c5e7b982b52b49413cbde406abedb74..daded8d6d329d2217f7cfa92796dfbe82ac70808 100644
--- a/soitool/modules/module_base.py
+++ b/soitool/modules/module_base.py
@@ -16,3 +16,13 @@ class ModuleBase(ABC):
     def render_onto_pdf(self):
         """Abstract method, should be implemented by derived class."""
         raise NotImplementedError
+
+    @classmethod
+    def get_user_friendly_name(cls):
+        """Abstract method, should be implemented by derived class."""
+        raise NotImplementedError
+
+    @classmethod
+    def get_icon(cls):
+        """Abstract method, should be implemented by derived class."""
+        raise NotImplementedError
diff --git a/soitool/modules/module_table.py b/soitool/modules/module_table.py
index e5478ef547fb7f5cec916aab6afd365bc12ab8b4..30f2c5a9bab95f2bcec965aa282aeeae66abbdae 100644
--- a/soitool/modules/module_table.py
+++ b/soitool/modules/module_table.py
@@ -1,6 +1,7 @@
 """Module containing subclassed SOIModule (QTableWidget, ModuleBase)."""
 from PySide2.QtWidgets import QTableWidget, QTableWidgetItem
 from PySide2 import QtGui, QtCore
+from PySide2.QtGui import QIcon
 from soitool.modules.module_base import ModuleBase
 
 HEADER_FONT = QtGui.QFont()
@@ -181,3 +182,13 @@ class TableModule(ModuleBase, QTableWidget, metaclass=Meta):
 
     def render_onto_pdf(self):
         """Render onto pdf."""
+
+    @classmethod
+    def get_user_friendly_name(cls):
+        """Get user-friendly name of module."""
+        return "Generisk tabell"
+
+    @classmethod
+    def get_icon(cls):
+        """Get icon of module."""
+        return QIcon("soitool/media/tablemodule.png")
diff --git a/soitool/new_module_dialog.py b/soitool/new_module_dialog.py
index e8bf12ed7548de6f1e47ed204510312b550014be..ee9f2ee9ee01014c0b916788fbc8ad3318d3eaec 100644
--- a/soitool/new_module_dialog.py
+++ b/soitool/new_module_dialog.py
@@ -14,51 +14,71 @@ from PySide2.QtWidgets import (
 from PySide2.QtCore import QSize, Qt
 from PySide2.QtGui import QIcon
 from soitool.modules.module_table import TableModule
+from soitool.modules.module_base import ModuleBase
+
+
+class ModulePlaceholder(ModuleBase):
+    """Dummy module used only to fill dialog with content while developing."""
+
+    def get_size(self):
+        """Not used."""
+        raise NotImplementedError
+
+    def set_pos(self, pos):
+        """Not used."""
+        raise NotImplementedError
+
+    def render_onto_pdf(self):
+        """Not used."""
+        raise NotImplementedError
+
+    @classmethod
+    def get_user_friendly_name(cls):
+        """Get placeholder name."""
+        return "Modul"
+
+    @classmethod
+    def get_icon(cls):
+        """Get standard placeholder icon."""
+        return QIcon("soitool/media/placeholder.png")
+
 
 # Constant holding all modules the user can choose from. This is intended as a
 # point of extensibility. Further modules that are developed can simply be
 # placed here, and the rest of the program will respect them.
-# Each list element is a tuple of ( <path to icon for module>,
-# <user friendly string name>, <class that implements module> )
 MODULE_CHOICES = [
-    ("soitool/media/tablemodule.png", "Generisk tabell", TableModule),
-    ("soitool/media/placeholder.png", "Autentifiseringstavle", None),
-    ("soitool/media/placeholder.png", "Subtraktorkoder", None),
-    ("soitool/media/placeholder.png", "Fritekst", None),
+    TableModule,
+    ModulePlaceholder,
+    ModulePlaceholder,
+    ModulePlaceholder,
 ]
 
 
 class NewModuleDialogListItem(QListWidgetItem):
-    """Custom list item that includes widget implementation.
+    """Custom list item that includes a widget implementation of a module.
 
     Parameters
     ----------
-    icon : QIcon
-        See QListWidgetItem's documentation:
-        https://doc.qt.io/qt-5/qlistwidgetitem.html
-    user_friendly_name : str
-        Text shown to user. See QListWidgetItem's documentation:
-        https://doc.qt.io/qt-5/qlistwidgetitem.html
-    widget_implementation : subclass of ModuleBase
+    widget : subclass of ModuleBase
         The widget that implements the module.
     """
 
-    def __init__(self, icon, user_friendly_name, widget_implementation):
-        super().__init__(icon, user_friendly_name)
-        self.widget_implementation = widget_implementation
+    def __init__(self, widget):
+        super().__init__(widget.get_icon(), widget.get_user_friendly_name())
+        self.widget_implementation = widget
 
 
 class NewModuleDialog(QDialog):
     """Dialog to let user select module to be added to the SOI.
 
     When the dialog is closed the user's choice is fetched by directly
-    inspecting the `self.list_module_choices` and `self.line_edit_name`
-    widgets. The dialog is otherwise used excactly as it's superclass QDialog:
-    https://doc.qt.io/qt-5/qdialog.html
+    inspecting the child widgets, for example: `self.list_module_choices` and
+    `self.line_edit_name`. The dialog is otherwise used excactly as it's
+    superclass QDialog: https://doc.qt.io/qt-5/qdialog.html
 
     Parameters
     ----------
-    module_choices : list of tuples. See docs for the `MODULE_CHOICES` constant
+    module_choices : list of subclasses of ModuleBase
         list of modules the user can choose from
     """
 
@@ -85,16 +105,8 @@ class NewModuleDialog(QDialog):
         self.list_module_choices.setResizeMode(QListWidget.Adjust)
 
         for i, module_choice in enumerate(module_choices):
-            (
-                icon_path,
-                user_friendly_name,
-                widget_implementation,
-            ) = module_choice
             self.list_module_choices.insertItem(
-                i,
-                NewModuleDialogListItem(
-                    QIcon(icon_path), user_friendly_name, widget_implementation
-                ),
+                i, NewModuleDialogListItem(module_choice),
             )
 
         # set the first element as the default choice, whatever it is
diff --git a/soitool/soi_workspace_widget.py b/soitool/soi_workspace_widget.py
index 6b243697abf21088a816b0489781f4be98fbb98e..45479f566ba61618934cb9797be057a790b55716 100644
--- a/soitool/soi_workspace_widget.py
+++ b/soitool/soi_workspace_widget.py
@@ -15,7 +15,7 @@ from soitool.soi import SOI, ModuleType, ModuleNameTaken
 from soitool.module_list import ModuleList
 from soitool.inline_editable_soi_view import InlineEditableSOIView
 from soitool.setup_settings import Setup
-from soitool.new_module_dialog import NewModuleDialog
+from soitool.new_module_dialog import NewModuleDialog, ModulePlaceholder
 from soitool.dialog_wrappers import exec_warning_dialog
 
 
@@ -84,7 +84,7 @@ class SOIWorkspaceWidget(QWidget):
             module_widget_implementation = chosen_module.widget_implementation
             is_attachment = new_module_dialog.checkbox_attachment.isChecked()
 
-            if module_widget_implementation is None:
+            if module_widget_implementation is ModulePlaceholder:
                 exec_warning_dialog(
                     text="Modulen ble ikke lagt til.",
                     informative_text="Den valgte modulen er ikke "