jQuery 2.1 | Trigger function after delay in textarea - timer

I use this to trigger a function once a pause in typing is initiated in a textarea:
var keyTimer;
$("#TEXTAREA").on('keyup mouseup', function(){
if (keyTimer) {
clearTimeout(keyTimer);
}
keyTimer = setTimeout(function () {
doFunction(); // Not working, triggers only once (on focus).
}, 500);
});
doFunction() triggers only at first keyup pause (on focus). That function must trigger at every pause (500). Now I need to blur TEXTAREA, then focus it again to reactivate doFunction() which is useless for me. Any solution greatly appreciated.
UPDATE:
Updated the code:
var keyTimer;
$("#TEXAREA").on('keyup mouseup', function(){
if (keyTimer) {
clearTimeout(keyTimer);
}
keyTimer = setTimeout(function () {
doFunction(); // Formulates a string
$("#TEXAREA").trigger('change');
}, 500);
}).on('change', function(){
alert('test'); // This triggers at every keyup/mouseup delay (500)
// This section of code must work after delay (500), but it doesn't,
// it only works on Textarea blur, which is not what I want:
var txtarea = $(this);
var livecount = $("#myValue").val(); // Comes from doFunction()
if ( livecount.length > 2800 ) {
txtarea.css('color','#C00'); // Change text color of textarea
} else if ( livecount.length <= 2800 ) {
txtarea.css('color','#000'); // Change text color of textarea
}
});

it looks like the only think in your code that is missing is the selector that you are using in the doFunction. You are using #myValue but are actually looking for the value inside of the #TEXTAREA. Here is my jsfiddle
function doFunction(){
console.log('not a test')
}
var keyTimer;
$("#TEXAREA").on('keyup mouseup', function(){
if (keyTimer) {
clearTimeout(keyTimer);
}
keyTimer = setTimeout(function () {
doFunction(); // Formulates a string
$("#TEXAREA").trigger('change');
}, 1000);
}).on('change', function(){
console.log('test'); // This triggers at every keyup/mouseup delay (500)
// This section of code must work after delay (500), but it doesn't,
// it only works on Textarea blur, which is not what I want:
var txtarea = $(this);
var livecount = $("#TEXAREA").val(); // Comes from doFunction()
if ( livecount.length > 2800 ) {
txtarea.css('color','#C00'); // Change text color of textarea
} else if ( livecount.length <= 2800 ) {
txtarea.css('color','#f00'); // Change text color of textarea
}
});

UPDATE - FINAL
Ok, got it working finally:
var keyTimer;
$("#TEXTAREA").on('keyup mouseup', function(){
$(this).change(); // Need this to update keyboard character input
}).on('change', function(){
if (keyTimer) {
clearTimeout(keyTimer);
}
keyTimer = setTimeout(function () {
doFunction(); // Formulates a string
}, 200); // Delay before doFunction() so it won't slow down keyboard input
var livecount = $("#myValue"); // String value from doFunction()
if ( livecount.val().length > 2800 ) {
$(this).css('color','red'); // Change textarea text color to red for overlimit
} else if ( livecount.val().length <= 2800 ) {
$(this).css('color','black'); // Change textarea text color to black for within limit
}
});
It was a long day ;-)

Related

Double click on a map object in amMaps using AngularJS

I am working on an application which is using ammaps. I have a number of points located on the map based on longitude and latitude value. I have achieved single click functionality by using the following code:
map.addListener("clickMapObject", function (event) {
$scope.$apply(function(){
$scope.colorPoints();
$scope.selectedRow = event.mapObject.idBase;
});
});
I want to achieve the functionality of double click. Could anyone let me know how I could do that in amMaps.
Technically, amMap does not support double-click events. However, you can simulate it with a clickMapObject event.
For that you'll need to ignore the first click. If the subsequent clickMapObject happens within 500ms or so, you register it as double-click.
Something like this:
map.addListener( "clickMapObject", function( event ) {
if ( false !== map.clickedObject && map.clickedObject === event.mapObject ) {
// doubleckick
map.clickedObject = false;
$scope.$apply( function() {
$scope.colorPoints();
$scope.selectedRow = event.mapObject.idBase;
} );
} else {
clearTimeout( map.clickedObjectTimeout );
map.clickedObject = event.mapObject;
map.clickedObjectTimeout = setTimeout( function() {
map.clickedObject = false;
}, 500 );
}
} );

