Script Refactoring and Layout Optimization
The ECMDE script is moved from individual create/edit pages into the base layout header to centralize JavaScript loading. This prepares the application for production optimizations such as browser caching and a single JavaScript entry point.
Form Update and Route Corrections
The update article form is refactored to use proper HTTP methods, switching to PUT for updates and DELETE for deletions. Route names and controller references are corrected to align with RESTful conventions.
Delete Button Integration
The delete functionality is embedded directly into the article form using a button with a DELETE request. Conditional rendering ensures the delete button only appears when editing an existing article.
Article State Signal Handling
The article state (draft/publish) is managed using signals and event bindings instead of data binding. Form payloads are updated to reflect the renamed state field, ensuring correct backend communication.
SSE and Flash Message Handling
Server-Sent Events (SSE) handling is adjusted to avoid consuming context prematurely, ensuring flash messages and redirects work correctly after form submissions.
Backend Bug Fix and Validation Flow
A logic error in backend publish-state handling is identified and resolved through parameter logging and debugging. Validation and state persistence now function correctly for creating, updating, and deleting articles.
Remaining UI Issues
Two frontend issues remain: editor focus is lost during typing, and table rows are not clickable. These improvements are planned for the next iteration.
Right, so we have a little leftover from the last episode that we need to fix. And that's because we have included this script to load in the ECMDE script in both new and edit article page. I want to instead add them into base layout where we're going to add to the header. When we do go to production, we will have set up some browser caching.
We'll also make it so that we have one entry point to load in all of our JavaScript files. And that makes it so that this will load very fast and not really affect the field of the page. So we're going to place this in the header. So it is available for us to call execute on whenever we do the validation and update the pages, create and edit article pages. To do that, we also need, let me just jump in,
here. We also need to go in to add men because we are not calling data init on the update form. Now it's back and showing. Great. We basically need to do the same thing as what we did with the update article page. So we can start by adding these
we data on key down and data on submit and the ID. Then we need to grab the update article, route, delete this, delete this, and delete this. Now we can also use the correct method, which is a put. And I just noticed that this is update article page. It should be update article. The same thing in router.
update article and we should have a put request. Great. Back to admin, restart the LSP. There we go. So now we are back here and we will have validation if we type something into the fields here. So if I delete and type, we have nothing.
interesting. Why do we not have, we have not included the article form elements cause. So I can get rid of most of this. But we have this button here that delete an article that we need to include in the
article form elements. And the way we can do that is to add it here. Go down, add it. We don't want this to be a submit because that will submit the entire form. So we just need it to be a button. We can remove this delete form as well. Then we go back, then we steal this route setup. So we can say instead data on click.
Then we will say FFT, Sprint F. And now again, instead of sending a post request to delete something, we can actually send a delete request. Let's start into very good. We pass this, we close it. And then next problem, we need an article ID. So let's pass an article ID of type UUID UUID.
Here, we don't need one, so we can just pass a uuid.nil. And down here, we can pass the actual article id. Then we can get rid of all of this. And we now just need to update our controller. Because we are also calling this in some places where
we actually need it to be. So we have to validate article, which is a controller. So we can say var article ID, UID, UID. That would be a little ID as a default. So pass that in here. Then if you go into our update, you can do this.
and say if ID param does not equal empty string, pass the ID and set article ID equal to ID. Do any more places we do, that's in the create article where we just pass a UID null. We have any more places I actually think is working now. So let's try and jump in here, refresh. And let's try and
Let's start by just clicking the delete button and see what happens. We get a 405 method not allowed. And that is because we haven't updated the method here to be a delete. Now if we refresh, can we actually send the delete? We can, we delete the article, beautiful. Now, let's make this look a little bit better. So instead,
We're going to say diff class called span and to. Close it. And then I close it here as well. And then place self ends. Now it shows up correctly, but this will also show up if we go to add an article, which is not correct.
fix this, we can say if article ID equals to UID, oh sorry, it does not equal to UID nil, then we show the delete button and it's gone. Right, let's close the development tools, go back into edit and let's now look at the next thing because we should have
The validation turns up. We do. But we have this article state here that does not get the value it should. To fix this, we can add a signal to the article state component where we will say data signals equals two. And here we're gonna use FFT sprint again. And inside of here we will say
article state is this value based on the boolean we will pass to it and then we use a tenor every tenor every tenor is sentence I don't know what's it called pass pop a lish close it close it pop lished
Then we remove this data bind and say data on click. Then we change the value to article state equals draft. Down here we say article was to publish. Do we want anything else? Let's just say name state and name state.
and we now have it show up. But we also changed the naming of this signal. So for it to actually go through, we need to update our article form payload here to be article states. And then do we have anything left over? We probably need to deal with the errors here. So if you say, grab,
This one. And we actually need to move this down here and add it here as well so we don't, because whenever we create this new SSE instance, we consume the context so that also a flash will not show up. So we need to make sure to call this after if you need to use any of the echo context. So same thing applies here where we can basically grab
All of this could maybe just actually standardize this, because it's the same. But let's just do this quick for now. Let's say sse redirect, edit article page. And we should be done basically. Let's try an update. Update is successfully. If we refresh, it stays on draft. Let's say pop is with
publish in the title. Save. And we get what we need. If I just try to publish with an empty article, we get the article title must be between five and a hundred characters. Let's put it back to what it was before. That was not what was supposed to happen. Why does it not stay unpublished?
Interesting. This one stays, right? Yes. Assuming that if we want the page load, because if we just click again, does it change? It does.
We have an error here somewhere. Okay, and what do we actually send? Update. We send this data to be published and we return. We should return the correct value. This is weird.
State equals publish, we update the article. And on refresh we stay on draft. Okay, if we go out to admin, do we have WebSocket? It's in draft. That is interesting. It doesn't switch back though, okay.
Now it switches back to edit, auto draft, even though we send article state publish. Okay, so I assume we have an error in our logic here. Right, so if we have publish true and publish at zero, then we set it. So if data.
publish okay and then up here we set it to say to current article publish add
Let's try again here. Publish. Save. Save. Right. What am I doing wrong here? Let's just log out the parameters.
I'm gonna kill the development server and move it up here. And say publish, save, give it a refresh, save again. What do we have? We have a lot of information here. Where is the, I should probably just have sent the published ads.
valid false. That is why it is turned into...
So it was not a URL bug, it was a backend logic bug. But now our edit article is working. We can save the draft, save the publish. We can create a new article. We have all the elements in place for validation. We should be able to create a draft article. And we get a new article created. We can delete it.
The only issue we have now is that whenever I type in here, you can see that it doesn't correctly keep focus. I can keep typing. So that we need to fix. We also need to fix that we can click any of these rows. We can navigate, but we can't click them. So next episode we're going to be making so we can click the table rows. And also so we can continue typing inside the editor and still have the validation be shown to us.