diff --git a/editor/css/editor.css b/editor/css/editor.css
index ea32a7da121b4c0a4c3c191a96f17a4562220278..7bb94545375f3010e6f63b535329ef15e1de226a 100644
--- a/editor/css/editor.css
+++ b/editor/css/editor.css
@@ -13,3 +13,38 @@ div#ks-editor section > * {
 div#ks-editor *.selected {
     background-color: lightblue;
 }
+
+div#ks-editor *.hidden {
+    display: none;
+}
+
+div#ks-editor input[type="text"] {
+    border-top-style: none;
+    border-left-style: none;
+    border-right-style: none;
+    letter-spacing: normal;
+}
+
+div#ks-editor .medium-width {
+    max-width: 20rem;
+}
+
+div#ks-editor input#node-name {
+    font-size: large;
+    font-weight: bolder;
+}
+
+div#ks-editor .bottom-space {
+    margin-bottom: 1rem;
+}
+
+div#ks-editor textarea {
+    max-width: 100%;
+    letter-spacing: normal;
+}
+
+div#ks-editor img#node-image-preview {
+    max-width: 5rem;
+    height: auto;
+    border-radius: 50%;
+}
diff --git a/editor/editor.php b/editor/editor.php
index 96866b5b68ddb17b7c521ec049b969d853b2aa76..8c901ce5c67d2b210d941d9371dbb567a8d95e78 100644
--- a/editor/editor.php
+++ b/editor/editor.php
@@ -1,23 +1,65 @@
-<div id="ks-editor">    <!--The id "ks-editor" indicates, that the javascript associated with this should automatically be executed-->
+<div id="ks-editor">
+    <!--The id "ks-editor" indicates, that the javascript associated with this should automatically be executed-->
     <h1>Interface</h1>
     <div id="2d-graph"></div>
     <section id="toolbar"></section>
-    <section>
-        <h3 id="selected-item">Nothing selected</h3>
-        <ul id="selected-params"></ul>
-        <section>
-            <h4>Sources</h4>
-            <ul id="selected-sources"></ul>
-        </section>
-        <section>
-            <h4>Targets</h4>
-            <ul id="selected-targets"></ul>
-        </section>
+    <section id="tool-menu">
+        <div id="connect-menu" class="hidden">
+            <label for="link-type">Link Type</label>
+            <select id="link-type" name="link-type">
+                <option value="Vorlesung">Lecture</option>
+                <option value="Algorithmus">Algorithm</option>
+                <option value="Definition">Definition</option>
+            </select>
+        </div>
+        <div id="collect-menu" class="hidden">
+            <h3>Collected items</h3>
+            <button id="clear-collection">Clear</button>
+            <ul id="selected-items"></ul>
+        </div>
+        <div id="select-menu" class="">
+            <p id="nothing-selected">Nothing selected</p>
+            <div id="node-selected" class="hidden">
+                <label for="node-name" hidden>Name</label>
+                <input type="text" id="node-name" name="node-name" placeholder="Enter name" class="bottom-space"></input>
+
+                <label for="node-image">Image</label>
+                <img id="node-image-preview" src="https://via.placeholder.com/150" />
+                <input type="text" id="node-image" name="node-image" placeholder="Enter file name" class="medium-width bottom-space" />
+
+                <label for="node-description">Description</label>
+                <textarea id="node-description" name="node-description" class="bottom-space"></textarea>
+
+                <label for="node-type">Type</label>
+                <select id="node-type" name="node-type" class="bottom-space medium-width">
+                    <option value="Vorlesung">Vorlesung</option>
+                    <option value="Algorithmus">Algorithmus</option>
+                    <option value="Definition">Definition</option>
+                    <option value="Beispiel">Beispiel</option>
+                    <option value="Ãœbung">Ãœbung</option>
+                    <option value="Kapitel">Kapitel</option>
+                </select>
+
+                <label for="node-references">References</label> <small>One URL per line</small>
+                <textarea id="node-references" name="node-references" class="bottom-space"></textarea>
+
+                <label for="node-videos">Videos</label> <small>One video URL per line</small>
+                <textarea id="node-videos" name="node-videos"></textarea>
+            </div>
+            <div id="link-selected" class="hidden">
+                <h3 id="link-name" class="bottom-space">aud1 ↔ Sortieren</h3>
+
+                <label for="link-type">Type</label>
+                <select id="link-type" name="node-type" class="bottom-space medium-width">
+                    <option value="Vorlesung">Vorlesung</option>
+                    <option value="Algorithmus">Algorithmus</option>
+                    <option value="Definition">Definition</option>
+                    <option value="Beispiel">Beispiel</option>
+                    <option value="Ãœbung">Ãœbung</option>
+                    <option value="Kapitel">Kapitel</option>
+                </select>
+            </div>
+        </div>
     </section>
     <button id="save" type="submit" class="primary">Save and publish</button>