Disable drag-drop while HTML5 file browse popup is open

I am working on an Angular JS application which has HTML5 file input button and a Drag - Drop area.
I need to disable the drag drop area as long as the file browse popup is open. What is the best way to achieve this?
Here is an example I just made for you, this is an updated Google DnD Controller that I made more advanced plus added the functionality you wanted.
window.fileBrowserActive = false; //init the controller to false
function DnDFileController(selector, onDropCallback) {
var el_ = document.querySelector(selector);//select our element
var overCount = 0;//over count is 0
this.dragenter = function(e)
{
e.stopPropagation();//stop propagation and prevent the default action if any
e.preventDefault();
overCount++;//increment and assign the overCount var to 1
if(fileBrowserActive == false)//if the fileBrowserAction is false we can add dropping class
{
el_.classList.add('dropping');
}
else //else add error or none at all it's your choice
{
el_.classList.add('error');
}
};
this.dragover = function(e)
{
e.stopPropagation();
e.preventDefault();
};
this.dragleave = function(e)
{
e.stopPropagation();
e.preventDefault();
if (--overCount <= 0) { //we decrement and assign overCount once if it's equal to or less than 0 remove the classes and assign overCount to 0
el_.classList.remove('dropping');
el_.classList.remove('error');
overCount = 0;
}
};
this.drop = function(e) {
e.stopPropagation();
e.preventDefault();
el_.classList.remove('dropping');
el_.classList.remove('error');
if(fileBrowserActive === false)
{ //if fileBrowserActive is false send the datatranser data to the callback
onDropCallback(e.dataTransfer);
}
else
{ //else send false
onDropCallback(false);
}
};
el_.addEventListener('dragenter', this.dragenter, false);
el_.addEventListener('dragover', this.dragover, false);
el_.addEventListener('dragleave', this.dragleave, false);
el_.addEventListener('drop', this.drop, false);
}
var isFileBrowserActive = function(e){
fileBrowserActive = true; //once clicked on it is active
this.onchange = function(e){ //create the onchange listener
if(e.target.value !== "") //if the value is not blank we keep it active
{ //so now user can't DnD AND use the file browser
fileBrowserActive = true;
}
else if(e.target.value == "") //if it is blank means they click cancel most likely
{
fileBrowserActive = false;//assign false back
} //remove the listener
this.removeEventListener('change',this.onchange,false);
};
//assign the listener for change
this.addEventListener('change',this.onchange,false);
};
var fB = document.getElementById('fileBrowser'); //grab our element for file input
fB.addEventListener('click',isFileBrowserActive,false); //assign the click event
var activation = new DnDFileController('#dragNDrop',function(e){ //grab our DnD element
console.log(e); //console log the e (either datatransfer || false)
});
Check out the This Fiddle to see how this works

Angular NgStyle background image isn't refreshing

