F
Filament3mo ago
SirFat

Form Design/Implementation Guidance Question

Hi, before I delve too far in experimentation, I'm curious as to whether anyone has an idea on approach. I want to create three HTML / Blade based panels which are clickable (and perhaps can be 'highlighted') that sets a variable accessible to the rest of the form and can behave in a live wire component/page. Use case: What type of cell service would you like?
[ IOT ] [ Data only ] [ Voice and Data ] <-- each of those panels are preferably driven from a blade When clicked, the clicked panel is clearly selected and sets a variable that subsequent parts of the form using ->hidden Closures can read and react to. Thoughts?
58 Replies
SirFat
SirFat3mo ago
Perhaps I'll ask a different question, is there any special trick to setting a variable using javascript that is available to the livewire component and can make it 'react'?
SirFat
SirFat3mo ago
cheers will haev a look OK, So I've managed to set the variable easy enough, but I have both the ViewField and the associated TextField with live() - But how do I instruct Livewire to act upon the variable change?
<div>
<div class="flex border-amber-800" onclick="setField()">
My test box
</div>
</div>

<script>
function setField() {
let component = Livewire.first()
alert("hello chopper");
component.set("test_field", "banana");
alert(component.get("test_field"));
component.set("test_field", "test");
alert(component.get("test_field"));
}
</script>
<div>
<div class="flex border-amber-800" onclick="setField()">
My test box
</div>
</div>

