در حال بارگذاری ...

Introducing Infolist Components0:00

So now we have our own custom form components. We have a custom color picker and a custom section. Now these can be used within forms. And forms in the admin panel would be anything on the create or edit pages of a resource. But on the Vue page, users can choose to use an infolist instead of a form. Now an infolist is a specialized read-only Vue, whereas a form is something that's editable. Since these are read-only, they do require separate components to be created. And these are called infolist components. So let's go about making a color infolist component and a section infolist component that complement our two custom form components.

Generating a Color Entry0:38

So let's go about making a ColorInfolist component and a SectionInfolist component that complement our two custom form components. Each of these in the infolist, here with the label, is called an entry. And an entry is the equivalent of a field for an infolist. So a field has state and it holds state from the database, for example. Now an entry also holds state and it has state from the database or an array. Let's create our color entry. So using php artisan make:infolist-entry. And it's going to ask us for the name of the entry. So in this case it's going to be colorEntry.

And it's going to ask us for the name of the entry. So in this case it's going to be color entry. Now Filament does actually include a color entry by default. So the color entry looks like this from Filament\Infolist\Components. You can pass in the name of the entry and pass in the data for it. So color. And we can pass in red here. Now if we refresh, this is what the default entry looks like. So we've just got a color, no text or anything. We can even pass in multiple colors.

So we've just got a color, no text or anything. We can even pass in multiple colors. So for example, green. Let's recreate this but also add a few more features along the way. So we can drop this down just to be simple. Just down to one color again. And instead of the infolist component's color entry, we can use our own color entry. So color entry from the infolist components namespace inside app. If we refresh, I'll show you exactly what we've got. The view for this entry is rendering the state just raw.

Rendering Color Blocks2:35

If we refresh, I'll show you exactly what we've got. The view for this entry is rendering the state just raw. And what we want to do is translate this into an actual block of color. So I'm probably going to use inline CSS for this. Simply because it makes it very easy for us to pass in raw value straight into CSS from the server. So let's make a new style tag. And the background-color is then going to be output as the state. Now if we refresh, this isn't actually going to do anything because that div doesn't have any height or width. So we should add that height and width. So height 5 and width 5.

So we should add that height and width. So color height 5 and width 5. Refreshing that doesn't look like... Oh, class not color. There we go. So we've got a block of color and we probably want to make this look slightly rounded as well. Maybe rounded like that. Cool. And maybe we want to even go further. And when you hover over a color, we want to show the raw color in a tooltip.

Adding Hover Tooltips4:00

And maybe we want to even go further. And when you hover over a color, we want to show the raw color in a tooltip. Now filament does ship with a tooltip library. And you can use it with the XTooltip directive in Alpine. So we can use XTooltip raw and then just pass in our state. We also need to initialize an Alpine.js component so that we can use the tooltip. So now let's hover over this and we have our raw value of the color. Now how do we handle the case where either one color can be passed in or indeed an array of colors? Let's leave this array here and think about that. So when we're passing in an array, the state here in this variable is going to be an array too.

Supporting Multiple Colors4:45

Let's leave this array here and think about that. So when we're passing in an array, the state here in this variable is going to be an array too. So this is going to be our raw color codes. Now since this could also be a string, we could use Laravel's ArrayWrap helper. And that basically ensures that if the state is already an array, it stays as an array. But if it's not an array, then it will wrap it in one. And this will make the state much more easy to handle I think. So the Array helper is part of the Illuminate\Support namespace. If we ArrayWrap, we get the same. But if we make this a string again, we now get an array for that as well.

If we ArrayWrap, we get the same. But if we make this a string again, we now get an array for that as well. So that's much more useful for us. And we can now just take this and loop through it with a forEach. So forEach and then our array as state. So each item in this array now has its own div. And we can quickly replace this state here. So now we can render two colors, and they both have their own tooltips. Now since we do have a tooltip here, and we have an Alpine component for each color, we probably can extract this out into a parent div.