I am trying to change the background image based on window resize. I am getting the correct output in console in terms of the image path that I need. But for some reason the url just doesn't update in the div.
This is in a directive:
angular.element($window).on('resize', function(){
waitForFinalEvent(function(){
checkSize();
}, 500);
});
$scope.index = 0;
var checkSize = function(){
var width = angular.element($window).width();
var height = angular.element($window).height()
console.log('w: ' +width);
console.log('h: '+height);
$scope.index ++;
if(width < 1050 && width > 800 ) {
$scope.slideImage = $scope.displaySlideImageM;
console.log('here1: ' +$scope.slideImage);
} else if(width < 799 && height < 800) {
$scope.slideImage = $scope.displaySlideImageM;
console.log('here2: ' +$scope.slideImage);
} else if(width < 799 && height > 800) {
$scope.slideImage = $scope.displaySlideImageP;
console.log('here3: ' +$scope.slideImage);
} else {
$scope.slideImage = $scope.displaySlideImageO;
console.log('here4: ' +$scope.slideImage);
}
}
var waitForFinalEvent = (function () {
var timers = {};
return function (callback, ms) {
if (timers) {
clearTimeout(timers);
}
timers = setTimeout(callback, ms);
};
})();
html:
<div class="result-slide" ng-style="{'background-image':'url('+ slideImage +'?v='+ index +')'}"></div>
As you can see I tried adding a random param to the end of the url with ?v=n to attempt to trigger the refresh. But although the index changes, the physical slideImage url isn't updating.
Can someone please shed some light to this issue?
A quick scan of your code shows that you should be using $timeout, instead of setTimeout. While both things execute the timer fine, setTimeout occurs outside of angular so the $scope assignments will not be updated. If you do use setTimeout, then you need to wrap your assignment code in $scope.apply().
You can read about it more here. https://docs.angularjs.org/api/ng/service/$timeout

ExtJS setTimeout call function but after destroy view I get some errors

I have a function that after 3000 seconds call other function to check new data for a grid.
onViewDestroy: function(view) {
console.log('view destroy');
var me = this;
if(me.timer) clearTimeout(me.timer);
},
afterRender: function(){
// start timer to load log grid in 3 secs
me.logTimer = setTimeout(Ext.bind(me.checkProcessLog, me), 3000);
},
checkProcessLog: function() {
console.log('check process log');
var me = this,
requestGrid = me.getRequestGrid(),
logGrid = me.getProcessLog(),
logStore = logGrid.getStore();
var selectedRecord = requestGrid.getSelectionModel().getSelection()[0];
// if the grid is expanded and the status of the process is pending or in progress
if (!logGrid.collapsed && (selectedRecord.get('Status') == 0 || selectedRecord.get('Status') == 1)) {
logStore.load({
callback: function(records, op, success) {
if (success) {
// start timer to load again log grid in 3 secs
me.logTimer = setTimeout(Ext.bind(me.checkProcessLog, me), 3000);
}
}
});
}
},
The problem that I have is that if I close my view (destroy) when the function has been called then all my variables such:
requestGrid = me.getRequestGrid(),
logGrid = me.getProcessLog(),
logStore = logGrid.getStore();
I get the error:
Cannot read property 'getStore' of undefined
And that make sense because the view has been destroyed. Any workaround to avoid this?
A simple check will do it :
requestGrid = me.getRequestGrid(),
logGrid = me.getProcessLog();
if(!logGrid) return false
logStore = logGrid.getStore();
This also will stop the function beeing called.

ad timer focus required

hi i want to show a timer that will stop if the window/tab is not in focus and when the user will back to the window/tab it will again start to countdown. i have following code and i tried some methods but not getting the desired result!hope one of you will able to solve my problem
function adTimer() {
timer++;
if(timer == fulltimer) {
var show="Click <img src=\"clickimages/"+key+".png\">";
$("#buttons").fadeIn();
$("#timer").html(show);
}
else {
setTimeout(adTimer, 1000);
}
$("#bar").width((timer/fulltimer)*200);
}
$(document).ready(function() {
if(id != -1) adTimer();
else $("#timer").html("Cheat Check");
});
Check for focus with a timer:
var focus;
function mytimer() {
if (focus) {
// Do stuff.
alert("test");
}
}
$(window).blur(function () {
focus = false;
});
$(window).focus(function () {
focus = true;
});
setInterval(mytimer, 1000);
Fiddle

Resources