diff --git a/js/5etools-importer.js b/js/5etools-importer.js index f315fde5..94c68eb1 100644 --- a/js/5etools-importer.js +++ b/js/5etools-importer.js @@ -705,7 +705,7 @@ function d20plusImporter () { // init list library const importList = new List("import-list", { - valueNames: options.listIndex || ["name"], + valueNames: options.listIndex || ["name", "source"], }); // reset the UI and add handlers @@ -730,6 +730,13 @@ function d20plusImporter () { d20plus.importer._importSelectPublished(importList); }); + $("#importlist-filter").bind("click", () => { + d20plus.importer._importFilterList(importList); + }); + $("#importlist-reset").bind("click", () => { + d20plus.importer._importResetList(importList); + }); + if (options.listIndexConverter) { const $iptFilter = $(`#import-list-filter`).show(); $(`#import-list-filter-help`).show(); @@ -1213,6 +1220,60 @@ function d20plusImporter () { }); }; + d20plus.importer._importFilterList = function (importList) { + const $winFilterList = $("#d20plus-import-filter-list"); + $winFilterList.dialog("open"); + const $btnImport = $winFilterList.find(".btn"); + const $winText = $winFilterList.find(".table-import-textarea"); + + $btnImport.on("click", () => { + + function filterList () { + const toSearch = $winText.val().toLowerCase().replaceAll(`"`, "").split("\n"); + const firstLine = toSearch[0]; + const filterUnofficial = !d20plus.cfg.getOrDefault("import", "allSourcesIncludeUnofficial"); + + // If no search terms are entered, reset the filter + if (toSearch.length == 1 && firstLine == '') { + importList.filter(); + return; + } + + const searchDict = {}; + toSearch.forEach(it => { + const items = it.split(","); + // If additional filters are added, they can go here + searchDict[items[0].trim()] = { + "name": items[0].trim(), + "source": items.length > 1 ? items[1].trim() : null, + // Some categories list their source in this format + "altsource": items.length > 1 ? `src[${items[1].trim()}]`: null, + } + }) + + // Filters to match names and sources on the list + x = importList + importList.filter(it => { + const name = it._values.name.toLowerCase(); + const source = it._values.source.toLowerCase(); + + if (!(name in searchDict)) return false; + if (!searchDict[name].source) return true; + if (searchDict[name].source === source || searchDict[name].altsource === source) return true; + return false; + }); + } + + filterList(); + + $winFilterList.dialog("close"); + }).appendTo($winFilterList); + }; + + d20plus.importer._importResetList = function (importList) { + importList.filter(); + }; + d20plus.importer.CharacterAttributesProxy = class { constructor (character) { this.character = character; diff --git a/js/5etools-template.js b/js/5etools-template.js index f24146dd..a3630a01 100644 --- a/js/5etools-template.js +++ b/js/5etools-template.js @@ -207,6 +207,7 @@ const d20plusTemplate = function () { $body.append(d20plus.template5e.importDialogHtml); $body.append(d20plus.template5e.importListHTML); $body.append(d20plus.template5e.importListPropsHTML); + $body.append(d20plus.template5e.importFilterList); $("#d20plus-import").dialog({ autoOpen: false, resizable: false, @@ -223,6 +224,12 @@ const d20plusTemplate = function () { width: 300, height: 600, }); + $("#d20plus-import-filter-list").dialog({ + autoOpen: false, + resizable: true, + width: 640, + height: 540, + }); // add class subclasses to the subclasses dropdown(s) d20plus.template5e._populateDropdown("#button-subclasses-select", "#import-subclasses-url", CLASS_DATA_DIR, classDataUrls, "", ["class"]); @@ -321,6 +328,9 @@ ${finalText} + + +
@@ -351,6 +361,30 @@ ${finalText}
+ Write down a vertical list of the items you want to filter and then Filter List > Select Visible > Import + [!]. +
++ You can either manually write down your list, or you can go to the corresponding page in 5etools > make your list > Table View > Copy CSV to Clipboard > Paste it here > Filter List + [?]. +
+ +