finalising the autocomplete helper, and added to technique skillids

This commit is contained in:
Vlyan
2022-02-18 22:33:47 +01:00
parent 193a10daed
commit a876bfa122
5 changed files with 65 additions and 24 deletions

View File

@@ -8,8 +8,10 @@
- Added the ability for technique with a skill set, to open the DicePicker with presets values. - Added the ability for technique with a skill set, to open the DicePicker with presets values.
- Some can interact with targets, but do the default difficulty if none. - Some can interact with targets, but do the default difficulty if none.
- Notes : Techniques in sheet need to be re-imported from the compendium or manually updated for this to work. - Notes : Techniques in sheet need to be re-imported from the compendium or manually updated for this to work.
- Compendiums : - Trying an autocomplete on some fields : clan, family, school, roles, demeanor.
- Techniques : Added difficulty and skill values (not all techniques). - Techniques Sheet & Compendiums :
- Added difficulty and skill values (not to all techniques).
- Trying an autocomplete on skill(id) field.
- DicePicker : - DicePicker :
- Added TN hidden difficulty visibility for GM (ex: ?2?). - Added TN hidden difficulty visibility for GM (ex: ?2?).
- Added a selection for techniques with skill list. - Added a selection for techniques with skill list.
@@ -26,12 +28,12 @@ Technique syntaxe "quick" explanation :
- `T` or `S` : `T`arget or `S`elf, define the actor to get the value. - `T` or `S` : `T`arget or `S`elf, define the actor to get the value.
- `prop1` / `prop2` : Can be any property in `actor` or `actor.data.data`. Limitations: currently no `size` or `distance` (range). - `prop1` / `prop2` : Can be any property in `actor` or `actor.data.data`. Limitations: currently no `size` or `distance` (range).
- `|` separator, optional if no min/max. - `|` separator, optional if no min/max.
- `min` or `max` : Between the selected targets search for the min/max of `prop2`. If no `prop2` found, take `prop1` as `prop2` (irrelevant for `@S`). - `min` or `max` : Between the selected targets, search for the min/max of `prop2`. If no `prop2` provided, take `prop1` as `prop2` (irrelevant for `@S`).
- `(prop2)` : define the property for the actor selection in multiple target, can be omitted if same as `prop1`. - `(prop2)` : define the property for the actor selection in multiple target, can be omitted if same as `prop1`.
- Exemples : - Exemples :
- `@S:vigilance` : Difficulty will be my own vigilance - `@S:vigilance` : Difficulty will be my own `vigilance`.
- `@T:vigilance|min` : Difficulty will be the vigilance from the target with the minimum vigilance (implicit) value. it's the same to wrote `@T:vigilance|min(vigilance)`. - `@T:vigilance|min` : Difficulty will be the `vigilance` from the target with the minimum vigilance (implicit) value. it's the same to wrote `@T:vigilance|min(vigilance)`.
- `@T:vigilance|max(statusRank)` : Difficulty will be the vigilance from the target with the maximum `statusRank` value. - `@T:vigilance|max(statusRank)` : Difficulty will be the `vigilance` from the target with the maximum `statusRank` value.
- Skill can be : - Skill can be :
- SkillId : `melee`, `fitness`... - SkillId : `melee`, `fitness`...
- SkillCategoryId : `scholar`, `martial`... - SkillCategoryId : `scholar`, `martial`...

View File