<script>
function setField() {
let component = Livewire.first()
alert("hello chopper");
component.set("test_field", "banana");
alert(component.get("test_field"));
component.set("test_field", "test");
alert(component.get("test_field"));
}
</script>
->schema([
ViewField::make("plan_details")
->view('forms.components.orders.technology-selection')
->live()
->viewData([
]),
Hidden::make("test_field"),
TextInput::make('imei_field')->required(),
TextInput::make('test_input_field')->hidden(fn(Get $get) :bool => $get("test_field") == "")->live()
])
->schema([
ViewField::make("plan_details")
->view('forms.components.orders.technology-selection')
->live()
->viewData([
]),
Hidden::make("test_field"),
TextInput::make('imei_field')->required(),
TextInput::make('test_input_field')->hidden(fn(Get $get) :bool => $get("test_field") == "")->live()
])
Because once I get that bit sorted, I'll be able to expand out the 'test box' into my separate boxes to allow the user to select the 'technology' that can then drive the rest of the form I've added a second step to see if the variable is actually being sent back to the server, and it would appear not.
Step::make('Next Page')
->schema([
ViewField::make("test_details")
->view('forms.components.orders.test-page-2')
->live()
->viewData([
"my_field" => function (Get $get): string {
return $get("test_field")??"";
}
]),
])
Step::make('Next Page')
->schema([
ViewField::make("test_details")
->view('forms.components.orders.test-page-2')
->live()
->viewData([
"my_field" => function (Get $get): string {
return $get("test_field")??"";
}
]),
])
(as usual I'm well out of my comfort zone =] )
awcodes
awcodes3mo ago
Can you verify that Livewire.first() is the correct Lw component?
SirFat
SirFat3mo ago
should only be one on the page, I presume I could alert component.name or something to that effect? apparently not name 😉
SirFat
SirFat3mo ago
No description
awcodes
awcodes3mo ago
I’m just thinking an actual listener and event might be better here.
SirFat
SirFat3mo ago
Possibly so, I'm somewhat clutching at straws. Did my use case make sense?
awcodes
awcodes3mo ago
Not totally. Lol. Sorry.
SirFat
SirFat3mo ago
all good, why I asked 🙂 OK, So you've seen my ordering page, I'm changing it up a little because I'm now dealing with IoT and Mobility Services. I want the user to start with a screen which says "Which Technology are you after" There will be three Div / html panels in front of them [ IOT ] [ Data ] [ voice/data ] when they click one of those, I want that to make the next part of the form appear, which will then be customised based on that selection
awcodes
awcodes3mo ago
Instead of the script tag, why not just make it an alpine component, since it can interact with livewire directly.
SirFat
SirFat3mo ago
Because I've never made one =]
awcodes
awcodes3mo ago
If you do it as a custom field then you can entangle the state via alpine that will allow it’s value to be used by live(), $get and $set out of the box.
SirFat
SirFat3mo ago
as in the HTML component?
SirFat
SirFat3mo ago
Would you suggest 1 or 3 coffees?
awcodes
awcodes3mo ago
It’s really not that bad.
SirFat
SirFat3mo ago
haha all good, just stirring. As you know, everything I seem to decide to do is a learning curve =]
awcodes
awcodes3mo ago
Understandable. Can be tricky at first.
SirFat
SirFat3mo ago
Cool. I'll give that route a go and see where I end up. But yeah, Sounds like custom field if that gets live() and get / set, that's essentially the interactivity I'm after because I'll then on the next page have a dynamic list of plans that need to do a similar thing.
awcodes
awcodes3mo ago
Just take it step by step. Realistically what you’re after is just a more stylistic radio group. 3 options. So, is just a form field. Since the form fields state can be entangled via alpine, any changes to the field can be “heard” just like any other field that uses live()
SirFat
SirFat3mo ago
Yeah, that is precisely the best way to describe it, stylistic radio group and the custom field would represent the entire group or just one of the items?
awcodes
awcodes3mo ago
And if you don’t need to store that fields value you can just do ->dehydrated(false) then it will all work as a trigger and not a record data point.
SirFat
SirFat3mo ago
Yeah, so out of the box stuff
awcodes
awcodes3mo ago
The entire group in my opinion. That’s how radios work. Only one option can be selected at a time.
SirFat
SirFat3mo ago
Yep, cool. Sounds like a good challenge, but if I can get it working will be useful for the rest of this exercise 🙂 cheers - as usual =]
awcodes
awcodes3mo ago
Stylized radios that don’t look like radios but are still semantic and accessible. For inspiration.
SirFat
SirFat3mo ago
the 'cards' ?
awcodes
awcodes3mo ago
Yep. Look at the code. It’s just normal radio fields. May need an account to see the code though. Sorry.
SirFat
SirFat3mo ago
That's OK 🙂
awcodes
awcodes3mo ago
But it’s just an example of how you can style normal radio inputs to look different.
SirFat
SirFat3mo ago
So would that still suggest the custom field route, or just a normal radio group and style over it?
awcodes
awcodes3mo ago
It’s still a custom field route. Because you need the custom blade view.
SirFat
SirFat3mo ago
Gotcha
awcodes
awcodes3mo ago
And you have to entangle the state back to form.
SirFat
SirFat3mo ago
Guess i'll start with the custom field with just a normal radio group, get that interacting properly and then overlay the pretty stuff
awcodes
awcodes3mo ago
That sounds like a good plan.
SirFat
SirFat3mo ago
entangling is a new concept to me also - I presume the 'How fields work' is the area to focus on
awcodes
awcodes3mo ago
Yea.
SirFat
SirFat3mo ago
<div x-data="{ state: $wire.$entangle('name') }"> <input x-model="state" /> <--- presume this is the radio group </div> and I presume that's setting 'name' with the result of the input output? and passing that back as state
awcodes
awcodes3mo ago
Yep, but you don’t want to hardcode ‘name’ You can use ‘$getStatePath()’ to entangle it dynamically.
SirFat
SirFat3mo ago
Yep was just reading up on that bit so then it honors whatever is in the inner input field and passes it back as-is I presume
awcodes
awcodes3mo ago
‘name’ in this case would be the value used in ::make() in the form schema. Yep.
SirFat
SirFat3mo ago
Perfect. OK. That makes sense. Yeah will start simple to get the concept working. Wish me luck!
awcodes
awcodes3mo ago
You got this. 💪
SirFat
SirFat3mo ago
heh cheers dude - you're getting one heck of a Xmas card at this point with the amount of times you've pointed me in the right direction (c: Is there a trick within the blade/custom field to ensure the field is accessible via Get? I was able to use child components to reuse Filament fields versus build my own within the Custom field, I can see 'state' and 'old' state in what his 'afterStateUpdated', but the subsequent live check returns null on the $get attempt. I can however, find the data within the 'data' array.
awcodes
awcodes3mo ago
What? Lol.
SirFat
SirFat3mo ago
SirFat
SirFat3mo ago
That might make it easier to understand my gibberish 😛 In TextInput::make('test_input_field') - the value of the Radio 'status' is accessible via $this->data["select_tech"]["status"] but not via $get("status")
awcodes
awcodes3mo ago
$get(‘select_tech.status’) The form data is a traversable tree. Could even be $get(‘../select_tech.status’) for example. You just to figure out the right traversal for the form’s data. Ie, if you’re in a repeater for example to access form data out side of the repeater you have to traverse outside the repeater with the ‘../‘ syntax
SirFat
SirFat3mo ago
gotcha that makes sense
awcodes
awcodes3mo ago
Very similar to directory traversal.
SirFat
SirFat3mo ago
is it a matter of experimentation or if I have xdebug and a breakpoint, should I just be looking at the structure of 'data' to understand the relationship? I would hazard a guess there is a science to it =]
SirFat
SirFat3mo ago
No description
SirFat
SirFat3mo ago
That's the ticket.
awcodes
awcodes3mo ago
Think about it this way. In afterStateUpdated() for instance $get and $set are relative to that specific field that is calling afterStateUpdated. So it’s relative to where you are trying to use it.
SirFat
SirFat3mo ago
Yeah, looks like it was a matter of getting the Custom field and then looking in there rather than trying to drill in further, which like you said, similar to a repeater, makes sense Cheers - good, one step forward. Now just to find the $379 to buy the cheat sheet to the styled radio group =]
Want results from more Discord servers?
Add your server
More Posts