Muhammad Mashaallah
Muhammad Mashaallah

Reputation: 1

intercept form submit event using javascript

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?

Upvotes: 0

Views: 558

Answers (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>

Upvotes: 1

Related Questions