jquery disable a button for a specific time - asp.net

i want to disable a button for a specific time. how can i do that?

Since this is likely to be a task you might like to repeat, I think the best way to do this would be to extend jQuery like so:
$.fn.timedDisable = function(time) {
if (time == null) { time = 5000; }
return $(this).each(function() {
$(this).attr('disabled', 'disabled');
var disabledElem = $(this);
setTimeout(function() {
disabledElem.removeAttr('disabled');
}, time);
});
};
This will allow you to call a function on a set of matched elements which will temporarily disable them. As it is written, you can simply call the function, and the selected elements will be disabled for 5 seconds. You would do that like so:
$('#some-button').timedDisable();
You can adjust the default time setting by changing the 5000 in the following line:
if (time == null) { time = 5000; }
You can optionally pass in a time value in milliseconds to control how long the elements will be disabled for. For example:
$('#some-button').timedDisable(1000);
Here's a working demo: http://jsfiddle.net/fG2ES/

Disable the button and then use setTimeout to run a function that enables the button after a few seconds.
$('#some-button').attr("disabled", "disabled");
setTimeout('enableButton()', 5000);
function enableButton(){
$('#some-button').removeAttr('disabled');
}

Try this.
(function(){
$('button').on('click',function(){
var $this=$(this);
$this
.attr('disabled','disabled');
setTimeout(function() {
$this.removeAttr('disabled');
}, 3000);
});
})();
You can find a working example here http://jsfiddle.net/informativejavascript/AMqb5/

Might not be the most elegant solution, but I thought I'd play with jQuery queues on this one...
​$.fn.disableFor = function (time) {
var el = this, qname = 'disqueue';
el.queue(qname, function () {
el.attr('disabled', 'disabled');
setTimeout( function () {
el.dequeue(qname);
}, time || 3000);
})
.queue(qname, function () {
el.removeAttr('disabled');
})
.dequeue(qname);
};
$('#btn').click( function () {
​$(this).disableFor(2000);​​​​
});
​
This is where I worked it out... http://jsfiddle.net/T9QJM/
And, for reference, How do I chain or queue custom functions using JQuery?

Related

METEOR - Show loader and run methods at specific time

I wanna build a loader circle what goes from 1 to 100% and in the meantime to run some methods.
loader circle
The scenario is:
load the page and start counting.
When the counter is at 50% pause counting and run the first method and when I have the result to start counting from where I was left.
count until 90% and run the second method.
I was trying something with Meteor.setInterval on onCreated but I'm not sure if it's the right method to do this.
Can someone give me some ideas about how to approach this?
Thanks!
There are several ways you can do this depending on your specific needs and you might even want to use one of the many Reactive Timer packages that are out there.
Here is one working example that only uses the Meteor API (no packages). Note, I did not actually incorporate the loader circle animation since it wasn't specifically part of the question.
Template definition
<template name="loader">
<h1>Loading...({{loadingPercentage}})</h1>
</template>
Template logic
Template.loader.onCreated(function() {
// used to update loader circle and triggering method invocation
this.elapsedTime = new ReactiveVar(0);
// handle for the timer
var timerHandle;
// starts a timer that runs every second that can be paused or stopped later
const startTimer = () => {
timerHandle = Meteor.setInterval(() => {
this.elapsedTime.set(this.elapsedTime.get() + 1);
}, 1000);
};
// pauses/stops the timer
const pauseTimer = () => {
Meteor.clearInterval(timerHandle);
};
// let's first start our timer
startTimer();
// runs every second and triggers methods as needed
this.autorun(() => {
const elapsedTime = this.elapsedTime.get();
// call methods based upon how much time has elapsed
if (elapsedTime === 5) {
pauseTimer();
// call method and restart the timer once it completes
Meteor.call('methodOne', function(error, result) {
// do stuff with the result
startTimer();
});
} else if (elapsedTime === 9) {
pauseTimer();
// call method and restart the timer once it completes
Meteor.call('methodOne', function(error, result) {
// do stuff with the result
// DO NOT RESTART TIMER!
});
}
});
});
Template.loader.helpers({
// helper used to show elapsed time on the page
loadingPercentage: function() {
return Template.instance().elapsedTime.get();
},
});
Let me know if you have any questions.
This is what i was trying to do:
Template.onboarding.onCreated(function(){
var instance = this;
instance.progress = new ReactiveVar(0);
instance.autorun(function(){
var loader = {
maxPercent: 100,
minPercent: instance.progress.get(),
start: function(){
var self = this;
this.interval = Meteor.setInterval(function(){
self.minPercent += 1;
if(self.minPercent >= self.maxPercent) {
loader.pause();
}
if( self.minPercent == 25) {
loader.pause();
Meteor.call('runMethodOne', (err,res)=>{
if (!err) loader.resume();
});
}
if(self.minPercent == 75) {
loader.pause();
Meteor.call('runMethodTwo', (err,res) =>{
if(res) loader.resume();
});
}
}
});
}
instance.progress.set(self.minPercent)
},50);
},
pause: function(){
Meteor.clearInterval(this.interval);
delete this.interval;
},
resume: function(){
if(!this.interval) this.start();
}
};
loader.start();
}
});
});

