Intro to Filament Forms0:00
Now let's dig into the Filament Forms functionality. So if we go to the Filament Docs and we go into the Form Builder Docs, we're going to go to the Getting Started here, and this is going to show us information about Filament fields that we have. So you can see that Filament has a lot of different options of different types of fields that you can implement within your forms. And then in this Getting Started documentation section, this gives you things that apply across the board, no matter which one of these you choose. So we're going to dig in and understand how these work a little bit. Now before we do that, what I want to do is set up hot reloading so that we can see the changes we make in the back end and how they reflect in the front end.
Setting Up Hot Reloading0:32
Now before we do that, what I want to do is set up hot reloading so that we can see the changes we make in the back end and how they reflect in the front end. And we have to do a little bit of work to make that happen in Filament. So let's go ahead and do that now. Let's open up phpStorm. The first thing we need to do is update our vite.config.js a little bit. So let's go to our vite.config.js file. And you can see here you define when you want to refresh the page. And we need to do a little bit of work here. So instead of just importing Laravel, we also need to import RefreshPaths. And so this is the standard RefreshPaths that are going to be used here when this is set to true. And instead of just doing that, we need to deconstruct an array
And so this is the standard RefreshPaths that are going to be used here when this is set to true. And instead of just doing that, we need to deconstruct an array with RefreshPaths. And then we need to add a couple more. We want App, Livewire, StarStar. And we also want the Filament directory here. So this is going to tell Vite to look in these directories. And whenever something is changed or saved in those directories, let's hot reload the browser. We're not done yet. We have to do one more thing. Let's go back to our AppPanelProvider. And so now here, if we go down to the bottom, let's add another method. This is going to be the register method. And I've just pasted this in here.
And so now here, if we go down to the bottom, let's add another method. This is going to be the register method. And I've just pasted this in here. So what we're doing is we're taking what's in the parent register method, but we're also adding the FilamentView we want to register a render hook. You don't need to fully understand what this is doing here. But basically what this is just doing is making sure Vite can recognize the pages within our FilamentPanelBuilder and do the hot reloading when it needs to. So we just need to import some of these views here. So now I'm going to bring my browser in here, and we're going to look at the code and the browser at the same time.
So now I'm going to bring my browser in here, and we're going to look at the code and the browser at the same time. And lastly, let's open up our terminal. We do need to npm install. We never actually did this, so everything was working without running npm install. And we need to run npm run dev. So now that we have our dev server running, let's go ahead and go back to phpStorm. And let's go back to our conference resource here. And so this is the form that we're looking at right here. Let's see if we want to update the label to conference name. I'm going to hit save.
TextInput Basics and Labels2:30
Let's see if we want to update the label to conference name. I'm going to hit save. And there you can see we've got hot reloading in our browser. So now as we make changes, you'll be able to see what happens here. So this is the first thing we did. We can change the label. So this name here, what you need to pass into the static make method is exactly what the database schema has defined for this field. So this is called name in our database. So that's how we tell filament. This is the field we're going to update as you type into this input. Now the label, we can make it whatever we want.
This is the field we're going to update as you type into this input. Now the label, we can make it whatever we want. So like we just updated it to conferenceName. If we just change it to conference, that's what it will be. We have validation. We actually have a lot of things available. Let's go ahead and go into the TextInput class and take a look at the TextInput and all the other ones we looked at previously extends this BaseField class. So if we look at this, there's a couple of things that we know we can do. We can autofocus the field. We can mark it as required, validate, have helper text, hints, and names.
We can autofocus the field. We can mark it as required, validate, have helper text, hints, and names. So all of these things, like I said, apply to every field that Filament offers. So as you're working with the different types of inputs, just remember that this stuff is available to all of them. For example, it can be marked as required. If we go back to our Conference resource, we have this marked as required. If we comment that out, you can see that the star is now gone and this field is no longer required. Obviously, our database schema defines that this is required,
and this field is no longer required. Obviously, our database schema defines that this is required, so we do want to make it required. So there's so much more we can do with this. Let's keep looking at a few options. Let's say you want it to be required, but you don't want this star here for whatever reason. You can even modify that. So if we do mark as required here and we just set that to false and save, now this field is going to be required on the back end when it's validated,
So if we do mark as required here and we just set that to false and save, now this field is going to be required on the back end when it's validated, but we don't have it marked as required here. So being required is just one of many validation features that Laravel provides, and there is a lot of validation that Filament provides out of the box too with these fluent methods that you can chain on. So we actually already see maxLength here is set to 255. Maybe we don't want our name to be that long, so we could set that to maybe 100 or 60. There's other things that we can do.
so we could set that to maybe 100 or 60. There's other things that we can do. For example, requiredIf, and we can pass in a closure to define what condition this would be required under. Basically, if you look at the Laravel validation docs and take a look at all the different options you have, you're most likely going to find a method here that you can chain onto your input that will do that validation for you. Now, I say almost everyone, not every single one has been built that way, or you might be creating your own custom rules in Laravel.
Now, I say almost everyone, not every single one has been built that way, or you might be creating your own custom rules in Laravel. And so if you need to add those, you can just add a rules method here. And if I did rules max 60 and deleted this, it's going to end up doing the exact same thing. And of course, if you needed to pass in, this could be an array of rules, you could have this. And if you created a new custom rule, you could add a comma here and say newCustomRule, import that, and you'd be able to have access.
Helper Text, Hints, Prefixes5:21
you could add a comma here and say new custom rule, import that, and you'd be able to have access to your custom validation methods as well. Now, let's just go back and bring this to where we were before. They actually have a lot of control over this input and the different ways that it renders in the browser. So let's take a look at sometimes it's nice to give your users some in context help of how do I fill out this field. So we have a couple methods for that. We have helper text, we can just say this is the name of the conference.
So we have a couple methods for that. We have helper text, we can just say this is the name of the conference. You can see now that we've updated with this little helper to help our users figure out what they need to do. Also, we have the option to add a hint. So here is the hint. And if we save that, you can now see that we can put it over here in the top right as well. You could even add a hint icon. And so if we wanted to,
You could even add a hint icon. And so if we wanted to, I don't have any of the other Heroicons memorized, but let's just say for whatever reason we wanted the stack, we can do that and you had an icon there. So it's really customizable and flexible to make it look the way you want it to look. Another thing you might've noticed is there's actually even a hint action. And so we'll get into actions more later,
is there's actually even a hint action. And so we'll get into actions more later, but you could actually even give people a hint here that would link out to your documentation or something else that might give them more information about how to actually complete this field. Another thing that you can do is make your input look really nice. So we can add prefixes and suffixes as well. So let's pretend the conference had a website field. So another thing we can do is we can actually call this a URL
So let's pretend the conference had a website field. So another thing we can do is we can actually call this a URL and that will do the URL validation. And then we can say a prefix. Let's just say we want it to look like this. So if we save here, we now have this prefix here. You can't type into it, but lyriconf.com. We could even just give our users some visual cues that instead of HTTPS, we could do a prefix icon. So let's take this and change it to Heroiconoglobalt.
that instead of HTTPS, we could do a prefix icon. So let's take this and change it to Heroiconoglobalt. And now we have this. And of course, for the label, let's change this to website just so everything makes sense. So you can do different things like that. You could also add a suffix. Let's pretend you know, for whatever reason, that the website is always going to end in a .com. We can do that.
that the website is always going to end in a .com. We can do that. And you've got a really nice looking text input. So let's bring this back to something that makes a little bit more sense. Remember, this was the name. Let's get the label. And lastly, we can also add, this is something you'll use a lot, a default value. So, you know, my conference here.
this is something you'll use a lot, a default value. So, you know, my conference here. Now, when I save this, nothing's going to update over here. The reason why is because we're on an edit page. So even though this form is being shared between edit and create, the default only applies when you're creating a new record. Even if this field were null, we expect because we're editing it, it is intended to be null.
we expect because we're editing it, it is intended to be null. So if we get out of here and try to, let's go back to our conferences and add a new conference. You can see it defaulted to my conference because we're on the create. But again, during the edit, that default is not going to do anything. So let's move down here. And instead of a text input for the description,
Rich Text, Markdown, Dates8:35
So let's move down here. And instead of a text input for the description, what if we wanted this to be a rich text editor? So we could do something like that. And you can see now we get this really nice, beautiful rich text editor with a bunch of different options here. Now this actually, in my opinion, maybe has too many options. So we can change that.
maybe has too many options. So we can change that and we can disable certain toolbar buttons that we don't want. So let's say for whatever reason, we don't want the italic. And now you can see italic is gone. Or if you don't want to, you know, start with everything and disable, you could instead just choose
you know, start with everything and disable, you could instead just choose which toolbar buttons that you want to use. So let's say we only want heading and bold, then we can do that too. It's not actually heading, it should be H2. And there you go. So you can fully customize what you want your rich editor to look like. If you don't like a rich text editor
what you want your rich editor to look like. If you don't like a rich text editor and you want markdown, that's supported as well. So if we do that and save, we've got, you know, some different things here. And then you can actually type markdown within here. Just like above, if we want to add a helper text, we can do that as well.
if we want to add a helper text, we can do that as well. So let's say we're happy with this and we're going to move on down to the date time picker. And maybe we just want a date picker. So we can change it to a date picker. So this one only has a date. This one has the date and the time. And these are your browser native date pickers.
This one has the date and the time. And these are your browser native date pickers and date time pickers. So you can see how that looks. If you don't like that and you want not the native version, there is actually a third-party JavaScript library that you can use for a date picker as well. And so that's a little bit different experience. So you get to choose which one you like.
And so that's a little bit different experience. So you get to choose which one you like. This works as well for the date time picker. So you can paste that in there and we'll do a refresh. And now the end date, this has the different date and the time here as well. So you can see how that works pretty nicely. And let's take a look at one more different type of input.
Toggles, Selects, and Migrations10:24
So you can see how that works pretty nicely. And let's take a look at one more different type of input. So I'm going to add a new one here for a field that doesn't actually exist in our database schema yet, but we have a toggle. And so we can import the toggle. We'll make, let's say isPublished. And let's say in this app, once you publish,
And let's say in this app, once you publish, this is going to actually like publish a website that people can use to find information about the conference. So if we let Copilot fill in some of this stuff here, we've got its default set to true. It's required. We don't actually want it to be required because it could be either or.
We don't actually want it to be required because it could be either or. So let's get rid of that. And you've got this nice little toggle that you can click on and off. And then this would just update the database, whatever field you have created that is published as a Boolean. If you don't like the toggle, you could change this to a checkbox.
If you don't like the toggle, you could change this to a checkbox. And when we save, it's a different UI experience. So for the status here, as we're moving on, this is not actually going to be a text input. It's going to be a select and max length doesn't make sense on a select. So let's get rid of that.
and max length doesn't make sense on a select. So let's get rid of that. And if we do a little refresh here, we have an option to select, but we don't have any options in here. So we could just add an options and give it a nice refresh. And now you can see we've got these options here, but I'm going to stop there because selects are so valuable and so important.
but I'm going to stop there because selects are so valuable and so important that I'm going to just devote the whole next video to select pickers and combo boxes and how you can use those. But before we do that, let's go ahead and make some changes to our database schema because let's say we do want 60 max length here. We want this to actually be a text.
because let's say we do want 60 max length here. We want this to actually be a text. I don't want a max length of 255 on the description. So let's change that to a text and let's add this published. Let's go back to full screen here and let's go to our create_conferences migration. All right, so instead of a string, we're just going to call this a text. Let's say we want this to be a max of 60.
we're just going to call this a text. Let's say we want this to be a max of 60 and then we wanted to add a boolean for isPublished. We'll default that to false. Another thing I like to do in my migrations, this is just personal preference, totally up to you. I like foreignId for user_id and then pass in the class. So I'm just going to make that little change. And if I go back to my terminal, I can clear out our dev server.
And if I go back to my terminal, I can clear out our dev server and just run php artisan migrate --fresh --seed. And so we're all done. So in the next video, we're going to go really deep into the select pickers and show you a little bit more advanced forms functionality.
