1

My code is the following. When I click the search button, it enters a for loop that prints 5000 times "hi". Before this calculation begins, I want to disable the button. After the console.log is finished, I want to reenable this button. But for some reason, this isn't working. (To be more precise, although here I am simply printing logs, my actually work involves various calculations that take around 5 seconds to finish using for loops.)

$("#search").click(function() {

   $("#search").prop("disabled",true);
   $("#search").text("Loading...");

   var i;
   for(i = 0; i < 50000; i++)
       console.log("hi");


   $("#search").prop("disabled",false);
   $("#search").text("Finished...");
});

https://jsfiddle.net/gs793zhx/

user2832367
  • 361
  • 1
  • 3
  • 8

4 Answers4

2

Try using .delay() with duration set to 1 , .queue() , .promise() , $.Deferred()

$("#search").click(function() {
  $(this).prop("disabled", true)
    .text("Loading...")
    .css("color", "red")
    .delay(1, "p")
    .queue("p", function(next) {
      next()
    })
    .dequeue("p")
    .promise("p")
    .then(function() {
      var elem = this;
      return $.Deferred(function(d) {
        var i = 0, max = 50000;
        for (;i < max; i++) {
          console.log("hi");
        }
        if (i === max) {
          d.resolveWith(elem, [i])
        }
      }).promise()
    }).then(function(data) {
      console.log(this, data);
      $(this).prop("disabled", false)
      .css("color", "blue")
      .text("Finished...");
    })
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<button type="button" id="search" class="btn btn-primary" style="width:100px; height:30px;">SEARCH</button>

jsfiddle https://jsfiddle.net/gs793zhx/1/

guest271314
  • 1
  • 10
  • 82
  • 156
  • @user2832367 Call to `jQuery()` : `$()` could be removed from `$(this)` at last `.then()` ; same results should be returned i.e.g.; `this.prop("disabled", false)` – guest271314 Oct 01 '15 at 06:07
  • Hi. Thanks for the answer. By any chance, do you know why the original didn't work? – user2832367 Oct 01 '15 at 07:41
  • @user2832367 Appear `for` loop begins before `$("#search").prop("disabled",true); $("#search").text("Loading...");` complete process . See also http://stackoverflow.com/questions/2734025/is-javascript-guaranteed-to-be-single-threaded , http://stackoverflow.com/questions/21718774/how-is-javascript-single-threaded , http://james.padolsey.com/javascript/looping-in-javascript/ . Note , if place `alert()` before `for` loop , returns expected results as well - allowing `.prop()` enough time to complete its operation https://jsfiddle.net/gs793zhx/2/ – guest271314 Oct 02 '15 at 02:23
1

use $("#search").attr("disabled","disabled"); and $("#search").removeAttr("disabled"); instead

Vance
  • 867
  • 5
  • 9
  • Is it just me or this isn't working? I can't get this to work. – user2832367 Oct 01 '15 at 05:12
  • @user2832367, your loop seems too fast.can you try setting a little delay on your for loop using setTimeout? Replace you `console.log("hi")` line inside your loop to `setTimeout(function(){console.log("hi");},500);` then make your loop shorter to 10 only just for testing – Vance Oct 01 '15 at 05:21
0

Problem is with browser's performance to log hi for 50000 times.

You may put logs into js variable and dump the variable once into the console.

var btn = $("#search");
btn.click(function() {
  btn.prop("disabled", true);
  btn.text("Loading...");
  var log = [];
  for (var i = 0; 50000 > i; i++)
    log.push("i: " + i);
  console.log(log);
  btn.prop("disabled", false);
  btn.text("Finished...");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id='search'>Search</button>
  • Is there any way to fix this problem? Sadly, i must perform such calculation (way more complex than printing log, but a lot of for loops) with javascript front-end. – user2832367 Oct 01 '15 at 05:10
-1
$("#search").click(function() {

$("#search").prop("disabled",true);
$("#search").text("Loading...");


var i;
for(i = 0; i < 50000; i++) {
    console.log("hi");
}
if(i==50000-1)
{
    $("#search").prop("disabled",false);
    $("#search").text("Finished...");       
}
});
Master Yoda
  • 536
  • 8
  • 21