Skip to main content

Why after I switch controller and switch back again , the form submit button Failure?

General • Asked by Larry Qu

after I switch the controller, and switch back, the form submit button Failure, if I refresh the page , it can works again.
the console and network no error log.


Sorry? Switch controller? As in an action? To another action? And then submit the button?
Could you be a bit more clear, so we can help? :)


I have recored a video to show the problem, please see the video . Thank you very much!

See Video


That looks like it could be a turbolinks problem. If you disable turbolinks, does it work?


I'am not disable turbolinks manually, it's default from rails 5.0.1.
How to make sure it works ?

Gemfile

gem 'turbolinks', '~> 5'

application.js

//= require turbolinks

submit just use form, not use js.
products.html

<table class="table table-striped">
  <thead>
    <tr>
      <th>Name</th>
      <th>Description</th>
      <th>Price</th>
      <th>Show</th>
      <th>Edit</th>
      <th>Destroy</th>
      <th>Amount</th>
      <th>购买</th>
      <th colspan="5"></th>
    </tr>
  </thead>

  <tbody>
      <tr>
        <form action="/carts" method="post" target="_blank">
          <td>羊肉</td>
          <td>纯天然羊肉,秋冬滋补佳品。</td>
          <td>30.0</td>
          <td><a href="/products/1">Show</a></td>
          <td><a href="/products/1/edit">Edit</a></td>
          <td><a data-confirm="Are you sure?" rel="nofollow" data-method="delete" href="/products/1">Destroy</a></td>

          <input name="cart[product_id]" value=1 type="hidden" />
          <input name="cart[user_id]" value=2 type="hidden" />

          <td><input type="number" name="cart[amount]" required="true" min="1" max="100" value="1" autofocus="true"> 公斤</td>
          <td><button type="submit" class="btn btn-primary">Add to Cart</button></td>


      </tr>
      <tr>
        <form action="/carts" method="post" target="_blank">
          <td>牛肉</td>
          <td>纯天然牛肉</td>
          <td>30.0</td>
          <td><a href="/products/2">Show</a></td>
          <td><a href="/products/2/edit">Edit</a></td>
          <td><a data-confirm="Are you sure?" rel="nofollow" data-method="delete" href="/products/2">Destroy</a></td>

          <input name="cart[product_id]" value=2 type="hidden" />
          <input name="cart[user_id]" value=2 type="hidden" />

          <td><input type="number" name="cart[amount]" required="true" min="1" max="100" value="1" autofocus="true"> 公斤</td>
          <td><button type="submit" class="btn btn-primary">Add to Cart</button></td>


      </tr>
  </tbody>
</table>

For testing purposes, just remove the = from //= require turbolinks in application.js - so it should look like this afterwards: // require turbolinks

Then just restart your server and test your page again.


I remove it, restart the server, but still not work.


Interesting... I've only seen this type of behavior caused by Turbolinks.

Is there any way you can create a github repo that reproduces the behavior so I can take a better look?



Here's an interesting thing I learned that I never knew before... you can't place a form inside an html table, tbody, or tr - it can exist inside td though. Check: http://stackoverflow.com/questions/5967564/form-inside-a-table

So a quick fix to your problem is to simply move the form tag outside your <table>...</table> tags.

Now a bigger issue I noticed with your project is that you're hard coding way too much stuff - for example, all your links are plain html, so instead of using <%= link_to "Some Link", some_link_path %> you're doing <a href="/some_link">Some Link</a> - you really should be using the helpers that rails provides. The same can be said for your form itself... below is what I refactored your form to. You'll need to be sure to put @cart = Cart.new inside your index action in app/controllers/products_controller.rb

<%= form_for(@cart) do |f| %>
  <table class="table table-striped">
    <thead>
      <tr>
        <th>Name</th>
        <th>Description</th>
        <th>Price</th>
        <th>Show</th>
        <th>Edit</th>
        <th>Destroy</th>
        <th>Amount</th>
        <th>购买</th>
        <th colspan="5"></th>
      </tr>
    </thead>

    <tbody>
      <% @products.each do |product| %>
        <tr>
          <td><%= product.name %></td>
          <td><%= product.description %></td>
          <td><%= product.price %></td>
          <td><%= link_to 'Show', product %></td>
          <td><%= link_to 'Edit', edit_product_path(product) %></td>
          <td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>

          <%= f.hidden_field :product_id, value: product.id %>
          <% if current_user %>
          <%= f.hidden_field :user_id, value: current_user.id %>
          <% end %>

          <td><%= f.number_field :amount, min: 1, max: 100, value: 1, autofocus: true, required: true %></td>
          <td><%= f.submit "Add to Cart", class: 'btn btn-primary' %></td>
        </tr>
      <% end %>
    </tbody>
  </table>
<% end %>

Thank you for help me refactor the code.
I replace table with div , div and form works well together.

About form and table, if use form in table , must include it completely in td tag.

form in td completely, validate pass.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table>
    <tr>
        <td>
            <form action="http://www.baidu.com">
                <input type="text" name="w" value="a">
                <input type="submit">
            </form>
        </td>
    </tr>
</table>
</body>
</html>

form in tr , out of td, validate error.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table>
    <tr>
      <form action="http://www.baidu.com">
        <td>
                <input type="text" name="w" value="a">
                <input type="submit">
        </td>
      </form>
    </tr>
</table>
</body>
</html>

Resources
validate
netsting form and table


I am very confused that checkout button also can not submit, until after refresh.

see video



Oops, sorry I just realized you are submitting the form via javascript.

Your checkout form isn't submitting because of Turbolinks. If you disable turbolinks and revisit the checkout page, you'll see your form submits just fine.

So in turbolinks 5, the "new" way to ensure your scripts are firing is to use $(document).on('turbolinks:load', function() {

So refactored, your JS cart would look like this:

$(document).on('turbolinks:load', function() {

    // checkout process
    $("#checkout").click(function(event) {
        $.get('/checkout/go',
            {
                address_id: $("#address").val(),
                ajax: new Date().getTime()
            },
            function(data, textStatus, xhr) {
                window.location.replace("/orders");
        });
    });

});

Yes! Thank you very much!


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 22,346+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.