@@ -750,16 +750,15 @@ export class HelpersL5r5e {
} }
/** /**
* Autocomplete method * Autocomplete for an input, from array values
* @param {jQuery} html HTML content of the sheet. * @param {jQuery} html HTML content of the sheet.
* @param {string} name Html name of the input * @param {string} name Html name of the input
* @param {string[]} list Array of string to display * @param {string[]} list Array of string to display
* @param {string} sep (optional) Separator * @param {string} sep (optional) Separator
*/ */
static autocomplete(html, name, list = [], sep = "") { static autocomplete(html, name, list = [], sep = "") {
/* // TODO tmp disabled
const inp = document.getElementsByName(name)?.[0]; const inp = document.getElementsByName(name)?.[0];
if (list.length < 1) { if (!inp || list.length < 1) {
return; return;
} }
let currentFocus; let currentFocus;
@@ -777,6 +776,18 @@ export class HelpersL5r5e {
} }
}; };
// Abort submit on change in foundry form
inp.addEventListener("change", (e) => {
if (e.doSubmit) {
closeAllLists();
$(inp).parent().submit();
return true;
}
e.preventDefault();
e.stopPropagation();
return false;
});
// execute a function when someone writes in the text field // execute a function when someone writes in the text field
inp.addEventListener("input", (inputEvent) => { inp.addEventListener("input", (inputEvent) => {
closeAllLists(); closeAllLists();
@@ -790,7 +801,9 @@ export class HelpersL5r5e {
let previous = [val]; let previous = [val];
let currentIdx = 0; let currentIdx = 0;
if (sep) { if (sep) {
currentIdx = (val.substring(0, inputEvent.target.selectionStart).match(new RegExp(`[${sep}]`, "g")) || []).length; currentIdx = (
val.substring(0, inputEvent.target.selectionStart).match(new RegExp(`[${sep}]`, "g")) || []
).length;
previous = val.split(sep); previous = val.split(sep);
val = previous[currentIdx].trim(); val = previous[currentIdx].trim();
} }
@@ -806,10 +819,7 @@ export class HelpersL5r5e {
inputEvent.target.parentNode.appendChild(listDiv); inputEvent.target.parentNode.appendChild(listDiv);
list.forEach((value, index) => { list.forEach((value, index) => {
if ( if (HelpersL5r5e.normalize(value.substring(0, val.length)) === HelpersL5r5e.normalize(val)) {
HelpersL5r5e.normalize(value.substring(0, val.length)) ===
HelpersL5r5e.normalize(val)
) {
const choiceDiv = document.createElement("DIV"); const choiceDiv = document.createElement("DIV");
choiceDiv.setAttribute("data-id", index); choiceDiv.setAttribute("data-id", index);
choiceDiv.innerHTML = `<strong>${value.substring(0, val.length)}</strong>${value.substring( choiceDiv.innerHTML = `<strong>${value.substring(0, val.length)}</strong>${value.substring(
@@ -822,8 +832,11 @@ export class HelpersL5r5e {
return; return;
} }
previous[currentIdx] = list[selectedIndex]; previous[currentIdx] = list[selectedIndex];
inp.value = previous.map(e => e.trim()).join(sep + " "); inp.value = previous.map((e) => e.trim()).join(sep + " ");
closeAllLists();
const changeEvt = new Event("change");
changeEvt.doSubmit = true;
inp.dispatchEvent(changeEvt);
}); });
listDiv.appendChild(choiceDiv); listDiv.appendChild(choiceDiv);
} }
@@ -868,10 +881,11 @@ export class HelpersL5r5e {
} //swi } //swi
}); });
// execute a function when someone clicks in the document // Close all list when click in the document (1st autocomplete only)
html.on("focusout", (e) => { if (html.find(".autocomplete").length <= 1) {
closeAllLists(e.target); html[0].addEventListener("click", (e) => {
}); closeAllLists(e.target);
//*/ });
}
} }
} }

View File

@@ -48,6 +48,31 @@ export class TechniqueSheetL5r5e extends ItemSheetL5r5e {
return super._updateObject(event, formData); return super._updateObject(event, formData);
} }
/**
* Listen to html elements
* @param {jQuery} html HTML content of the sheet.
* @override
*/
activateListeners(html) {
super.activateListeners(html);
// *** Everything below here is only needed if the sheet is editable ***
if (!this.isEditable) {
return;
}
// Autocomplete
game.l5r5e.HelpersL5r5e.autocomplete(
html,
"data.skill",
Array.from(game.l5r5e.HelpersL5r5e.getCategoriesSkillsList()).reduce((acc, [cat, skills]) => {
acc.push(cat, ...skills);
return acc;
}, []),
","
);
}
/** /**
* Sanitize the technique difficulty * Sanitize the technique difficulty
* @param {string} str * @param {string} str

File diff suppressed because one or more lines are too long

View File

@@ -925,7 +925,7 @@ button {
.autocomplete-items { .autocomplete-items {
position: absolute; position: absolute;
border: 1px solid #d4d4d4; border: 1px solid #6e7e6b;
border-bottom: none; border-bottom: none;
border-top: none; border-top: none;
z-index: 99; z-index: 99;
@@ -938,7 +938,7 @@ button {
padding: 10px; padding: 10px;
cursor: pointer; cursor: pointer;
background-color: #fff; background-color: #fff;
border-bottom: 1px solid #d4d4d4; border-bottom: 1px solid #6e7e6b;
text-align: left; text-align: left;
} }
.autocomplete-items div:hover { .autocomplete-items div:hover {