Creating an interim TJSDocument / document attribute bridge
Hi @wasp... Just moving discussion here as it is a better forum post.
So I have made a system with TRL for my friend's homebrew game system, and I'm working on getting document updates to work. Binding values of inputs directly to the TJSDocument isn't yet supported, so this is what I cooked up thus far:
Is this in line what is expected, pretty much?
10 Replies
It might be a good starter to review the TJSDocument code:
https://github.com/typhonjs-fvtt-lib/svelte/blob/main/src/store/document/TJSDocument.js
It is a custom store, so you can directly access attributes from the TJSDocument instance itself and there is no reason to use
get
from svelte/store
. In general, except for the very rare case usage of get
is an anti-pattern and one that can be avoided with custom stores. It has limited use for when you directly use writable
or a basic Svelte store, but even then is a sign of code that can be revised.
Another aspect to consider is being careful in naming variables. By using const document
you override the browser document reference, so that is something to just keep in mind if you ever need to use it inside of a Svelte component, so it is generally recommended to use doc
or some other variable name for the TJSDocument instance.
Another aspect to consider with the above approach is perhaps debouncing the updateDocument
function so that not every single change hits the underlying update cycle to the Foundry document.
Your code rewritten with the initial changes without the debounce aspect will look like this:
Thanks, very useful!
I'm writing a Svelte action that does some fancy stuff for updating that I'll post in just a bit. Not exactly the solution I'll be employing in TRL to handle all of this, but a useful interim.
OK... Here is a basic change event Svelte action that can be reused across input / select / text area elements. Granted I haven't tested it thoroughly and there is always more one can do. Read up on change event as it only fires at certain points like an input element losing focus or Enter key pressed of standard input elements. This is what Foundry uses though as well for standard sheets.
This is a good opportunity to learn about Svelte actions. https://svelte.dev/tutorial/actions
Use it like this:
accessor
should be a .
separated string with the attribute field you are reading / updating.
Here is a brief example with the "Hello World demo" modified like above:Look at that beauty
Looks like 0.0.24 material to me 😄
It's certainly one way of handling document updates specifically around change events. I'm going to be hard pressed just to finish the API refactoring / API docs before
0.0.24
drops. I'm working remotely from mid-July through October and won't have as much time to work on TRL during that time though probably a little bit.
This is one handy way to use a Svelte action though that can be repeatedly applied. The problem with getting that into 0.0.24
is that it should be thoroughly tested against a variety of input sources / checkboxes, etc. and I'm definitely not going to have time for that. Perhaps if you can give it a go and start working w/ this action and finding any corner cases it could possibly be included.
In the future I'd like to get more of a reactive solution in place where on going input updates the underlying document as well instead of change events.I'll definitely test it out and see what edge cases emerge - my friend's system is entirely homebrew and made by him and his friends, so it's very low-stakes to work on, which is nice 😄
Very cool.. Yeah I'll point folks to this post as it'll likely be handy for others too.
It should be noted that there is no handling at all for many edge cases like when the underlying document is deleted for instance. Ideally though as the developer you can handle that in other ways; all of this will be much smoother in a forthcoming TRL release.
I implemented this pretty neatly, thanks for this! I added a check so that it can be used with checkboxes and such too:
so that the value can be gotten like this:
Excellent. Yeah there will be a few tweaks for sure. The
default
case of the switch should also fall through to value
as an input element without a type is a text input, but I suppose you don't have to add that as valueKey
is "value" to begin with. Perhaps you just have to add the cases where it will change, etc.
I assume that there also need to be some changes on how checkbox
inputs are set from doc values in onDocChange
.
I will consider adding this action in a future TRL update, but I'd like to thoroughly evaluate all input element types.
This action approach is useful when directly using forms / input elements to modify document contents.
The 2nd half of the TJSDocument work and building managed stores for document attributes for "real time" reactive updates is definitely more involved, but will allow access to stores in a managed way similar to the reactive embedded collections API.