When I press on the link “Hallo”, I want that the link “Okay” is visible and focused. However, when I click on “Hallo”, the “Okay” link will become visible, but its not focused. Only if I click again the link “Okay” will be focused. How can I achieve it with to show and focus the link with one click?
a:focus{ color:yellow; }
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script> <div x-data="{open:false}"> <a href="#" @click="open=true;$refs.foo.focus()" >Hallo</a> <div x-show="open"> <a href="#" x-ref="foo">Okay</a> </div> </div>
Advertisement
Answer
When your JS is executed, the foo
element is not shown yet, so it cannot be focused. You need to wait for it to be shown before focusing it. $nextTick
allows you to do just that:
$nextTick
is a magic property that allows you to only execute a given expression AFTER Alpine has made its reactive DOM updates. This is useful for times you want to interact with the DOM state AFTER it’s reflected any data updates you’ve made.
a:focus{ color:yellow; }
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script> <div x-data="{open:false}"> <a href="#" @click="open=true;$nextTick(() => { $refs.foo.focus(); });" >Hallo</a> <div x-show="open"> <a href="#" x-ref="foo">Okay</a> </div> </div>
Is it possible to pass $nextTick to a function and call it there? Or can I only call it inline?
You can add a myMethod
property to x-data
, and access everything through this
:
const appData = { open: false, myMethod() { this.open = true; this.$nextTick(() => { this.$refs.foo.focus(); }); } };
a:focus { color: yellow; }
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script> <div x-data="appData"> <a href="#" @click="myMethod">Hallo</a> <div x-show="open"> <a href="#" x-ref="foo">Okay</a> </div> </div>