2

Hi I'm trying to write a JQuery function to;

  1. Change the class of a button with class .load-on-click to be a btn-warning and change the button text to loading

  2. Then, after a timeout, return the button to the previous class it had before it was changed to btn-warning, and return the button text to same text it had before it was changed.

I currently have it working below, but can't get it to return to it's previous class, I've just temporarily set it to btn-primary; if anyone know how I would do this, that would be great, thanks.

    jQuery("#ntc-web-main .load-on-click").click(function () {
        var buttonText = jQuery(this).text();

        jQuery(this)
            .text("Loading")
            .removeClass(
                "btn-default btn-primary btn-success btn-info btn-danger btn-link"
            )
            .addClass("btn-warning");

        //revert to original state,
        setTimeout(function () {
            jQuery(this)
                .text(buttonText)
                .removeClass("btn-warning")
                .addClass("btn-primary");
        }, 10000);
    });
Sarun UK
  • 6,210
  • 7
  • 23
  • 48
edpo1996
  • 39
  • 5
  • you are losing the "this" context. use an arrow function instead. https://stackoverflow.com/questions/28798330/arrow-functions-and-this – Markus Dresch Oct 27 '20 at 12:27
  • Does this answer your question? [The Binding of "this"](https://stackoverflow.com/questions/56157472/the-binding-of-this) – Markus Dresch Oct 27 '20 at 12:32

2 Answers2

1

jQuery("#ntc-web-main .load-on-click").click(function () {
        var buttonText = jQuery(this).text();

        jQuery(this)
            .text("Loading")
            .removeClass(
                "btn-default btn-primary btn-success btn-info btn-danger btn-link"
            )
            .addClass("btn-warning");

        //revert to original state,
        setTimeout(() => {
            jQuery(this)
                .text(buttonText)
                .removeClass("btn-warning")
                .addClass("btn-primary");
        }, 10000);
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id='ntc-web-main'>
<button class='load-on-click'>
click me
</button>
</div>
Sarun UK
  • 6,210
  • 7
  • 23
  • 48
1

Your actual problem is the setTimeout scope. Inside the setTimeout callback, the this refers to the callback instead of the button event.

In my case, I use the old good var that = this; that makes a reference to this.

jQuery(document).ready(
    function() {
        jQuery("#ntc-web-main .load-on-click").on(
            'click',
            function () {
                var that = this;
                var original = jQuery(that).text();
                
                jQuery(that)
                  .text("Loading")
                  .removeClass(
                    "btn-default btn-primary btn-success btn-info btn-danger btn-link"
                  )
                  .addClass("btn-warning");
                  
                setTimeout(
                    function () {
                      jQuery(that)
                          .text(original)
                          .removeClass("btn-warning")
                          .addClass("btn-primary");
                      }, 
                      2000
                );
            }
        );
    }
);
button {
  background: #EFEFEF;
  border: none;
  padding: 15px;
  outline: none;
}

button.btn-warning {
  background: #EF7788;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="ntc-web-main">
    <button class="load-on-click btn-default btn-primary btn-success btn-info btn-danger btn-link">
        Do something
    </button>
</div>
KodeFor.Me
  • 13,069
  • 27
  • 98
  • 166