تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Widgets Overview Setup0:00

Let's talk about widgets in Filament, which gives us the ability to view and summarize data in a variety of places. We can do it on the dashboard. You actually already have two widgets on your dashboard that come standard when you create a panel. You can also have widgets at the top of a resource, like on a list page, maybe you want to summarize what's happened with all the records, or what's the total count, something like that. So let's add a widget to our project right now. We just started working with the Attendee model in the last video, and I want to keep working with that. So we need an Attendee resource. Let's do that really quickly. And we'll use the --generate flag here so we get the form and the table generated for us. And now let's create our first simple widget. So we're going to do that.

Generate Stats Widget0:32

really quickly. And we'll use the --generate flag here so we get the form and the table generated for us. And now let's create our first simple widget. So we're going to do that with the command make:filament-widget. And we're not going to pass anything in here. We're going to let it guide us through what we want. So the first thing is the name of it. So let's call it AttendeesCount, or AttendeesStatsWidget. And what type of widget do we want? We want a stats overview. This is just going to display the current value. We'll go back to a chart in a minute. And where do we want to create this? So this is actually an important question, because it says it's optional here. But if you don't put it in a resource, this is actually going to show up

Register Widget in Resource1:04

this? So this is actually an important question, because it says it's optional here. But if you don't put it in a resource, this is actually going to show up on your dashboard. So you probably don't want to do that. Maybe you do. But for me, I only want it to show up when I go to the attendees list. And we do want to create it inside our app panel. And so now we've got some instructions. We need to register the widget in the attendee resource, and then, again, in getHeader or getFooter widgets. So let's do that first. So in our IDE, let's go to the newly created attendee resource. And we don't have a method here, so we just need to add it. I like to put it down here under the relations. We say getWidgets. And this is just going to be an

And we don't have a method here, so we just need to add it. I like to put it down here under the relations. We say getWidgets. And this is just going to be an array that just includes the one widget that we have. We'll come back and add another one later. So this is going to be AttendeesStatsWidget class. And let's copy this because this registers the widgets, and then where do we want to use them? We want to use it on the list attendees page. So we're going to do a getHeader widget. We want it above the table, not below. And then here we're going to pass in the exact same array. And then we just need to go into this class and create some data here. So we have this getStats method, and why don't we check the FilamentDocs to see what it's

And then we just need to go into this class and create some data here. So we have this getStats method, and why don't we check the FilamentDocs to see what it's expecting here. So when we're in the FilamentDocs, we want to be in the Widgets section. And then let's go down to the StatsOverview widget. That's the one we created. And you can see here that it's expecting these stat classes. And let's copy what we have here and just paste it into our app. And then let's go to the browser and take a look at what we see. So we refresh the page. We have the AttendeeResource here. And when we go here, we can see that it gives us these header widgets that show the data that we passed in. Now obviously this is just hard-coded data. Why don't we see two things?

Compute Stats and Styling2:40

that it gives us these header widgets that show the data that we passed in. Now obviously this is just hard-coded data. Why don't we see two things? We want to see just how many attendees we have total. And then also let's sum up the revenue to see how much revenue we've generated from those attendees. So let's start with the count of attendees. And if we go back to our IDE, we will get rid of one of these. So this is going to be AttendeesCount. And then this one we're going to implement next is going to be TotalRevenue. So now we just need to pass the value in here. This could be as simple as, let's get our attendee model and call count on it. That should actually work. And then on the TotalRevenue, we could do something like

as simple as, let's get our Attendee model and call count on it. That should actually work. And then on the TotalRevenue, we could do something like Attendee::sum('TicketCost'). Alright, let's go back to the browser, give it a refresh. And so there we go. We can see we have six attendees. The TicketCost is actually showing in dollars not cents, but that's fine. If we want to change that, we could do this divided by 100. And there we go. Our revenue is $3,000 off of six attendees. And we have the ability to make these a little more visually interesting. So we can add a description. So we can do that here. And we can hard code something like the total number

visually interesting. So we can add a description. So we can do that here. And we can hard code something like the total number of attendees. We can also add an icon here. A description icon. If we take a look at how that changed. There we go. Total number of attendees here. So that works. You might also want to see at a glance, are these attendees trending up or are they trending down? And you can actually do that with a chart. So if we add a chart method and attach it to the class, we can just pass in an array of values. So let's just say we're adding a single attendee every day.

