3
votes

Original Post

My custom dashboard has buttons that contain both a Font Awesome icon and a text description of the button or form action. I have a problem with my forms and buttons that a form doesn't submit upon clicking on a font awesome icon within a button that has a jQuery click event. I could use some help figuring out what I'm doing incorrectly.

In this image example, there is a font awesome magnifying glass "search" icon, followed by the text "Search".

In this image example, there is a font awesome magnifying glass "search" icon, followed by the text "Search".

If I click anywhere on the button, my jQuery works correctly by replacing the inner HTML of the button with the font awesome icon spinner icon and with text "Searching ...". If I click directly on the font awesome icon, the form does not submit. If I click anywhere else on the button aside from the font awesome icon, the form submits properly. If I remove my jQuery click() functions that replace the innerHTML when buttons are clicked, the form submits properly even when the font awesome icon is directly clicked. It has something to do with the jquery click html code but I'm not sure what I'm doing incorrectly.

What am I doing wrong with my jQuery that's causing the form to not submit when the font awesome icon is clicked within the button?

This image shows that the jQuery correctly replaced the inner HTML of the button, but the form doesn't submit when the font awesome icon is clicked on directly. The form only submits when the button is clicked anywhere else except for directly on the font awesome icon.

This image shows that the jQuery correctly replaced the inner HTML of the button, but the form doesn't submit when the font awesome icon is clicked on directly. The form only submits when the button is clicked anywhere else except for directly on the font awesome icon.

Here's my jQuery and HTML for this Search button

$(document).ready(function() {
  $('#search-btn').click(function() { 
    $(this).html('<i class="fas fa-spinner fa-spin gap-right"></i> Searching ...'); 
  });
  //$('#search-btn').click(function() { $('#search-btn').html('<i class="fas fa-spinner fa-spin gap-right"></i> Searching ...'); });
});
<link href="https://fontawesome.com/v4.7.0/assets/font-awesome/css/font-awesome.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="submit" id="search-btn" name="search" value="Search" class="btn btn-primary gap-right"><i class="fas fa-search gap-right"></i> Search</button>

Any advice would be greatly appreciated. If more information or clarification is needed, please let me know and I will update. Thanks.

Update 1/6/2020

Example: https://www.seibertron.com/dashboard/test/button-problem-public.php

The issue in the above example is with the "search" button. If you click on the right side of the button, it works as expected (with a spinner icon and changing the text from "Search" to "Searching ..."). If you click on the font-awesome magnifying glass icon on the left side of the Search button, it does not submit. The reset button works in the example because it's just using traditional javascript to redirect the user and is not submitting a form. Thank you in advance for taking a look at this issue!


Update and Resolution 1/6/2020

Thanks to fyrye, I took his suggestion and modified my buttons.js jQuery file to the following, which worked for my custom Inspinia dashboard. In addition, while I was researching this issue last night, I came across an alternate solution that is built into Bootstrap which might work for other users wishing to add this functionality to their code: How to add a spinner icon to button when it's in the Loading state?

Happy coding!

$(document).ready(function(){
  $('form').on('submit', function(e) {
    $(this).find('#test-search-btn').html('<i class="fa fas fa-spinner fa-spin gap-right"/> Searching...');
    $(this).find('#search-btn').html('<i class="fa fas fa-spinner fa-spin gap-right"/> Searching...');
    $(this).find('#add-btn').html('<i class="fas fa-spinner fa-spin gap-right"></i> Adding ...');
    $(this).find('#approve-btn').html('<i class="fas fa-spinner fa-spin gap-right"></i> Saving ...');
    $(this).find('#save-btn').html('<i class="fas fa-spinner fa-spin gap-right"></i> Saving ...');
    $(this).find('#copy-btn').html('<i class="fas fa-spinner fa-spin gap-right"></i> Copying ...');
    $(this).find('#move-btn').html('<i class="fas fa-spinner fa-spin gap-right"></i> Moving ...');
    $(this).find('#upload-btn').html('<i class="fas fa-spinner fa-spin gap-right"></i> Uploading ...');
    $(this).find('#nav-refresh-btn').html('<i class="fas fa-refresh fa-lg fa-spin gap-right"></i>');
    $(this).find('#load-btn').html('<i class="fas fa-spinner fa-lg fa-spin gap-right"></i> Loading ...');
    $(this).find('#generate-btn').html('<i class="fas fa-spinner fa-lg fa-spin gap-right"></i> Generating ...');
  });

  $('#cancel-btn').click(function() { $(this).html('<i class="fas fa-spinner fa-spin gap-right"></i> Canceling ...'); });
  $('#reset-btn').click(function() { $(this).html('<i class="fas fa-spinner fa-spin gap-right"></i> Resetting ...'); });

  $('.button-save').click(function() { $(this).html('<i class="fas fa-spinner fa-spin gap-right"></i> Saving ...'); });
  $('.button-go-back').click(function() { $(this).html('<i class="fas fa-spinner fa-spin gap-right"></i> Loading ...'); });
  $('.button-sm-edit').click(function() { $(this).html('<i class="fas fa-spinner fa-spin fa-lg" title="Loading ..."></i>'); });
  $('.button-sm-delete').click(function() { $(this).html('<i class="fas fa-spinner fa-spin fa-lg" title="Deleting ..."></i>'); });
  $('.button-sm-build').click(function() { $(this).html('<i class="fas fa-spinner fa-spin fa-lg" title="Building ..."></i>'); });
  $('.button-sm-code').click(function() { $(this).html('<i class="fas fa-spinner fa-spin fa-lg" title="Generating ..."></i>'); });

  $('#navbar-toggle-btn').click(function(e) {
    $(this).html('<i class="fas fa-spinner fa-spin" title="Loading ..."></i>');
    setTimeout(
        function () {
          $('#navbar-toggle-btn').html('<i class="fas fa-bars"></i>');
        }, 500);
  });
});
2
What are the styles for "gap-right". Could this be the issue?Richard Lovell
I'm fairly certain this is not a CSS issue, but rather a jQuery issue, though I could be completely wrong! Either way, here is the CSS for "gap-right" per your request. .gap-right { margin-right:10px; }Seibertron
Could you try .gap-right { padding-right:10px; } instead?Richard Lovell
It just changed how the spinner looks because the margin is gone. The CSS shouldn't have anything to do with whether or not the form submits, which I can isolate has to do with the jQuery code if I comment out the line for this button.Seibertron

