Code Monkey home page Code Monkey logo

Comments (32)

KostasKostogloy avatar KostasKostogloy commented on May 28, 2024 2

@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.

KostasKostogloy avatar KostasKostogloy commented on May 28, 2024 1

@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.

SimoTod avatar SimoTod commented on May 28, 2024 1

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.

rickclare avatar rickclare commented on May 28, 2024 1

@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.

SimoTod avatar SimoTod commented on May 28, 2024 1

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 avatar SimoTod commented on May 28, 2024 1

@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.

rickclare avatar rickclare commented on May 28, 2024 1

@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.

SimoTod avatar SimoTod commented on May 28, 2024

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.

nyrf avatar nyrf commented on May 28, 2024

hotwired/turbo#39

<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.

error

from alpine-turbo-drive-adapter.

SimoTod avatar SimoTod commented on May 28, 2024

Thanks, I'll have a look in the next few days and see if i can replicate.

from alpine-turbo-drive-adapter.

nyrf avatar nyrf commented on May 28, 2024

Thanks, i modified

document.addEventListener('turbo:load', initCallback)
to document.addEventListener('turbo:render', initCallback) can make it works, I'm not sure if that's the right way.

from alpine-turbo-drive-adapter.

SimoTod avatar SimoTod commented on May 28, 2024

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.

SimoTod avatar SimoTod commented on May 28, 2024

there's a turbo:submit-end that we might be able to use

from alpine-turbo-drive-adapter.

nyrf avatar nyrf commented on May 28, 2024

Thanks, you're right, i'll try again later.

from alpine-turbo-drive-adapter.

SimoTod avatar SimoTod commented on May 28, 2024

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.

nyrf avatar nyrf commented on May 28, 2024

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.

SimoTod avatar SimoTod commented on May 28, 2024

@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.

KostasKostogloy avatar KostasKostogloy commented on May 28, 2024

@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:

  1. Disable turbo on the form
  2. 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
  3. Use a frame and lose flash messages
  4. 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.

SimoTod avatar SimoTod commented on May 28, 2024

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.

SimoTod avatar SimoTod commented on May 28, 2024

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.

nyrf avatar nyrf commented on May 28, 2024

@SimoTod Great, thanks. I've tested and it works.

from alpine-turbo-drive-adapter.

SimoTod avatar SimoTod commented on May 28, 2024

Thanks for confirming @nyrf

from alpine-turbo-drive-adapter.

rickclare avatar rickclare commented on May 28, 2024

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.

SimoTod avatar SimoTod commented on May 28, 2024

@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.

rickclare avatar rickclare commented on May 28, 2024

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>
  1. Before submitting the registration form, the "app-environment" <div> hides itself on click (as expected).

  2. 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)

  3. 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.

SimoTod avatar SimoTod commented on May 28, 2024

@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.

rickclare avatar rickclare commented on May 28, 2024

@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.

rickclare avatar rickclare commented on May 28, 2024

@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.

rickclare avatar rickclare commented on May 28, 2024

@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.

SimoTod avatar SimoTod commented on May 28, 2024

@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.

rickclare avatar rickclare commented on May 28, 2024

@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.

SimoTod avatar SimoTod commented on May 28, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.