-    <section>
-        <h3>Collected items</h3>
-        <ul id="selected-items"></ul>
-        <button id="clear-collection">Clear</button>
-    </section>
-</div>
+</div>
\ No newline at end of file
diff --git a/editor/js/display.js b/editor/js/display.js
deleted file mode 100644
index da979d1db8b0ddac2292946bb25f4b6c267eee8d..0000000000000000000000000000000000000000
--- a/editor/js/display.js
+++ /dev/null
@@ -1,178 +0,0 @@
-import jQuery from "jquery";
-import { PLUGIN_PATH } from "../../config";
-import * as Graph from "./graph";
-import { graph, state } from "./editor";
-
-const ID_TOOLBAR = "#toolbar";
-const ID_SELECTEDITEM = "#selected-item";
-const ID_SELECTED_PARAMS = "#selected-params";
-const ID_SELECTED_SOURCES = "#selected-sources";
-const ID_SELECTED_TARGETS = "#selected-targets";
-const ID_SELECTEDITEMS = "#selected-items";
-
-const DOM_LIST_ITEM = "li";
-
-const TOOL_ICON_SRC = PLUGIN_PATH + "editor/images/tools/";
-const TOOL_ICON_FORMAT = ".png";
-const TOOL_SELECTED_CLASS = "selected";
-
-export default class Display {
-    constructor(tools) {
-        this.tools = Object.values(tools);
-        this.previousTool = undefined;
-
-        this.renderToolbar(this.tools);
-    }
-
-    setSelectedTool(tool) {
-        var selectedTool = jQuery(Display.getToolIdTag(tool));
-        selectedTool.addClass(TOOL_SELECTED_CLASS);
-
-        if (this.previousTool !== undefined) {
-            var previousTool = jQuery(Display.getToolIdTag(this.previousTool));
-            previousTool.removeClass(TOOL_SELECTED_CLASS);
-        }
-
-        this.previousTool = tool;
-    }
-
-    renderToolbar(tools) {
-        this.fillDomList(ID_TOOLBAR, tools, this.toolRenderer);
-
-        tools.forEach((tool) => {
-            this.toolClickEvent(tool);
-        });
-    }
-
-    static getToolIdTag(tool) {
-        return ID_TOOLBAR + "-" + tool.getKey();
-    }
-
-    static getToolId(tool) {
-        return Display.getToolIdTag(tool).substr(1);
-    }
-
-    toolRenderer(tool) {
-        return (
-            '<button id="' +
-            Display.getToolId(tool) +
-            '" title="' +
-            tool.getName() +
-            '"><img src="' +
-            TOOL_ICON_SRC +
-            tool.getIcon() +
-            TOOL_ICON_FORMAT +
-            '"></button>'
-        );
-    }
-
-    toolClickEvent(tool) {
-        jQuery("button" + Display.getToolIdTag(tool)).on(
-            "click",
-            "",
-            tool,
-            (e) => {
-                state.setTool(e.data);
-            }
-        );
-    }
-
-    setSelectedItem(item) {
-        jQuery(ID_SELECTEDITEM).html(Display.toStr(item));
-
-        var paramsDOM = jQuery(ID_SELECTED_PARAMS);
-        paramsDOM.empty();
-
-        var params = Graph.NODE_PARAMS;
-        if (item === undefined) {
-            params = [];
-        } else if (item.link) {
-            params = Graph.LINK_PARAMS;
-        }
-
-        params.forEach((param) => {
-            paramsDOM.append(
-                "<" +
-                    DOM_LIST_ITEM +
-                    ">" +
-                    param +
-                    " <textarea>" +
-                    (item[param] === undefined ? "" : item[param]) +
-                    "</textarea></" +
-                    DOM_LIST_ITEM +
-                    ">"
-            );
-        });
-
-        // Render Source and Target list
-        var sources = [];
-        var targets = [];
-        if (item !== undefined && item.node) {
-            var nodes = graph.data[Graph.GRAPH_NODES];
-            for (var i = 0; i < nodes.length; i++) {
-                if (
-                    graph.existsLink(
-                        nodes[i][Graph.NODE_ID],
-                        item[Graph.NODE_ID]
-                    )
-                ) {
-                    sources.push(nodes[i]);
-                } else if (
-                    graph.existsLink(
-                        item[Graph.NODE_ID],
-                        nodes[i][Graph.NODE_ID]
-                    )
-                ) {
-                    targets.push(nodes[i]);
-                }
-            }
-        } else if (item !== undefined && item.link) {
-            sources.push(item[Graph.LINK_SOURCE]);
-            targets.push(item[Graph.LINK_TARGET]);
-        }
-
-        this.fillDomList(ID_SELECTED_SOURCES, sources, this.graphItemRenderer);
-        this.fillDomList(ID_SELECTED_TARGETS, targets, this.graphItemRenderer);
-    }
-
-    setSelectedItems(items, itemsContext) {
-        this.fillDomList(ID_SELECTEDITEMS, items, this.graphItemRenderer);
-    }
-
-    graphItemRenderer(item) {
-        return (
-            "<" +
-            DOM_LIST_ITEM +
-            ">" +
-            Display.toStr(item) +
-            "</" +
-            DOM_LIST_ITEM +
-            ">"
-        );
-    }
-
-    fillDomList(listId, items, itemRenderer) {
-        var listCont = jQuery(listId);
-        listCont.empty();
-
-        items.forEach((i) => listCont.append(itemRenderer(i)));
-    }
-
-    static toStr(item) {
-        if (item === undefined) {
-            return "UNDEFINED";
-        }
-
-        if (item.node) {
-            return item[Graph.NODE_LABEL] + " [" + item[Graph.NODE_ID] + "]";
-        } else if (item.link) {
-            return (
-                Display.toStr(item[Graph.LINK_SOURCE]) +
-                " <-> " +
-                Display.toStr(item[Graph.LINK_TARGET])
-            );
-        } else {
-            return "UNDEFINED";
-        }
-    }
-}
diff --git a/editor/js/graph.js b/editor/js/graph.js
index 29badadc8014ef00fc9cd4667e52203f7e15c574..16aaef23718de17e48a05ff74df2cae09fce819a 100644
--- a/editor/js/graph.js
+++ b/editor/js/graph.js
@@ -1,11 +1,15 @@
 import ManagedData from "./manageddata";
 import { PLUGIN_PATH, COLOR_PALETTE } from "../../config";
 
