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

Scaffolding Custom Field0:01

As you've no doubt realised by now, Nova has many different options when it comes to fields. So many in fact that you very rarely need to reach outside the box for anything custom. But if you do want something more specialised, Nova absolutely has you covered. In our case, on our reviews index, we represent the star rating of a review using nothing more than an integer. But if you go on a webshop, you usually see iconography for star ratings. Five stars either filled in or outlined. And I think it would be nice to bring that into our admin panel as well. So why don't we go ahead and create our very own star rating field in Nova. It all starts, as most things do, from the terminal. php artisan nova:field

It all starts, as most things do, from the terminal. php artisan nova:field And you format the name of the field as you would format a composer dependency or an npm dependency. In our case, I'll prefix with the name of our website. And then using kebab case, I'll provide the name of our field, star-rating. During the installation process of creating a custom field, you'll be asked a series of questions. And I highly recommend you answer yes to all of them. It will make your life a lot easier. Once Nova has finished scaffolding your new field, you'll find a new nova components directory at the root of your project,

Building Field Assets1:20

Once Nova has finished scaffolding your new field, you'll find a new Nova components directory at the root of your project, under which you'll find the field you've just created, in our case, starRating. Note that it has its own package.json file and its own node_modules folder. It's entirely siloed outside of being symlinked into your project. And that means you can even create third-party fields that you can share around different projects. It's a really cool way of doing things. Because it has its own separate package.json file and its own mix file, we need to tell it to build and compile our dependencies. Thankfully, we can ask it to watch our dependencies for our field.

Using Field in Resource1:58

we need to tell it to build and compile our dependencies. Thankfully, we can ask it to watch our dependencies for our field so that we don't have to keep building whilst we're editing the field itself. I'll cd into the Nova components/star-rating directory, and I'm going to run the npm run watch command in order to compile and continue to compile our field whenever we make changes to its source code. Now we need to make use of it in one of our resources. So inside our Review resource, I'm going to replace number here with our starRating field. And since our starRating field doesn't have min or max methods, I'll remove those. I'll keep the rules in place though because they make a lot of sense.

And since our star rating field doesn't have min or max methods, I'll remove those. I'll keep the rules in place though because they make a lot of sense. Now on the front end, everything works more or less as it did before. I see the number 4 here. If I click to view details, I see 4 again. If I click edit, I see 4 again down here. Note that we're no longer using a number input though. This is a text input. Let's go ahead and make the needed changes inside the IDE. Inside our star rating field directory, I'll go to resources/js/components,

Editing Form Component2:57

Let's go ahead and make the needed changes inside the IDE. Inside our star rating field directory, I'll go to resources/js/components, and note that you have 3 options to choose from here. The detail field is the field that will show on a detail page. The form field will show on any forms, and the index field will show on the index. Let's start with the form field and work from there. Obviously it's wrapped inside this default field component, and the defaultField component will give you all of the chrome necessary to display your field in a nice, presentable manner. So I'd recommend leaving that in place if at all possible.

to display your field in a nice, presentable manner. So I'd recommend leaving that in place if at all possible. The input default type is text, and we saw confirmation of that in the browser. Let's change that back to number, and why don't we hard code min of 1 and max of 5 whilst we're here. That should be all the changes we need. We still want to represent it as a number field in the front end, so this should work just fine. If I try to go above 5, I'm not allowed. If I try to go below 1, I'm not allowed.

Rendering Stars on Index3:57

If I try to go above 5, I'm not allowed. If I try to go below 1, I'm not allowed. And now I can update the review and everything should save as it did before. I can see one star here. If I go back to reviews, I see one in the index as well. Okay, why don't we now play around with changing the stars on index so that we can see that iconography we were talking about. I'll open up the index field.view component, and currently we can see exactly what we'd expect, a basic output of the field value.

and currently we can see exactly what we'd expect, a basic output of the field value. Instead of doing that, why don't we create an unordered list. Inside that unordered list, we'll do a for loop, and I'll foreach over a range of n in 5, seeing as there will be a maximum of 5 stars. Then I need to output an SVG dependent on the field value. We'll grab the SVG from Heroicons. Let me copy the SVG for a star, and then we can paste that directly into the browser here.