to the class, we can just pass in an array of values. So let's just say we're adding a single attendee every day. So there's our little chart. And if we go back and review it in the browser, you can see we have this chart here. Now let's say because it's trending up, we like that. That means it's green. It's success. So we can also add the color here and call it success. Now let's take a look one more time. And there we've got that. Now let's say some people are canceling and the numbers go down. We could go back to 411 and save this. And if we refresh

down. We could go back to 411 and save this. And if we refresh you can see the chart starts trending down. And of course we're just hard coding values. That's not what you're going to do. You're going to want to pass closures into any of these things to generate your data. You could also just generate your data here and pass it in that way. So one thing that isn't really working is we've got three columns, but we only have two widgets. So we can change that pretty easily just with the getColumns method. And we override that and we can manually return two. Let's go to the browser and take a look. And there we go. So we've got these two widgets

Build Chart Widget5:20

And we override that and we can manually return two. Let's go to the browser and take a look. And there we go. So we've got these two widgets that are kind of summarizing the table data for us. And these stats widgets are really good for showing what is the status right now of my model. But you also might want to see some of the history. And that's where the chart widgets come in. So let's go ahead and create a ChartWidget now and add it here as well. Before we do that, we actually want to generate a few more Attendees. And let's go into the AttendeeFactory and we're going to change the createdAtDate because that's the date we're going to use for the chart. And instead of just always being now, let's do a faker, this

the date we're going to use for the chart. And instead of just always being now, let's do a faker, this dateTimeBetween. And let's say minus three months and now. Let's go into Tinker and generate like 300 attendees. So I've got the code in here. We just need to generate a Conference first because an attendee belongs to a Conference. And let's spin up 300 of them. So now let's just go back to the browser and make sure that they all work. Let's give it a quick refresh. And so yeah, we've got a bunch of users now. 306. And we've got a lot more revenue. So let's make a chart.

refresh. And so yeah, we've got a bunch of users now. 306. And we've got a lot more revenue. So let's make a chart. And if we look at the createdAt columns here, they're all different. So we're going to be able to see over time how many people have registered for our conference. So let's go back to the terminal and we're going to do a filament widget again. We're going to let it guide us through. This is going to be attendee chart widget. And of course, we're going to select chart here. It is the attendee resource. And it's in the app panel. Now we get to choose which type of chart we want. Now we can do a bar chart or let's do a line chart here. And again, it's telling us we need to

And it's in the app panel. Now we get to choose which type of chart we want. Now we can do a bar chart or let's do a line chart here. And again, it's telling us we need to register it. So let's go do that. Go to the attendee resource attendeeChartWidget. And again, we'll just copy this and bring it over to the listAttendees and paste it here. Now let's go into the chartWidget and see what we have. So in a chartWidget, you're going to define what type of chart with this getType method. So because we chose line, we're going to get a line. And then we have a heading. So let's call this attendeeSignups. So now again, we need to pass in some data. Let's reference the filament docs to see what it's expecting here.

call this attendeeSignups. So now again, we need to pass in some data. Let's reference the filament docs to see what it's expecting here. So from the filament docs, we're going to go to chart widgets now. And we can see down here it's expecting a data set. The data is formatted this way. So let's again copy the hardcoded values for now just to see what we get. And we'll paste it in here. And let's go to the browser and take a look at what we have. So here we go. We have a nice attendeesSignup. And all this is, again, hardcoded here. So these aren't the actual values. We're going to do that next. But we can see that it works here. And again, let's say we're just going to have the one chart. We don't want to add any additional ones.

the actual values. We're going to do that next. But we can see that it works here. And again, let's say we're just going to have the one chart. We don't want to add any additional ones. So we can change this with the columnSpan. And let's just call this full. And it's probably also a little too tall. So let's say a maxHeight. And let's just make it like 250 pixels. Let's go back to the browser and give it a refresh. And we can see this is a little bit better. It's not too tall. And actually, let's even make it 200. There we go. Because we don't want to push the table so far down that you can't even see the table. So this looks nice. Now let's get the data actually working. And to do that, the filament

Query Chart Data with Trend8:36

There we go. Because we don't want to push the table so far down that you can't even see the table. So this looks nice. Now let's get the data actually working. And to do that, the filament docs have a really nice recommendation. So let's go back and reference those docs. And if we scroll down and you can see how to generate chart data from Eloquent, they actually recommend that we require this package. So let's do that. We'll go into our terminal. composer require this package. And if we go back to the docs, we can see that we have this Trend. And the Trend class allows us to basically pass in either a query or a model and choose between what dates and how we want to count it.

