From cbfd8d0a4e8aef0422a7c00b3edfd8d979fb2def Mon Sep 17 00:00:00 2001 From: reschan Date: Sat, 23 Oct 2021 20:51:54 +0700 Subject: [PATCH] feat: add custom dropdown --- sq2bs.css | 36 ++++++++++---- sq2bs.html | 86 ++++++++++++++-------------------- sq2bs.js | 94 ++++++++++++++++++++++++++++++++++--- sq2build.js | 4 +- sq2builder.js | 101 ++-------------------------------------- sq2display_constants.js | 2 - 6 files changed, 157 insertions(+), 166 deletions(-) diff --git a/sq2bs.css b/sq2bs.css index 3b5485f..432a771 100644 --- a/sq2bs.css +++ b/sq2bs.css @@ -145,12 +145,39 @@ } /* equipment field specifics */ +/* inputs and dropdowns */ .form-control { transition: none !important; box-shadow: none !important; width: 95% !important; } +ul { + list-style-type: none; +} + +ul.search-box { + position: absolute; + padding: 0; +} + +li.search-item { + cursor: pointer; +} + +li.search-item:hover { + background-color: hsl(0, 0%, 11%) !important; +} + +input { + min-width: 0; + width: 100%; +} + +input.equipment-input { + font-weight: bold; +} + .text-right { float: right; } @@ -168,15 +195,6 @@ font-weight: bold; } -input { - min-width: 0; - width: 100%; -} - -input.equipment-input { - font-weight: bold; -} - .scaled-font { font-size: 2.5rem; } diff --git a/sq2bs.html b/sq2bs.html index 2c7182a..d1f4e56 100644 --- a/sq2bs.html +++ b/sq2bs.html @@ -12,6 +12,7 @@ + @@ -29,7 +30,7 @@
-
+
@@ -46,19 +47,17 @@
- - - +
- +
-
+
@@ -75,19 +74,17 @@
- - - +
- +
-
+
@@ -104,19 +101,17 @@
- - - +
- +
-
+
@@ -133,19 +128,17 @@
- - - +
- +
-
+
@@ -162,19 +155,17 @@
- - - +
- +
-
+
@@ -191,19 +182,17 @@
- - - +
- +
-
+
@@ -220,19 +209,17 @@
- - - +
- +
-
+
@@ -249,19 +236,17 @@
- - - +
- +
-
+
@@ -278,12 +263,10 @@
- - - +
- +
@@ -307,10 +290,10 @@
- +
- +
@@ -410,20 +393,20 @@
-
- Basic -
Offense
Defense
+
+ Overall +
-
+
@@ -1159,6 +1142,7 @@
+ diff --git a/sq2bs.js b/sq2bs.js index 16a9f6a..989d761 100644 --- a/sq2bs.js +++ b/sq2bs.js @@ -1,11 +1,14 @@ let equipment_keys = ['weapon', 'helmet', 'chestplate', 'leggings', 'boots', 'ring1', 'ring2', 'bracelet', 'necklace']; +let weapon_keys = ['dagger', 'wand', 'bow', 'relik', 'spear'] let skp_keys = ['str', 'dex', 'int', 'def', 'agi']; document.addEventListener('DOMContentLoaded', function() { + for (const i in equipment_keys) { document.querySelector("#"+equipment_keys[i]+"-choice").setAttribute("oninput", "update_fields('"+equipment_keys[i]+"'); calcBuildSchedule()"); document.querySelector("#"+equipment_keys[i]+"-powder").setAttribute("oninput", "calcBuildSchedule()"); } + document.querySelector("#level-choice").setAttribute("oninput", "calcBuildSchedule()") let skp_fields = document.getElementsByClassName("skp-update"); @@ -26,7 +29,7 @@ function calcBuildSchedule(){ calcBuildTask = setTimeout(function(){ calcBuildTask = null; calculateBuild(); - }, 500); + }, 1000); } function updateStatSchedule(){ @@ -52,16 +55,26 @@ function doSearchSchedule(){ // equipment field dynamic styling function update_fields(type, alt="") { let item = itemMap.get(document.querySelector("#"+type+"-choice").value); - if (item) { + if (item && ((item.type == type.replace(/[0-9]/g, '')) || (item.category == type))) { + // powder styling document.querySelector("#"+type+"-powder").setAttribute("placeholder", item["slots"]+" slots"+alt); - document.querySelector("#"+type+"-choice").classList.remove("text-light", "is-invalid"); + + if (item['slots'] == 0) { + document.querySelector("#"+type+"-powder").disabled = true; + } else { + document.querySelector("#"+type+"-powder").disabled = false; + } + + // input box styling + document.querySelector("#"+type+"-choice").classList.remove("text-light", "is-invalid", 'Normal', 'Unique', 'Rare', 'Legendary', 'Fabled', 'Mythic', 'Set'); document.querySelector("#"+type+"-choice").classList.add(item.tier); if (type == 'weapon') { document.querySelector("#"+type+"-img").setAttribute('src', 'media/items/new/generic-'+item.type+'.png'); } } else if (document.querySelector("#"+type+"-choice").value == '') { - document.querySelector("#"+type+"-choice").classList.remove("is-invalid"); + document.querySelector("#"+type+"-choice").classList.remove("is-invalid", 'Normal', 'Unique', 'Rare', 'Legendary', 'Fabled', 'Mythic', 'Set'); + document.querySelector("#"+type+"-powder").setAttribute("placeholder", '0 slots'); } else { document.querySelector("#"+type+"-choice").classList.remove('Normal', 'Unique', 'Rare', 'Legendary', 'Fabled', 'Mythic', 'Set'); @@ -75,12 +88,81 @@ function init_field_styles() { } } +function get_item_color(item) { + item = itemMap.get(item); + if (item) {return item.tier} else {return ''} +} + // tabular stats -let tabs = ['minimal-stats', 'minimal-offensive-stats', 'minimal-defensive-stats']; +let tabs = ['all-stats', 'minimal-offensive-stats', 'minimal-defensive-stats']; function show_tab(tab) { for (const i in tabs) { document.querySelector("#"+tabs[i]).style.display = "none"; } document.querySelector("#"+tab).style.display = ""; -} \ No newline at end of file +} + +// autocomplete initialize +function init_autocomplete() { + let dropdowns = new Map() + for (const i in equipment_keys) { + // build dropdown + let item_arr = []; + if (equipment_keys[i] == 'weapon') { + for (const weaponType of weapon_keys) { + for (const weapon of itemLists.get(weaponType)) { + let item_obj = itemMap.get(weapon); + if (item_obj["restrict"] && item_obj["restrict"] === "DEPRECATED") { + continue; + } + item_arr.push(weapon); + } + } + } else { + for (const item of itemLists.get(equipment_keys[i].replace(/[0-9]/g, ''))) { + let item_obj = itemMap.get(item); + if (item_obj["restrict"] && item_obj["restrict"] === "DEPRECATED") { + continue; + } + item_arr.push(item) + } + } + + // create dropdown + dropdowns.set(equipment_keys[i], new autoComplete({ + data: { + src: item_arr + }, + selector: "#"+ equipment_keys[i] +"-choice", + wrapper: false, + resultsList: { + tabSelect: true, + class: "search-box dark-7 rounded-bottom px-2 fw-bold dark-shadow-sm", + element: (list, data) => { + // dynamic result loc + let position = document.getElementById(equipment_keys[i]+'-dropdown').getBoundingClientRect(); + list.style.top = position.bottom + window.scrollY +"px"; + list.style.left = position.x+"px"; + list.style.width = position.width+"px"; + }, + }, + resultItem: { + class: "scaled-font search-item", + selected: "dark-5", + element: (item, data) => { + item.classList.add(get_item_color(data.value)); + }, + }, + events: { + input: { + selection: (event) => { + event.target.value = event.detail.selection.value; + update_fields(equipment_keys[i]); + calcBuildSchedule(); + }, + }, + } + })); + } +} diff --git a/sq2build.js b/sq2build.js index bdb3918..0cbf697 100644 --- a/sq2build.js +++ b/sq2build.js @@ -317,12 +317,12 @@ class Build{ } this.powders[4] = this.powders[4].slice(0,this.weapon.get("slots")); this.weapon.set("powders",this.powders[4].slice()); - document.getElementsByClassName("powder-specials")[0].style.display = "grid"; + // document.getElementsByClassName("powder-specials")[0].style.display = "grid"; } catch (Error) { const weapon = itemMap.get("No Weapon"); this.powders[4] = this.powders[4].slice(0,weapon.slots); this.weapon = expandItem(weapon, this.powders[4]); - document.getElementsByClassName("powder-specials")[0].style.display = "none"; + // document.getElementsByClassName("powder-specials")[0].style.display = "none"; errors.push(new ItemNotFound(equipment[8], "weapon", true)); } } diff --git a/sq2builder.js b/sq2builder.js index ab42bcc..2dd6a02 100644 --- a/sq2builder.js +++ b/sq2builder.js @@ -69,103 +69,11 @@ let powderInputs = [ "weapon-powder", ]; - - -/* - * Function that takes an item list and populates its corresponding dropdown. - * Used for armors and bracelet/necklace. - */ -function populateItemList(type) { - let item_list = document.getElementById(type+"-items"); - for (const item of itemLists.get(type)) { - let item_obj = itemMap.get(item); - if (item_obj["restrict"] && item_obj["restrict"] === "DEPRECATED") { - continue; - } - let el = document.createElement("option"); - el.value = item; - item_list.appendChild(el); - } -} - -/* - * Populate dropdowns, add listeners, etc. - */ function init() { console.log("builder.js init"); - - for (const armorType of armorTypes) { - populateItemList(armorType); - // Add change listener to update armor slots. - /* - document.getElementById(armorType+"-choice").addEventListener("change", (event) => { - let item_name = event.target.value; - let nSlots = undefined; - if (itemMap.has(item_name)) { - let item = itemMap.get(item_name); - nSlots = item["slots"]; - //console.log(item); - } - else { - let crafted_custom_item = getCraftFromHash(item_name) !== undefined ? getCraftFromHash(item_name) : (getCustomFromHash(item_name) !== undefined ? getCustomFromHash(item_name) : undefined); - if (crafted_custom_item !== undefined) { - nSlots = crafted_custom_item.statMap.get("slots"); - } - } - if (nSlots !== undefined) { - document.getElementById(armorType+"-slots").textContent = nSlots + " slots"; - } - else { - document.getElementById(armorType+"-slots").textContent = "X slots"; - } - });*/ - } - - let ring1_list = document.getElementById("ring1-items"); - let ring2_list = document.getElementById("ring2-items"); - for (const ring of itemLists.get("ring")) { - let item_obj = itemMap.get(ring); - if (item_obj["restrict"] && item_obj["restrict"] === "DEPRECATED") { - continue; - } - let el1 = document.createElement("option"); - let el2 = document.createElement("option"); - el1.value = ring; - el2.value = ring; - ring1_list.appendChild(el1); - ring2_list.appendChild(el2); - } - - populateItemList("bracelet"); - populateItemList("necklace"); - - let weapon_list = document.getElementById("weapon-items"); - for (const weaponType of weaponTypes) { - for (const weapon of itemLists.get(weaponType)) { - let item_obj = itemMap.get(weapon); - if (item_obj["restrict"] && item_obj["restrict"] === "DEPRECATED") { - continue; - } - let el = document.createElement("option"); - el.value = weapon; - weapon_list.appendChild(el); - } - } - - // Add change listener to update weapon slots. - /* - document.getElementById("weapon-choice").addEventListener("change", (event) => { - let item_name = event.target.value; - let item = itemMap.has(item_name) ? itemMap.get(item_name) : (getCraftFromHash(item_name) ? getCraftFromHash(item_name) : (getCustomFromHash(item_name) ? getCustomFromHash(item_name) : undefined)); - if (item !== undefined && event.target.value !== "") { - document.getElementById("weapon-slots").textContent = (item["slots"] ? item["slots"] : (item.statMap !== undefined ? ( item.statMap.has("slots") ? item.statMap.get("slots") : 0): 0) )+ " slots"; - } else { - document.getElementById("weapon-slots").textContent = "X slots"; - } - });*/ - - decodeBuild(url_tag); init_field_styles(); + init_autocomplete(); + decodeBuild(url_tag); } function getItemNameFromID(id) { @@ -833,10 +741,11 @@ function calculateBuildStats() { for (let i in player_build.items) { // displaysq2ExpandedItem(player_build.items[i], buildFields[i], true); } - + console.log(player_build) + console.log("build") displaysq2ArmorStats(player_build); displaysq2BuildStats("all-stats", player_build, build_all_display_commands); - displaysq2BuildStats("minimal-stats", player_build, build_basic_display_commands); + // displaysq2BuildStats("minimal-stats", player_build, build_basic_display_commands); displaysq2BuildStats("minimal-offensive-stats",player_build, build_offensive_display_commands); displaySetBonuses("set-info",player_build); displayNextCosts("int-info",player_build); diff --git a/sq2display_constants.js b/sq2display_constants.js index c1d2447..4a9e7c9 100644 --- a/sq2display_constants.js +++ b/sq2display_constants.js @@ -2,7 +2,6 @@ * Display commands */ let build_all_display_commands = [ - "#table", "#defense-stats", "str", "dex", "int", "def", "agi", "mr", "ms", @@ -29,7 +28,6 @@ let build_all_display_commands = [ ]; let build_offensive_display_commands = [ - '#table', "str", "dex", "int", "def", "agi", "mr", "ms", "sdRaw", "sdPct",