Introducing Dirty States0:00
When you work with forms, you will eventually need to work with dirty states. Now, if you're not familiar with that term, it's basically just when the form data has changed from its original value. It can be at the form level, or we can apply that same terminology to the individual form fields. And implementing your own dirty tracking system is, eh. But thankfully, Livewire has this covered. It's built in, and it's very easy to use. At the most basic level, we want to display a message when the form data has changed. So let's add a div, and let's say that the form data has changed.
Showing Dirty Messages0:38
At the most basic level, we want to display a message when the form data has changed. So let's add a div, and let's say that the form data has changed. Now, of course, if we were to view this in the browser, we would see this message, because, well, it's right here. We're not hiding it or anything, but we only want to display this when the form data has changed. And we can do so with the wire:dirty attribute. This hides the element that it is applied to, and it will only show it when the data has changed. So that can be for the title, or it could be for the content, or the published value,
has changed. So that can be for the title, or it could be for the content, or the published value, or even the notification options. It doesn't matter. If the data is different, the form is dirty, and therefore, our message has changed. Now, we can do the exact opposite by using the remove modifier. In this case, the form data has not changed. So now in the browser, we see our message that the form has not changed. But if we make a change, then our message is removed from the document. And there are times when we will want that functionality.
Targeting Specific Fields1:38
But if we make a change, then our message is removed from the document. And there are times when we will want that functionality. But most of the time, we want to display something when the form is dirty. And we usually want to do it for a specific form field. Like, for example, I want to display a message only when the title has changed. I don't care about the content or anything else, just the title. And I can do that by using another attribute called wire:target. Then we specify the property that we want to watch. In this case, it is the title from the form. And now we will see our message only when we change the title.
In this case, it is the title from the form. And now we will see our message only when we change the title. If we make a change to the content or anything else, we are not notified of those changes. And that is incredibly useful because that gives us the ability to, well, provide a very nice user experience. Like, for example, we can add an asterisk to each one of the labels to show the user that, hey, this data has changed. So let's do that. Instead of a div element, we're going to use a span. And let's cut this out because we're going to paste it in in a variety of places.
Instead of a div element, we're going to use a span. And let's cut this out because we're going to paste it in in a variety of places. The first is going to be for our title label. And we don't want a message, we just want an asterisk. And then we just need to use this span element for our other labels. So for our content, we would do the same thing. But we need to change the wire:target to look at the form's content property. We'll do the same thing for the published checkbox. But the notification options are a little bit different. One, because we actually have two properties.
But the notification options are a little bit different. One, because we actually have two properties. We have the allowNotifications and the notifications property. But two, notifications is an array. And there's really no way that we can granularly track if email, SMS, or push was changed. I mean, yes, we could if we had individual properties for those individual values, but we don't. We track that data in an array. So I think we could get away with doing something like this.
We track that data in an array. So I think we could get away with doing something like this. For our notification options, we will display the * here, just to note that, hey, the notification options changed. And what we want to listen for here is the notifications property. We don't necessarily care about the allowNotifications, just if the notifications changed. So now in the browser, if we make a change to the title, we see that only the title is being marked as changed. And that's great.
Styling Dirty Labels4:15
we see that only the title is being marked as changed. And that's great. If we make a change to the content, we see that indicator at the label. If we make a change to published or the notification options, we see those indicators as well. But I want to take this a step further, and I want to change the color of the labels. And Livewire makes that very easy to do. We just need to replicate some things. For example, we are still going to use our span elements here,
We just need to replicate some things. For example, we are still going to use our span elements here, because we still want to display this asterisk. But now we want to make a change to the label element itself, only when the title changes. So here we will need to reuse the wire:target attribute and set it to form.title. But we can't really just use the wire:dirty attribute here, because by default that is going to remove the label from the page. And that is definitely not user friendly.
because by default that is going to remove the label from the page. And that is definitely not user friendly. Instead, we can use a modifier called class. And then whatever class we specify will be applied to the element when the target element is dirty. So yes, there is some duplication, but there's really not a way around that. We need to make changes both to the label element and the span element that it contains. So let's take those attributes, let's copy them, and then let's paste them into the other labels.
So let's take those attributes, let's copy them, and then let's paste them into the other labels. So for the content, we need to change the target once again. Let's scroll on down to published. We want to change the label here, but the target needs to be form.published. And then for the notification options, we will apply this for the div that contains that text. But once again, we change the target to notifications. And now inside of the browser, whenever we make a change, not only do we see our indicator, but the text of the label has changed.
Enabling Save on Dirty6:03
And now inside of the browser, whenever we make a change, not only do we see our indicator, but the text of the label has changed. If we check content, yes, published, yes, and notifications. All of those are working as they should. The main thing now is our Save button. There are a couple of things here. For a form that is clean, we shouldn't be able to click on the Save button at all. And we can, so this should be disabled by default. So let's go ahead and let's add disabled. And while that's all well and good, there's still this hover state.
So let's go ahead and let's add disabled. And while that's all well and good, there's still this hover state. Even though we can't click on it, it still kind of indicates that yes, we can click on this element. And I don't want that, so let's get rid of this hover. In fact, let's change the color of this because that's indigo and everything else is blue. But I want that hover effect when we can click on the Save button. So here we can say that when the form is dirty, apply the hover class to change the background to blue-900.
So here we can say that when the form is dirty, apply the hover class to change the background to blue-900. But we can also do this. When it is disabled, we will apply an opacity of 75. And I guess we can also go ahead and change the background color as well. So if it's disabled, we'll say blue-300. So that now it might not look the best, but we can definitely see that there's no indication that we can click on this button at all. But now we need to be able to remove the disabled attribute when the form is dirty.
button at all. But now we need to be able to remove the disabled attribute when the form is dirty. And we can do that with wire:dirty, but then we would use another modifier called attr, or I'm just gonna call it attribute. Now, if we were to set a value here, it would apply whatever attribute we specify when the form is dirty. And that's not what we want in this case. We want to remove the disabled attribute because it's already here. So we will need to use another modifier called remove. And I don't think the order of these modifiers matter.
So we will need to use another modifier called remove. And I don't think the order of these modifiers matter. So if we do something like this, it's a little more clear. So when the form is dirty, remove the disabled attribute. So now whenever we make a change to our form data, we can see that the disabled attribute is removed from our button. The hover state is now applied, and we can click on that to submit our changes. I want that article published, so let's go back, let's publish it, let's save it. And now we have a form that is much more nicer to use. Now, I don't think we need to apply really any of those to the create.
Applying to Create Form8:29
And now we have a form that is much more nicer to use. Now, I don't think we need to apply really any of those to the createArticle form, maybe we need to for the save button. So let's do that. In fact, let's copy what we have for our save button. That way we get the same experience regardless of if we are creating or if we are editing. So this is title, this is content. Let's not publish this, let's get push notifications, and that works fine. Livewire's dirty tracking system is very easy to use.
Let's not publish this, let's get push notifications, and that works fine. Livewire's dirty tracking system is very easy to use. We can easily show or hide messages or indicators. We can add or remove CSS classes or attributes to elements. And we can track changes at a general level or we can be very specific by targeting changes to a single property. It's very powerful, very well thought out. And the great thing is, we don't have to write it ourselves. Thanks. Thanks.
Thanks. Thanks. Thanks. Thanks.
