This post assumes you have already have Vue working within your application and have setup the ability to use components. Laravel does this for you automatically, but setting that up is covered elsewhere (see here, here, here or here).
Background
Today I was working through a template I maintain for client projects. It contains items that I continually have to setup for any project (roles, permissions, companies, locations, users). I've been developing it since Laravel 5.3 (notably not long), but it has helped tremendously not only in saving time, but also implementing new pieces into an existing framework.
Case in point is that today, I was working through an aspect where I wanted to have the user check a checkbox verifying they wanted to delete a resource, prior to being able to click the delete button. This is kind of a "are you suuuuuuure" without the implementation of a modal dialog box.
I've been turning to Vue a lot lately (as are all the cool kids), and this seemed like this request might check all my personal boxes for using Vue:
- Is this code likely to be reused throughout the application? Yep. Anywhere I want the user to verify something prior to allowing them to proceed further.
- Does this take a non-trivial task, and make it super-easy? Yep. Not that making a check-box trigger javascript is difficult...but it is something that can be done once and forgotten in Vue.
- Will it save time? I can make Vue do all kinds of cool things, but if I need to just change the color of a button, maybe just stick with plain old javascript. Let's make sure this isn't one of those cases. It's not!
My Requirements:
- I want it to be a reusable template, and allow for the use of slots. This means that anything I put within the <ct-verify></ct-verify> tags would be hidden until the checkbox is checked.
- I want to pass through the verification message as a property. This way it's not a generic "I agree" message.
- Setup a default message, in case I don't pass a verification message through.
- Create this as a component, to allow for the item to be used across various projects.
Here's What It'll Look Like
Before Click:
1. Notice that there is nothing in the HTML where the text should be. Love me some Vue.
After Click:
1. Bam. Form available.
Additionally, when the checkbox is NOT clicked, the hidden html is actually removed from the page. This means that it cannot be accessed by a dastardly individual with the means and attitude to cause a problem.
When Clicked (see the form tag)
When Not clicked
Required coding within the blade/html/php page:
```
<ct-verify agreement="By clicking delete, I verify I am removing all data related to this company.">
<b>WHATEVER YOU WANT</b><br>
<button type="submit" class="button is-danger">ANYTHING</button>
</ct-verify>
```
Caveats
1. I use the Laravel framework as I love it. But this tutorial can be done without the use of that as long as you pull in the appropriate items (https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js)
2. I am using the Bulma framework for the css styling. I did this to avoid the use of jquery in the latest version of my template.
Solution
Component File
Component Explanation:
- Props - two properties are required and both have defaults. The first property is "agreement" and this is the text that you want the visitor to agree to prior to being "shown the goods". The "selected" property is a boolean and is what we use to initially set the checkbox value. There may be cases where you want it checked by default. Passing through a value of "true" when the component is called will do this.
- Data - this contains one item "isSelected" which is a boolean set to false. Per Vue 2.0 standards, we shouldn't edit a prop directly (they are supposed to be immutable), so we create a new value in the data section.
- mounted - after the component is loaded, we set the component's isSelected data value = the selected property that was initially passed in. This is the ONLY time we care what was passed in from the prop. From here on out, it just uses the "isSelected" value to trigger visibility.
- methods - this is where the magic happens. We have a function called updateSelected(), and we set the component's "isSelected" function = to the opposite of what it's currently set to (this.isSelected = ! this.isSelected). WTH?
- If you look at the <input> section of our template, you will see the following code @change="updateSelected". This is vue's way of saying "any time this checkbox is clicked, fire the updateSelected function." The updateSelected function changes the component's isSelected value to the opposite of what it was before...effectively a toggle.
Calling From HTML / PHP
- Notice that the only thing I am passing through is the agreement text. As we are setting the "selected" value as a default of false, I have no need to pass that through as a property.
- The <ct-delete> form is another vue component I created. However you can place whatever you'd like instead of this. I mean anything.