Is it possible to display a UI transition to reflect changes in a collection with meteorjs?

I would like to display a pulse transition when my collection change.
In my html file, I have that:
<template name="menuItemTag">
<div class="app-menu-item-tag ui label">{{ count }}</div>
</template>
In my js file, I expose the count variable for my template like that:
Template.menuItemTag.count = function() {
return MyCollection.find().count();
};
With that the count change in the ui when the collection is updated.
Now, I would like to display a pulse transition on my div label each time the count value change.
I tried to use the cursor.observe
Template.menuItemTag.rendered = function() {
MyCollection.find().observe({
added: function (id, user) {
$('.app-menu-item-tag:nth(0)').transition('pulse');
},
removed: function () {
$('.app-menu-item-tag:nth(0)').transition('pulse');
}
});
};
Unfortunately, it is call too many times when the template is rendered the first time.
If initialy I have 40 items in my collection, the transition is played 40 times...
Is there a clean way for playing a ui transition on changes and avoid the collection initialisation?
Try this:
Template.menuItemTag.count = function() {
return Session.get('count');
};
Template.menuItemTag.rendered = function() {
this.countComputation = Deps.autorun(function() {
Session.set('count', MyCollection.find().count());
$('.app-menu-item-tag:nth(0)').transition('pulse');
});
};
Template.menuItemTag.destroyed = function() {
this.countComputation.stop();
};
Thanks sbking for your answer, I still have a problem on initialization of the collection.
I propose below to defer the first animation util the collection will be completely filled:
Template.menuItemTag.count = function() {
return Session.get('count');
};
Template.menuItemTag.rendered = function() {
var that = this;
this.countComputation = Deps.autorun(function() {
Session.set('count', MyCollection.find().count());
// Cancel playing UI transition. The collection is not completely initialized
if (that.handleTimeout) {
Meteor.clearTimeout(that.handleTimeout);
}
// Play the UI transition without the timeout if the collection is initialized
if (that.noNeedTimeoutAnymore) {
$('.app-menu-item-tag:nth(0)').transition('pulse');
}
// Tentative to play the UI transition during the collection feeding
else {
that.handleTimeout = Meteor.setTimeout(function() {
$('.app-menu-item-tag:nth(0)').transition('pulse');
// At this point we know that the collection is totaly initialized
// then we can remove the timeout on animation for the future update
that.noNeedTimeoutAnymore = true;
}, 1500); // You can adjust the delay if needed
}
});
};
Template.menuItemTag.destroyed = function() {
this.countComputation.stop();
};

Deep link to a position in a page, using Meteor JS

I have a meteor app with multiple pages. I want to be able to deeplink to an anchor somewhere halfway the page.
Traditionally, in normal html, you'd make an somewhere in your page, and link to it via /mypage.html#chapter5.
If I do this, my meteor app won't scroll down to that spot.
What is the best approach around this?
#Akshat 's answer works for on the same page, but what if you want to be able to pass around a url w/ a "#" in it? I did it how the meteor docs did.
Template.myTemplate.rendered = function() {
var hash = document.location.hash.substr(1);
if (hash && !Template.myTemplate.scrolled) {
var scroller = function() {
return $("html, body").stop();
};
Meteor.setTimeout(function() {
var elem = $('#'+hash);
if (elem.length) {
scroller().scrollTop(elem.offset().top);
// Guard against scrolling again w/ reactive changes
Template.myTemplate.scrolled = true;
}
},
0);
}
};
Template.myTemplate.destroyed = function() {
delete Template.myTemplate.scrolled;
};
Stolen from the source to the meteor docs.
Are you using some kind of javascript router? Meteor Router?
You could use something like a javascript based scrolling method. One such example is with JQuery: (You can place this in your link/buttons click handler)
Template.hello.events({
'click #theitemtoclick':function(e,tmpl) {
e.preventDefault();
$('html, body').animate({
scrollTop: $("#item_id").offset().top
}, 600);
}
});
Then tag your html item where you would put your anchor with the id:
<h1 id="item_id">Section X</h1>
Currently, there's an issue in IronRouter where the hash is removed from the url. This is discussed here and here. Fortunately there is a fix even though it doesn't appear to be in the stable version.
My Iron Router solution with traditional anchor tags:
1) Apply the IronRouter fix above
2)
Router.configure({
...
after: function () {
Session.set('hash', this.params.hash);
},
...
});
3)
function anchorScroll () {
Deps.autorun(function (){
var hash = Session.get('hash');
if (hash) {
var offset = $('a[name="'+hash+'"]').offset();
if (offset){
$('html, body').animate({scrollTop: offset.top},400);
}
}
Session.set('hash', '');
});
}
Template.MYTEMPLATE.rendered = function (){
anchorScroll();
};
Unfortunately this has to be set in each template's .rendered() otherwise the anchor tag is not guaranteed to be in the DOM.
For better or worse this will scroll again with a code push.
Mike's Answer didn't quite work for me. The hash was returning empty in the onRendered callback. I nested the code in an additional Meteor.setTimeout
fyi I'm using Blaze.
Below worked like a charm :)
Template.myTemplate.onRendered(function() {
Meteor.setTimeout(function(){
var hash = document.location.hash.substr(1);
if (hash && !Template.myTemplate.scrolled) {
var scroller = function() {
return $("html, body").stop();
};
Meteor.setTimeout(function() {
var elem = $("a[name='" + hash + "']");
if (elem.length) {
scroller().scrollTop(elem.offset().top);
// Guard against scrolling again w/ reactive changes
Template.myTemplate.scrolled = true;
}
},
0);
}
},0);
});
Template.myTemplate.destroyed = function() {
delete Template.myTemplate.scrolled;
};

