-
Notifications
You must be signed in to change notification settings - Fork 430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Input field missing from form with errors, even though it is in the HTML response #1291
Comments
I think you just have a browser plugin that interfering with morphing. For example, if I disable LastPass your page works fine. Here is a reproduction test of what I think is happening: require "bundler/inline"
gemfile true do
source "https://rubygems.org"
gem "rails"
gem "propshaft"
gem "puma"
gem "sqlite3", "~> 1.4"
gem "turbo-rails"
gem "capybara"
gem "cuprite", require: "capybara/cuprite"
end
ENV["DATABASE_URL"] = "sqlite3::memory:"
ENV["RAILS_ENV"] = "test"
require "active_record/railtie"
# require "active_storage/engine"
require "action_controller/railtie"
require "action_view/railtie"
# require "action_mailer/railtie"
# require "active_job/railtie"
require "action_cable/engine"
# require "action_mailbox/engine"
# require "action_text/engine"
require "rails/test_unit/railtie"
class App < Rails::Application
config.load_defaults Rails::VERSION::STRING.to_f
config.root = __dir__
config.hosts << "example.org"
config.eager_load = false
config.session_store :cookie_store, key: "cookie_store_key"
config.secret_key_base = "secret_key_base"
config.consider_all_requests_local = true
config.action_cable.cable = {"adapter" => "async"}
config.turbo.draw_routes = false
Rails.logger = config.logger = Logger.new($stdout)
routes.append do
root to: "application#index"
post "/", to: "application#create"
end
end
Rails.application.initialize!
class ApplicationController < ActionController::Base
include Rails.application.routes.url_helpers
def index
render inline: <<~TEMPLATE, formats: :html
<html>
<head>
<meta name="turbo-refresh-method" content="morph">
<%= csrf_meta_tags %>
<script type="importmap" data-turbo-track="reload">
{ "imports": { "@hotwired/turbo-rails": "<%= asset_path("turbo.js") %>" } }
</script>
<script type="module">
import "@hotwired/turbo-rails"
</script>
</head>
<body>
<form action="/" accept-charset="UTF-8" method="post">
<label for="user_password">Password</label><div>
<input type="password" name="user[password]" id="user_password"/>
<div class="shadowroot"></div>
</div>
<input type="submit" name="commit" value="Submit"/>
</form>
<script charset="utf-8">
const shadow = document.querySelector(".shadowroot").attachShadow({mode: "open"});
const observer = new MutationObserver((mutationList) => {
mutationList.forEach((mutation) => {
mutation.removedNodes.forEach((node) => {
if (node.id === "user_password") {
shadow.host.remove();
}
});
});
});
observer.observe(document.querySelector("form"), {subtree: true, childList: true})
</script>
</body>
</html>
TEMPLATE
end
def create
render inline: <<~TEMPLATE, formats: :html, status: 422
<html>
<head>
<meta name="turbo-refresh-method" content="morph">
<%= csrf_meta_tags %>
<script type="importmap" data-turbo-track="reload">
{ "imports": { "@hotwired/turbo-rails": "<%= asset_path("turbo.js") %>" } }
</script>
<script type="module">
import "@hotwired/turbo-rails"
</script>
</head>
<body>
<form action="/" accept-charset="UTF-8" method="post">
<div class="field_with_errors">
<label for="user_password">Password</label>
</div>
<div>
<div class="field_with_errors">
<input type="password" name="user[password]" id="user_password"/>
</div>
</div>
<input type="submit" name="commit" value="Submit"/>
</form>
</body>
</html>
TEMPLATE
end
end
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :cuprite,
using: :chrome,
screen_size: [1400, 1400],
options: {
js_errors: true,
headless: true
}
end
Capybara.configure do |config|
config.server = :puma, {Silent: true}
config.default_normalize_ws = true
end
require "rails/test_help"
class TurboSystemTest < ApplicationSystemTestCase
test "a bug" do
visit "/"
click_button "Submit"
assert_selector "#user_password"
end
end A few things to note:
|
This is so helpful thanks! I had noticed disabling the Lastpass extension "fixed" it but didn't know how to proceed from there. I'm using Phlex as my view templates and they have a built-in mechanism to add spacing so I'll try that! Presumably this is still a bug in turbo or idiomorph? Or is it the Lastpass extension that has the bug? |
considering that result depends on a single insignificant whitespace between tags, it looks like an idiomorph bug to me. |
@4lllex This worked! I literally added a line that said: whitespace # https://github.com/hotwired/turbo/issues/1291#issuecomment-2319513075 to the label method in my |
Hi Turbo developers!
I'm experiencing a weird issue I don't know how to debug. You can see it for yourself here: https://devvelo.com/users/sign_up
If you get any error when submitting the form (for example, a password too short or confirmation doesn't match password), the form is re-rendered with the error message but the input itself is removed from the DOM. If you inspect the response, you can see the input is returned as part of the 422 response, but Turbo chooses not to render it / to remove it.
Disabling Turbo on the form causes it to behave as expected.
This is a standard Rails FormBuilder field, so it is wrapped with a
.field_with_errors
in the response - might this have something to do with it? Have I made some silly mistake? What tools would you use to debug this?Thanks so much in advance for your help!
The text was updated successfully, but these errors were encountered: