1

I have the following function

function removecost(e,parent) {

        e.preventDefault();
        var current_Explanation = parent;
        var other_Explanations = current_Explanation.siblings('.repeatingcostsection');


        if (other_Explanations.length === 0) {
            alert("You should atleast have one Cost Section");
            return;
        }
        current_Explanation.slideUp('slow', function() {
            current_Explanation.remove();

            // reset Explanation indexes
            other_Explanations.each(function() {
               resetAttributeNames($(this));
            })

        })
}

The function doesn't do any special. It is called on a delete icon's onclick attribute and checks the number of siblings for current_Explanation. If they are greater than zero then it removes current_Explanation. If the siblings length is 0 then it alerts a message "You should atleast have one Cost Section".

The functionality works absolutely fine if the user clicks slowly on the icon. But if user clicks clicks continuously very fast on the icon, the alert message is not shown and all blocks are removed because

I think

other_Explanations.each(function() {
               resetAttributeNames($(this));
            });

is not completed properly.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Manish Jangir
  • 5,329
  • 4
  • 42
  • 75

2 Answers2

0

you need to disable the button till the whole processing is done

function removecost(e,parent) {

        e.preventDefault();

        $(e.target).prop('disabled', true); //disable it here


        var current_Explanation = parent;
        var other_Explanations = current_Explanation.siblings('.repeatingcostsection');


        if (other_Explanations.length === 0) {
            alert("You should atleast have one Cost Section");
            return;
        }
        current_Explanation.slideUp('slow', function() {
            current_Explanation.remove();

            // reset Explanation indexes
            other_Explanations.each(function() {
               resetAttributeNames($(this));
            })

           $(e.target).prop('disabled', false); //enable it again
        })
}

Note that you need to enable it once the slide up is complete.

gurvinder372
  • 66,980
  • 10
  • 72
  • 94
  • I wanted to have some other solution instead of disabling it. By the way disabling the target is not working. – Manish Jangir Jan 20 '16 at 07:00
  • @ManishJangirBlogaddition.com any specific reason for that? Did I missed any limitation you had posted in your question itself? – gurvinder372 Jan 20 '16 at 07:06
  • Are you really sure, that disabling a dom element will also disable the click event also? – Manish Jangir Jan 20 '16 at 07:20
  • @ManishJangirBlogaddition.com if it is not a form input element then it wont work since disabled property is for input elements. you can still disable click event temporarily using this http://stackoverflow.com/questions/1921855/jquery-how-can-i-temporarily-disable-the-onclick-event-listener-after-the-even – gurvinder372 Jan 20 '16 at 07:25
0

you need a debounce function or throttle function, which could throttle the amount of times your codes runs.

here is an example:

 function throttle(fn, threshhold, scope) {
        threshhold || (threshhold = 250);
        var last,
            deferTimer;
        return function () {
            var context = scope || this;

            var now = +new Date,
                args = arguments;
            if (last && now < last + threshhold) {//last execute time
                // store timer
                clearTimeout(deferTimer);
                deferTimer = setTimeout(function () {
                    last = now;
                    fn.apply(context, args);
                }, threshhold);
            } else {
                last = now;
                fn.apply(context, args);//after Nth , have to wait threshhold to execute(N+1)th time.
            }
        };
    }

you can use it in this way:

  $btn.on('click',throttle(function(){
      //your codes
  },300));

and this means your codes will be execute only once during 300ms

you can also using underscore to achieve same effect

jilykate
  • 5,430
  • 2
  • 17
  • 26