jQuery: wait to perform a task until an animation finished

I have a div which is placed in any pages. When you click on this div, it will be closed by using jquery checking on its css class:
$('.content-box-header').click(function
() {
$(this).parent().children('.content-box-content').slideFadeToggle(200);
}
In several pages, I need to set that div with a specific ID in order to perform some tasks after that div closed. For example:
$('#divleft').live('click', function
(e) { runTask(); }
The above sample is trigger on that div with the specific ID = divleft.
The problem is that, I would like to check something ONLY after the div is really closed, but in my current situation, runTask() is performed before the div is closed.
SO my question is that how could the method runTask(); is delayed after the div is really closed?
Thanks in advance!!!!
I think what you are looking for is .queue(). See the documentation here: http://api.jquery.com/queue/
You can call this on a set of matched elements to get some information about the remaining effects to be run. So in your case you could do something like this:
$('#divleft').live('click', function (e) {
runTaskAfterAnimation()
});
function runTaskAfterAnimation() {
if ($('.content-box-content').queue('fx').length == 0) {
runTask();
} else {
setTimeout(runTaskAfterAnimation, 10);
}
}
View a demonstration here: http://jsfiddle.net/LeHHj/2/
This time it definitely works ;)
In your case, just use
$('.content-box-header').click(function () { $(this).parent().children('.content-box-content').slideFadeToggle(200, function() { runTask(); }); }
You can store the function on the div using jQuery's data() method.
This lets you set an 'afterClick' function on your element:
$('.content-box-header').click(function () {
var $this = $(this);
$this.parent().children('.content-box-content').slideUp(200, function () {
var after = $this.data('afterClick');
if (after) after();
});
});
$('#divleft').data('afterClick', function () { runTask(); });
You need to check if the item you are wanting to runTask() on is :animated and if so 'register' a callback (via .data()) for when it's done
.live('click', doRunTask);
doRuntask = function() {
if ($(this).is(':animated'))
$(this).data('afterAnimation', runTask);
else
runTask();
});
$('.content-box-header').click(function () {
$(this).parent().children('.content-box-content').slideFadeToggle(200, function() {
var cb = $(this).data('afterAnimation');
cb && cb();
});
}

Scope problem with SetTimeOut

I don't know why but this code is not working ? Why would it not ? I guess it is because scope problem I am having here :
function washAway(obj) {
alert($(obj)); // says HTML Object which is fine
setTimeout(function() {
alert($(obj)); // says undefined
$(obj).fadeOut("slow", function() {
$(this).remove();
});
}, 2000);
};
At the point where the function in the timeout executes, it has no way to know what obj is - it was a parameter passed into the method where the timeout was set up, but the function inside has no reference to it.
An alternative approach is to write a jQuery plugin to wait before it acts like this:
function($){ //to protect $ from noConflict()
$.fn.pause = function(duration) {
$(this).animate({ dummy: 1 }, duration);
return this;
};
}
Then you can use:
$(obj).pause(2000).fadeOut("slow", function() { $(this).remove(); });
Any ways, I've found my answer after a couple of try/wrong. But I am still wondering why it didn't work out.
Here is the code :
function washAway(obj) {
alert($(obj).attr("id"));
var a = function() {
var _obj = obj;
return function() {
$(_obj).fadeOut("slow", function() {
$(this).remove();
});
};
};
setTimeout(a(), 2000);
};
Edit : I think I understood the problem here :
Because we are talking about closures here, when washAway execution finishes, the variable obj is destroyed so setTimeOut function callback function can't use that resource because it is no more available on the stack and it is not also a global variable.

Resources