0

I am using Rails-6, with Bootstrap-4. I am using Bootstrap Card to display my form. The form is simple with a lable,text field, file upload and submit button. here is the outout Here is code for my form:

<%= javascript_pack_tag 'photo', 'data-turbolinks-track': 'reload' %>
<div class="card text-center">
  <div class="card-header">
    Add New Photo
  </div>
  <div class="card-body">
    <%= form_for @photo do |f| %>
      <%= render "shared/errors", object: @photo %>
      <%= f.hidden_field :image, value: @photo.cached_image_data %>
      <%= f.label :title %>
      <%= f.text_field :title %>
      <%= f.label :image %>
      <%= f.file_field :image %>
      <% if @photo.image_data? %>
        <%= image_tag @photo.image_url(:medium) %>
        Remove attachment: <%= f.check_box :remove_image %>
      <% end %>
      <%= f.submit %>
    <% end %>
  </div>
  <div class="card-footer text-muted">
  </div>
</div>

In my Javascript pack I have intercepted form submit event by using the javascript.

$(document).ready(function(){
  function processForm(e) {
      if (e.preventDefault) e.preventDefault();
      alert('intercepted form submission');
      /* do what you want with the form */
      // You must return false to prevent the default form behavior
      return false;
  }

  var form = document.getElementById('new_photo');
  if (form.attachEvent) {
      form.attachEvent("submit", processForm);
      alert('attachEvent');
  } else {
      form.addEventListener("submit", processForm);
      alert("addEventListener");
  }
});

I noticed that when I put my complete form in Bootstrap-Card-Body (as in above code)then the event works as desired and the attached function executes on clicking submit button.

But when I put the Form-Submit button in Bootstrap-Card-Footer (as per code below) then on clicking the submit button the attached function does not execute.

    <%= javascript_pack_tag 'photo', 'data-turbolinks-track': 'reload' %>
<div class="card text-center">
  <div class="card-header">
    Add New Photo
  </div>
  <div class="card-body">
    <%= form_for @photo do |f| %>
      <%= render "shared/errors", object: @photo %>
      <%= f.hidden_field :image, value: @photo.cached_image_data %>
      <%= f.label :title %>
      <%= f.text_field :title %>
      <%= f.label :image %>
      <%= f.file_field :image %>
      <% if @photo.image_data? %>
        <%= image_tag @photo.image_url(:medium) %>
        Remove attachment: <%= f.check_box :remove_image %>
      <% end %>
  </div>
  <div class="card-footer text-muted">
    <%= f.submit %>
    <% end %>
  </div>
</div>

here is what it looks like. moved form submit button in card-body

Why it happen? What concept I am missing? How do I make the attached event listner to fire when I Click Submit button placed in Card-Footer?

1 Answer 1

1

In this part of your example:

<div class="card-body">
  <%= form_for @photo do |f| %>
  <%= render "shared/errors", object: @photo %>
  <%= f.hidden_field :image, value: @photo.cached_image_data %>
  <%= f.label :title %>
  <%= f.text_field :title %>
  <%= f.label :image %>
  <%= f.file_field :image %>
  <% if @photo.image_data? %>
    <%= image_tag @photo.image_url(:medium) %>
    Remove attachment: <%= f.check_box :remove_image %>
  <% end %>
</div>

<div class="card-footer text-muted">
  <%= f.submit %>
  <% end %>
</div>

After Rails done compiling your view template to html it will look (roughly) like below:

<div class="card-body">
  <form method="post" action="/photos" ...>
    <input ... />
    <input ... />
</div>

<div class="card-footer text-muted">
  <input type="submit" ... />
  </form>
</div>

It will not be a valid HTML at all. The first div (.card-body) lacks the closing </form> tag. But the second div (.card-footer) has an unexpected closing </form> tag. Browsers still gracefully handle this by closing the <form> tag before the first </div> for you, but the <input type="submit" ... /> button will be outside the form and so the submit button won't work anymore.

I recommend you to change your code like below. Just let the <form> tag surround your whole card:

<%= javascript_pack_tag 'photo', 'data-turbolinks-track': 'reload' %>

<div class="card text-center">
  <%= form_for @photo do |f| %>
    <div class="card-header">
      Add New Photo
    </div>

    <div class="card-body">
        <%= render "shared/errors", object: @photo %>
        <%= f.hidden_field :image, value: @photo.cached_image_data %>
        <%= f.label :title %>
        <%= f.text_field :title %>
        <%= f.label :image %>
        <%= f.file_field :image %>
        <% if @photo.image_data? %>
          <%= image_tag @photo.image_url(:medium) %>
          Remove attachment: <%= f.check_box :remove_image %>
        <% end %>
    </div>

    <div class="card-footer text-muted">
      <%= f.submit %>
    </div>
  <% end %>
</div>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.