2 Answers

3
votes

The issue is caused by the propagation of the click event being stopped, before the submit event can be dispatched. Since the source of the click event (<i class="fas fa-search">) is no longer valid, when it is removed from the DOM by using $(this).html(),

To resolve the issue you can simply change the class names of the icon element. Then wrap your text in a span to allow you to change only the text within the span.

jQuery(function($) {
    $('#search-btn').on('click', function() {
        $(this).find('.fas')
            //add the spinner icon
            .addClass('fa-spinner fa-spin')
            //remove the search icon
            .removeClass('fa-search')
            //update the text
            .next().text('Searching...');
    });
    
    /* DEMO PURPOSES ONLY - do not use below */
    $('#search-form').on('submit', function(e) {
       e.preventDefault();
       window.alert('Form submitted successfully.');
    });
    /* END DEMO PURPOSES ONLY */
});
.gap-right {
   margin-right: 10px;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>

<form id="search-form" action="about:blank">
  <button type="submit" id="search-btn" name="search" value="Search" class="btn btn-primary gap-right">
    <i class="fas fa fa-search gap-right"></i> 
    <span>Search</span>
  </button>
</form>

Alternatively you can monitor the submit event of the form and change the button entirely instead.

jQuery(function($) {
    $('#search-form').on('submit', function(e) {
       $(this).find('#search-btn')
           .html('<i class="fa fas fa-spinner fa-spin gap-right"/> Searching...');
       
       /* DEMO PURPOSES ONLY - do not use below */
       e.preventDefault();
       window.alert('Form submitted successfully.');
       /* END DEMO PURPOSES ONLY */
    });
});
.gap-right {
   margin-right: 10px;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>

<form id="search-form" action="about:blank">
  <button type="submit" id="search-btn" name="search" value="Search" class="btn btn-primary gap-right">
    <i class="fas fa fa-search gap-right"></i> Search
  </button>
</form>

In all of the snippets, I disabled the actual form submission, otherwise you would not see the button change. Be sure to not use the JavaScript below DEMO PURPOSES ONLY
Since a CDN of fontawesome 5 is not available without registering, I used the fontawesome 4 CDN and the fa class name to generate the icons.

1
votes

So basically you need

  1. Change the type from submit to button.
  2. Change the icon by adding and removing class.
  3. Submit the form programmatically after a while.

So your code can be something like that:

$(document).ready(function(){
 $('#search-btn').on('click', function() {
   		$(this).find('.fa').addClass('fa-spinner fa-spin').removeClass('fa-search'); // change icon
        setInterval(function(){ document.querySelector('#demo').submit(); }, 2000); // submit the form after two seconds
   });    
});
.gap-right {margin-right: 10px;}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form id="demo">
  <button type="button" id="search-btn" name="search" value="Search" class="btn btn-primary gap-right"><i class="fa fa-search gap-right"></i> Search</button>
</form>

Note: this demo usets FA v4* so i changed .fas to .fa in order for it to work.

Note 2: Many thanks to @fyrye.


This is the old answer that works BUT effects html5 validation since it use preventDefault() method. You can read more about it here - basically you should avoid prevent the default behavior of the browser unless it a must.

$(document).ready(function(){
  $('#search-btn').click(function(e) { 
    e.preventDefault();   //  cancel submit action
    $(this).html('<i class="fa fa-spinner fa-spin gap-right"></i> Searching ...');  // change text
    setInterval(function(){ document.forms[0].submit(); }, 2000); // submit after two seconds
  });    
});
.gap-right {margin-right: 10px;}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form name="demo">
  <button type="submit" id="search-btn" name="search" value="Search" class="btn btn-primary gap-right"><i class="fa fa-search gap-right"></i> Search</button>
</form>