allows us to basically pass in either a query or a model and choose between what dates and how we want to count it. So let's copy this in. Let's copy all of this in. And then we're going to modify it for our use case. So here we go. We're going to replace all of this with this. So we do need to import the Trend class. And our model here is Attendee. And so it's going to, by default, look at the created_at date. So we don't have to pass that in. Let's say we want subMonth(3). And the end is just going to be now. And then we can say perMonth.

Add Chart Filters9:40

sub month three. And the end is just going to be now. And then we can say per month. And we want to count the records. So then the label here is signups. We've got our data. We need to import the class. And let's see what we end up with. So we've got this nice little graph that shows us over the last four months we had 46, 93, 110 and then 57. So one of the really nice things that we can do is actually add different filters to the charts and change. Let's say we want to change the amount of time we want to look

actually add different filters to the charts and change. Let's say we want to change the amount of time we want to look back. Maybe we want the last three months. Maybe we just want the last month or the last week. So let's see how we can do that. And we come back to our Chart model. Or sorry, our Chart class. And let's add a filters. So we can return an array here of what options we want. So let's say we want to see data over a week. So this will be the last week. Maybe we want over a month. And then let's say three months. Okay, so these are our options. We also do need to default to one of them.

And then let's say three months. Okay, so these are our options. We also do need to default to one of them. So let's just come in here and add the filter. And it's going to default to let's say three months. And then this is really simply again, this is a Livewire component. So if you know Livewire, this is just a public property on Livewire. And we can access it from here. So if we want to get the filter, we can say this->filter. And now we can use this to change the data that we want to create. So why don't we do a little match here. And we can match the filter. And Copilot's helping us.

data that we want to create. So why don't we do a little match here. And we can match the filter. And Copilot's helping us out here. So let's take the recommendation here add a semicolon, and let's see what it came up with. So the data, if the filter is week, we're going to start a week ago. And you've got this method perDay. So it's going to group the data by day. If we pick month, we're also going to group the data by day. And then if we pick threeMonths, we're going to group it by month. So now let's get rid of this. And let's go ahead and take a look at what we have in the browser. So I'll give it a refresh here.

So now let's get rid of this. And let's go ahead and take a look at what we have in the browser. So I'll give it a refresh here. And now you can see that we have the last three months chosen. But if we update it to the last month it's going to go back. It's going to recalculate the data that we need. And this shows us how many signups we got every day over the last month. And if we go in the last week, we'll get it like that. So a really powerful way to visualize your data here. Now the last thing I want to share that makes this really cool is, let's say we come down here. We haven't added any filters, but let's just do a search here. And so now we've filtered all of those 306 attendees down to just 3 with the filters. Well, wouldn't it be nice if all the data up here

Sync Widgets to Table12:20

And so now we've filtered all of those 306 attendees down to just three with the filters. Well, wouldn't it be nice if all the data up here also reacted to just what is visible in the table? Sometimes you might want this, sometimes you might not. But Filament makes it easy to do. So we can implement this by adding a couple traits on our different classes. Let's go back to PhpStorm. And we're here in the widget, the AttendeeChart widget. So let's go ahead and use InteractsWithPageTable. So let's make sure we pick the correct one here. And then we just need to go to the ListAttendees. And here we need to add a trait. And this is going to be ExposedTable.

And then we just need to go to the ListAttendees. And here we need to add a trait. And this is going to be ExposedTable to Widgets. Okay, and so that sets us up to do the last part, which is we need to actually get the query from this class and send it into the widget. Let's go into the Chart widget, because that's where we added our trait here. And we just need to update the data that we're getting. So right now we're passing in a model, but what we need to do is pass in a query. And here we just need to get the PageTable query. So this GetPageTableQuery. And so we can take this and put it

we just need to get the PageTable query. So this GetPageTableQuery. And so we can take this and put it in here. So this is provided to us by this trait here. So we go back and refresh the page. And we're getting an error here. We have to define a GetTablePage on your widget. So I always forget to do this. Let's go back to our widget class. So we're in the Chart widget here, so we also have to define a GetTablePage. And so, we're going to return the ListAttendees class. And so, of course, we need to do this to tell this class which