Let me copy the SVG for a star, and then we can paste that directly into the browser here. I only want to show the filled in star if n is less than or equal to the field value. Otherwise, I want to show the outline SVG, so I'll copy the source code for that from Heroicons, and I'll paste it down here, and obviously I can slap a v-else on that. I wonder if this will work. We'll refresh our index, and sure enough, we have a bunch of stars that do show the correct values,

We'll refresh our index, and sure enough, we have a bunch of stars that do show the correct values, but it looks hella ugly. We need to fix that immediately. Because Nova uses Tailwind, we're welcome to use Tailwind classes as well, where it makes sense inside our custom fields. So here let's add flex as an option. Let's say the text should be text-yellow-500, seeing as that's the correct color for a star,

Let's say the text should be yellow 500, seeing as that's the correct color for a star, and we'll drop this to heights and widths of 2, and heights and widths of 2. Okay, the stars themselves look much better. The sizing is correct, but they're still showing vertically instead of horizontally, and that's because I've been a bit of an idiot, and I've not wrapped this correctly in HTML. Let's create a list item inside the unordered list.

and I've not wrapped this correctly in HTML. Let's create a list item inside the unordered list where we loop over the n in 5, and then I'll wrap the SVGS inside that list item like so. Let's see how that looks. That is much better, and this is looking very much like the classic star rating you're used to seeing on all those different websites. One thing I will say is that a few fields are showing 0 stars. What that actually is is that there is no value set.

One thing I will say is that a few fields are showing 0 stars. What that actually is is that there is no value set. I don't want it to seem like there are 0 stars. I'd rather just show a dash, so we can change to implement that functionality. Where we have our unordered list, I'm going to do a v-if check, and I'll check if there actually is a fieldValue. If there's not a fieldValue, I can use v-else, then I'm simply going to show a dash in its place.

If there's not a field value, I can use VELTS, then I'm simply going to show a dash in its place, and when I refresh this, yeah. Now for null values, we just see a dash, which I think is much clearer and easier to understand. Now you could absolutely call it a day when it comes to our custom field here, but I want to go a little bit further and allow us to customize the maximum number of stars we're able to set inside php, inside our resource.

Adding maxStars Metadata7:05

and allow us to customize the maximum number of stars we're able to set inside php, inside our resource. So where we have starRating here, I want to be able to say something like maxStars, and pass, let's say, 10, and I can change the max in the rules here, and see that update in the front end. In order to do this, I'm going to have to add a maxStars method to our field itself.

I'm going to have to add a maxStars method to our field itself. So we'll set that here, maxStars, and it will receive an integer with the maximum that you want to set, and it will return a method called withMeta. So this is where you will set any data that will be passed down to your front end view component. In our case, we'll set a property called maxStars, which is just going to be equal

In our case, we'll set a property called maxStars, which is just going to be equal to whatever we've set here in the method. Now in our index, we want to update this hard-coded five to instead check for those maxStars, and I'm going to perform this check in a computed property. We'll call it maxStars, like so, and I'll return this.field,

We'll call it maxStars, like so, and I'll return this.field, and any custom metadata you add will be a property on the field. So this.field.maxStars, or 5 as a default. And now instead of calling 5 here at the top, we can instead just check the value of maxStars. Now in our browser, when we refresh, we should see 10 stars for each item in the index. Obviously, if I click to edit this,

we should see 10 stars for each item in the index. Obviously, if I click to edit this, we're still only going to be able to go up to 5 here because our number input has a hard-coded maximum of 5. We need to change that as well. So in the form field where we have our input max, I'm going to alter this to instead check for the field maxStars, or again, if we haven't set one, we'll fall back to 5.

or again, if we haven't set one, we'll fall back to 5. And now in the browser, when we refresh, we should be able to go up to 10. Sure enough, we can. So that's how simple it is to add custom methods in php, in your Nova resources, that then show and display on the front end by passing metadata between the two. The only thing left to do is come back into the terminal,

by passing metadata between the two. The only thing left to do is come back into the terminal, stop running npm run watch, instead run npm run prod, which will build our JavaScript and CSS ready for production, and we can ship the distributed files along with our source code. And, well, that's really all you need to know about creating custom fields in Nova. Again, you very rarely need to reach

about creating custom fields in Nova. Again, you very rarely need to reach for anything like this, but if you do, it's so nice to know that Nova allows you to leave the white picket fence and start your own adventure.

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