+const LINK_NAME_CONNECTOR = " → ";
+
 export const NODE_LABEL = "name";
 export const NODE_ID = "id";
-export const NODE_GROUP = "group";
+export const NODE_TYPE = "type";
 export const NODE_DESCRIPTION = "description";
 export const NODE_IMAGE = "image";
+export const NODE_REFERENCES = "references";
+export const NODE_VIDEOS = "videos";
 
 export const LINK_SOURCE = "source";
 export const LINK_TARGET = "target";
@@ -19,7 +23,15 @@ export const IMAGE_SIZE = 12;
 export const IMAGE_SRC = PLUGIN_PATH + "datasets/images/";
 
 export const LINK_PARAMS = [LINK_TYPE];
-export const NODE_PARAMS = [NODE_ID, NODE_LABEL, NODE_IMAGE, NODE_DESCRIPTION];
+export const NODE_PARAMS = [
+    NODE_ID,
+    NODE_LABEL,
+    NODE_IMAGE,
+    NODE_DESCRIPTION,
+    NODE_REFERENCES,
+    NODE_VIDEOS,
+    NODE_TYPE,
+];
 export const LINK_SIM_PARAMS = ["index"];
 export const NODE_SIM_PARAMS = ["index", "x", "y", "vx", "vy", "fx", "fy"]; // Based on https://github.com/d3/d3-force#simulation_nodes
 
@@ -154,6 +166,53 @@ export class Graph extends ManagedData {
         return false;
     }
 