List Attendees class. And so, of course, we need to do this to tell this class which List class are we actually getting the query from. So now if we go back to our browser it looks like there's an OrderBy clause that is causing an issue here, and I don't think we care about the OrderBy clause, so I'll bet we can just remove any OrderBy from the query before we execute it. Let's go back in here. We're also duplicating this, so let's get the query and then so we're going to pass in query. Let's do that for the other two as well.

and then so we're going to pass in query. Let's do that for the other two as well. Sorry. We need to get the query here and the orders. This should actually get our Eloquent query and just set any OrderBy to an empty array, which means it won't be ordered. Let's see if this works. And it looks like it did work. So I've got the filter for my name, and we have none until October when we have three. If we get rid of that, this should update.

Widget Polling Controls15:00

for my name, and we have none until October when we have three. If we get rid of that, this should update soon. Now you might be wondering why is it updating? Well, we actually have polling on widgets. You may not want polling on widgets but it is good to have, especially if you're tying your widgets to any filters that are being applied here. If you want to change that you can change the polling interval on your chart. You could just say poll, and let's say we want every one second because we want it to update as people are making changes here. So if we start searching here, this is going to update

because we want it to update as people are making changes here. So if we start searching here, this is going to update pretty quickly. I think the default is 10 seconds, and it ensures that the charts reflect the data that is changing in the table. Now you may not connect them, you may not do any of that. A lot of times if I'm not connecting my table to my widgets, I will actually set the polling interval to null, and then it will never poll, and the refresh will only happen when I tell it to. So that's another option for you. Now let's go ahead and make the other chart update with this just so we can make sure that it's all working the same. We'll do

Now let's go ahead and make the other chart update with this just so we can make sure that it's all working the same. We'll do the stats widget, we'll add this. Remember we have to do the getTablePage and we need to pass in the listAttendees. Let's import. And then of course in the data here, we can't just hard code this, we need to get the query. So this getPageTableQuery, count I don't think we're going to have the issue with the orderBy, that shouldn't matter here. And same thing here, let's just do

Dashboard and Custom Widgets16:36

I don't think we're going to have the issue with the orderBy, that shouldn't matter here. And same thing here, let's just do this get page table query, and let's go back and take a look, and give it a refresh, and everything seems to be good. And if I search for Kevin, we're down to 3 and 1500. So everything's working there. The reason the chart didn't update, again, is because we updated the polling. So if it doesn't poll, it's not going to get the new data. So let's finish up by looking at the other types of widgets really quickly. Like I said on the dashboard, if you wanted to add something to the dashboard, you could do that. Let's go back to our terminal, let's make a Filament widget.

Like I said on the dashboard, if you wanted to add something to the dashboard, you could do that. Let's go back to our terminal, let's make a filament widget test chart or actually, let's not even make it a chart. We're going to delete this so it doesn't matter. We could do a table. This is probably only going to be used on dashboards. You probably don't want to add a table widget to a list attendees, which already has a table. So think about that for your dashboard stuff. And then custom, it's literally just a Livewire component, and you can build whatever you want in it. So if you need to make something custom, that's available to you. So let's just do a custom one. We're not going to create it.

Livewire component, and you can build whatever you want in it. So if you need to make something custom, that's available to you. So let's just do a custom one. We're not going to create it inside a resource. We'll put it in the app panel. And so this test chart is available. If we go to the test chart and pull it up, we just have this view here for a string. And let's just type hello. And go back to our dashboard. You can see we have a widget here that says hello. So this is a Livewire component. You can do whatever you want, whatever you would normally do in any Livewire component, and make it work here. Again, all those modifiers and properties that we had in the others.

Remove Default Dashboard Widgets18:12

whatever you would normally do in any Livewire component, and make it work here. Again, all those modifiers and properties that we had in the others work here as well. So if we want the column span to be full, we'll do that here and refresh. And it works. Now lastly, you might want to get rid of these widgets here. They're nice as a kind of demo when you start building your app, but you probably, you may not want those when you deploy your app to production. So let's take a look at that. If we go to our app/Providers directory, you'll see in here we are discovering widgets in this folder. So that's why when we just created that widget it ends up in that folder. And we tell Laravel

widgets in this folder. So that's why when we just created that widget it ends up in that folder. And we tell Laravel in the AppServiceProvider to go find those and put them on the dashboard. And then we also are manually passing in these two widgets. So if we take this modifier off entirely and refresh, you'll see now that those are gone and we just have the ones that we wanted to add. Thanks.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