Bootstrap 4 Loading Spinner in button

It seems like spinner CSS is not present in the loaded CSS library. Please try below codes

In CSS

    @keyframes spinner-border {
      to { transform: rotate(360deg); }
    } 
    .spinner-border{
        display: inline-block;
        width: 2rem;
        height: 2rem;
        vertical-align: text-bottom;
        border: .25em solid currentColor;
        border-right-color: transparent;
        border-radius: 50%;
        -webkit-animation: spinner-border .75s linear infinite;
        animation: spinner-border .75s linear infinite;
    }
    .spinner-border-sm{
        height: 1rem;
        border-width: .2em;
    }

In JS

$(document).ready(function() {
    $("#btnFetch").click(function() {
      $(this).prop("disabled", true);
      $(this).html(
        `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>Loadingg...`
      );
    });
});

Code Pen


You have to add Bootstrap 4.2.1 for this code while you are using 4.0

$(document).ready(function() {
    $("#btnFetch").click(function() {
      // disable button
      $(this).prop("disabled", true);
      // add spinner to button
      $(this).html(
        `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...`
      );
    });
});
<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">

<div style="margin:3em;">
  <form class="form-inline" id="topicForm" action="" method="POST">
    <input type="text" id="inputTopic" name="topic" class="form-control mb-2 mr-sm-2" placeholder="Topic of interest" required autofocus/>
    <button type="button" id="btnFetch" class="btn btn-primary mb-2">Submit</button>
  </form>
</div>

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>

This works for me. It stores the original text/html as an attribute & restores it from there.

    $(document).ready(function() {
        $("#btnFetch").click(function() {
           var $this = $(this);
           
           //Call Button Loading Function
           BtnLoading($this);
    
           //Call Button Reset Function after AJAX or your code execution
           BtnReset($this);
        });
    });
    
    function BtnLoading(elem) {
        $(elem).attr("data-original-text", $(elem).html());
        $(elem).prop("disabled", true);
        $(elem).html('<i class="spinner-border spinner-border-sm"></i> Loading...');
    }
    
    function BtnReset(elem) {
        $(elem).prop("disabled", false);
        $(elem).html($(elem).attr("data-original-text"));
    }