KeyboardState.pressed is always true after .prompt or alert - Why? - javascript

As the title says, I have tried THREEx and Stemkovskis standalone KeyboardState.js , and neither of them seems to update properly.
This is my code:
m_vKeyboard = new THREEx.KeyboardState();
// m_vKeyboard.update(); // if using stemkovskis
if (m_vKeyboard.pressed("F")) {
alert("And now it is always true!");
}
you click the F key once, release it; alert window pops up, click OK, it pops up again for all eternity. How come?

Many browsers repeat keydown. Read more here and here (ctrl+f : auto-repeat).
Here's a proposed solution for your specific problem :
A. when keydown store its state as true in some array and make it false on keyup.
wasPressed['F'] = true; //on keydown
wasPressed['F'] = false; //on keyup
B. when checking for next keydown check its state as well.
if (m_vKeyboard.pressed("F") && !wasPressed['F'])
Find full implementation : Here
UPDATE
var wasPressed = {};
if( keyboard.pressed('F') && !wasPressed['f'] ){
alert("F was pressed");
prompt("Enter data : ");
wasPressed['f'] = true;
}
UPDATE 2
keyboard.domElement.addEventListener('keydown', function(event){
wasPressed = {};
})

I'm wondering if it has something to do with alert() being a blocking call. Using the code below gives me your same issue. If I comment out the alert() and un-comment the console.log() it seems to work fine. However, I'm not sure if that helps your issue.
var m_vKeyboard = new THREEx.KeyboardState();
setInterval(function () {
var key = "F";
var pressed = m_vKeyboard.pressed(key);
alert("And now it is always true!");
//console.log("key", key, "pressed", pressed);
}, 100);

Just add this to the beginning of onKeyDown in KeyboardState.js:
if (event.repeat) return;

Related

Fix double call and get before value

I am learning JQuery by example. Please check this fiddle: http://jsfiddle.net/4tjof34d/2/
I have two problems:
1 : showText() gets called twice when a person hits enter and thus console.log(this.id+ " " +this.value); gets called twice, What do I add so that it only gets called once?
2: I get the id and value of the textbox, but I also want to know what was the old id and value so that I can do a comparison test. How do I do that?
eg:
var oldValue = ? // How do I do this?
var newValue = this.value;
Then I can do something like:
if(newValue != oldValue)
{
// Do .ajax() - update DB
}
for your first issue showText is called twice ie,on blur and on enter
change your blur function as follows
$('.input').blur(showText).keyup(function (e) {
if(e.which === 13) {
this.blur();
}
});
for second issue i will go with a global variable as flag
http://jsfiddle.net/x1ez7Lek/6/

Popup - if user enters bad input, how can I get it to error on submit

I have a popup on my page that has a typeahead input on it. Right now you can type garbage and click submit and it lets you. I'm trying to write code that will throw an error on the popup if you type something that isn't included in the typeahead options and it won't let you submit it until you fix it. Here is my code, it is for making a school schedule that has classes in the typeahead dropdown.
var schedule = schedule.content.get();
var validClasses = Fp.filter(schedule.classes, function (class) { return !class.passed; }),
inputClasses = $('.optimizeViaClasses input.className').map(function () { return $(this).val(); }),
isErrorForValidClasses = Fp.all(inputClasses, function (inputClass) { return Fp.contains(validClasses, inputClass); });
if(validClasses !== inputClasses){
$errorMessage.text('Your selection does not match the class(es) in the current schedule!');
$errorMessage.show();
}
Right now if you enter garbage in the input field, this will throw an error but still let the user submit. How can I stop the user from submitting until the input is correct?
Here is my button:
$submitBtn.on('click', function(event){
if(inputParameters() !== false){
$myPopUp= $modal.find('#myData').detach()[0];
}
event.preventDefault();
});
and I checked the output of inputClasses in the Google developer console, it outputs the class and a prevObject. I just need the class...
Let javascript return either True or false and if the popup comes out return false other wise true.
For instance if it get into if return false other wise true.
since you modified your code i suppose you might want to try this instead:
http://api.jquery.com/event.stoppropagation/
also you might want to be doing something along the lines of this if stoppropagation does not result in the desired effect:
$("#formid").on("submit",function(e){
// declare isValid outside of this and set it in your validation function or call it inside this and check for that.
if(isValid) {
e.stopPropagation();
}
});
at least that's how i went about solving such issues usually. i hope it helps.
got it. the error i had was throwing an error.
var schedule = schedule.content.get(),
validClasses = Fp.filter(schedule.classes, function (class) { return !class.passed; }),
inputClasses = $('.optimizeViaClasses input.className').map(function () { return $(this).val(); }),
actualValidClasses = Fp.pluck(validClasses, 'className');
$.each(inputClasses , function(index, value){
if($.inArray(value, actualValidClasses ) === -1){
$errorMessage.text('Your selection does not match the class(es) in the current schedule!');
$errorMessage.show();
error = true;
return false;
}
});

Changing placeholder triggers input event in IE 10

