00:00
(upbeat music)
00:02
So with your HTML forms,
00:06
there's gonna be times where you need to be able to send up
00:08
an array of data or even an array of objects.
00:11
And our cast and crew members
00:13
are one such instance for our movies.
00:15
Let's add them in down here
00:17
just above our update movie button.
00:19
So let's start by jumping into our creator edit page
00:21
right above that button.
00:23
We can give ourselves a little heading to mark
00:24
that this is where they will be.
00:26
Do font bold and just say this is the crew members.
00:30
And we'll just focus on the crew members here for now.
00:32
We will have a div with an ID of crew list.
00:36
This is the div that will list out
00:38
all the crew members attached to the movie within.
00:41
So we'll have this as class, flex, flex column,
00:44
and we'll have one child inside of this list
00:47
per crew member that we are attaching.
00:49
So we'll have a gap of three there as well.
00:51
And in here is where we can do an each to loop over them.
00:54
So we'll do an each member in,
00:56
and we'll call this variable crew members
00:58
whenever we get around to querying it.
01:00
Then we'll end our each.
01:02
And inside of here, we'll have another div class flex,
01:05
and we'll do a gap of three here as well
01:08
because we're gonna have multiple fields.
01:09
The first field that we need to have is a select,
01:12
and the options for the select are gonna be Cineasts.
01:14
So we can copy either our director or writer field
01:17
as a good starting point for this input,
01:20
pasting it in its place.
01:21
The label we can do as crew member.
01:24
The name we will circle back to momentarily,
01:27
whether or not it's selected.
01:29
Instead of doing movie dot something,
01:31
instead we're gonna query this information
01:33
directly from the crew movies and cast movies pivot tables.
01:37
So we'll be working directly with columns
01:40
as they're defined inside of the table here.
01:42
So this will be our member dot cynist_id,
01:47
as that's what the column is literally called
01:49
within our crew movies pivot table.
01:52
And that'll be in charge of discerning
01:53
whether or not this particular option is selected
01:56
as we loop over our cynist options.
01:58
Our next form input for the individual crew member
02:02
that we're on is going to be a self-closing form input.
02:05
The type's gonna be text, so we can omit that
02:07
with a label of title so that we can discern the title
02:11
of this individual crew member for this particular movie.
02:14
And the name for that will be title as well.
02:16
Additionally, we can add in the default value for this.
02:19
Again, that's gonna come from our member dot,
02:21
and we have a title column directly on that pivot table.
02:24
Lastly, we wanna be able to remove this member
02:27
from the movie.
02:28
So we'll have a button of type button
02:31
so that whenever we click this button,
02:32
it doesn't actually submit our form.
02:34
We'll have an onclick handler.
02:36
In onclick, what we wanna do is reach up
02:38
to the parent of the button that encapsulates
02:40
all of the fields specific to the individual crew member.
02:43
So that would be this div right here,
02:45
which happens to be the direct parent of our button.
02:48
So we can get access to this button element via this,
02:51
reach for its parent element,
02:54
and then remove that parent element,
02:56
thus in turn removing all of the individual fields
02:59
that we have specific to this crew member.
03:01
And the way that we're going to save this on our controller
03:04
is to sync the data.
03:06
So by simply removing it out of our HTML form,
03:08
it's going to serve as a delete
03:10
anytime that we come to update or save our crew members.
03:13
And we can put a little and times character,
03:16
which will be a little X to serve
03:18
as the indicator for that button.
03:20
Okay, so that should do it
03:21
for our field specific to a crew member.
03:24
Now what we need to do is add the ability
03:25
to add an additional crew member to this crew list.
03:29
So underneath this crew list,
03:31
right above our submit or create button,
03:33
we can add in another button of type button.
03:36
Onclick will add a crew member,
03:40
and we'll create that function here momentarily.
03:42
And we can give this a label of add crew member.
03:45
Now this will be a client side function.
03:47
So we'll want to plop this inside of a script tag.
03:50
So we'll add a script tag down at the bottom of our page
03:53
with a function add crew member defined.
03:57
For this function, what we're going to want to do
03:59
is be able to essentially plop one of the contents
04:02
that we're looping over here for our crew members,
04:05
so that we'll be able to select what that new crew member is
04:08
and define their title as well.
04:10
If you're using something like HTML or Unpoly,
04:13
you would be able to reach out to your server
04:15
to get back that HTML to append into your document.
04:17
We're not, so we're going to reapply this exact HTML
04:22
somewhere that we can easily access it
04:23
from our client side script.
04:25
And to make this easily doable,
04:27
we're going to cut out all of that HTML
04:29
that we're looping over and move it into a component.
04:31
So let's scroll on up to,
04:33
we should have components movie here.
04:35
Let's right click that, create a new file.
04:37
This will be our crew member fields
04:40
or something of the sort.
04:42
There's not a very distinct name
04:43
that would be applicable for this
04:45
and paste the contents that we had cut out in.
04:48
These are the fields applicable to one single crew member
04:50
that we're binding into a movie.
04:52
We'll circle back and fill in the names here.
04:54
Oh, I defaulted to filling in the name here.
04:56
We'll circle back and fill in
04:57
both of these names here momentarily,
04:59
because we're going to need to specify them
05:00
in a specific way.
05:02
So let's jump back into our creator edit
05:03
and let's add in our self-closing
05:05
movie.crewmemberfields component.
05:09
Inside of here, we'll need to pass the member in
05:11
as well as the Cinest options that we have
05:15
specifically for the select,
05:17
so that we'll be able to select
05:18
the applicable crew member Cinest record.
05:20
We can give this component here a copy
05:23
and outside of our form, above our script,
05:26
let's go ahead and add in a template tag
05:28
and give this an ID of crew template
05:31
or something of the sort and paste the component inside.
05:35
So now EdgeJS will render our crew member fields
05:38
both inside of this template,
05:40
as well as for each one of our crew members
05:43
already bound into our movie.
05:44
This section here will serve as kind of the default value
05:47
whenever we're editing.
05:48
Any pre-existing crew members will load in here via Edge.
05:51
Otherwise, we'll get a template that we'll be able to clone
05:54
and append in anytime that we click
05:57
our add crew member button.
05:58
Now we have a little bit of more work to do here.
06:01
So first and foremost,
06:02
we're not going to have a member for this one.
06:04
So we'll want to pass it in as null,
06:06
meaning that we need to jump into this component
06:08
and make sure that that is nullable.
06:10
So we can just use optional chaining
06:11
for both references of our member
06:14
to make sure that that is valid.
06:16
Next, we need to take care of the names for both of these.
06:19
Now, there's a number of different ways
06:20
we can go about adding a name in for this
06:22
and square brackets are going to be necessary
06:25
in order for us to send this up as an array
06:28
or even an object.
06:29
So we can give it a baseline name of crew
06:32
and it will send up as such.
06:33
And we can specify that crew is going to be an array
06:36
by adding square brackets to the end of it,
06:38
similar to how you would in TypeScript
06:40
if you have a type that is an array.
06:42
Then we can specify kind of an object key
06:44
specifically for this field
06:46
by doing another bracket pair
06:48
and adding the name of the object property
06:50
that we want this to be applicable to,
06:52
which in this case, ID would probably be good
06:55
as the value is going to be sent as ID.
06:57
We can do something similar down here for our title as well.
07:00
So we'll have crew, add that into an array,
07:03
do another set of brackets
07:05
and give it a property name of title.
07:07
Now I'm pretty sure we're going to have an underlying issue
07:10
with this approach,
07:11
but we'll go ahead and test it out and see how it goes.
07:13
So in order for us to test this out,
07:15
we need to rig up our add crew member button.
07:18
So outside of our add crew member function,
07:19
what would be good is to already have a reference
07:21
to our crew template, as well as our crew list.
07:24
So let's go ahead and query both of those.
07:26
So we could do const crew list equals document.getElementByID
07:31
and pass in the crew list ID there.
07:34
And we could do const crew template equals document.getElementByID
07:39
crew template.
07:41
Within our crew list, what we can do is append child,
07:45
essentially a clone of our crew template.
07:48
So we can take our crew template, reach for the content,
07:51
tell it to clone the node,
07:53
pass in true there to clone it deeply.
07:55
And then this should clone the crew templates contents
07:58
and append that element into our crew list.
08:01
So let's give it a save.
08:02
And then let's jump into our movie validator
08:05
and let's rig this up in a way
08:06
where it's gonna come up invalid,
08:08
just so that we can easily get back
08:09
and see exactly what it is that we're posting up.
08:12
So let's do crew and let's say vine date.
08:16
We're certainly not gonna be posting a date up
08:18
for our crew.
08:19
So that should most certainly fail.
08:21
And then on our creator edit,
08:22
let's go and scroll up to the top
08:24
and let's plop an instance of our flash messages.
08:26
So let's inspect it out, flash messages,
08:29
and we can reach for all of them
08:31
just so that we can easily see exactly what it is
08:33
that we're posting up here
08:34
as we submit and test out our crew list functionality.
08:38
Okay, so we don't need to do anything
08:39
in our movies controller yet
08:40
because our validator should prevent us from getting there.
08:43
And it looks like we have an error,
08:45
cannot read Sinus ID.
08:46
I'm gonna go ahead and refresh that
08:47
to see if that was, okay, yep.
08:49
That was just something we saved along the way
08:50
with an invalid state.
08:51
So we are good to go now.
08:53
If we hit add crew member, look at that,
08:55
we get our crew member field.
08:57
We have our crew member selects.
08:58
So we could select somebody there,
09:00
type in some title, and we can also clear them out.
09:03
So if we added another one, but we only wanted one,
09:05
we can clear that out.
09:06
Let's start by trying to update our movie.
09:08
Okay, you can see our validation most certainly failed
09:11
and you can see that we're getting back crew ID
09:13
with a value of 33 and a title of some title.
09:16
So this is sending up as an object rather than an array.
09:20
However, if we come back down here
09:22
and we add in two crew members,
09:25
and let's make sure that they're a little bit different,
09:27
and let's go ahead and post again,
09:29
you'll see that now crew is still an object,
09:31
but ID and title is now an array of values
09:36
where it was previously just a string.
09:38
And I'm going to double check myself
09:40
to make sure I'm remembering that correctly as well.
09:42
So if we post that back up, you can see,
09:44
yep, most definitely just a string.
09:46
So what we kind of need to do
09:48
is normalize its expectations a little bit
09:51
by specifying an index of our array
09:54
that we want the items to be members of.
09:56
So if we hide this back away,
09:58
within our crew members fields,
10:00
if we specify now an index within here,
10:04
so we'll switch these two back ticks,
10:06
both of them right down here,
10:08
and inject in an index,
10:11
which will provide as a prop to this component.
10:13
So an index just like so, give that a save,
10:16
jump back out to our creator edit,
10:18
and then we'll need to grab the index out of our loop there,
10:22
pass an index in here,
10:23
and we're not going to have a specific index
10:26
to be able to patch in here.
10:27
So that's where things get a little tricky on this front.
10:30
Instead, we want to do index
10:32
with some sort of placeholder that we can replace.
10:34
So maybe a capitalized index string.
10:36
And then instead of directly cloning the node
10:39
and impending it directly in,
10:41
we're instead going to want to get the HTML of the template.
10:44
So rather than cloning it as we were before,
10:47
reaching for the content,
10:48
we'll want to instead just do crew template inner HTML.
10:52
And this will allow us to easily replace
10:55
all instances of that index placeholder
10:58
that we added into that component
11:00
with the const next index,
11:04
which is our crew list children length.
11:08
Because instead of our crew list,
11:09
we have one child div per crew member that we're adding in.
11:13
So that's going to equate to the next index
11:16
that we want to append into that list.
11:18
So we can pass that in here, next index, just like so.
11:22
Then in order for us to be able to append the child in,
11:24
we're going to need a node.
11:25
We could do inner HTML and append in that way,
11:28
but that's going to re-render the entire DOM,
11:31
which would get rid of any adjustments
11:33
that we had previously made to this section of our form.
11:35
So we do want to use append child here.
11:38
So we can do const temp and create a new element.
11:43
We just patch that as a div,
11:44
and then we can do temp inner HTML equals our HTML,
11:49
and then reach for that temp.firstElementChild, like so.
11:54
So now if we give this a save,
11:55
we jump back into our browser.
11:57
Let's start by adding a single crew member in
11:59
and see how this posts.
12:00
So let's select somebody there,
12:02
some title there, update our movie,
12:05
and you can see exactly how that switched things up.
12:07
So rather than doing crew as an object
12:10
with individual ID and title properties
12:13
with either a string or array there,
12:15
it's now crew is an array,
12:17
and we have a single object with ID and title
12:20
as properties inside of there.
12:22
So if we add two in now,
12:24
so let's add that twice, add crew member, add crew member,
12:27
select some random people here,
12:28
and give them some title one and some title two,
12:33
update our movie again,
12:34
you'll see that we still get back an array,
12:36
but now we have two different objects inside of our array
12:39
with some title one and some title two.
12:41
This is really ideal for how we're gonna want to
12:44
patch it up on our server side inside of our controller.
12:47
So we'll want to keep forward
12:49
with this particular syntax here,
12:51
but there is a downside that we'll need to account for
12:53
later on here as well.
12:55
But for now, let's go ahead and get this saving.
12:57
So let's first jump into our movie validator
12:59
and update our validator to accept in
13:01
exactly as we're posting it.
13:02
So we're gonna have a vine array,
13:05
and we're gonna wanna make sure that that array is optional
13:07
because we may not have any crew members being sent up.
13:09
Inside of our array,
13:10
we're gonna want this to be a vine object,
13:12
so an array of objects,
13:14
and for those objects,
13:15
we're gonna have an ID of type vine number,
13:18
and we can even do an is exist check,
13:21
making sure that the table of our sinists
13:24
and the column ID contains the value
13:27
that we're sending up here,
13:28
and then title vine string for the crew members title.
13:33
Give that a safer formatting,
13:34
and this should now match the syntax
13:36
with how we're posting it up.
13:37
So let's jump into our movies controller next
13:39
and get it added.
13:40
So we have the additional field within our validator of crew
13:44
which contains our crew members,
13:46
and what we're gonna wanna do is get back an object
13:50
where the key is the ID and the object is the ID's title,
13:55
and it also has a sort order for them as well.
14:00
So we're gonna want this format.
14:02
So if we have multiple, it would be like ID two,
14:04
so on and so forth, looking like that.
14:07
So we can use reduce to easily build that object.
14:10
So const crew members equals crew reduce,
14:15
and that's going to be optional.
14:16
We'll have our accumulator object, our row,
14:20
and an index so that we can add in the sort.
14:22
Our accumulator is going to start out as an empty object,
14:26
and for each time that we're looping over it,
14:28
we're going to take that accumulator
14:30
and add in the rows ID with an object of title,
14:35
row.title, and sort_order,
14:39
because remember we need to post this in
14:41
as is defined in the database
14:42
since we don't have a model defining this pivot table,
14:45
and the index will serve as our sort order there.
14:48
Then of course, we'll need to return back
14:50
that accumulator for the next loop.
14:52
Now we're gonna have some red squigglies
14:54
because we haven't defined a type for this.
14:56
So we'll need to type hint this reduce as well,
14:59
and we can type hint this as a record
15:02
where the key is a number,
15:04
and the value is an object with title, string,
15:08
sort, order, number, just like so.
15:11
And we need an extra caret there at the end of that.
15:14
Give that a save so it should format
15:15
and get rid of all of our squigglies.
15:17
It looks good.
15:18
And now all we need to do is await,
15:20
take the movie,
15:21
reach for the relationship of our crew members,
15:24
and we'll want to use sync
15:25
because our crew members here is the source of truth.
15:28
If we've removed somebody from the crew members
15:30
and we want to delete them,
15:31
and anyone that we add in, we want to append in.
15:34
So sync will take care of both of those use cases in one go,
15:37
and just use our crew members here
15:39
as the source of truth for who the crew members are.
15:42
And of course, this is optional,
15:45
so it may not have a value at all.
15:47
So we can default that to an empty array
15:50
if we didn't provide anybody in.
15:52
Okay, so this should get us to where we can
15:54
at least save some people in,
15:56
and then we'll take a look at the next issue.
15:58
So let's add some crew members,
16:00
take a look and add Camille in,
16:02
maybe they got the food,
16:04
and then we'll do Leela,
16:06
maybe they did the hair for the movie.
16:08
We can go ahead and update our movie,
16:10
and now you can see we got redirected right back
16:12
to our movies pagination page,
16:14
and we can see for this movie,
16:15
we have a crew members of two now instead of zero.
16:19
Go back in the edit,
16:20
we're not gonna see them yet
16:21
because we haven't added it into the query,
16:22
so let's do that next.
16:23
Jump up to our update,
16:25
we'll worry about creation here
16:27
after we get all of our issues resolved,
16:29
and we're going to want to query this as mentioned earlier,
16:31
directly from our pivot table.
16:33
So const crew members equals await,
16:36
we can reach for the database module to do this,
16:39
from crew movies, which is the name of the pivot table,
16:43
where that movie ID equals movie.id,
16:47
and again, know that we're using the table and column names
16:50
as we define this out of the database
16:51
because we're using the database module,
16:53
which does not go through our Lucid models.
16:55
And then lastly, we want to order by the sort order field,
17:00
give that a safer formatting,
17:02
and edit into our page states,
17:03
so crew members there.
17:05
All right, now if we jump back into our browser,
17:07
we should now see both of our crew members,
17:09
we'll give it a refresh, there they are.
17:10
So all looks good, right?
17:12
We can add in an additional crew member and it should work.
17:16
So let's add Natasha, maybe she did makeup,
17:19
update our movie, and sure enough,
17:20
added in A-OK, we should now have three, which we do.
17:23
The issue comes in though, with these indexes
17:27
that we are defining on these elements.
17:29
So we have crew zero ID, as we remove these items,
17:33
this index is not going to auto update
17:35
because we're not touching those elements in any way
17:38
whenever we make that removement.
17:40
So if we take a look at the first item now,
17:41
its first index is one.
17:43
Why is this an issue?
17:45
Well, let's go ahead and try to update our movie
17:47
and we'll see.
17:47
So let's take a look at our flash message.
17:49
The value that we're now posting up is crew with an array,
17:53
and the first index which we removed is now null,
17:56
because there was no representation
17:58
for the first index of this array.
18:01
What we could do, so let's go into alpinejs.dev,
18:05
and I'm just gonna go ahead and copy their script
18:08
right there from the CDN.
18:10
If you want to, you can go into your script
18:11
and fully install it,
18:13
but we're just going to want it on this one individual page.
18:16
So we'll plop it in just before our script here.
18:18
Believe it or not,
18:19
this is actually going to drastically simplify what we have.
18:22
So we can get rid of our template
18:24
as well as our script here as a whole too.
18:26
So we go ahead and remove that, scroll on up,
18:29
and rather than doing an ID crew list,
18:31
what we can do instead is x-data,
18:34
define the state of say our members as,
18:38
and we can use EdgeJS's interpolation
18:41
to now stringify our crew members
18:45
and pass it directly into the members variable
18:47
on the client side via alpinejs.
18:50
AlpineJS is like a very lightweight version
18:53
of Vue or React.
18:55
It's going to sprinkle in client side JavaScript
18:58
DOM manipulation for us
19:00
so that we can easily perform re-renders
19:02
of our inner child content as it updates.
19:06
This is going to make swapping out that index
19:08
as we remove items super easy,
19:10
and it's going to eliminate the issues
19:12
that we've seen thus far.
19:13
This stringifies a JavaScript helper.
19:15
Actually, I believe it's js-stringify.
19:17
It used to just be stringify in version five
19:20
and advanced js6,
19:21
they've now namespaced it underneath js.
19:23
This will take what we pass in
19:24
and safely stringify it so that we can easily pass it in
19:27
as a value here in our attribute.
19:29
This x-data is how we define state for Alpine
19:32
similar to again, Vue or React state.
19:35
And that's going to make sure that we have access
19:36
to members inside of this div right here,
19:40
essentially serving as kind of a micro component
19:43
for AlpineJS.
19:44
Meaning that we can actually dive back
19:46
into our crew member fields component.
19:49
And if we wanted to, we could reapply all of this
19:51
just right back out inside of AlpineJS.
19:55
And since we have all of our members,
19:56
we can loop over it using Alpine
19:58
and get rid of our EdgeJS loop there as well.
20:01
We'll want to add in a template,
20:04
which is what EdgeJS uses for loops,
20:05
do x for member in members,
20:09
add in a key of member.id,
20:13
and in that template,
20:14
we can go ahead and cut that out
20:15
and paste it down at the bottom of our div here,
20:19
scroll up a little bit and give ourselves an indent.
20:21
So next what we need to do is move the name from EdgeJS
20:24
now to our client side via AlpineJS
20:27
because Alpine now contains who our members are
20:30
rather than our EdgeJS loop.
20:33
Now, so that we're not spending a ton of time
20:35
mutating our forms so that they support AlpineJS,
20:38
that's certainly doable.
20:40
Instead, what we're going to do is just swap these
20:42
from using EdgeJS to Alpine.
20:44
So let's go and jump into our form
20:46
and select our span here
20:48
just to make sure that we're using the same styling.
20:50
And we have a label class flex flex call,
20:54
and then we have that span with our crew member label.
20:58
And then we have a select with the name
21:02
and then our options.
21:04
So we can cut out our EdgeJS loop with those options
21:07
and paste it in here.
21:09
The name is now going to be an interpolation from AlpineJS
21:13
and we'll do double curly braces there
21:14
so that we can inject
21:16
and we'll want the index out of the loop.
21:18
And then we can do crew, inject that index
21:21
and say that this is the ID field.
21:23
So now every time AlpineJS loops over this to update it,
21:27
it will inject the correct index
21:29
based off of the loop index,
21:31
fixing our issue that we were running into.
21:33
Now we are doing our selected check in EdgeJS still,
21:37
but we need to switch this to Alpine
21:38
because member is now in our client side via Alpine.
21:42
So we can use interpolated selected here
21:45
to say if member.sinist_id equals,
21:50
and we can use EdgeJS to interpolate in
21:53
who this current sinist.id is.
21:56
So a nice blending of client side
21:58
and server side code here going on.
22:00
Server side being our EdgeJS interpolations
22:03
and client side being our AlpineJS interpolations here.
22:05
Scroll down here, we'll take care of our input next.
22:08
Let's select the label that we have going on,
22:10
paste it in, do input type text, name,
22:15
and then do our interpolated name here,
22:17
backticks, crew, inject in the index,
22:21
and then add in that this is the title field.
22:23
And then for the model, this would be an X model.
22:26
And I think for AlpineJS,
22:28
you need to do members, reach for the index.title.
22:31
Similar to how view two was.
22:33
And end that up.
22:34
We can actually switch our select to do that as well,
22:37
thinking about it.
22:38
So we could scroll up,
22:39
let's end our label before we do that.
22:40
So end our label there.
22:41
Now let's scroll up,
22:43
and rather than doing our selected,
22:45
we can do X model, members, index, and reach for the ID,
22:50
which means that we can get rid of this
22:51
on our option altogether.
22:53
Scroll down a little bit further
22:54
because this is no longer just going to remove the element,
22:57
but rather remove the item out of our members array.
22:59
And we'll need to switch this to an at click now.
23:02
And we can do members equals members.filter,
23:06
item or item.id does not equal member.id.
23:11
And then for our ad crew members,
23:14
what we'll want to do is instead members push,
23:18
we can do an ID and reach for EdgeJS's
23:22
since the first option.id there to plop that in
23:27
and title as just an empty string,
23:29
directly mutating the state that we have up here
23:32
in our x-data.
23:33
You could also define this method directly in x-data
23:35
and call it from our button to there as well.
23:38
So let's give that a save,
23:39
jump back into our browser and okay,
23:41
it looks like everything's still working.
23:42
Let's do a sanity check refresh.
23:44
Cool.
23:45
Let's try to update our movie real quick
23:46
just to make sure everything goes.
23:47
And it looks like it did not get our titles.
23:50
Okay, scroll back down, right click the field,
23:53
inspect, and it looks like I messed up the index
23:57
there a little bit.
23:58
Let's hide our browser back away
23:59
and see if we can fix that.
24:00
Scroll on down to where we have that title.
24:02
And sure enough, I put a square bracket in.
24:04
Get rid of that.
24:05
Try that one more time.
24:06
So let's jump back up into our browser,
24:07
refresh for sanity sake, try to update it and cool.
24:10
Okay, so it went okay, but we only now have one person.
24:13
That's not right.
24:14
Okay, so I rewrote this whole thing
24:16
for the crew members here three times
24:17
just to see that I had a very small issue
24:20
that was preventing our ad crew members button from working
24:22
and it caused a few other issues.
24:24
So let's go ahead and hide our browser back away
24:26
before we test this out.
24:28
And the issue was that the ad crew members button
24:31
is outside the realms of our x-data.
24:34
So it doesn't know or have access to that state
24:37
because it's not encapsulated by it.
24:39
So what we wanna do is cut that state out of this div,
24:42
wrap it in another div,
24:44
since this div in particular is for listing out
24:47
each one of our members, it has that flex flex call on it.
24:50
So we don't want that to be on there,
24:52
but instead on a parent div,
24:54
and then we can indent everything up through our button
24:59
and encapsulate our button now
25:01
in that extra div that we have.
25:03
So now if we collapse down our template,
25:06
our x-data and the div containing it
25:08
is now including our button.
25:11
Additionally, I'm not sure if I had this initially or not,
25:13
but we also wanted the selects X model
25:16
to reference the members index Cynist ID
25:20
rather than just the ID.
25:22
That might've been another issue that I had
25:24
that was causing some strangeness.
25:25
So with both of those in place,
25:27
we should now have a working system
25:29
without the oddities that we've seen in the past,
25:33
where we'll have a differentiation in our post behavior,
25:36
depending on the number of items that we have being posted.
25:38
So for example, if we post up here
25:40
with Quincy Abernathy as test two,
25:42
Jermaine R as test three,
25:44
and we maybe add in somebody else here as test four,
25:47
Natasha, test four, updates.
25:50
There we go.
25:51
We see that we get crew members of three.
25:53
If we go back in the edit and we remove two,
25:56
which was one of the issues that we had solved
25:57
because now this would be index one
25:59
and this would be index two.
26:01
AlpineJS should fix that for us.
26:03
Automatically now making this index zero
26:05
since we've removed the original zero
26:07
and now this index one.
26:09
So let's try to update and sure enough, it worked.
26:11
Awesome.
26:12
So now we have two crew members
26:14
and if we take this now down to one,
26:16
so let's run through that again.
26:17
Leave just Natasha, update once more.
26:20
Awesome.
26:21
Now we just have one.
26:22
So everything there is now working a-OK.
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!