data binding for owned item properties
Additions: - now also text, number, and range input fields of owned items can be bound to HTML (input) elements of the char sheet Changes: - moved prototype handle for checkboxes to own function - replaced some static HTML elements in item list with input fields - item-num-val HTML elements (e.g. item quantity) now have a max-width
This commit is contained in:
parent
5d83e26e81
commit
d8423ce364
3 changed files with 100 additions and 33 deletions
|
@ -62,12 +62,7 @@ export class DS4ActorSheet extends ActorSheet<DS4ActorDataType, DS4Actor, DS4Ite
|
|||
li.slideUp(200, () => this.render(false));
|
||||
});
|
||||
|
||||
html.find(".item-equip").on("click", (ev) => {
|
||||
const id = $(ev.currentTarget).parents(".item").data("itemId");
|
||||
const item = duplicate(this.actor.getOwnedItem(id)); // getOwnedItem is typed incorrectly, it actually returns a ItemData<DS4ItemDataType>, not an Item
|
||||
setProperty(item, "data.equipped", !getProperty(item, "data.equipped")); // TODO: use "."" accessors instead, once typing has been fixed
|
||||
this.actor.updateOwnedItem(item);
|
||||
});
|
||||
html.find(".item-change").on("change", this._onItemChange.bind(this));
|
||||
|
||||
// Rollable abilities.
|
||||
html.find(".rollable").click(this._onRoll.bind(this));
|
||||
|
@ -102,6 +97,67 @@ export class DS4ActorSheet extends ActorSheet<DS4ActorDataType, DS4Actor, DS4Ite
|
|||
return this.actor.createOwnedItem(itemData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle changes to properties of an Owned Item from within character sheet.
|
||||
* Can currently properly bind: checkboxes, text/number/range input.
|
||||
* Assumes the item property is given as the value of the HTML element property 'data-property'.
|
||||
* @param {Event} ev The originating change event
|
||||
* @private
|
||||
*/
|
||||
private _onItemChange(ev: JQuery.ChangeEvent<HTMLFormElement>): void {
|
||||
ev.preventDefault();
|
||||
console.log("Current target:", $(ev.currentTarget).get(0)["name"]);
|
||||
const el: HTMLFormElement = $(ev.currentTarget).get(0);
|
||||
const id = $(ev.currentTarget).parents(".item").data("itemId");
|
||||
const item = duplicate(this.actor.getOwnedItem(id)); // getOwnedItem is typed incorrectly, it actually returns a ItemData<DS4ItemDataType>, not an Item
|
||||
const property: string = $(ev.currentTarget).data("property");
|
||||
let newValue;
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
// One needs to differentiate between e.g. checkboxes (value="on") and select boxes etc.
|
||||
// Checkbox:
|
||||
if (el.type === "checkbox") {
|
||||
newValue = el.checked; //!getProperty(item, property);
|
||||
}
|
||||
|
||||
// Text input:
|
||||
else if (el.type === "text") {
|
||||
newValue = el.value;
|
||||
}
|
||||
|
||||
// Numbers and ranges:
|
||||
else if (["number", "range"].includes(el.type)) {
|
||||
newValue = el.value.trim();
|
||||
}
|
||||
|
||||
// // Radio Checkboxes (untested, cf. FormDataExtended.process)
|
||||
// else if (el.type === "radio") {
|
||||
// const chosen: HTMLFormElement = el.find((r: HTMLFormElement) => r["checked"]);
|
||||
// newValue = chosen ? chosen.value : null;
|
||||
// }
|
||||
|
||||
// // Multi-Select (untested, cf. FormDataExtended.process)
|
||||
// else if (el.type === "select-multiple") {
|
||||
// newValue = [];
|
||||
// el.options.array.forEach((opt: HTMLOptionElement) => {
|
||||
// if (opt.selected) newValue.push(opt.value);
|
||||
// });
|
||||
|
||||
// unsupported:
|
||||
else {
|
||||
throw TypeError("Binding of item property to this type of HTML element not supported; given: " + el);
|
||||
}
|
||||
setProperty(item, property, newValue);
|
||||
this.actor.updateOwnedItem(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle clickable rolls.
|
||||
* @param {Event} event The originating click event
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
.item-num-val {
|
||||
text-align: center;
|
||||
max-width: 2.5em;
|
||||
}
|
||||
|
||||
.item-description {
|
||||
|
|
|
@ -16,10 +16,12 @@
|
|||
<div class="item-name flex3">{{localize 'DS4.ItemName'}}</div>
|
||||
<div title="{{localize 'DS4.AttackType'}}">{{localize 'DS4.AttackTypeAbbr'}}</div> {{!-- SPECIFIC --}}
|
||||
<div class="flexrow flex15">
|
||||
<div class="item-num-val" title="{{localize 'DS4.WeaponBonus'}}">{{localize 'DS4.WeaponBonusAbbr'}}
|
||||
<div class="item-num-val" title="{{localize 'DS4.WeaponBonus'}}">
|
||||
{{localize 'DS4.WeaponBonusAbbr'}}
|
||||
</div> {{!-- SPECIFIC --}}
|
||||
<div class="item-num-val" title="{{localize 'DS4.OpponentDefense'}}">
|
||||
{{localize 'DS4.OpponentDefenseAbbr'}}
|
||||
</div> {{!-- SPECIFIC --}}
|
||||
<div class="item-num-val" title="{{localize 'DS4.OpponentDefense'}}">{{localize
|
||||
'DS4.OpponentDefenseAbbr'}}</div> {{!-- SPECIFIC --}}
|
||||
</div>
|
||||
<div class="flex4">{{localize 'DS4.Description'}}</div>
|
||||
{{!-- add button --}}
|
||||
|
@ -34,18 +36,19 @@
|
|||
<li class="item flexrow" data-item-id="{{item._id}}">
|
||||
<div class="flexrow flex15">
|
||||
{{!-- equipped? --}}
|
||||
{{#if itemData.equipped}}<i class="fas fa-check-square item-equip"></i>
|
||||
{{else}}<i class="far fa-square item-equip"></i>
|
||||
{{/if}} {{!--SPECIFIC --}}
|
||||
<input class="item-change" type="checkbox" {{checked itemData.equipped}} data-dtype="Boolean"
|
||||
data-property="data.equipped" title="{{localize 'DS4.ItemEquipped'}}"> {{!--SPECIFIC --}}
|
||||
{{!-- image --}}
|
||||
<div class="item-image">
|
||||
<img src="{{item.img}}" title="{{item.name}}" width="24" height="24" />
|
||||
</div>
|
||||
{{!-- amount --}}
|
||||
<div class="item-num-val">{{itemData.quantity}}</div>
|
||||
<input type="number" class="item-num-val item-change" value="{{itemData.quantity}}" data-dtype="Number"
|
||||
data-property="data.quantity" title="{{localize 'DS4.Quantity'}}">
|
||||
</div>
|
||||
{{!-- name --}}
|
||||
<h4 class="item-name flex3">{{item.name}}</h4>
|
||||
<input type="text" class="item-name flex3 item-change" value="{{item.name}}" data-dtype="String"
|
||||
data-property="name" title="{{localize 'DS4.ItemName'}}">
|
||||
{{!-- item specifics --}}
|
||||
<div>
|
||||
<img src="{{lookup ../../config.attackTypesIcons itemData.attackType}}"
|
||||
|
@ -96,18 +99,19 @@
|
|||
<li class="item flexrow" data-item-id="{{item._id}}">
|
||||
<div class="flexrow flex15">
|
||||
{{!-- equipped? --}}
|
||||
{{#if itemData.equipped}}<i class="fas fa-check-square item-equip"></i>
|
||||
{{else}}<i class="far fa-square item-equip"></i>
|
||||
{{/if}} {{!--SPECIFIC --}}
|
||||
<input class="item-change" type="checkbox" {{checked itemData.equipped}} data-dtype="Boolean"
|
||||
data-property="data.equipped" title="{{localize 'DS4.ItemEquipped'}}"> {{!--SPECIFIC --}}
|
||||
{{!-- image --}}
|
||||
<div class="item-image">
|
||||
<img src="{{item.img}}" title="{{item.name}}" width="24" height="24" />
|
||||
</div>
|
||||
{{!-- amount --}}
|
||||
<div class="item-num-val">{{itemData.quantity}}</div>
|
||||
<input type="number" class="item-num-val item-change" value="{{itemData.quantity}}" data-dtype="Number"
|
||||
data-property="data.quantity" title="{{localize 'DS4.Quantity'}}">
|
||||
</div>
|
||||
{{!-- name --}}
|
||||
<h4 class="item-name flex3">{{item.name}}</h4>
|
||||
<input type="text" class="item-name flex3 item-change" value="{{item.name}}" data-dtype="String"
|
||||
data-property="name" title="{{localize 'DS4.ItemName'}}">
|
||||
{{!-- item specifics --}}
|
||||
<div title="{{lookup ../../config.armorMaterialTypes itemData.armorMaterialType}}">
|
||||
{{lookup ../../config.armorMaterialTypesAbbr itemData.armorMaterialType}}
|
||||
|
@ -154,18 +158,19 @@
|
|||
<li class="item flexrow" data-item-id="{{item._id}}">
|
||||
<div class="flexrow flex15">
|
||||
{{!-- equipped? --}}
|
||||
{{#if itemData.equipped}}<i class="fas fa-check-square item-equip"></i>
|
||||
{{else}}<i class="far fa-square item-equip"></i>
|
||||
{{/if}} {{!--SPECIFIC --}}
|
||||
<input class="item-change" type="checkbox" {{checked itemData.equipped}} data-dtype="Boolean"
|
||||
data-property="data.equipped" title="{{localize 'DS4.ItemEquipped'}}"> {{!--SPECIFIC --}}
|
||||
{{!-- image --}}
|
||||
<div class="item-image">
|
||||
<img src="{{item.img}}" title="{{item.name}}" width="24" height="24" />
|
||||
</div>
|
||||
{{!-- amount --}}
|
||||
<div class="item-num-val">{{itemData.quantity}}</div>
|
||||
<input type="number" class="item-num-val item-change" value="{{itemData.quantity}}" data-dtype="Number"
|
||||
data-property="data.quantity" title="{{localize 'DS4.Quantity'}}">
|
||||
</div>
|
||||
{{!-- name --}}
|
||||
<h4 class="item-name flex3">{{item.name}}</h4>
|
||||
<input type="text" class="item-name flex3 item-change" value="{{item.name}}" data-dtype="String"
|
||||
data-property="name" title="{{localize 'DS4.ItemName'}}">
|
||||
{{!-- item specifics --}}
|
||||
<div class="flex05 item-num-val">{{itemData.armorValue}}</div> {{!-- SPECIFIC --}}
|
||||
{{!-- description --}}
|
||||
|
@ -204,20 +209,22 @@
|
|||
<li class="item flexrow" data-item-id="{{item._id}}">
|
||||
<div class="flexrow flex15">
|
||||
{{!-- equipped? --}}
|
||||
{{#if itemData.equipped}}<i class="fas fa-check-square item-equip"></i>
|
||||
{{else}}<i class="far fa-square item-equip"></i>
|
||||
{{/if}} {{!--SPECIFIC --}}
|
||||
<input class="item-change" type="checkbox" {{checked itemData.equipped}} data-dtype="Boolean"
|
||||
data-property="data.equipped" title="{{localize 'DS4.ItemEquipped'}}"> {{!--SPECIFIC --}}
|
||||
{{!-- image --}}
|
||||
<div class="item-image">
|
||||
<img src="{{item.img}}" title="{{item.name}}" width="24" height="24" />
|
||||
</div>
|
||||
{{!-- amount --}}
|
||||
<div class="item-num-val">{{itemData.quantity}}</div>
|
||||
<input type="number" class="item-num-val item-change" value="{{itemData.quantity}}" data-dtype="Number"
|
||||
data-property="data.quantity" title="{{localize 'DS4.Quantity'}}">
|
||||
</div>
|
||||
{{!-- name --}}
|
||||
<h4 class="item-name flex3">{{item.name}}</h4>
|
||||
<input type="text" class="item-name flex3 item-change" value="{{item.name}}" data-dtype="String"
|
||||
data-property="name" title="{{localize 'DS4.ItemName'}}">
|
||||
{{!-- storage location --}}
|
||||
<div class="flex2">{{{itemData.storageLocation}}}</div> {{!-- SPECIFIC --}}
|
||||
<input type="text" class="flex2 item-change" value="{{itemData.storageLocation}}" data-dtype="String"
|
||||
data-property="data.storageLocation" title="{{localize 'DS4.StorageLocation'}}"> {{!-- SPECIFIC --}}
|
||||
{{!-- description --}}
|
||||
<div class="flex4 item-description">{{{itemData.description}}}</div>
|
||||
{{!-- edit & delete buttons --}}
|
||||
|
@ -257,12 +264,15 @@
|
|||
<img src="{{item.img}}" title="{{item.name}}" width="24" height="24" />
|
||||
</div>
|
||||
{{!-- amount --}}
|
||||
<div class="item-num-val">{{itemData.quantity}}</div>
|
||||
<input type="number" class="item-num-val item-change" value="{{itemData.quantity}}" data-dtype="Number"
|
||||
data-property="data.quantity" title="{{localize 'DS4.Quantity'}}">
|
||||
</div>
|
||||
{{!-- name --}}
|
||||
<h4 class="item-name flex3">{{item.name}}</h4>
|
||||
<input type="text" class="item-name flex3 item-change" value="{{item.name}}" data-dtype="String"
|
||||
data-property="name" title="{{localize 'DS4.ItemName'}}">
|
||||
{{!-- storage location --}}
|
||||
<div class="flex2">{{{itemData.storageLocation}}}</div> {{!-- SPECIFIC --}}
|
||||
<input type="text" class="flex2 item-change" value="{{itemData.storageLocation}}" data-dtype="String"
|
||||
data-property="data.storageLocation" title="{{localize 'DS4.StorageLocation'}}"> {{!-- SPECIFIC --}}
|
||||
{{!-- description --}}
|
||||
<div class="flex4 item-description">{{{itemData.description}}}</div>
|
||||
{{!-- edit & delete buttons --}}
|
||||
|
|
Loading…
Reference in a new issue