Now since we do have a tooltip here, and we have an Alpine component for each color, we probably can extract this out into a parent div. Simply because then we have one Alpine component for the entire entry, instead of having to make one for each color. Which is probably going to work out better for us in the long run. So we can pass in state here. That looks good. We probably also need some styling here to make sure they're not touching. And they could be next to each other. So FlexFlexWrapGap1 maybe.

Configuring Dynamic Width6:45

And they could be next to each other. So FlexFlexWrapGap1 maybe. And we have our styling. Now configuration for entries is very similar to configuration for other components. So we pass in our width method and our getWidthGetter and our width property. I'm just going to copy this from our color picker, because we've already done most of the work. So let's copy this in. And make a width option for our color entry. So now people should be able to pass in a width like this. By default it probably should be 5.

So now people should be able to pass in a width like this. By default it probably should be 5. So let's also add options for 4 and 6. Let's pass in 4 just to test. And we want to be able to make these classes dynamic. So the way I do that normally is using the class directive. And this allows us to pass in a dynamic class. So, for example, we could pass in height5, width5 as a string. And this is only going to be rendered in the HTML if the width from the getWidth method is 5. And we could repeat this.

And this is only going to be rendered in the HTML if the width from the getWidth method is 5. And we could repeat this. So we go, if the width is 4, then output the height4 and width4. If the width is 6, then we output that. And that should work. What's going wrong here? Oh, we need to also extract the static class here into its own string. So we don't have two class directives. Cool. Now we have 4 and we can make that 6.

Cool. Now we have 4 and we can make that 6. But what happens if we leave the width blank? We now have nothing. And that's because the width is null by default. Now we could go in and go, if the width is 5 or the width is null, then do that. But if someone puts in an unsupported width, it's probably better that we just render 5 instead. So we can extract this into a match statement. And a match statement will help us clean up this code. So we can go, getWidth, and then each arm of the match statement handles a new size.

And a match statement will help us clean up this code. So we can go, getWidth, and then each arm of the match statement handles a new size. So we can go, 4 translates into height4, width4. 5 translates into height5, width5. And our default could be height6, width6, for example. So let's get rid of that. Now this match statement is going to be returning a string. So it will just get merged in with this rounded class. So we have our two width6 colours. And we can pass it in 4.

So we have our two width6 colours. And we can pass it in 4. And we could pass in 5. Now this is good. But I think we can enhance this a little bit by allowing the user to customise the width for each colour individually. So I'm thinking the syntax for this could be passing in a closure to the width, being able to receive the state here. So the state here is going to be the name of the colour. And then return a width from here. So return 3, or 4, or 5, or 6.

And then return a width from here. So return 3, or 4, or 5, or 6. And this will make it dynamic based on which colour it is. So let's get rid of that for now. The way we do this is essentially passing in the current state into this getWidth getter. Now since this is a variable that's mapped to this getWidth method on our entry, it also accepts arguments. So we could pass in the state here, which is going to be our colour. And when we evaluate, we can pass in the state as a parameter to the closure, like this. Now this parameter is only going to be used when we evaluate here.

And when we evaluate, we can pass in the $state as a parameter to the closure, like this. Now this parameter is only going to be used when we evaluate here. It's not going to be used on any other evaluate method. So that gets passed in. And we pass in our $state to the getter. Now if we run our function and we accept the $state, we can use a different match statement to determine which size to use based on the colour. So let's do... If the colour is red, then it should be 4. And if the colour is green, then it should be 6.

If the colour is red, then it should be 4. And if the colour is green, then it should be 6. Now this is going to be returning a string. No, this will be returning an int. And the colour has been passed in successfully. And now the width is different per colour. Making use of function evaluation like this will make your component very flexible and that's especially useful if you're going to be releasing it as a plugin.

Creating a custom infolist entry class and view using the CLI. Consuming a custom infolist entry in a Filament infolist. Defining configuration options for a custom infolist entry using getter and setter methods. Allowing infolist entries to render multiple pieces of data at once. Using the Alpine Tooltip package to dynamically rendering a tooltip popup in a view.

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