Basic Problem
input event --calls--> update() --calls--> geoInput.receive() --triggers--> input event
Explanation
Okay I've run into a strange problem which is causing my code to loop infinitely. I have the following bit of jQuery:
var geoInput = $('#Geo').on('input', function() {
_this._controller.update({
geo: this.value
});
}).get(0);
As you can see it's just a basic event listener and it's calling an update function in my controller. At the end of the update function is a method which broadcasts for the geoInput field to update. This is handled by the following:
geoInput.receive = function(formState) {
this.value = formState.geo;
this.placeholder = _this._placeholders.geo;
}
For some reason
this.placeholder = _this._placeholders.geo;
is triggering the input event on that field. You can see how this can be problematic as this creates an infinite loop. I'm sure this is what's happening because when I return before that line the loop doesn't occur. Also, if I change to say, a keyup event, the loop also doesn't occur.
Question
Why is this happening and how can I fix it?
I've tried!
I've looked at this for hours and done quite a few searches to no avail. This code works as expected in Chrome and FF.
The funny thing is that the INPUT event occurs if you just add an item to the INPUT attributes placheholder or value other than the Latin alphabet.
It's problem IE10 and IE11
var $input = $('<input type="text" placeholder="Бубу"/>');
//or
var $input = $('<input type="text" value="世界へようこそ"/>');
$input.on('input',function(){
alert('input even occur');
});
Without seeing your fiddle, I think you can fix the issue with this code:
var previousGeoInput = '';
var geoInput = $('#Geo').on('input', function() {
if (previousGeoInput === this.value) {
return;
}
previousGeoInput = this.value;
_this._controller.update({
geo: this.value
});
}).get(0);
Check the event keycode/charcode if it's 0 then it's IE being stupid and you can just cancel the event.

Why would a jQuery function be only selectively run?

I am trying to debug this (incomplete) script, but it is behaving inconsistently. The main problem is when I click off of an item, sometimes the $(editObj).removeAttr('style'); runs and sometimes not. Through the Chrome inspector I can see that the editObj variable in each case is properly defined, but it isn't always getting its inline style attribute removed. Sometimes, and sometimes not. Cannot determine the reason.
I'm a bit out of my element with this code. Maybe something about it is obvious; Regardless I'd appreciate some ideas on why this sort of unpredictable might be occuring!
var editObj = null;
var inputType = 'text';
var input = '#textEdit';
var formId = '#form_undefined'
$(function() {
$("#textEdit").click(function(event) {
event.stopPropagation();
});
$('body').click(function(event) {
if (editObj){
//textedit contents to editobj and
if (inputType == 'text'){
$(editObj).text($("#textEdit").val());
}
$("#textEdit").removeAttr('style').hide();
$(editObj).removeAttr('style');
var previewId = $(editObj).attr('id');
var formId = previewId.replace('bzm', 'form');
$("#" + formId).val($("#textEdit").val());
//ajax modify database
editObj = null;
}
});
$(".editable").not("video, img, textarea")
.click(function(event) {
event.stopPropagation();
loadEditor($(this));
});
});
function loadEditor(element){
$("#textEdit")
.copyCSS(element)
.offset($(element).offset())
.css("display", "block")
.val($(element).text())
.select();
$(element).css("color", "transparent");
editObj = element;
}
I've had trouble in the past with .removeAttr('style'); not actually removing all the inline styles.
Use
$(editObj).attr('style', '');
instead of
$(editObj).removeAttr('style');
I dint see any code that initializes e editobj variable.. May be Im missing Anthony.. Anyways what are the chances of the edit obj being null.. Just put a log statement in the click function to always log ur editobj and see if it is null smtimes

Preventing blur when user clicks on specific div not working in Firefox

I am using jquery to keep the focus on a text box when you click on a specific div. It works well in Internet Explorer but not in Firefox. Any suggestions?
var clickedDiv = false;
$('input').blur(function() { if (clickedDiv) { $('input').focus(); } });
$('div').mousedown(function() { clickedDiv = true; })
.mouseup(function() { clickedDiv = false });
Point to note: the focus() method on a jquery object does not actually focus it: it just cases the focus handler to be invoked! to actually focus the item, you should do this:
var clickedDiv = false;
$('input').blur( function() {
if(clickeddiv) {
$('input').each(function(){this[0].focus()});
}
}
$('div').mousedown(function() { clickedDiv = true; })
.mouseup(function() { clickedDiv = false });
Note that I've used the focus() method on native DOM objects, not jquery objects.
This is a direct (brute force) change to your exact code. However, if I understand what you are trying to do correctly, you are trying to focus an input box when a particular div is clicked when that input is in focus.
Here's my take on how you would do it:
var inFocus = false;
$('#myinput').focus(function() { inFocus = true; })
.blur(function() { inFocus = false; });
$('#mydiv').mousedown(function() {
if( inFocus )
setTimeout( function(){ $('#myinput')[0].focus(); }, 100 );
}
Point to note: I've given a timeout to focussing the input in question, so that the input can actually go out of focus in the mean time. Otherwise we would be giving it focus just before it is about to lose it. As for the decision of 100 ms, its really a fluke here.
Cheers,
jrh
EDIT in response to #Jim's comment
The first method probably did not work because it was the wrong approach to start with.
As for the second question, we should use .focus() on the native DOM object and not on the jQuery wrapper around it because the native .focus() method causes the object to actually grab focus, while the jquery method just calls the event handler associated with the focus event.
So while the jquery method calls the focus event handler, the native method actually grants focus, hence causing the handler to be invoked. It is just unfortunate nomenclature that the name of this method overlaps.
I resolved it by simply replace on blur event by document.onclick and check clicked element if not input or div
var $con = null; //the input object
var $inp = null; // the div object
function bodyClick(eleId){
if (eleId == null || ($inp!= null && $con != null && eleId != $inp.attr('id') &&
eleId != $con.attr('id'))){
$con.hide();
}
}
function hideCon() {
if(clickedDiv){
$con.hide();
}
}
function getEl(){
var ev = arguments[0] || window.event,
origEl = ev.target || ev.srcElement;
eleId = origEl.id;
bodyClick(eleId);
}
document.onclick = getEl;
hope u find it useful

Categories