Updating Currency Format Dynamically
I have a
opening_balance
field that is supposed to dynamically update as soon as the state of another field is updated, but I can't get it to update quickly enough. I can only get it to update after the Form is created or edited but not while editing. It is kind of hard to set the opening balance field in this context so I am not sure what I could do. I need help please. If nothing I can do it is okay because it still works after creation, etc. But would still be nice.53 Replies
Can you clarify some please? The snippet you sent has a currency_code field that seems unrelated to your question about your opening_balance. What field affects the opening_balance? Maybe I'm not seeing the entire code block?
Yes, I will clarify. The TextInput Mask's pattern block options for
opening_balance
are dynamically set based on the chosen value of the currency_code
field (it's changed state). For example, a user selects the option "USD" for the currency_code
field. Now that "USD" is selected, the pattern block configuration should change based on the "USD" value. The configuration values come from the akaunting/laravel-money
package.Ahh...I see that now...sorry
All good, everything works great but only after the form is reloaded (e.g. after creation, or editing)
Having the mask's values update automatically after changing the currency_code value/state would be nice...
I actually thought about making something like this a plugin, but unless I can figure this out I am not sure
...checking...
I couldn't get it to work. I think ultimately it's because alpine isn't receiving the updated configuration. I think you'd have to entangle the configuration for it to react to your changes.
Ok just thought of and kind of tested a REALLY hacky work around (assuming I'm fully understanding your requirements). Create two duplicate input fields, and then toggle their visibility between each select update. This will force the new one to be added to the DOM with the new configuration. You can even maintain whatever value is in
opening_balance
using afterStateUpdated()
on your select. You need to name each input differently, but you can handle the different inputs in the handleRecordCreation
method. I mean talk about a hack! (Please let there be a better way! 🤣)Could you show me what you specifically mean by the two input fields?
Or like an example would be cool
Here's a demo video...is this what you mean:
That is exactly what I mean
Ok hold on
Ok so a few things:
I'm setting visible based on the currency code just for the demo BUT you wouldn't want to do that.
You'd want to set some type of on/off flag and then just switch between the two
You could probably set a flag somewhere, and then in the
afterStateUpdated()
method just toggle that on each change,
And then if you need the balance you need to swap between getting and setting the balances depending on what flag is set
The above code was really just to get a quick demo workingOkay I will try with what you gave me, I really appreciate your help! This will be great if it works
The nice thing is you really don't visually see the inputs being swapped out. It's hacky behind the scenes but to the end user I don't know if they'd notice
Updated the notes above a bit for clarity
Okay so this works but only when there are 2 options, which for you would be dollar and euro. There are essentially hundreds a user can choose from so I can't use for example:
For one text input, and:
How else could I handle this do you think?
Yes, that's why you need to use a flag and then by toggling the flag it'll just swap the inputs.
Hmm maybe I am not sure I have used such flags before
What we're trying to accomplish is just swapping the fields so that it'll load the new configuration, whatever that configuration could be.
Hold on.
I think I got it
This seems to work:
For one of them:
And the other:
I'm sure there is a better way though
That seems like a viable option. I like it too since it won't unnecessarily swap out the balance if the same code is already selected.
I guess this is really the only way for right now.
Now watch Dan come in here and give an awesome one liner!!!!!!!! 🤣
I hope so
I wonder if its something to do with the imask library but idk
But I think this is the only way currently since the real problem is that the mask in alpine doesn't get reloaded. We need to force the reload
I'm testing it out right now and it seems like the max amount of times I can switch the option is like 3 times. After that it doesn't reload anymore. Better than nothing though!
Then that's probably related to referencing the currency code. Try setting a hidden input:
hidden::make('flag')->default(true)
and then in afterStateUpdated()
toggle it ($set('flag', ! $get('flag'))
and then reference that in your visible ->visible(fn (Closure $get) => $get('flag'))
and ->visible(fn (Closure $get) => ! $get('flag'))
You might need to be specific about (bool) $get('flag')
and ! (bool) $get('flag')
since I think the inputs are strings.
You know what we really need is a refresh()
method on inputs that would reload them for usJust verified that, for example: If it was "USD", changing it to "EUR" would make it reload, but then I have to switch back to "USD" again for a different option to be reloaded again before switching. So I can't do: Switch from USD to EUR, then EUR to AUD, I have to do a Switch from USD to EUR, then back to USD then to AUD.
Agreed
Are you sure...I got it working for me to switch however i wanted it to
I'm just using and array of 0,1,2,3,4,5, but the concept is the same. It switches however it needs too
The number is the currency code that is set in
->pattern()
Hmm can I see your updated version?
Hmm this worked but removed the value in the field on some currencies. Weird.
You mean the amount in the balance?
Yeah
Yeah, that's what I was referencing earlier that I think you have to swap the get/set balance. So something like:
(or maybe the other way around).
If not then it'll override with the incoming input field that is blank
Do you think this is a reliable way to do this though? 😂 I mean yeah some of these work, but idk if its something I would commit to github for my application.
It was the other way around for me:
Damn sure as hell hack tho
haha! I don't blame you!
Huge hack!
Changing Filament forever haha
I appreciate your help man, hopefully Dan can come in here and show an easy fix. If not then I might just have to go with the hack 👍
But hey...I found this comment in the Filament docs today:
I think we all have code like this!
Just add a comment so at least people know that YOU KNOW its a hack!!!!
True true
And the idea of the hidden input actually came from my work on the ToggleColumn that was causing problems. There was a hidden input they were using there to store state...so it's not too far out there. (thankfully we were able to get rid of all of that)
I think its something to do with the Imask library though, I saw related issues on the filament github thread.
At the least this is a cool record of some killer collaboration on solving a problem!
Yeah I was thinking the same thing.
Come save us Super Dan!
Night
You too
yeah i dont know, i would stay away from the masking feature completely and just use prefix() for the currency symbol
Hmm alright. I was wondering, I guess will the same library be used for V3? I wonder if there is something like the
akaunting/laravel-money
package (Filament's TextColumn
option money()
) but for the TextInput
field instead...if it works better in livewire 3, we will keep it. if not, we will replace it.
Okay thanks
Please tell me you used our hack! 🤣🤣🤣🤣
Haha still deciding