Planning Steps Feature0:05
All right, let's move on to steps now. So remember, if we had this idea, we need to put it into actionable steps, right? And each step can be completed. So originally when we made the migration, we defined that a step consists of a description and a completed status. That of course can be toggled. Okay? We got this. So as you can imagine, just like links, if I scroll down to my modal here, steps can also be one or many.
Building Steps UI0:26
So as you can imagine, just like links, if I scroll down to my modal here, steps can also be one or many. So I'm hoping that I can reuse a lot of the markup that we wrote in the last episode. So let's do this. I'm gonna select this whole thing here and above it, we'll put steps first. All right, so this section will represent our steps. All right, so this is where we would loof over any existing steps. I'll just hide that for now until we get to that point.
over any existing steps. I'll just hide that for now until we get to that point. And then this is where we would display an input and a button to add a new step to the idea. Great. So let's just make some updates. Very similar. This will be a new step. It's a simple text box. The ID is new step. If we require that for the placeholder, what needs to be done? No auto complete class of input. Spell check. False.
what needs to be done? No auto complete class of input. Spell check. False. That's fine. Okay, so now I need to submit a new step. And we would do that by deferring to some array we have on our Alpine component called steps. And we'll push new step and then reset new step. Yeah, very, very similar as it turns out. Alright, so let's scroll up to the top where we define our component.
Alright, so let's scroll up to the top where we define our component. And yeah, once again, we're gonna have basically the same thing, a new step and a list of steps. Very similar. Okay, so yeah, I'm about ready to take a look in the browser. Let me just do a final check here. Disabled if new. Nope, that's new Step Disabled. If you haven't typed anything into the new step form yet, submit it.
Testing With Alpine Devtools2:01
If you haven't typed anything into the new step form yet, submit it. That gets appended to a steps array. This all looks right. All right, let's have a look. Alright, So let's bring up our modal. Scroll down and yep, here's our steps. Now remember if I app pin this, we're not gonna see anything, but I'll show you a little tip. Uh, just Google alpine js chrome extension
but I'll show you a little tip. Uh, just Google alpine js chrome extension and you'll be able to install something just like this where you can review the data here. So notice if I scroll down here for New Step, of course that is being synchronized, but our steps are raised empty. So let's go ahead and append to it. And sure enough, we have one item there. It works. Let's do another one. A pens. And now we have two items. Perfect, exactly what we want.
Let's do another one. A pens. And now we have two items. Perfect, exactly what we want. So now let's come back and scroll up and take care of the section where we display all of the steps you've completed. And this one will be just slightly different. So this time of course, we are working with steps rather than links. So I'll start by selecting these and swap it out with steps. And then let's do each individual one. There you go.
So I'll start by selecting these and swap it out with steps. And then let's do each individual one. There you go. Next I'm gonna change the label to how about actionable steps? Okay, so one more time, let's give it a go. Research things, add a new one. And now I can see it listed here. That's working. Now can I remove it? Yes I can because it's basically the same functionality as our links.
Yes I can because it's basically the same functionality as our links. But again, there's still a little bit more. And by the way, I think some of that will become more clear once we reach the step of editing an existing idea because we'll have to ask, well can we reuse this modal? And if so, what tweaks do we need to make to allow for that? Alright, so now back in my editor, this will now be submitted, right?
Validating Steps Request3:39
Alright, so now back in my editor, this will now be submitted, right? So if we scroll up at the moment, this will contain an array effectively of all of our steps. And that will be posted to the server. Let's go to idea controller. Let's come to the store action. Of course, that first hits the uh, store idea request. And if I scroll down, here's our current rules. Okay, now let's add some more for the steps themselves. So we will have steps and then validation
Okay, now let's add some more for the steps themselves. So we will have steps and then validation for each item within the step steps can be knowable or an array, and each individual steps should be a string max 2 55. Yes, something like that. Okay, so let's give it a shot. Let's come back and now, as we did before, let's die and dump all of the request data to see if we received everything we need. So once again, the modal gibberish title.
to see if we received everything we need. So once again, the modal gibberish title. Let's do in progress some description, actionable steps, let's say research options. Uh, do a thing and then scroll down. We can add a link as well. Let's create that and let's give it a shot. Alright, so now this is basically what we would want, right? We have our title, the current status, the description, an array of steps, and also, uh, an array of links.
We have our title, the current status, the description, an array of steps, and also, uh, an array of links. Okay? But now this does beg the question, how do we associate an insert steps for an idea when the steps are not included on the ideas table? Well, I'll show you. The first step will be to tweak this request. Validated will now contain step information. But again, just to make this crystal clear, there are no steps on the ideas table.
But again, just to make this crystal clear, there are no steps on the ideas table. Instead, we created a dedicated table to store our step information and then we associate it with the idea. Okay? So that's the first step, no pun intended, is we need to tweak this just a little bit. Now, I'll show you a fun thing we can do. Um, I can say request validated, and this will give me, of course, all
Um, I can say request validated, and this will give me, of course, all of the validated request attributes refreshed. And of course we still get this. However, maybe you've also run across a method called safe, give me the safely validated attributes. And that might be confusing because you basically get the same thing. However, notice it's wrapped within this validated inputs, uh, object, which means, uh, you'll see this is that class,
However, notice it's wrapped within this validated inputs, uh, object, which means, uh, you'll see this is that class, you have a bunch of helper methods. Basically give me all of the data. Give me only these attributes, give me the attributes, accept these. So that means I can do things like this. Give me the safe attributes, but only the title. Come back refresh. Now we get just the title. I could say accept the title
Come back refresh. Now we get just the title. I could say accept the title or in our case, accept the steps. Give me everything. Accept the steps. And this is what I want to insert into our database. All right? So I could say I could, I could tweak this, give me the safe, accept the steps and insert that. And then when we call create, that will return the newly created, uh, excuse me, the newly created idea.
Persisting Steps to Database6:46
that will return the newly created, uh, excuse me, the newly created idea. Awesome. All right, so now let's insert these steps. And you'll remember if I do request, um, steps, that's gonna be an array, right? Refresh, it'll be an array of two items, which means we need to create two steps. So of course we could loop over them and then create a step for each one. That's an in plus one problem,
and then create a step for each one. That's an in plus one problem, but you know, just not that big of a deal for two or three items. But we also have, um, a create mini method that we can use. Or there's even, um, there's an upsert, uh, method we could use. But create mini's. Fine. I could say idea. Give me the steps relationship and I could call create for one record,
Give me the steps relationship and I could call create for one record, or I can call create mini for multiple records. And then you can do things like this. Each step needs a description. So I could say step one, and here's step two, you get the idea. So all we have to do now is format this properly. Rather than passing an array of strings, I wanna pass an array
Rather than passing an array of strings, I wanna pass an array of arrays basically, uh, that are keyed. So here's what we'll do. Let's collect our request steps. We're gonna map over them, and for each step, I wanna return a new array, uh, that is basically keyed like this. Alright? So insert this collection of steps into the related table and then, uh, return a redirect.
of steps into the related table and then, uh, return a redirect. And that should do the trick. All right, let's come back. Let's try to complete the submission. All right, it redirects back. Here we go. Here's our gibberish title. And I don't think at the moment on the show page, we are showing the steps themselves. So let's switch over to Table Plus and see if they were inserted.
So let's switch over to Table Plus and see if they were inserted. Alright, so let's go into idea. Here's that new one we created and let's see if we have some steps. And sure enough we do, we have two steps that are associated with the idea of five. It's working. Awesome. Alright, so now I'd love to switch back to this page real quick and display them.
Alright, so now I'd love to switch back to this page real quick and display them. So let's visit the idea slash show page. And just like before, we will place it above the links. So yeah, once again, we're gonna have a condition. We're gonna say, all right, let's check if we even have any steps. Uh, and only in that case should we render them of course. So maybe we can reuse a lot of this. Once again, I'm gonna save us as much writing,
So maybe we can reuse a lot of this. Once again, I'm gonna save us as much writing, especially markup as we can. It's not fun to watch on a video, I get it. So we're gonna have our actionable steps, and then of course this time we're gonna loop over our steps relationship. So that will be a step instance. Our card will no longer be a link. It's just gonna be a panel basically.
Our card will no longer be a link. It's just gonna be a panel basically. And within here we'll have a div that basically consists of our button and this is like the, uh, check mark status, basically, is it completed or not? And then after that we would have the wrapped in a span, we'll have the description itself. All right, so that would be step description. So yeah, then if we want the check mark to be immediately
All right, so that would be step description. So yeah, then if we want the check mark to be immediately to the left of the description, once again, let's do a display of flex item center dap, X of three, something like that. And let's have a look in the browser. Alright, here we go. So they're green, which I don't like, but nonetheless I have a section for an icon of a check mark. And then we have the actionable step. Cool. So I think in this case, our card can be pretty bare bones.
And then we have the actionable step. Cool. So I think in this case, our card can be pretty bare bones. Yep, a little better. Alright, so now, yeah, let's just clear that out and make that an icon or something. Now I don't think I have one. I probably should. Uh, but instead we'll just use an HTML character, something like this and check. And that'll give us, yeah, just a, a basic check mark. Uh, I'd like a background color.
And that'll give us, yeah, just a, a basic check mark. Uh, I'd like a background color. So let's add some classes here. Oh, and actually on this note, don't forget, you could do, of course the the semantic thing would be to do an input type of checkbox, right? So if I were to come back, you know, you can select this, but I want control the presentation a bit more. So instead I'm gonna have a diviv or a button that has a roll of checkbox
So instead I'm gonna have a diviv or a button that has a roll of checkbox that will effectively do the same thing, but give me just a bit more control over how it is presented. Okay? So on the button, let's apply a few classes. I'll paste these in and yeah, a size just sets a width and a height to the same amount. Flex items justify center that just perfectly centers something in the middle,
Flex items justify center that just perfectly centers something in the middle, make it a little rounded and then add a, uh, a text color for the icon itself. If I come back, yeah, it's there, but because we have the the four gun color, what I should maybe do is set a border and a border of primary just so I can see the edges there. Okay, so then when the user selects it, we would need
so I can see the edges there. Okay, so then when the user selects it, we would need to change the state if the step is completed. In that case, we'll set a background color of that green. Otherwise we'll just have an outline of the green. Uh, and at this point we don't have anything completed, but if we manually toggle that, let's go into steps and just turn that to one. Now, if I come back and give it a refresh, this is what it would look like.
Toggling Step Completion11:51
Now, if I come back and give it a refresh, this is what it would look like. Not the most beautiful thing ever, but it's fine. Alright, so now let's add support for toggling these. Now one option again is to reach for Alpine, but I think what we're gonna do in this case is just wrap each one within its own form. Something like this. This we're gonna default to post, but actually if you think about it,
This we're gonna default to post, but actually if you think about it, we are updating the status of a step. So what I really wanna do here in addition to CSRF protection is declare that this is probably a patch request. I'm patching or I'm updating this step and I'm changing the completed to false. Alright, so what is the end point? Let's see what we got here. We don't have anything yet.
Alright, so what is the end point? Let's see what we got here. We don't have anything yet. So let's do it here. Let's listen for a patch request to, um, you have two choices. You could do something a little bit more long form like of the ideas then for the steps relationship and for this specific step updated. And that's fine and we can link these, but I dunno, over the years, I've just decided to keep it simple and do something like this.
but I dunno, over the years, I've just decided to keep it simple and do something like this. All right, that's gonna hit a new step controller we create and let's give it the update action. Let's give it a name of step, do update, and of course you need to be signed in. Alright, let's create that now, we'll do it from the terminal. This time make me a controller called step controller. And let's just make it, um, empty for now.
This time make me a controller called step controller. And let's just make it, um, empty for now. All right, let's import that visit it, define the action update. We are updating this step, we need authorization, and we have again, a whole episode dedicated to authorization. But then assuming we are authorized, uh, we can say step and we're going to update it.
But then assuming we are authorized, uh, we can say step and we're going to update it. And at the moment, all we're doing is toggling the completed, um, status. So I can say, well, if we're toggling it, just set it equal to the opposite of what it currently is, like that, and then we can return back. Alright, so let's reference that now back to our show view. Our action is now going to be the route for step update
to our show view. Our action is now going to be the route for step update and I gotta send through the step itself. Now, in this case, we don't actually have any input data, we're just making a request, we're passing through the step we care about, and then it's toggling the completed status. So I think this actually should work. The only thing we should do real quick, um, is let's make sure we have a type of submit.
The only thing we should do real quick, um, is let's make sure we have a type of submit. And yeah, let's just be again, for, for accessibility purposes, let's ensure that this is playing the role of a checkbox. All right, I wanna try it out now. Alright, so here we are. Why don't we toggle research options and it works. Give it a refresh and you can see it's still checked. Let's uncheck both of them. Give it a refresh and it works. Alright, so now maybe you wanna do the line through thing.
Let's uncheck both of them. Give it a refresh and it works. Alright, so now maybe you wanna do the line through thing. If it's fully complete, well we could say right here, let's make a line through and then reduce the text color to be more of a muted, uh, tone. So give it a refresh. There we go. Yeah. So that would signal if the step has been completed. So let's tweak that and say, all right, well if the step is completed only on that condition,
So let's tweak that and say, all right, well if the step is completed only on that condition, should we add those classes? Yeah, that looks good. So uncheck goes away. Let's complete this one. Let's complete that one. And they're all done. Perfect. All right, so let's go full screen. So now we've added support for actionable steps as part of an idea. So for example, if I'm preparing a course,
as part of an idea. So for example, if I'm preparing a course, maybe Laravel from scratch course 2026 edition. I'd brainstorm maybe the episode list here. Actionable steps would be plan outline, record episodes, edit videos, publish. Yep. I would include maybe a link to the project. And if we create it, we have our new project.
Yep. I would include maybe a link to the project. And if we create it, we have our new project. All right, here's our steps. So I've already done the outline, of course, and I'm currently working on the episodes. So this is looking great and I'll see you in the next episode where we move on to featured images.
