colinaut / alpinejs-plugin-simple-validate

Simple Alpine form validation plugin
97 stars 4 forks source link

Access $validate magic in function component x-data params #5

Closed k8n closed 1 year ago

k8n commented 1 year ago

It would be nice to be able to do something like the following.

<form x-data="dataThing()" id='the_form'>
...
<button @click="doIt()">
...
<script>
function dataThing() {
  return {
    doIt() {
      if (Alpine.validate.isComplete('the_form')) // this would be nice
        doSomething();
    }
  };
}
...

Any workarounds?

Relevant discussions here:

Summary of available workarounds by Tom Davies but nothing fitting: https://codepen.io/atomgiant/pen/ExVYdXz

colinaut commented 1 year ago

I haven't really experimented with applying functions directly to x-data. Why not just use the Alpine.data using the function return method and this to create a dedicated component? All magic properties are passed there.

<form x-data="dataThing" id='the_form'>
...
<button @click="doIt()">
...
<script>
  document.addEventListener('alpine:init', () => {
    Alpine.data('dataThing', function () {
      return {
        doIt() {
          if (this.$validate.isComplete('the_form')) doSomething();
        }
      }
    })
  })
</script>
...

You could also just forgo all that too and just do:

<button @click="if ($validate.isComplete('the_form')) doSomething()">

This latter approach is how I would handle it as it's simpler.

k8n commented 1 year ago

That is a good point. In my app I am trying to access magic from Alpine.store. But I suppose that’s bad design. I’ll close this for now. Thanks!

colinaut commented 1 year ago

Even though this is closed I wanted to add some thoughts on the issue. To be honest, $store in Alpine is odd and I don't fully understand it's quirks. Alpine.store is a global separate from Alpine.data, which I assume is why you can't use magic functions within them. $validate won't work nor will built in magics like $dispatch. Supposedly, $persist is exposed globally and works in Alpine.store but I've run into issues with that (might have been my fault).

These quirks make it that I don't use Alpine.store too often. I like single-value stores but for more complicated stuff I usually reach for Alpine.data.

Note that the x-validate has it's own separate reactive data. See below. The button that is referencing the .isComplete is technically in a completely different part of the data scope but it will still work. Magic functions still won't work in $store — again I don't know why — but this at least expends it's usefulness.

<form id="form" x-data x-validate>
...
</form>
<div x-data>
<button @click="if ($validate.isComplete('the_form')) doSomething()">Do It</button>
</div>

You could just roll your own vanilla or Alpine plugin depending on what you are developing. I created x-validate to replace/simplify/reuse a bunch of AlpineJS code I had made. I had a bunch of javascript in external scripts that with x-validate I was able to replace with just a few directives written write on the DOM tags. Extending Alpine with directives and magics is fairly easy and fun to code!

k8n commented 1 year ago

Thanks for the insight!