Using JavaScript, we can make our own live-editing functionality without the use of Blade’s @liveAttribute() method and Kanka’s standard modals. For instance, you can make checkboxes that immediately update the entity when ticked and unticked directly on the sheet. Here is a helpful wrapper function that assumes you use the attribute dump provided by my tutorial to locate the appropriate API URL.
// Wrapper function for updating attribute values through the API
function postLiveEdit (name, value) {
axios.post(attributes[name].apis.update.url, new URLSearchParams({value: value})).then(res => {
// Update the local value of the attribute in the dump
attributes[name].value = value;
/* Any additional processing can be done here, e.g. cascading changes to other parts of the sheet */
// Notify user; for iframe-based transclusions, send it to the parent window
let message = "<em>" + attributes[name].name.replace(/\[range:.*\]/g, "") + "</em> updated successfully";
(document.querySelector(".toast-container")) ? window.showToast(message) : window.parent.showToast(message);
}).catch(err => {
// Notify user; for iframe-based transclusions, send it to the parent window
let message = "Failed to update <em>" + attributes[name].name.replace(/\[range:.*\]/g, "") + "</em> (error code: " + err.status + ")";
(document.querySelector(".toast-container")) ? window.showToast(message) : window.parent.showToast(message);
});
}
Using this, you only need to provide a name (attribute slug) and value any time you wish to update an attribute. Here is an example from my Daggerheart character sheet, where I have groups of checkboxes wrapped in a div with a data-stat attribute that specifies the slug. My script runs through all such divs and creates an event listener on each of them:
// Watch live attribute containers to update their related attribute on change
document.querySelectorAll('.daggerheart [data-stat]').forEach( (liveAtt) => {
let attributeName = liveAtt.dataset.stat;
// React to clicks
liveAtt.addEventListener("click", (event) => {
let numTicked;
/* A bunch of processing occurs here to determine the new value based on what exactly was clicked within the div */
// Update server-side attribute
postLiveEdit(attributeName, numTicked);
});
});
You can also very easily create new attributes on the entity programmatically:
Only the name is mandatory; see the API docs for all possible parameters, such as each type_id.
Likewise, you can easily delete an existing attribute with a simple post to the corresponding URL, should the need arise (though you should have a very good reason to do so):
axios.post(attributes.slug.apis.delete.url);
Watch this space for a way to live-update ability charges through the API.