+    changeDetails(selectionDetails) {
+        if (selectionDetails.node === true) {
+            this.changeNodeDetails(selectionDetails[NODE_ID].newDetails);
+        } else if (selectionDetails.link === true) {
+            this.changeLinkDetails(
+                selectionDetails[LINK_SOURCE][NODE_ID],
+                selectionDetails[LINK_TARGET][NODE_ID],
+                selectionDetails
+            );
+        }
+    }
+
+    changeNodeDetails(nodeId, newDetails) {
+        var nodes = this.data[GRAPH_NODES];
+        for (var i = 0; i < nodes.length; i++) {
+            // Is relevant node?
+            if (nodes[i][NODE_ID] !== nodeId) {
+                continue; // No
+            }
+
+            // Changed details
+            nodes[i] = Object.assign(nodes[i], newDetails);
+
+            // All done
+            return;
+        }
+    }
+
+    changeLinkDetails(sourceId, targetId, newDetails) {
+        var links = this.data[GRAPH_LINKS];
+        for (var i = 0; i < links.length; i++) {
+            // Is relevant link?
+            if (
+                links[i][LINK_SOURCE][NODE_ID] !== sourceId ||
+                links[i][LINK_TARGET][NODE_ID] !== targetId
+            ) {
+                continue; // No
+            }
+
+            // Changed details
+            links[i] = Object.assign(links[i], newDetails);
+
+            // All done
+            return;
+        }
+    }
+
     connectNodes(sourceId, targetIds) {
         targetIds.forEach((targetId) => {
             if (
@@ -163,21 +222,8 @@ export class Graph extends ManagedData {
                 return;
             }
 
-            var link = {};
-
-            link[LINK_SOURCE] = sourceId;
-            link[LINK_TARGET] = targetId;
-
-            this.data[GRAPH_LINKS].push(link);
+            this.addLink(sourceId, targetId);
         });
-
-        this.storeCurrentData(
-            "Created link connecting [" +
-                sourceId +
-                "] with [" +
-                targetIds.join() +
-                "]"
-        );
     }
 
     getCleanData(data = undefined, simulationParameters = false) {
@@ -350,4 +396,22 @@ export class Graph extends ManagedData {
 
         return newNode;
     }
+
+    static toStr(item) {
+        if (item === undefined) {
+            return "UNDEFINED";
+        }
+
+        if (item.node) {
+            return item[Graph.NODE_LABEL];
+        } else if (item.link) {
+            return (
+                Graph.toStr(item[Graph.LINK_SOURCE]) +
+                LINK_NAME_CONNECTOR +
+                Graph.toStr(item[Graph.LINK_TARGET])
+            );
+        } else {
+            return "UNDEFINED";
+        }
+    }
 }
diff --git a/editor/js/state.js b/editor/js/state.js
index d779f3dd07b89a439c9c0289176fc3990b5d19e5..cbf44c4cf38a0b1822215103f512744f78992e3d 100644
--- a/editor/js/state.js
+++ b/editor/js/state.js
@@ -7,7 +7,7 @@ import DeleteTool from "./tools/deletetool";
 import AddNodeTool from "./tools/addnodetool";
 import ConnectTool from "./tools/connecttool";
 import { graph } from "./editor";
-import Display from "./display";
+import Toolbar from "./toolbar";
 import * as Graph from "./graph";
 
 export const TOOLS = {
@@ -24,13 +24,14 @@ export const CONTEXT = {
     node: "node",
     link: "link",
     mixed: "mixed",
+    nothing: "nothing"
 };
 
 export class State extends Tool {
     constructor() {
         super("State");
 
-        this.display = new Display(TOOLS);
+        this.display = new Toolbar(TOOLS);
 
         this.tool = undefined;
         this.setTool(TOOLS.select);
@@ -38,7 +39,7 @@ export class State extends Tool {
         // Shared variables
         this.selectedItem = undefined;
         this.selectedItems = new Set();
-        this.itemsContext = undefined;
+        this.itemsContext = CONTEXT.nothing;
 
         this.keyStates = {};
     }
@@ -49,7 +50,7 @@ export class State extends Tool {
         }
 
         if (this.tool !== undefined) {
-            this.tool.onToolDeactivate(tool);
+            this.tool.deactivateTool(tool);
         }
 
         this.previousTool = this.tool;
@@ -57,29 +58,25 @@ export class State extends Tool {
         this.display.setSelectedTool(tool);
 
         if (this.tool !== undefined) {
-            this.tool.onToolActivate();
+            this.tool.activateTool();
         }
     }
 
     setSelectedItem(item) {
         this.selectedItem = item;
-        this.display.setSelectedItem(item);
     }
 
     addSelectedItem(item) {
         this.selectedItems.add(item);
-        this.display.setSelectedItems(this.selectedItems, this.itemsContext);
     }
 
     removeSelectedItem(item) {
         this.selectedItems.delete(item);
-        this.display.setSelectedItems(this.selectedItems, this.itemsContext);
     }
 
     clearSelectedItems() {
         this.selectedItems.clear();
-        this.itemsContext = undefined;
-        this.display.setSelectedItems(this.selectedItems, this.itemsContext);
+        this.itemsContext = CONTEXT.nothing;
     }
 
     onNodeClick(node) {
@@ -237,8 +234,6 @@ export class State extends Tool {
 
     redraw() {
         this.display.setSelectedTool(this.tool);
-        this.display.setSelectedItem(this.selectedItem);
-        this.display.setSelectedItems(this.selectedItems, this.itemsContext);
     }
 
     isLinkHighlighted(link) {
diff --git a/editor/js/toolbar.js b/editor/js/toolbar.js
new file mode 100644
index 0000000000000000000000000000000000000000..a4b93c25e70aab9386f1c69b7d5ea40d900003dc
--- /dev/null
+++ b/editor/js/toolbar.js
@@ -0,0 +1,78 @@
+import jQuery from "jquery";
+import { PLUGIN_PATH } from "../../config";
+import { state } from "./editor";
+
+const ID_TOOLBAR = "#toolbar";
+
+const TOOL_ICON_SRC = PLUGIN_PATH + "editor/images/tools/";
+const TOOL_ICON_FORMAT = ".png";
+const TOOL_SELECTED_CLASS = "selected";
+
+export default class Toolbar {
+    constructor(tools) {
+        this.tools = Object.values(tools);
+        this.previousTool = undefined;
+
+        this.renderToolbar(this.tools);
+    }
+
+    setSelectedTool(tool) {
+        var selectedTool = jQuery(Toolbar.getToolIdTag(tool));
+        selectedTool.addClass(TOOL_SELECTED_CLASS);
+
+        if (this.previousTool !== undefined) {
+            var previousTool = jQuery(Toolbar.getToolIdTag(this.previousTool));
+            previousTool.removeClass(TOOL_SELECTED_CLASS);
+        }
+
+        this.previousTool = tool;
+    }
+
+    renderToolbar(tools) {
+        this.fillDomList(ID_TOOLBAR, tools, this.toolRenderer);
+
+        tools.forEach((tool) => {
+            this.toolClickEvent(tool);
+        });
+    }
+
+    static getToolIdTag(tool) {
+        return ID_TOOLBAR + "-" + tool.getKey();
+    }
+
+    static getToolId(tool) {
+        return Toolbar.getToolIdTag(tool).substr(1);
+    }
+
+    toolRenderer(tool) {
+        return (
+            '<button id="' +
+            Toolbar.getToolId(tool) +
+            '" title="' +
+            tool.getName() +
+            '"><img src="' +
+            TOOL_ICON_SRC +
+            tool.getIcon() +
+            TOOL_ICON_FORMAT +
+            '"></button>'
+        );
+    }
+
+    toolClickEvent(tool) {
+        jQuery("button" + Toolbar.getToolIdTag(tool)).on(
+            "click",
+            "",
+            tool,
+            (e) => {
+                state.setTool(e.data);
+            }
+        );
+    }
+
+    fillDomList(listId, items, itemRenderer) {
+        var listCont = jQuery(listId);
+        listCont.empty();
+
+        items.forEach((i) => listCont.append(itemRenderer(i)));
+    }
+}
diff --git a/editor/js/tools/collecttool.js b/editor/js/tools/collecttool.js
index 472163a61dafbdb1ba6f34ab6aeddde8bdb6dd5a..ffd3f71db598a33f7613e741fb93dfd8f0947daf 100644
--- a/editor/js/tools/collecttool.js
+++ b/editor/js/tools/collecttool.js
@@ -1,10 +1,11 @@
 import Tool from "./tool";
 import { state } from "../editor";
 import { CONTEXT } from "../state";
+import { CollectMenu, COLLECTION_KEY } from "./menus/collectmenu";
 
 export default class CollectTool extends Tool {
     constructor(key) {
-        super("Collect", "collect", key);
+        super("Collect", "collect", key, new CollectMenu());
     }
 
     onNodeClick(node) {
@@ -18,6 +19,8 @@ export default class CollectTool extends Tool {
         } else {
             state.addSelectedItem(node);
         }
+
+        this.menu.value(COLLECTION_KEY, state.selectedItems);
     }
 
     onLinkClick(link) {
@@ -31,11 +34,14 @@ export default class CollectTool extends Tool {
         } else {
             state.addSelectedItem(link);
         }
+
+        this.menu.value(COLLECTION_KEY, state.selectedItems);
     }
 
-    onKeyUp(key) {
-        if (key.keyCode === 17) {
-            state.setTool(state.previousTool);
+    onMenuChange(key, value) {
+        if (key === COLLECTION_KEY && value === undefined) {
+            state.clearSelectedItems();
+            this.menu.value(COLLECTION_KEY, []);
         }
     }
 }
diff --git a/editor/js/tools/connecttool.js b/editor/js/tools/connecttool.js
index 5fb9de144545ec2e6d2940a7833e832ad2884243..d0e8efc4cefea2a6db54541cd0b969ac4ac53250 100644
--- a/editor/js/tools/connecttool.js
+++ b/editor/js/tools/connecttool.js
@@ -1,12 +1,13 @@
 import Tool from "./tool";
 import { graph, state } from "../editor";
 import * as Graph from "../graph";
+import ConnectMenu from "./menus/connectmenu";
 
 const KEEP_SOURCE_KEY_ID = 17;
 
 export default class ConnectTool extends Tool {
     constructor(key) {
-        super("Connect two nodes", "connect", key);
+        super("Connect two nodes", "connect", key, new ConnectMenu());
         this.keepSource = false;
     }
 
@@ -21,9 +22,13 @@ export default class ConnectTool extends Tool {
         }
 
         // Add new link
+        var details = {};
+        details[Graph.LINK_TYPE] = this.menu.value("link-type");
+
         var link = graph.addLink(
             state.selectedItem[Graph.NODE_ID],
-            node[Graph.NODE_ID]
+            node[Graph.NODE_ID],
+            details
         );
 
         if (link === undefined) {
diff --git a/editor/js/tools/menus/collectmenu.js b/editor/js/tools/menus/collectmenu.js
new file mode 100644
index 0000000000000000000000000000000000000000..ca181963b1954e700b82932ab76c84d401942b73
--- /dev/null
+++ b/editor/js/tools/menus/collectmenu.js
@@ -0,0 +1,54 @@
+import jQuery from "jquery";
+import { Graph } from "../../graph";
+import ToolMenu from "./toolmenu";
+
+export const COLLECTION_KEY = "collection";
+
+const SELECTED_ITEMS_ID = "#selected-items";
+const CLEAR_BUTTON_ID = "#clear-collection";
+
+const DOM_LIST_ITEM = "li";
+
+export class CollectMenu extends ToolMenu {
+    constructor() {
+        super();
+        this.hooked = false;
+    }
+
+    hookClearButton() {
+        // On button press: Notify tool about clearing and empty list
+        jQuery(CLEAR_BUTTON_ID).on("click", (e) => {
+            this.notifyTool(COLLECTION_KEY, undefined);
+        });
+    }
+
+    afterSet(key, value) {
+        if (this.hooked === false) {
+            this.hookClearButton();
+            this.hooked = true;
+        }
+
+        if (key === COLLECTION_KEY) {
+            this.fillDomList(SELECTED_ITEMS_ID, value, this.itemListRenderer);
+        }
+    }
+
+    itemListRenderer(item) {
+        return (
+            "<" +
+            DOM_LIST_ITEM +
+            ">" +
+            Graph.toStr(item) +
+            "</" +
+            DOM_LIST_ITEM +
+            ">"
+        );
+    }
+
+    fillDomList(listId, items, itemRenderer) {
+        var listCont = this.find(listId);
+        listCont.empty();
+
+        items.forEach((i) => listCont.append(itemRenderer(i)));
+    }
+}
diff --git a/editor/js/tools/menus/connectmenu.js b/editor/js/tools/menus/connectmenu.js
new file mode 100644
index 0000000000000000000000000000000000000000..4f148b0b8e815e1c1dad3212365b0f5578bfb780
--- /dev/null
+++ b/editor/js/tools/menus/connectmenu.js
@@ -0,0 +1,15 @@
+import ToolMenu from "./toolmenu";
+
+const LINK_TYPE_SEL = "#link-type";
+
+export default class ConnectMenu extends ToolMenu {
+    constructor() {
+        super();
+    }
+
+    beforeGet(key) {
+        if (key === "link-type") {
+            return this.find(LINK_TYPE_SEL).val();
+        }
+    }
+}
\ No newline at end of file
diff --git a/editor/js/tools/menus/selectmenu.js b/editor/js/tools/menus/selectmenu.js
new file mode 100644
index 0000000000000000000000000000000000000000..40602f1d8e402cd9265299bfd60c476f8491eb2f
--- /dev/null
+++ b/editor/js/tools/menus/selectmenu.js
@@ -0,0 +1,147 @@
+import * as Graph from "../../graph";
+import { CONTEXT } from "../../state";
+import ToolMenu from "./toolmenu";
+
+const HIDDEN_CLASS = "hidden";
+
+export const SELECTION_KEY = "selection";
+
+const CONTEXT_NOTHING = "#nothing-selected";
+const CONTEXT_NODE = "#node-selected";
+const CONTEXT_LINK = "#link-selected";
+
+const NODE_NAME_ID = "#node-name";
+const NODE_IMG_ID = "#node-image";
+const NODE_DESC_ID = "#node-description";
+const NODE_TYPE_ID = "#node-type";
+const NODE_REF_ID = "#node-references";
+const NODE_VIDEOS_ID = "#node-videos";
+const NODE_MENU = [
+    NODE_NAME_ID,
+    NODE_IMG_ID,
+    NODE_DESC_ID,
+    NODE_TYPE_ID,
+    NODE_REF_ID,
+    NODE_VIDEOS_ID,
+];
+
+const LINK_NAME_ID = "#link-name";
+const LINK_TYPE_ID = "#link-type";
+const LINK_MENU = [LINK_TYPE_ID];
+
+const MENU = [...NODE_MENU, ...LINK_MENU];
+
+export class SelectMenu extends ToolMenu {
+    constructor() {
+        super();
+        this.context = undefined;
+        this.map = [
+            { menu: NODE_NAME_ID, property: Graph.NODE_LABEL },
+            { menu: NODE_IMG_ID, property: Graph.NODE_IMAGE },
+            { menu: NODE_DESC_ID, property: Graph.NODE_DESCRIPTION },
+            { menu: NODE_TYPE_ID, property: Graph.NODE_TYPE },
+            { menu: NODE_REF_ID, property: Graph.NODE_REFERENCES },
+            { menu: NODE_VIDEOS_ID, property: Graph.NODE_VIDEOS },
+            { menu: LINK_TYPE_ID, property: Graph.LINK_TYPE },
+        ];
+        this.hooked = false; // Can only hook menu events once, but have to do it later, when they are loaded
+    }
+
+    hookMenu() {
+        MENU.forEach((menu) => {
+            console.log(this.find(menu));
+            // Subscribes to change event for each menu element
+            this.find(menu).on("change", (e) => {
+                var newValue = e.target.value;
+                console.log(newValue);
+
+                // Modify stored selection
+                this.values[SELECTION_KEY][this.toProperty(menu)] = newValue;
+
+                // Notify tool
+                this.tool.onMenuChange(
+                    SELECTION_KEY,
+                    this.values[SELECTION_KEY]
+                );
+            });
+        });
+    }
+
+    toProperty(menu) {
+        for (var i = 0; i < this.map.length; i++) {
+            if (this.map[i].menu === menu) {
+                return this.map[i].property;
+            }
+        }
+        return undefined;
+    }
+
+    toMenu(property) {
+        for (var i = 0; i < this.map.length; i++) {
+            if (this.map[i].property === property) {
+                return this.map[i].menu;
+            }
+        }
+        return undefined;
+    }
+
+    setContext(context) {
+        if (context === this.context) {
+            return; // Only do something if it changes
+        }
+
+        // Disable previous context
+        this.getDomToContext(this.context).addClass(HIDDEN_CLASS);
+
+        // Store and activate new context
+        this.context = context;
+        this.getDomToContext(this.context).removeClass(HIDDEN_CLASS);
+    }
+
+    getDomToContext(context) {
+        var id = CONTEXT_NOTHING;
+
+        if (context === CONTEXT.link) {
+            id = CONTEXT_LINK;
+        } else if (context === CONTEXT.node) {
+            id = CONTEXT_NODE;
+        }
+
+        return this.find(id);
+    }
+
+    afterSet(key, value) {
+        if (this.hooked !== true) {
+            this.hookMenu();
+            this.hooked = true;
+        }
+
+        if (key !== SELECTION_KEY) {
+            return;
+        }
+
+        if (value.node) {
+            this.fillNode(value);
+            this.setContext(CONTEXT.node);
+        } else if (value.link) {
+            this.fillLink(value);
+            this.setContext(CONTEXT.link);
+        } else {
+            this.setContext(CONTEXT.nothing);
+        }
+    }
+
+    fillNode(node) {
+        NODE_MENU.forEach((menu) => {
+            this.find(menu).val(node[this.toProperty(menu)]);
+        });
+    }
+
+    fillLink(link) {
+        this.find(LINK_NAME_ID).text(Graph.Graph.toStr(link));
+
+        LINK_MENU.forEach((menu) => {
+            this.find(menu).val(link[this.toProperty(menu)]);
+        });
+    }
+}
diff --git a/editor/js/tools/menus/toolmenu.js b/editor/js/tools/menus/toolmenu.js
new file mode 100644
index 0000000000000000000000000000000000000000..73c2ac7a3073662ebc293bbe0aaa9530301ff90a
--- /dev/null
+++ b/editor/js/tools/menus/toolmenu.js
@@ -0,0 +1,77 @@
+import jQuery from "jquery";
+
+export default class ToolMenu {
+    constructor() {
+        this.warnings = false;
+        this.values = {};
+    }
+
+    loadTool(tool) {
+        this.tool = tool;
+        this.menuId = this.tool.getKey() + "-menu";
+    }
+
+    show() {
+        this.getMenu().removeClass("hidden");
+    }
+
+    hide() {
+        this.getMenu().addClass("hidden");
+    }
+
+    beforeGet(key) {
+        if (this.warnings) {
+            console.warn('Method "beforeGet" not implemented.');
+        }
+    }
+
+    afterSet(key, value) {
+        if (this.warnings) {
+            console.warn('Method "afterSet" not implemented.');
+        }
+    }
+
+    notifyTool(key, value) {
+        this.values[key] = value;
+        this.tool.onMenuChange(key, value);
+    }
+
+    value(key, newValue) {
+        // If key not defined
+        // (be it by giving no arguments, or giving it an undefined value)
+        // Return all values as dict.
+        if (key === undefined) {
+            return this.values;
+        }
+
+        // Is key valid?
+        // If not, create undefined entry
+        if (key in this.values == false) {
+            this.values[key] = undefined;
+        }
+
+        // If value not defined, returned specified value.
+        if (newValue === undefined) {
+            newValue = this.beforeGet(key);
+
+            if (newValue !== undefined) {
+                this.values[key] = newValue;
+            }
+
+            return this.values[key];
+        }
+        // If bot defined, store specified value.
+        else {
+            this.values[key] = newValue;
+            newValue = this.afterSet(key, newValue);
+        }
+    }
+
+    find(selector) {
+        return this.getMenu().find(selector);
+    }
+
+    getMenu() {
+        return jQuery("#tool-menu #" + this.menuId);
+    }
+}
diff --git a/editor/js/tools/selecttool.js b/editor/js/tools/selecttool.js
index 921263e667f5530c35c5501645a0fe6345de31bf..4af6892e8b3996bafe8707b7cbff1b45f8eff27f 100644
--- a/editor/js/tools/selecttool.js
+++ b/editor/js/tools/selecttool.js
@@ -1,27 +1,31 @@
 import Tool from "./tool";
-import { state } from "../editor";
+import { graph, state } from "../editor";
 import { TOOLS } from "../state";
+import * as SelectMenu from "./menus/selectmenu";
 
 export default class SelectTool extends Tool {
     constructor(key) {
-        super("Select", "select", key);
+        super("Select", "select", key, new SelectMenu.SelectMenu());
     }
 
     onNodeClick(node) {
         state.setSelectedItem(node);
+        this.menu.value(SelectMenu.SELECTION_KEY, node);
     }
 
     onLinkClick(link) {
         state.setSelectedItem(link);
+        this.menu.value(SelectMenu.SELECTION_KEY, link);
     }
 
     onBackgroundClick(event, positions) {
         state.setSelectedItem(undefined);
+        this.menu.value(SelectMenu.SELECTION_KEY, {});
     }
 
-    onKeyDown(key) {
-        if (key.keyCode === 17) {
-            state.setTool(TOOLS.collect);
+    onMenuChange(key, value) {
+        if (key === SelectMenu.SELECTION_KEY) {
+            graph.changeDetails(value);
         }
     }
 }
diff --git a/editor/js/tools/tool.js b/editor/js/tools/tool.js
index e3fade0276387f02f241a2fa77797eef2f48392e..0c7b3ad8fca720d14580e416fc1283a690790da7 100644
--- a/editor/js/tools/tool.js
+++ b/editor/js/tools/tool.js
@@ -1,9 +1,14 @@
 export default class Tool {
-    constructor(name, icon, key) {
+    constructor(name, icon, key, menu) {
         this.name = name;
         this.icon = icon;
         this.key = key;
         this.warnings = false;
+        this.menu = menu;
+
+        if (this.menu !== undefined) {
+            this.menu.loadTool(this);
+        }
     }
 
     getName() {
@@ -18,6 +23,28 @@ export default class Tool {
         return this.icon;
     }
 
+    onMenuChange(key, value) {
+        if (this.warnings) {
+            console.warn('Method "onMenuChange" not implemented.');
+        }
+    }
+
+    activateTool() {
+        if (this.menu !== undefined) {
+            this.menu.show();
+        }
+
+        this.onToolActivate();
+    }
+
+    deactivateTool(nextTool) {
+        this.onToolDeactivate(nextTool);
+
+        if (this.menu !== undefined) {
+            this.menu.hide();
+        }
+    }
+
     onToolActivate() {
         if (this.warnings) {
             console.warn('Method "onToolActivate" not implemented.');