diff --git a/src/public/javascripts/dialogs/attributes.js b/src/public/javascripts/dialogs/attributes.js
index 7e5659f76..51246041c 100644
--- a/src/public/javascripts/dialogs/attributes.js
+++ b/src/public/javascripts/dialogs/attributes.js
@@ -4,13 +4,12 @@ import infoService from "../services/info.js";
import treeUtils from "../services/tree_utils.js";
import attributeAutocompleteService from "../services/attribute_autocomplete.js";
import utils from "../services/utils.js";
+import libraryLoader from "../services/library_loader.js";
const $dialog = $("#attributes-dialog");
const $saveAttributesButton = $("#save-attributes-button");
const $ownedAttributesBody = $('#owned-attributes-table tbody');
-const attributesModel = new AttributesModel();
-
function AttributesModel() {
const self = this;
@@ -254,9 +253,15 @@ function AttributesModel() {
}
}
+let attributesModel;
+
export async function showDialog() {
utils.closeActiveDialog();
+ await libraryLoader.requireLibrary(libraryLoader.KNOCKOUT);
+
+ attributesModel = new AttributesModel();
+
// lazily apply bindings on first use
if (!ko.dataFor($dialog[0])) {
ko.applyBindings(attributesModel, $dialog[0]);
diff --git a/src/public/javascripts/services/library_loader.js b/src/public/javascripts/services/library_loader.js
index 9bdccb58e..4aba9765b 100644
--- a/src/public/javascripts/services/library_loader.js
+++ b/src/public/javascripts/services/library_loader.js
@@ -49,6 +49,8 @@ const PRINT_THIS = {js: ["libraries/printThis.js"]};
const SORTABLE = {js: ["libraries/sortable.min.js"]};
+const KNOCKOUT = {js: ["libraries/knockout.min.js"]};
+
async function requireLibrary(library) {
if (library.css) {
library.css.map(cssUrl => cssLoader.requireCss(cssUrl));
@@ -85,5 +87,6 @@ export default {
RELATION_MAP,
LINK_MAP,
PRINT_THIS,
- SORTABLE
+ SORTABLE,
+ KNOCKOUT
}
\ No newline at end of file
diff --git a/src/views/desktop.ejs b/src/views/desktop.ejs
index 1dedf66fc..9a33ef8cc 100644
--- a/src/views/desktop.ejs
+++ b/src/views/desktop.ejs
@@ -205,8 +205,6 @@
-
-