Transcript from the "Forms" Lesson
>> Okay, let's talk about forms, one of my favorite topics. So in the chat on loading, we saw how to get data from the server to the browser, but sometimes you need to send data in the opposite direction. You need to get data from the browser back to the server, and that's where the form element, which is the web platform's way of submitting data comes into play.
[00:00:19] So let's build a little todo app. We've already got an in memory database setup in this lips of a database module, and we're just putting everything in a map. Obviously in a real app, you would use an actual database but we're not gonna do that for this tutorial.
[00:00:33] And we have a load function in source/routes/page.server.js, that uses the cookies API to get ahold of the current user ID, if the user doesn't yet have an ID, it assigns one. It gets the todos that belong to that user. So this allows us to have a per-user todo list, but we need to add a form so that we can create new todos.
[00:00:54] So go over to src/route/page.svelte, and below the H1, we're gonna add a form element With a method of post, cuz we're gonna post some data to the server. Inside there, we'll create a label, Add some text, add a todo, Then we'll create an input. Give it a name which is gonna be description.
[00:01:29] And I'm gonna disable autocomplete as well. So we can now type into this form and submit some data, but we get a 405 error because no actions exist for this page right now so we can fix that. What we need to do is create an action in our page.server.js file.
[00:01:54] This is the counterpart to the load function. So down here, create an actions object. And we're gonna create a default action, Which is gonna be an async function. That's gonna grab the cookies and the request object. And first of all, is gonna grab the description from that input by requesting the form data And getting the description.
[00:02:33] And it's gonna create it todo in the mat that belongs to the current user. So db.createTodo(cookies.get(userid) data.get Description. Okay, this request object here, this is a standard request interface that is part of the web platform. You can learn about the request object on MDN if you're not familiar, it's something that you'll use a lot in web development.
[00:03:09] And SvelteKit uses standard web APIs as far as it can. When we call await request.formData, that returns an instance of the FormData API, which is the same object that you get in the browser if you call new FormData, and then pass in a form element. So now if we type in some data, And hit Enter, post it to the server, you'll see that it reloads the page with the new data.
[00:04:40] Most of the time you will need to have multiple actions on a page. So in the case of our todo app, we wanna be able to delete todos once we've completed them. First thing we're gonna do is get rid of the default action and turn it into a named action, call it create.
[00:05:36] Now the first thing we wanna do before we implement the delete action inside our page is we need to update the form action that creates the todo. So go back to page.svelte, scroll up to the form, and we're gonna add an action attribute. By default, the action is the same as the current page.
[00:05:56] And so if you just have form method equals post without specifying an action, that is gonna call the default action on the page that you're currently on. But in this case, we wanna use a named action. We'll do that by adding a query parameter with a value of create with a slash in front of it.
[00:06:18] So what this means is we take the current URL and we append a query string with a parameter whose name is /create and which doesn't have a value. And that tells SvelteKit that we're trying to invoke the create action on this page. Now the action doesn't have to be on this page, you can actually have an action that points to a different page entirely, which is very useful when you're building things like login and logout forms that should exist on all pages of your app.
[00:06:54] Okay, so lastly, we wanna create a form for each of the todos in our list. So inside here, instead of just having that description, lead form method = POST, Invoke the delete action. And you'll recall that inside the action, we were referring to an ID property that we need to make available.
[00:07:20] So each todo has an ID already. And to add that to the form without showing it to the user, because the user doesn't want a random string of digits, we'll do input type = hidden, give it a name of id so that we can get it with form.getid, and the value is gonna be todo.id.
[00:07:52] Let a span containing the todo description. And then we're gonna add a button with a label So that people who can't see the icon that is about to appear can also understand what this button is going to do. Okay, you'll see that we have these little trash can icons down here that's coming from the remove.svg which is being controlled down here with some CSS.
[00:08:32] So if we've wired everything up correctly, then we should now be able to delete todos as well as add them. And indeed it works. And so if we refresh the page, we'll see that those todos stay deleted.