I would like to get my autocomplete to return a "hidden" property when I blur out of the textbox or press enter. The data is in format {value: "Pal", pts: "30"}. I want to obtain pts. Here's an example:
http://jsfiddle.net/ctuAg/4/
Typing a letter or two and choosing a name from the dropdown updates the "points" textbox as expected (10 times the name length). Now, I'd like to know if there's a way of triggering this points update when a name is fully typed and then Enter is pressed, or blurred (tab or mouse click). That is, have the autocomplete search a match to the textbox value and update points.
So far as I've seen only clicking on a name in the dropdown causes the points to be updated.
I did some searching and the closest function/trigger I found was search. I tried placing this inside blur but .pts returns undefined. This might be the answer, how should I use it in my case?
$("#autocomp").autocomplete({
search: function(event, ui) {
alert(ui.item.pts);
}
});
As a basic extension of your example, you can simply check whether the value of #autocomp is in the array on enter press:
$("#autocomp").keypress(function(event) {
var keycode = (event.keyCode ? event.keyCode : event.which);
if(keycode == '13') {
$("#status").append("Enter pressed\n");
/* NEW CODE HERE */
// loop through the array and check the value against available names
for ( var i = 0, l = names.length; i < l; i++) {
// if the name matches, update #points
if ($(this).val() === names[i].value) {
$("#points").val(names[i].pts);
}
}
/* END NEW CODE */
$("#points").focus();
}
});
Though it might not be the most efficient way to do it, it gets the job done. Fiddle here: http://jsfiddle.net/ctuAg/6/
Related
I am working on a module, which should select the only possible value of a Multi- or Single selection field, if there is only one valid value and a empty one available.
So far its working fine, until I use ACLs to disable selection values.
For example, I got a single selection field with 3 possible values. Then I disable 2 of them (ACL - if there is a special Queue selected) so theres only one value (+ an empty one) left.
My module wont pick the last value at first, but when I change anything else on the same page (second onchange call) it will pick the last possible value.
The first if condition checks if the Field has only one possible value in it. When I log the 'Change' array it always got the disbaled values still in there even when the 'change' that called the whole function was the ACL disabling those values.
Im still kinda new to javascript and havent found a solution yet.
I would realy appreciate any help.
$('.TableLike').on("change", function () {
var Change = [];
$('.Row').each( function() {
$(this).children().next().children().next().children().each( function(index) {
Change[index] = $(this).text()
} )
if ( (!Change[2] || /.*Field needed.*/i.test(Change[2])) && Change[0] === "-") {
SoleOption = Change[1];
$(this).children().next().children().next().children().each(function() {
if ($(this).text() === "-") {
$(this).removeAttr("selected");
}
if ($(this).text() === SoleOption) {
$(this).attr("selected", "selected");
}
} )
$(this).children().next().children().children().children().val(SoleOption)
}
SoleOption = "";
Change = [];
} )
} )
I managed to fix the issue with the setTimeout() Method.
So the DOM updated before the ACL did the changes.
I opened up the setTimeout Method after the onChange method and inserted all the code thats supposed to run after the change into the setTimeout method.
I hope this will be helpfull for others in the future.
In my TinyMCE.init method, I have a setup function like this one :
setup: function(ed){
ed.onKeyUp.add(function(ed, e){
var count = ed.getBody().innerText.length;
var key = e.keyCode || e.charCode;
console.log(count);
console.log(ed.getBody().innerText);
});
}
If my textarea is empty, when I press Backspace (key = 8), count equals 0.
When I press Delete (key = 46), count equals 1.
In both cases, console.log(ed.getBody().innerText); returns an empty string.
I want to use this to count (and limit) the size of my TinyMCE.
Does anyone can illuminate me about that strange difference ?
Delete is character code 127 in the ASCII-Table. The delete char is written into the textinput and therefore counts to the length of it, but is not displayed, because control characters dont get displayed.
This is indeed strange behaviour, because actually the delete character should not be written into the text field, but it seems like it does
I need to fire an event anytime the content of a textbox has changed.
I cant use keyup nor can I use keypress.
Keyup and keydown doesn't work if you hold down on the key.
Keypress triggers before the text has actually changed. It doesn't recognize backspace or delete either.
So now I'm assuming I'm going to have to build some custom logic or download a plugin. Are there any plugins out there? Or if I should build one, what constraints should I look out for?
For eg. Facebook does it with their search at the top. you can press and hold.
another example is writing a stackoverflow question. Right below the editor, the contents are copied in real time, backspace and everythng works. How do they do it?
I just took a look at SO's source. It looks like they do something a lot like this:
function updatePreview(){
$('div').text($('textarea').val());
}
$('textarea').bind('keypress', function(){
setTimeout(updatePreview, 1);
}
);
They do some extra stuff to make HTML tags for bold and italics and links and such and they time it. They increase the delay from 1 to longer if it takes too long to generate the HTML.
I had success using jQuery (in Chrome). If you hold a key down, it counts every change, not just the first one, and it counts non-print keys like backspace.
HTML
<input id="txt" type="text" />
<span id="changeCount">0</span>
JavaScript
$('#txt').keydown(function(event) {
// Don't count the keys which don't actually change
// the text. The four below are the arrow keys, but
// there are more that I omitted for brevity.
if (event.which != 37 && event.which != 38 &&
event.which != 39 && event.which != 40) {
// Replace the two lines below with whatever you want to
// do when the text changes.
var count = parseInt($('#changeCount').text(), 10) + 1;
$('#changeCount').text(count);
}
});
Like I said above, you'll want to filter out all of the key codes that don't change the text, like ctrl, shift, alt, enter, etc. There's also the boundary condition if you press the backspace or delete key when the textbox is empty or if the textbox has a maximum length and a printable key is pressed, but it's not terribly difficult to handle those either.
Here's a working jsfiddle example.
How about a poll? Do a setInterval and call a function that checks the text say every 500ms? You don't want to detect content change on every key anyway because it gets kinda slow in some older browser/older computer and you would notice a lag between typing and the text displaying.
You need a watcher type functionality.
It resorts to setInterval polling if the other features are not available: http://james.padolsey.com/javascript/monitoring-dom-properties/
I have a simple solution that we use happily in one of our project.
you can try it # http://jsfiddle.net/zSFdp/17/
var i = 0;
$('#text').bind('check_changed', function(){
var t = $(this);
// do something after certain interval, for better performance
delayRun('my_text', function(){
var pv = t.data('prev_val');
// if previous value is undefined or not equals to the current value then blablabla
if(pv == undefined || pv != t.val()){
$('#count').html(++i);
t.data('prev_val', t.val());
}
}, 1000);
})
// if the textbox is changed via typing
.keydown(function(){$(this).trigger('check_changed')})
// if the textbox is changed via 'paste' action from mouse context menu
.bind('paste', function(){$(this).trigger('check_changed')});
// clicking the flush button can force all pending functions to be run immediately
// e.g., if you want to submit the form, all delayed functions or validations should be called before submitting.
// delayRun.flush() is the method for this purpose
$('#flush').click(function(){ delayRun.flush(); });
The delayRun() function
;(function(g){
var delayRuns = {};
var allFuncs = {};
g.delayRun = function(id, func, delay){
if(delay == undefined) delay = 200;
if(delayRuns[id] != null){
clearTimeout(delayRuns[id]);
delete delayRuns[id];
delete allFuncs[id];
}
allFuncs[id] = func;
delayRuns[id] = setTimeout(function(){
func();
delete allFuncs[id];
delete delayRuns[id];
}, delay);
};
g.delayRun.flush = function(){
for(var i in delayRuns){
if(delayRuns.hasOwnProperty(i)){
clearTimeout(delayRuns[i]);
allFuncs[i]();
delete delayRuns[i];
delete allFuncs[i];
}
}
};
})(window);
Zurb has a great plugin which might be useful for you
http://www.zurb.com/playground/jquery-text-change-custom-event
What is the best way to grab the last two characters typed into a textarea box?
I need the last 2 characters typed NOT the last two characters of the overall string.
Appreciate the help!
You need to catch the keypress event on the textarea and then keep a log of keys that were pressed. Note that this is going to catch arrow keys, shift, alt, etc so if you just want characters you need to filter them out.
Simple example:
var keyPresses = [];
textarea.onkeypress = function(ev){
ev = ev || window.event;
var key = ev.keyCode || ev.which;
keyPresses.push(key);
}
Here's a demo of doing it with jQuery, while displaying the last two characters that were entered: http://jsfiddle.net/Ender/5gUHb/
And the source:
var keys = [];
$('#target').keypress(function(e) {
keys.unshift(e.which);
update();
});
function update() {
$('#last')
.prepend($('<li/>').text(String.fromCharCode(keys[0])))
.children(':eq(2)').remove();
}
This demo captures the keypress event on the text area, unshifts the value onto the array (because then the indexes are representative of the number of keys that have been pressed since that key was pressed) and then updates the display.
The display update simply pushes the first value from the array to the top of a <ul> and removes the child (if any) at index 2 in the list.
Note additionally that because of the way jQuery deals with .keypress(), you do NOT have to filter out modifier or arrow keys.
UPDATE
Please see Tim Down's comment to my answer for an explanation of what filtering should take place. My initial note was mistaken, based on a quick test in Chrome.
Im using the most recent moo release and trying to write a function that evaluates the user given expression on event "keyup". As soon as my test's are passing I put the focus on the next input element automatically to improve the user experience and speed, since he uses the form many times.
So I came up with something like that:
var getNextInputElement = function(element){
returns the next input element
}
var checkDay = function(event){
var input = $('booking_day').get('value');
if (input.length > 1 && input < 32) {
$('booking_day').erase('class');
if (!(event.key == "tab")) {
getNextInputElement($('booking_day')).focus();
}
else {
$('booking_day').focus();
}
}
else if(input.length > 1) {
$('booking_day').set('class','error');
}
else {
$('booking_day').erase('class');
}
};
window.addEvent('domready', function() {
$('new_booking').reset();
$('booking_day').addEvent('keyup', checkDay);
$('booking_day').focus();
});
Works fine so far. But if I try to "shift-tab" back to my input field
getNextInputElement($('booking_day')).focus();
is evaluated and focus reset to the next input field. So the user cannot roll back to previosly entered data. I do not find any possibility to catch that shift-tab event. Since two keys are pressed, there are two events fired. One for "tab" and a second one, but not for "shift". The event.key.code of this event seems to be outside the scope that mootools realizes.
Anyone out there who can help on this problem?
Thanks.
Jason
You can add event for both "Shift+Tab" keys
Link : http://mootools.net/docs/more/Interface/Keyboard