Comments (32)
@SimoTod turbo:submit-end
doesn't seem to do the trick. I fixed it on my project by initializing alpine components on turbo:render
.
turbo:render
can trigger twice (when you visit a cached page) so it's not optimal, but I can't see a way around it 🤷♂️
If we use turbo:render
listener, we can remove the one on turbo:load
. Otherwise we would be initializing alpine components 2-3 times on each page visit (if we use both).
For anyone looking for a quick workaround till this is resolved, try this:
window.addEventListener('turbo:render', function (event) {
window.Alpine.discoverUninitializedComponents((el) => {
window.Alpine.initializeComponent(el)
});
});
from alpine-turbo-drive-adapter.
@SimoTod thanks for your hard work 🙇♂️
I am going to test this in the next few days and get back to you.
from alpine-turbo-drive-adapter.
The problem with using render is that it might break the page in other edge cases introducing flickerings, etc. I'll check safari tomorrow.
from alpine-turbo-drive-adapter.
@SimoTod that's great, thank you for jumping on the fix so quickly. I'll do some more testing tomorrow to double check v1.0.4 in the browsers that I have access to (everything popular apart from MS Edge)
Thanks again.
from alpine-turbo-drive-adapter.
I believe edge doesn't support ??
so it needs to be transpiled properly. The cdn version should already be compatible with ms edge and possibly ie11
from alpine-turbo-drive-adapter.
@SimoTod thank you for your perseverance with this. I'll find some time tomorrow to test out the new version and report back. Have a great weekend.
It will likely be Sunday. I decided to run a few more tests for both features first. 👍
from alpine-turbo-drive-adapter.
@SimoTod I've retested the scenario where I had the original issue, using v1.1.0, and the problem is no longer there (i.e. my Alpine markup is working perfectly after submitting a form that returns a 422 response)
I successfully tested with the following browsers:
✅ Safari v14.1 (MacOS)
✅ Google Chrome v90.0 (MacOS)
✅ Firefox v88.0 (MacOS)
✅ iOS Safari v14.1 (on iPhone iOS 14.5)
✅ MS Edge v90.0 (Windows 10)
✅ Android Chrome v83 (on Android 11 - via Android Studio simulator)
Thanks again for your patience and getting this fixed so quickly, nice job.
from alpine-turbo-drive-adapter.
Sorry, I'm not a ruby developer but I'm not totally sure this is the right repository. Unless we are saying that it would work as expected with only alpine and without the turbolinks bridge.
By the way, could you post the generated html please? Thanks
from alpine-turbo-drive-adapter.
<div x-data="{text: 'demo' }">
<div x-text="text">demo</div>
</div>
<form action="/posts" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="ufX5eM9Ld2hGYyia8R4zGAS_wFvwNHzv2-CsUV0UKuR1bEpPhfuqfXDgtHTV_gDecNDNzLV-ipvSCyWkzevp-w">
<div class="form-group">
<label for="post_title">
<input type="text" name="post[title]" id="post_title" />
</div>
<div class="form-group">
<input type="submit" name="commit" value="Save post" class=" btn btn-primary"/>
</div>
</form>
After submit form and sever return 422 status, alpine fail to init all data and events.
from alpine-turbo-drive-adapter.
Thanks, I'll have a look in the next few days and see if i can replicate.
from alpine-turbo-drive-adapter.
Thanks, i modified
alpine-turbo-drive-adapter/src/bridge.js
Line 89 in 9bbfe00
document.addEventListener('turbo:render', initCallback)
can make it works, I'm not sure if that's the right way.from alpine-turbo-drive-adapter.
I'll need to have a look. In Turbolinks, render gets called multiple times when you have cached previews which is not the best for Alpine, maybe it has changed in Turbo. It seems weird that it calls render but it doesn't call load after maybe I can ask the guys at Turbo.
from alpine-turbo-drive-adapter.
there's a turbo:submit-end
that we might be able to use
from alpine-turbo-drive-adapter.
Thanks, you're right, i'll try again later.
from alpine-turbo-drive-adapter.
if the code use turbo frames, it replaces the content and triggers the alpine update.
The problem seems to be when you don't use a frame. In that case, it doesn't seem to replace the content with the response but it just re-renders the old age but it doesn't trigger a load event.
To be fair, it seems like a turbo bug, if the page is replaced, it should trigger the load event at the end.
from alpine-turbo-drive-adapter.
Thanks for your reply, yes, the turbo:load
won't be triggered, i will use turbo frame to submit form until there is a PR.
from alpine-turbo-drive-adapter.
@KostasKostogloy I know but I would really like Turbo to fix their bug or at least clarify the behaviour because it's not consistent/correct. They should either not refresh the page when there is an error or trigger a load event IMO. If you look at the bug above, people have the same issues with other frameworks, it's not just an alpine thing.
Turbo is still in beta so it may change.
Out of curiosity, is there a reason why you don't use turbo frames with forms? It seems to be the standard way to do it.
To clarify, the problem with render is that it gets called twice when you visit a cached page so, with the solution above, it will get called 3 times, not a big issue but something to be aware of.
from alpine-turbo-drive-adapter.
@SimoTod the main reason is that we display flash messages on the page and if we enclosed the form in a frame those would be outside of it (and not get displayed).
Problem's context: You want a form to submit with POST
on the same route it gets rendered on. Turbo will not replace the dom unless you use a 422 response to trick it into doing so.
So our options were:
- Disable turbo on the form
- Do redirect on our controller to
GET
on the same route after doing our processing. If we did that we wouldn't be able to keep form input, which would be reset - Use a frame and lose flash messages
- Use 422 response and add the snippet I posted above to initialize alpine
So there was no perfect solution and since 4. did not introduce any perceptible slowdown, we opted for that.
from alpine-turbo-drive-adapter.
Thanks for your feedback. I need to think about that before switching to turbo:render.
4 works but it's based on the assumption that an internal behaviour of Turbo won't ever change (I don't think they state anywhere that a 422 refreshed the page) so maybe keep an eye on it until they tag the first stable release.
from alpine-turbo-drive-adapter.
Better late than never. @nyrf @KostasKostogloy or anyone else following the bug report.
Could you test https://cdn.jsdelivr.net/gh/SimoTod/alpine-turbo-drive-adapter@bug/422-responses/dist/alpine-turbo-drive-adapter.min.js and let me know if it resolves your issues, please?
I decided not to use load because in some edge cases calling Alpine on the cached version would introduce some small bugs so I went down the turbo:submit-end route.
from alpine-turbo-drive-adapter.
@SimoTod Great, thanks. I've tested and it works.
from alpine-turbo-drive-adapter.
Thanks for confirming @nyrf
from alpine-turbo-drive-adapter.
Thanks for the fix @SimoTod. I've installed v1.0.3 of alpine-turbo-drive-adapter (upgraded from v1.0.2) and performed some initial testing myself - the problems we were having around this issue look to be fixed in Firefox (v88) and Chrome (v90).
However, for me at least, the problem still seems to exist in Safari (Safari v14.1, MacOS Big Sur 11.3). Is anyone experiencing this issue in Safari only?
(Note that the workaround fix suggested in #29 (comment) does "fix" the issue in all browsers that I've tested with, so perhaps there's some quirk of Safari that needs to be taken account of?)
from alpine-turbo-drive-adapter.
@rickclare It took less than expected. I was able to replicate it in Safari.
1.0.4 should fix the issue. Thanks for reporting it.
from alpine-turbo-drive-adapter.
Hi @SimoTod I've performed some more testing with v1.0.4
Unfortunately I'm still experiencing the issue in Safari only (no problems in Firefox or Chrome)
If it helps with diagnosis - my scenario is a simple user-registration page (run-of-the-mill Ruby-on-Rails MVC), which has the following markup:
<form action="/register" accept-charset="UTF-8" method="post">
<input type="hidden" name="authenticity_token" value="0j2wnYnsareCIghBGUzTCF3qv5b51aq46Pi2E2pYxHyN4vx8u0PB1JXFBzc8VNBXxSKmA3OKcoAXsHDyoxiqrw==">
<label for="member_email">Email</label>
<input id="member_email" name="member[email]" type="email">
<label for="member_password">Password</label>
<input id="member_password" name="member[password]" type="password">
<button type="submit">Register</button>
</form>
<div class="app-environment"
x-data="{ visible: true }"
x-on:click="visible = false"
x-show="visible">
Development
</div>
-
Before submitting the registration form, the "app-environment"
<div>
hides itself on click (as expected). -
After submitting the form with invalid values (i.e. resulting in a 422 response rendering the form again with validation errors) the
<div>
no longer responds to a click (i.e. indicating that AlpineJS is not initialising itself properly) -
After submitting the form with valid values (i.e. resulting in a redirect) the
<div>
hides itself on click (as expected).
I'm happy to keep testing any fixes that you release. I would love to help with the fix itself, but my javascript-fu isn't advanced enough to be able to suggest a solution.
from alpine-turbo-drive-adapter.
@rickclare I'm not a rail developer so I would need the response from the form submission if you can kindly send it over (The example I built in php is working okay in safari)
You can get it from safari > right click > inspect element (you need to enable it in preferences if you haven't yet) > network tab > your request. I need the content of both the preview tab and headers tab.
Thanks
from alpine-turbo-drive-adapter.
@SimoTod No problem, here is the response from Safari's Network tab:
Headers:
Summary
URL: https://localhost:4443/register
Status: 422
Source: Network
Address: 127.0.0.1:4443
Initiator:
localhost:1:882
Request
:method: POST
:scheme: https
:authority: localhost:4443
:path: /register
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Accept: text/vnd.turbo-stream.html, text/html, application/xhtml+xml
Accept-Encoding: gzip, deflate, br
Accept-Language: en-gb
Host: localhost:4443
Origin: https://localhost:4443
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Safari/605.1.15
Connection: keep-alive
Referer: https://localhost:4443/register
Content-Length: 121
Cookie: _secret_key=SFMyNTY.g3QAAAABbQAAAAtfY3NyZl90b2tlbm0AAAAYSHNheFYySzVWVVZfdC1BQVFXd3VYU1Y1.Rpw0UKoGbo3ZvQa47y-y9Y8W047AMMJDIUuVfUoIPbc
X-CSRF-Token: cEEvCgR3DG17BBIYAmIiDR0OMxIANQVx82NrREGX-QDGvOcLLYDgXfSD
Response
:status: 422
Content-Type: text/html; charset=utf-8
X-XSS-Protection: 1; mode=block
Cache-Control: max-age=0, private, must-revalidate
Date: Fri, 30 Apr 2021 09:28:51 GMT
Content-Length: 4386
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
x-download-options: noopen
x-permitted-cross-domain-policies: none
cross-origin-window-policy: deny
x-request-id: FnqYt9qh_WhxX8QAAABH
Request Data
MIME Type: application/x-www-form-urlencoded;charset=UTF-8
_csrf_token: cEEvCgR3DG17BBIYAmIiDR0OMxIANQVx82NrREGX-QDGvOcLLYDgXfSD
member[email]: [email protected]
member[password]: 123456
Preview:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover">
<meta charset="UTF-8" content="PTgQOh91D15hPgI3N0QiESAgLhsNBRdHuKqBIGDk7kThCicPqwYnUVAr" csrf-param="authenticity_token" method-param="_method" name="csrf-token">
<link data-turbo-track="reload" rel="stylesheet" href="/css/app.css">
<script data-turbo-track="reload" defer src="/js/app.js"></script>
</head>
<body>
<form action="/register" accept-charset="UTF-8" method="post"><input name="authenticity_token" type="hidden" value="PTgQOh91D15hPgI3N0QiESAgLhsNBRdHuKqBIGDk7kThCicPqwYnUVAr">
<div class="notification is-danger">
Something went wrong! Please check the errors below
</div>
<label for="member_email">Email address</label>
<input id="member_email" name="member[email]" type="email" value="[email protected]">
<label for="member_password">Password</label>
<input id="member_password" name="member[password]" type="password">
<span class="is-danger">should be at least 12 characters</span>
<button class="button is-primary" data-form-target="button" type="submit">Register</button>
</form>
<div class="app-environment"
x-data="{ visible: true }"
x-on:click="visible = false"
x-show="visible">
Development
</div>
</html>
from alpine-turbo-drive-adapter.
@SimoTod It might be a red-herring (I might be reading it wrong), but could you double-check that the v1.0.4 release built correctly?
For example, when I pull down the v1.0.4 package from npm and inspect it's contents, I'm seeing some of the v1.0.3 code still existing in dist/alpine-turbo-drive-adapter.esm.js
$ rg -F version
alpine-turbo-drive-adapter/package.json
3: "version": "1.0.4",
---
$ rg "data-alpine-was-cloaked"
alpine-turbo-drive-adapter/src/bridge.js
7: el.setAttribute('data-alpine-was-cloaked', el.getAttribute('x-cloak') ?? '')
43: el.setAttribute('data-alpine-was-cloaked', el.getAttribute('x-cloak') ?? '')
66: document.body.querySelectorAll('[x-for],[x-if],[data-alpine-was-cloaked]').forEach((el) => {
68: if (el.hasAttribute('data-alpine-was-cloaked')) {
69: el.setAttribute('x-cloak', el.getAttribute('data-alpine-was-cloaked') ?? '')
70: el.removeAttribute('data-alpine-was-cloaked')
alpine-turbo-drive-adapter/dist/alpine-turbo-drive-adapter.js
64: el.setAttribute('data-alpine-was-cloaked', (_el$getAttribute = el.getAttribute('x-cloak')) !== null && _el$getAttribute !== void 0 ? _el$getAttribute : '');
106: el.setAttribute('data-alpine-was-cloaked', (_el$getAttribute2 = el.getAttribute('x-cloak')) !== null && _el$getAttribute2 !== void 0 ? _el$getAttribute2 : '');
130: document.body.querySelectorAll('[x-for],[x-if],[data-alpine-was-cloaked]').forEach(function (el) {
132: if (el.hasAttribute('data-alpine-was-cloaked')) {
135: el.setAttribute('x-cloak', (_el$getAttribute3 = el.getAttribute('data-alpine-was-cloaked')) !== null && _el$getAttribute3 !== void 0 ? _el$getAttribute3 : '');
136: el.removeAttribute('data-alpine-was-cloaked');
alpine-turbo-drive-adapter/dist/alpine-turbo-drive-adapter.esm.js
29: el.setAttribute('data-alpine-was-cloaked', el.getAttribute('x-cloak') ?? '');
65: el.setAttribute('data-alpine-was-cloaked', el.getAttribute('x-cloak') ?? '');
88: document.body.querySelectorAll('[x-for],[x-if],[data-alpine-was-cloaked]').forEach(el => {
90: if (el.hasAttribute('data-alpine-was-cloaked')) {
91: el.setAttribute('x-cloak', el.getAttribute('data-alpine-was-cloaked') ?? '');
92: el.removeAttribute('data-alpine-was-cloaked');
106: el.setAttribute('data-alpine-was-cloaked', (_el$getAttribute2 = el.getAttribute('x-cloak')) !== null && _el$getAttribute2 !== void 0 ? _el$getAttribute2 : '');
...
from alpine-turbo-drive-adapter.
@SimoTod Actually, ignore the above. I was seeing a syntax error when testing v1.0.4 in Microsoft Edge for the following line, which lead me down a rabbit hole! Perhaps it's my webpack build system that's a fault?
SCRIPT1002: SCRIPT1002: Syntax error
alpine-turbo-drive-adapter.esm.js (29,50)
29: el.setAttribute('data-alpine-was-cloaked', el.getAttribute('x-cloak') ?? '')
from alpine-turbo-drive-adapter.
@rickclare So... The UMD version (the one that is served by the CDN too) works correctly in Safari but the ESM version doesn't. I assume that, if you instruct your bundler to generate a file compatible with edge and safari, it would work.
However, I've recompiled with slightly different settings and the ESM version seems to behave now. For just a few bytes more, I'm happy to include an ESM version that works out of the box with Safari.
I'll run a few more tests and I'll release it over the weekend with the other pending PR to support turbo-streams. It's going to be 1.1.0
from alpine-turbo-drive-adapter.
@SimoTod thank you for your perseverance with this. I'll find some time tomorrow to test out the new version and report back. Have a great weekend.
from alpine-turbo-drive-adapter.
Unfortunately, the Safari was still happening (some times was working and sometimes wasn't). I believe something to do with the submit-end event being triggered on the document before the page update and Safari ignoring the delayed callback once the DOM was updated.
I gave up and switched to turbo:render :)
I found out that Turbo adds a data-turbo-preview attribute when rendering the preview from the cache while waiting for the page so I can skip the first render event when Turbo triggers them twice.
from alpine-turbo-drive-adapter.
Related Issues (20)
- Missing readme
- Disappearing template loop items HOT 7
- x-for elements disappearing after Livewire rerender HOT 11
- v0.2.0 - x-for loop items disappear HOT 3
- Use Alpine.clone to avoid existing component being reset when navigating using the history. HOT 7
- IE 11 support HOT 4
- Turbo Drive compatibility HOT 12
- Issue with data-turbolinks-permanent combined with x-cloak HOT 3
- Figure out if the plugin is testable somehow HOT 9
- JS file always runs after the turbo:load event, causing x-data to throw a ReferenceError on first navigation HOT 6
- Turbo stream - not initialising HOT 5
- after fired turbo:render x-data not exists HOT 12
- Currently Breaks with Alpine.js & Livewire HOT 14
- Add github action to publish the library on npm when a new version is tagged. HOT 1
- Alpine v3 compatability HOT 36
- How can I keep the cdn link updated HOT 5
- Necessary if caching disabled? HOT 1
- Add npm instructions HOT 3
- Components hidden by default, such as mobile navigation menus, get cached and cause flickering when navigating between pages. HOT 19
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from alpine-turbo-drive-adapter.