diff --git a/src/module/actor/sheets/actor-sheet.ts b/src/module/actor/sheets/actor-sheet.ts index 4ec6878e..9122a8d8 100644 --- a/src/module/actor/sheets/actor-sheet.ts +++ b/src/module/actor/sheets/actor-sheet.ts @@ -8,13 +8,13 @@ import { ModifiableDataBaseTotal } from "../../common/common-data"; import { DS4 } from "../../config"; import { getCanvas, getGame } from "../../helpers"; -import { DS4Item } from "../../item/item"; import { DS4Settings, getDS4Settings } from "../../settings"; import notifications from "../../ui/notifications"; +import { enforce } from "../../utils"; import { isCheck } from "../actor-data-properties"; /** - * The base Sheet class for all DS4 Actors + * The base sheet class for all {@link DS4Actor}s. */ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetData> { /** @override */ @@ -38,12 +38,7 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD return `${basePath}/${this.actor.data.type}-sheet.hbs`; } - /** - * This method returns the data for the template of the actor sheet. - * It explicitly adds the items of the object sorted by type in the - * object itemsByType. - * @returns The data fed to the template of the actor sheet - */ + /** @override */ async getData(): Promise<DS4ActorSheetData> { const itemsByType = Object.fromEntries( Object.entries(this.actor.itemTypes).map(([itemType, items]) => { @@ -69,6 +64,9 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD return data; } + /** + * Adds tooltips to the attributes, traits, and combatValues of the actor data of the given {@link ActorSheet.Data}. + */ protected addTooltipsToData(data: ActorSheet.Data): ActorSheet.Data { const valueGroups = [data.data.data.attributes, data.data.data.traits, data.data.data.combatValues]; @@ -80,6 +78,9 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD return data; } + /** + * Generates a tooltip for a given attribute, trait, or combatValue. + */ protected getTooltipForValue(value: ModifiableDataBaseTotal<number>): string { return `${value.base} (${getGame().i18n.localize("DS4.TooltipBaseValue")}) + ${ value.mod @@ -92,151 +93,92 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD activateListeners(html: JQuery): void { super.activateListeners(html); - // Everything below here is only needed if the sheet is editable if (!this.options.editable) return; - // Add Inventory Item - html.find(".item-create").on("click", this.onItemCreate.bind(this)); - - // Update Inventory Item - html.find(".item-edit").on("click", (ev) => { - const li = $(ev.currentTarget).parents(".item"); - const id = li.data("itemId"); - const item = this.actor.items.get(id); - if (!item) { - throw new Error(getGame().i18n.format("DS4.ErrorActorDoesNotHaveItem", { id, actor: this.actor.name })); - } - if (!item.sheet) { - throw new Error(getGame().i18n.localize("DS4.ErrorUnexpectedError")); - } - item.sheet.render(true); - }); - - // Delete Inventory Item - html.find(".item-delete").on("click", (ev) => { - const li = $(ev.currentTarget).parents(".item"); - this.actor.deleteEmbeddedDocuments("Item", [li.data("itemId")]); - li.slideUp(200, () => this.render(false)); - }); - - html.find(".item-change").on("change", this.onItemChange.bind(this)); + html.find(".control-item").on("click", this.onControlItem.bind(this)); + html.find(".change-item").on("change", this.onChangeItem.bind(this)); html.find(".control-effect").on("click", this.onControlEffect.bind(this)); html.find(".change-effect").on("change", this.onChangeEffect.bind(this)); html.find(".rollable-item").on("click", this.onRollItem.bind(this)); - html.find(".rollable-check").on("click", this.onRollCheck.bind(this)); } /** - * Handle creating a new embedded Item for the actor using initial data defined in the HTML dataset + * Handles a click on an element of this sheet to control an embedded item of the actor corresponding to this sheet. + * * @param event - The originating click event */ - protected onItemCreate(event: JQuery.ClickEvent): void { + protected onControlItem(event: JQuery.ClickEvent): void { event.preventDefault(); - const header = event.currentTarget; - - const { type, ...data } = foundry.utils.deepClone(header.dataset); + const a = event.currentTarget; + switch (a.dataset["action"]) { + case "create": + return this.onCreateItem(event); + case "edit": + return this.onEditItem(event); + case "delete": + return this.onDeleteItem(event); + } + } + /** + * Creates a new embedded item using the initial data defined in the HTML dataset of the clicked element. + * + * @param event - The originating click event + */ + protected onCreateItem(event: JQuery.ClickEvent): void { + const { type, ...data } = foundry.utils.deepClone(event.currentTarget.dataset); const name = getGame().i18n.localize(`DS4.New${type.capitalize()}Name`); - const itemData = { name: name, type: type, data: data, }; - - DS4Item.create(itemData, { parent: this.actor }); + Item.create(itemData, { parent: this.actor }); } /** - * Handle changes to properties of an Owned Item from within character sheet. - * Can currently properly bind: see getValue(). - * Assumes the item property is given as the value of the HTML element property 'data-property'. - * @param ev - The originating change event + * Opens the sheet of the embedded item corresponding to the clicked element. + * + * @param event - The originating click event */ - protected onItemChange(ev: JQuery.ChangeEvent): void { - ev.preventDefault(); - const el: HTMLFormElement = $(ev.currentTarget).get(0); - const id = $(ev.currentTarget).parents(".item").data("itemId"); + protected onEditItem(event: JQuery.ClickEvent): void { + const id = $(event.currentTarget).parents(".item").data("id"); const item = this.actor.items.get(id); - if (!item) { - throw new Error(getGame().i18n.format("DS4.ErrorActorDoesNotHaveItem", { id, actor: this.actor.name })); - } - const itemObject = item.toObject(); - const property: string | undefined = $(ev.currentTarget).data("property"); - - // Early return: - // Disabled => do nothing - if (el.disabled || el.getAttribute("disabled")) return; - // name not given => raise - if (property === undefined) { - throw TypeError("HTML element does not provide 'data-property' attribute"); - } - - // Set new value - const newValue = this.getValue(el); - foundry.utils.setProperty(itemObject, property, newValue); - item.update(itemObject); + enforce(item, getGame().i18n.format("DS4.ErrorActorDoesNotHaveItem", { id, actor: this.actor.name })); + enforce(item.sheet); + item.sheet.render(true); } /** - * Collect the value of a form element depending on the element's type - * The value is parsed to: - * - Checkbox: boolean - * - Text input: string - * - Number: number - * @param el - The input element to collect the value of - * @param inverted - Whether or not the value should be inverted + * Deletes the embedded item corresponding to the clicked element. + * + * @param event - The originating click event */ - private getValue(el: HTMLFormElement, inverted = false): boolean | string | number { - // One needs to differentiate between e.g. checkboxes (value="on") and select boxes etc. - // Checkbox: - if (el.type === "checkbox") { - const value: boolean = el.checked; - return inverted ? !value : value; - } - - // Text input: - else if (el.type === "text") { - const value: string = el.value; - return value; - } - - // Numbers: - else if (el.type === "number") { - const value = Number(el.value.trim()); - return value; - } - - // // Ranges: - // else if (el.type === "range") { - // const value: string = el.value.trim(); - // return value; - // } - - // // Radio Checkboxes (untested, cf. FormDataExtended.process) - // else if (el.type === "radio") { - // const chosen: HTMLFormElement = el.find((r: HTMLFormElement) => r["checked"]); - // const value: string = chosen ? chosen.value : null; - // return value; - // } - - // // Multi-Select (untested, cf. FormDataExtended.process) - // else if (el.type === "select-multiple") { - // const value: Array<string> = []; - // el.options.array.forEach((opt: HTMLOptionElement) => { - // if (opt.selected) value.push(opt.value); - // }); - // return value; - - // unsupported: - else { - throw new TypeError("Binding of item property to this type of HTML element not supported; given: " + el); - } + protected onDeleteItem(event: JQuery.ClickEvent): void { + const li = $(event.currentTarget).parents(".item"); + this.actor.deleteEmbeddedDocuments("Item", [li.data("id")]); + li.slideUp(200, () => this.render(false)); } + /** + * Applies a change to a property of an embedded item depending on the `data-property` attribute of the + * {@link HTMLInputElement} that has been changed and its new value. + * + * @param event - The originating change event + */ + protected onChangeItem(event: JQuery.ChangeEvent): void { + return this.onChangeEmbeddedDocument(event, ".item", "Item"); + } + + /** + * Handles a click on an element of this sheet to control an embedded effect of the actor corresponding to this + * sheet. + * + * @param event - The originating click event + */ protected onControlEffect(event: JQuery.ClickEvent): void { event.preventDefault(); const a = event.currentTarget; @@ -250,45 +192,115 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD } } + /** + * Creates a new embedded effect. + * + * @param event - The originating click event + */ protected onCreateEffect(): void { - const createData = { + const effectData = { label: getGame().i18n.localize(`DS4.NewEffectLabel`), icon: "icons/svg/aura.svg", origin: this.actor.uuid, }; - ActiveEffect.create(createData, { parent: this.actor }); + ActiveEffect.create(effectData, { parent: this.actor }); } + /** + * Opens the sheet of the embedded effect corresponding to the clicked element. + * + * @param event - The originating click event + */ protected onEditEffect(event: JQuery.ClickEvent): void { - const id = $(event.currentTarget).parents(".effect").data("effectId"); + const id = $(event.currentTarget).parents(".effect").data("id"); const effect = this.actor.effects.get(id); - if (!effect) { - throw new Error(getGame().i18n.format("DS4.ErrorActorDoesNotHaveEffect", { id, actor: this.actor.name })); - } + enforce(effect, getGame().i18n.format("DS4.ErrorActorDoesNotHaveEffect", { id, actor: this.actor.name })); effect.sheet.render(true); } + /** + * Deletes the embedded item corresponding to the clicked element. + * + * @param event - The originating click event + */ protected onDeleteEffect(event: JQuery.ClickEvent): void { const li = $(event.currentTarget).parents(".effect"); - const id = li.data("effectId"); + const id = li.data("id"); this.actor.deleteEmbeddedDocuments("ActiveEffect", [id]); li.slideUp(200, () => this.render(false)); } + /** + * Applies a change to a property of an embedded effect depending on the `data-property` attribute of the + * {@link HTMLInputElement} that has been changed and its new value. + * + * @param event - The originating change event + */ protected onChangeEffect(event: JQuery.ChangeEvent): void { - event.preventDefault(); - const currentTarget = $(event.currentTarget); - const element: HTMLFormElement = currentTarget.get(0); - const id = currentTarget.parents(".effect").data("effectId"); - const property: string | undefined = currentTarget.data("property"); - const inverted = Boolean(currentTarget.data("inverted")); + return this.onChangeEmbeddedDocument(event, ".effect", "ActiveEffect"); + } - if (element.disabled || element.getAttribute("disabled")) return; - if (property === undefined) { - throw TypeError("HTML element does not provide 'data-property' attribute"); + /** + * Applies a change to a property of an embedded document of the actor belonging to this sheet. The change depends + * on the `data-property` attribute of the {@link HTMLInputElement} that has been changed and its new value. + * + * @param event - The originating change event + * @param documentSelector - The selector for the closest parent of the changed {@link HTMLInputElement}, which + * contains the `data-id` attribute providing the `id` of the embedded document to be + * changed. + * @param documentName - The name of the embedded document to be changed. + */ + protected onChangeEmbeddedDocument( + event: JQuery.ChangeEvent, + documentSelector: string, + documentName: "Item" | "ActiveEffect", + ): void { + event.preventDefault(); + const element = $(event.currentTarget).get(0); + enforce(element instanceof HTMLInputElement); + if (element.disabled) return; + + const effectElement = element.closest(documentSelector); + enforce(effectElement instanceof HTMLElement); + const id = effectElement.dataset["id"]; + const property = element.dataset["property"]; + const inverted = Boolean(element.dataset["inverted"]); + enforce(property !== undefined, TypeError("HTML element does not provide 'data-property' attribute")); + + const newValue = this.parseValue(element, inverted); + this.actor.updateEmbeddedDocuments(documentName, [{ _id: id, [property]: newValue }]); + } + + /** + * Parses the value of the given {@link HTMLInputElement} depending on the element's type + * The value is parsed to: + * - checkbox: `boolean` + * - text input: `string` + * - number: `number` + * + * @param element - The input element to parse the value from + * @param inverted - Whether or not the value should be inverted + */ + protected parseValue(element: HTMLInputElement, inverted = false): boolean | string | number { + switch (element.type) { + case "checkbox": { + const value: boolean = element.checked; + return inverted ? !value : value; + } + case "text": { + const value: string = element.value; + return value; + } + case "number": { + const value = Number(element.value.trim()); + return value; + } + default: { + throw new TypeError( + "Binding of item property to this type of HTML element not supported; given: " + element, + ); + } } - const newValue = this.getValue(element, inverted); - this.actor.updateEmbeddedDocuments("ActiveEffect", [{ _id: id, [property]: newValue }]); } /** @@ -299,9 +311,7 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD event.preventDefault(); const id = $(event.currentTarget).parents(".item").data("itemId"); const item = this.actor.items.get(id); - if (!item) { - throw new Error(getGame().i18n.format("DS4.ErrorActorDoesNotHaveItem", { id, actor: this.actor.name })); - } + enforce(item, getGame().i18n.format("DS4.ErrorActorDoesNotHaveItem", { id, actor: this.actor.name })); item.roll().catch((e) => notifications.error(e, { log: true })); } @@ -323,7 +333,7 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD const check = target.dataset.check; if (!check) return super._onDragStart(event); - if (!isCheck(check)) throw new Error(getGame().i18n.format("DS4.ErrorCannotDragMissingCheck", { check })); + enforce(isCheck(check), getGame().i18n.format("DS4.ErrorCannotDragMissingCheck", { check })); const dragData = { actorId: this.actor.id, @@ -338,7 +348,7 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD /** @override */ protected async _onDropItem(event: DragEvent, data: ActorSheet.DropData.Item): Promise<unknown> { - const item = await DS4Item.fromDropData(data); + const item = await Item.fromDropData(data); if (item && !this.actor.canOwnItemType(item.data.type)) { notifications.warn( getGame().i18n.format("DS4.WarningActorCannotOwnItem", { diff --git a/src/module/settings.ts b/src/module/settings.ts index 96a86481..a2d1017e 100644 --- a/src/module/settings.ts +++ b/src/module/settings.ts @@ -5,10 +5,12 @@ import { getGame } from "./helpers"; export function registerSystemSettings(): void { + const game = getGame(); + /** * Track the migrations version of the latest migration that has been applied */ - getGame().settings.register("ds4", "systemMigrationVersion", { + game.settings.register("ds4", "systemMigrationVersion", { name: "System Migration Version", scope: "world", config: false, @@ -16,7 +18,7 @@ export function registerSystemSettings(): void { default: -1, }); - getGame().settings.register("ds4", "useSlayingDiceForAutomatedChecks", { + game.settings.register("ds4", "useSlayingDiceForAutomatedChecks", { name: "DS4.SettingUseSlayingDiceForAutomatedChecksName", hint: "DS4.SettingUseSlayingDiceForAutomatedChecksHint", scope: "world", @@ -25,7 +27,7 @@ export function registerSystemSettings(): void { default: false, }); - getGame().settings.register("ds4", "showSlayerPoints", { + game.settings.register("ds4", "showSlayerPoints", { name: "DS4.SettingShowSlayerPointsName", hint: "DS4.SettingShowSlayerPointsHint", scope: "world", @@ -42,9 +44,10 @@ export interface DS4Settings { } export function getDS4Settings(): DS4Settings { + const game = getGame(); return { - systemMigrationVersion: getGame().settings.get("ds4", "systemMigrationVersion"), - useSlayingDiceForAutomatedChecks: getGame().settings.get("ds4", "useSlayingDiceForAutomatedChecks"), - showSlayerPoints: getGame().settings.get("ds4", "showSlayerPoints"), + systemMigrationVersion: game.settings.get("ds4", "systemMigrationVersion"), + useSlayingDiceForAutomatedChecks: game.settings.get("ds4", "useSlayingDiceForAutomatedChecks"), + showSlayerPoints: game.settings.get("ds4", "showSlayerPoints"), }; } diff --git a/src/module/utils.ts b/src/module/utils.ts new file mode 100644 index 00000000..7c9c184e --- /dev/null +++ b/src/module/utils.ts @@ -0,0 +1,10 @@ +import { getGame } from "./helpers"; + +export function enforce(value: unknown, message?: string | Error): asserts value { + if (!value) { + if (!message) { + message = getGame().i18n.localize("DS4.ErrorUnexpectedError"); + } + throw message instanceof Error ? message : new Error(message); + } +} diff --git a/src/templates/sheets/actor/components/add-button.hbs b/src/templates/sheets/actor/components/add-button.hbs index 61dd303f..1fc86419 100644 --- a/src/templates/sheets/actor/components/add-button.hbs +++ b/src/templates/sheets/actor/components/add-button.hbs @@ -12,8 +12,8 @@ SPDX-License-Identifier: MIT !-- @param type: An optional property to use as data-type attribute }} <div> - <a class="control-{{documentType}} {{documentType}}-create" title="{{localize title}}" data-action="create" {{#if - type}}data-type="{{type}}" {{/if}}> + <a class="control-{{documentType}}" title="{{localize title}}" data-action="create" {{#if type}}data-type="{{type}}" + {{/if}}> <i class="fas fa-plus"></i> {{localize "DS4.UserInteractionAdd"}} </a> diff --git a/src/templates/sheets/actor/components/control-button-group.hbs b/src/templates/sheets/actor/components/control-button-group.hbs index 263a028e..89713898 100644 --- a/src/templates/sheets/actor/components/control-button-group.hbs +++ b/src/templates/sheets/actor/components/control-button-group.hbs @@ -7,14 +7,14 @@ SPDX-License-Identifier: MIT {{!-- !-- Render a group of an "edit" and a "delete" button. -!-- The current item is defined by the data-item-id HTML property of the parent li element. +!-- The current item is defined by the data-id attribute of the parent li element. !-- @param documentType: The type of document that is controlled by this button group, item or effect !-- @param editTitle: The title to use for the edit link element (will be localized) !-- @param deleteTitle: The title to use for the delete link element (will be localized) --}} <div class="ds4-control-button-group"> - <a class="ds4-control-button-group__button control-{{documentType}} {{documentType}}-edit" data-action="edit" + <a class="ds4-control-button-group__button control-{{documentType}}" data-action="edit" title="{{localize editTitle}}"><i class="fas fa-edit"></i></a> - <a class="ds4-control-button-group__button control-{{documentType}} {{documentType}}-delete" data-action="delete" + <a class="ds4-control-button-group__button control-{{documentType}}" data-action="delete" title="{{localize deleteTitle}}"><i class="fas fa-trash"></i></a> </div> diff --git a/src/templates/sheets/actor/components/currency.hbs b/src/templates/sheets/actor/components/currency.hbs index 99e70195..7635f91e 100644 --- a/src/templates/sheets/actor/components/currency.hbs +++ b/src/templates/sheets/actor/components/currency.hbs @@ -10,7 +10,7 @@ SPDX-License-Identifier: MIT <div class="ds4-currency"> {{#each data.data.currency as |value key|}} <label for="data.currency.{{key}}" class="flex05">{{lookup ../config.i18n.characterCurrency key}}</label> - <input class="ds4-currency__value ds4-currency__value--{{key}} item-change" type="number" min="0" step="1" + <input class="ds4-currency__value ds4-currency__value--{{key}} change-item" type="number" min="0" step="1" name="data.currency.{{key}}" id="data.currency.{{key}}" value="{{value}}" data-dtype="Number" /> {{/each}} </div> diff --git a/src/templates/sheets/actor/components/effect-list-entry.hbs b/src/templates/sheets/actor/components/effect-list-entry.hbs index 4d7243eb..9106ddfe 100644 --- a/src/templates/sheets/actor/components/effect-list-entry.hbs +++ b/src/templates/sheets/actor/components/effect-list-entry.hbs @@ -9,7 +9,7 @@ SPDX-License-Identifier: MIT !-- Render an effect list entry row. !-- @param effectData: The data of the item. --}} -<li class="ds4-effect-list__row effect" data-effect-id="{{effectData._id}}"> +<li class="ds4-effect-list__row effect" data-id="{{effectData._id}}"> {{!-- enabled --}} <input class="ds4-effect-list__editable ds4-effect-list__editable--checkbox change-effect" type="checkbox" {{checked (ne effectData.disabled true)}} data-dtype="Boolean" data-property="disabled" data-inverted="true" diff --git a/src/templates/sheets/actor/components/effect-list-header.hbs b/src/templates/sheets/actor/components/effect-list-header.hbs index 87ef2326..fdac8824 100644 --- a/src/templates/sheets/actor/components/effect-list-header.hbs +++ b/src/templates/sheets/actor/components/effect-list-header.hbs @@ -8,7 +8,7 @@ SPDX-License-Identifier: MIT {{!-- !-- Render an effect list header row. --}} -<li class="ds4-effect-list__row ds4-effect-list__row--header" data-effect-id="{{effectData._id}}"> +<li class="ds4-effect-list__row ds4-effect-list__row--header"> {{!-- enabled --}} <div title="{{localize 'DS4.EffectEnabled'}}">{{localize 'DS4.EffectEnabledAbbr'}}</div> diff --git a/src/templates/sheets/actor/components/item-list-entry.hbs b/src/templates/sheets/actor/components/item-list-entry.hbs index d4331243..01adc41d 100644 --- a/src/templates/sheets/actor/components/item-list-entry.hbs +++ b/src/templates/sheets/actor/components/item-list-entry.hbs @@ -15,10 +15,10 @@ SPDX-License-Identifier: MIT !-- @param hideDescription: A flag to disable the description column. !-- @param @partial-block: Custom column headers can be passed using the partial block. --}} -<li class="ds4-item-list__row item" data-item-id="{{itemData._id}}"> +<li class="ds4-item-list__row item" data-id="{{itemData._id}}"> {{!-- equipped --}} {{#if isEquipable}} - <input class="ds4-item-list__editable ds4-item-list__editable--checkbox item-change" type="checkbox" {{checked + <input class="ds4-item-list__editable ds4-item-list__editable--checkbox change-item" type="checkbox" {{checked itemData.data.equipped}} data-dtype="Boolean" data-property="data.equipped" title="{{localize 'DS4.ItemEquipped'}}"> {{/if}} @@ -30,12 +30,12 @@ SPDX-License-Identifier: MIT {{!-- amount --}} {{#if hasQuantity}} - <input class="ds4-item-list__editable item-change" type="number" min="0" step="1" value="{{itemData.data.quantity}}" + <input class="ds4-item-list__editable change-item" type="number" min="0" step="1" value="{{itemData.data.quantity}}" data-dtype="Number" data-property="data.quantity" title="{{localize 'DS4.Quantity'}}" /> {{/if}} {{!-- name --}} - <input class="ds4-item-list__editable item-change" type="text" value="{{itemData.name}}" data-dtype="String" + <input class="ds4-item-list__editable change-item" type="text" value="{{itemData.name}}" data-dtype="String" data-property="name" title="{{htmlToPlainText itemData.data.description}}" /> {{!-- item type specifics --}} diff --git a/src/templates/sheets/actor/components/items-overview.hbs b/src/templates/sheets/actor/components/items-overview.hbs index cdabde8f..049a1792 100644 --- a/src/templates/sheets/actor/components/items-overview.hbs +++ b/src/templates/sheets/actor/components/items-overview.hbs @@ -117,7 +117,7 @@ documentType='item' type='shield'}} {{#> systems/ds4/templates/sheets/actor/components/item-list-entry.hbs itemData=itemData isEquipable=true hasQuantity=true}} {{!-- storage location --}} - <input class="ds4-item-list__editable item-change" type="text" value="{{itemData.data.storageLocation}}" + <input class="ds4-item-list__editable change-item" type="text" value="{{itemData.data.storageLocation}}" data-dtype="String" data-property="data.storageLocation" title="{{localize 'DS4.StorageLocation'}}"> {{/systems/ds4/templates/sheets/actor/components/item-list-entry.hbs}} {{/each}} @@ -137,7 +137,7 @@ documentType='item' type='equipment'}} {{#each itemsByType.loot as |itemData id|}} {{#> systems/ds4/templates/sheets/actor/components/item-list-entry.hbs itemData=itemData hasQuantity=true}} {{!-- storage location --}} - <input class="ds4-item-list__editable item-change" type="text" value="{{itemData.data.storageLocation}}" + <input class="ds4-item-list__editable change-item" type="text" value="{{itemData.data.storageLocation}}" data-dtype="String" data-property="data.storageLocation" title="{{localize 'DS4.StorageLocation'}}"> {{/systems/ds4/templates/sheets/actor/components/item-list-entry.hbs}} {{/each}} diff --git a/src/templates/sheets/actor/components/talent-rank-equation.hbs b/src/templates/sheets/actor/components/talent-rank-equation.hbs index ce91c8b9..3480b5f1 100644 --- a/src/templates/sheets/actor/components/talent-rank-equation.hbs +++ b/src/templates/sheets/actor/components/talent-rank-equation.hbs @@ -18,7 +18,7 @@ disable the input element !-- @param localizeString: The string to use as key for the localized tooltip --}} {{#*inline "talentRankValue"}} -<input class="ds4-talent-rank-equation__value item-change" data-dtype="Number" type="number" min="0" step="1" {{#if (eq +<input class="ds4-talent-rank-equation__value change-item" data-dtype="Number" type="number" min="0" step="1" {{#if (eq property 'base' ) }}max="{{talentRank.max}}" {{/if}} {{disabled}} data-property="data.rank.{{property}}" value="{{lookup talentRank property}}" title="{{localize localizeString}}" /> {{/inline}} diff --git a/src/templates/sheets/actor/tabs/spells.hbs b/src/templates/sheets/actor/tabs/spells.hbs index d683f340..c3b5314f 100644 --- a/src/templates/sheets/actor/tabs/spells.hbs +++ b/src/templates/sheets/actor/tabs/spells.hbs @@ -76,7 +76,7 @@ titleKey=titleKey}} title="{{lookup ../../config.i18n.spellTypes itemData.data.spellType}}" /> {{!-- spell bonus --}} - <input class="ds4-item-list__editable item-change" type="text" data-dtype="String" data-property="data.bonus" + <input class="ds4-item-list__editable change-item" type="text" data-dtype="String" data-property="data.bonus" value="{{itemData.data.bonus}}" title="{{localize 'DS4.SpellBonus'}}" /> {{!-- max. distance --}}