Realtime Textarea Character Count in Titanium App (iOS) - javascript

I want to have a counter on my textfield that starts at 140 and subtracts the number of characters in the text area.
Here is my event listener:
contentArea.addEventListener('change', function(e) {
if(e.value.length >= 200) {
contentArea.value = e.value.substring(0, 200);
} else {
countLabel.text = 140 - e.value.length;
}
});
Basically, the user is allowed to submit if they have 140 or fewer characters. I don't want to just block it once they hit the limit, so I let them go a decent amount over. But I want to to update this count label with an accurate representation of their count.
The problem is checking the count on every change automatically accepts any autocorrect suggestion and causes for a really bad UX.
Is there any way around this?

Sounds like a messy way to do things but you could try adding a looping timer when the textArea focus() event fires, that keeps checking the length and updating the display. Then on the blur() event remove the timer.

Related

How to simulate the space button like the real person on the keyboard using JS

I'd like to find out how can I simulate the space button click on the keyboard like a real person would do that. I have some examples here.
First one is using jsFiddle. jsFiddle is just to make things simpler, I'm gonna test it out and then use it in my project code. The links can be found below.
I've read about the new KeyboardEvent() constructor, however, I don't think it would fix my problem. Maybe I'm doing something wrong, but I need to simulate the space button press like it would be real.
I'm sure document.getElementById('test').value += ' '; isn't doing anything "realistic", it just changes the value of #text element. After examples, I'll show you how I'd like it to work with images.
Here is my example jsFiddle: https://jsfiddle.net/od5g4u43/.
Stacksnippet:
document.getElementById('test').addEventListener('keydown', function(ev) {
document.getElementById('test').value += ' ';
});
(function() {
var e = new Event('keydown');
e.which = e.keyCode = 32; // 32 is the keycode for the space bar
document.getElementById('test').dispatchEvent(e);
})();
<input id="test" type="text" value="opa!">
And my full project code can be found here: https://codepen.io/Kestis500/pen/ddbwpq.
So, we just reloaded a page. Don't care about the different environment. It's my project code and you shouldn't care about any jQuery or JS stuff except the code in the jsFiddle or Stacksnippet.
The same code as in the jsFiddle or Stacksnippet is in the middle of the codepen.com full code, inside "select" event.
Again, you don't need to go there but if you want to test it out by yourself, go ahead.
Enter the character "a" into the search box.
document.getElementById('test').value += ' '; worked and now we have an extra space after the actual search box value. The results should change they didn't. It was done using code.
Let's try the same thing but without document.getElementById('test').value += ' '; line or anything what's inside jsFiddle or Stacksnippet. I just removed the space generated by code like the real person (on the keyboard pressed the backspace when I was focused on the search box.
EDIT 3
Thank you, it worked! I just have a fresh fork of this code on the codepen here.
I've made some changes to your code so it works for my problem and instead of printing each character, now it prints and removes the space super quickly. setTimeout(..., 0); is because to wait until the JS Stack is clear.
function updateSearchField() {
t0 = performance.now();
$("#search").focus();
//update the search field with a character and
//trigger the keypress event for the autocomplete
$("#search")
.val($("#search").val() + " ")
.keydown();
t1 = performance.now();
}
setTimeout(function() {
updateSearchField();
setTimeout(function() {
var $text = $("#search").val();
$("#search").val($text.substring(0, $text.length - 1));
}, t1 - t0);
console.log(t1 - t0);
}, 0);
Explanation of this can be found here (video).
Dispatched events don't behave the same way that real user actions do -- they only fire the event (so that event listeners can respond to them). A dispatched keydown event on an input field does not change the value of the field, it just fires the event itself.
You need to change the value of the field directly (just as you're doing with the document.getElementById('test').value += ' ';) and then dispatch whichever event or events your remaining code is watching for to update the autocomplete results.
You've got a few things going on here. First, you can't simply set the value as you are doing - what you want to do is set each character individually with a timeout between each update. This will give the appearance of a user typing. Secondly, you are using Jquery UI autocomplete which will require keypress events after each update to tell the autocomplete to refresh its search results. Here is a quick solution that solves what you are looking for.
function showDemo() {
//give focus to the search field
$("#search").focus();
//the search content split into a string array
var characters = "anarchist symbolism".split("");
//the time between each character keypress
var timeout = 0;
characters.forEach(function(character) {
//setup a random keypress time in milliseconds to simulate a real user typing
timeout += Math.floor(Math.random() * 670);
setTimeout(function() {
//update the search field for this character at this
//timeout interval
updateSearchField(character);
}, timeout);
});
}
function updateSearchField(character) {
//update the search field with a character and
//trigger the keypress event for the autocomplete
$("#search")
.val(function(i, val) {
return val + character;
})
.keypress();
//intialize a keydown event with any key code to setup the keypress listener
var e = jQuery.Event("keydown");
e.which = 32;
$("#search").trigger(e);
}
You may also not want this to start immediately, especially with the animations you have in the codepen example. You may want to delay the start of this with a timeout:
//wait 4 seconds before initializing the demo. This can be anything,
//just to give the user time so it does not happen immediately
setTimeout(showDemo, 4000);
Here is a codepen fork of your example with this code to show the result: https://codepen.io/kyledodge/pen/xYKmmy

Double firing of function referencing self in Javascript

I am using a simple script which :
displays a message after 3 seconds if user has not clicked by then (using a setTimeout),
then if user clicks within 5 seconds, then the message should not appear within the defined setTimeout,
after this previous click if the user does not click for 5 seconds, then the user will see the message and so on...
this goes on a like a loop.
My script acually works but I have an issue because it seems it is double firing "exponentially". I think my error is how I created this "loop" and self referencing the setTimerForMsg inside itself.
Here is a Demo: https://jsfiddle.net/3wm7z576/11/
Here is the code:
html
<div id="zone">
<span id="msg" class="displayNone">this is the messager</span>
</div>
js
setTimerForMsg(3000, 5000);
function setTimerForMsg(initial_timelaps, new_timelaps) {
var timer = setTimeout(showMsg, initial_timelaps);
$("#zone").on('click', function(e) {
//if user clicks before msg appears (but after timer was initiated )
clearTimeout(timer);
//if user went beyond timer laps and msg already visible on Step (n)
//remove it when move to Step (n+1)
$('#msg').addClass('displayNone');
console.log("message1");
//loop the process for the next Step
setTimerForMsg(new_timelaps, new_timelaps);
});
}
function showMsg() {
$('#msg').removeClass('displayNone');
console.log('message2');
}
This issue is important because while this script is simple, in my real app it does other things that could drain the browser performance so I can't have them be done 64 times!
And you can see here in the console of the Demo, each time I click the events occur twice : 2 times , then 4 times then 8, then 16, then 32 times, and so on...
use $("#zone").off('click', ... to remove the eventListner you previously added. Otherwise you're just adding more and more click actions.
Documentation here
Well first of all your new_timelaps parameter is unused, this might cause some confusion.
As for the exponential growth in logs, this is caused by the fact that you don't remove your event listener, so everytime the time for your interval is passed or you click ur button another click event with the same function is aplied to your button.
How you would solve this is by using
$( "#zone").unbind( "click" )
to make sure the event is only aplied once and not get aplied again or the old ones get removed.

JavaScript onkeypress delayed trigger

I have an html input for an optional phone number, along with 2 radio inputs (Leave Message, Dont Leave Message):
<input type="text" class="input-medium phoneNum2" name="secondaryPhone" id="secondaryPhone" onkeypress="toggleRadio(this)" onblur="toggleRadio(this)" placeholder="703-555-1010" value="<cfoutput>#session.secondaryPhone#</cfoutput>" />
Notice I have two events running (deleting one of them yields the same issue, having both helps out, but I'd rather have only one event unless necessary).
The scenario here is: The second somebody starts typing into the input, it checks to see if one of the radio buttons is already checked. If not, default select yes. If for some reason they delete the phone number as they do not want to give it, both radio buttons should be de-selected (only the onblur works there). And if the "Don't Leave Message" is selected BEFORE the user starts typing, it should not default to yes.
Here is the JavaScript:
function toggleRadio(x) {
y = document.getElementById("contactSecondaryYes");
z = document.getElementById("contactSecondaryNo");
if (x.value.length < 1) {
y.checked = false;
z.checked = false;
}
if (x.value.length > 0 && !z.checked) y.checked = true;
}
Now for the issue: The default option yes is only triggered when I type in 2 characters, instead of the desired 1 (almost like a delay in the code?). If I have "No" Selected before I start typing, it defaults to yes once I type in the 2 characters. Likewise for reverse, nothing is "de-selected" when there are 0 characters during the onkeypress event, only when the input loses focus during the onblur event.
Am I using the wrong events? Is there a logic flaw? There are no error messages, and no, I cannot use jQuery here, so please don't give me jQuery answers or the usual "Why no jQuery?" (I love jQuery I simply have reasons I cannot use it).
Edit: I also tried ordering the JavaScript like this, to no avail.
function toggleRadio(x) {
y = document.getElementById("contactSecondaryYes");
z = document.getElementById("contactSecondaryNo");
if (x.value.length > 0 && !z.checked) y.checked = true;
if (x.value.length < 1) {
y.checked = false;
z.checked = false;
}
}
Basically I want to know why the code is acting like there is a delay, and is there a way to fix it?
Try using onkeyup instead:
onkeyup="toggleRadio(this)"

simulate backspace key on text input field

Can someone provide a good example to simulate the backspace key on a <INPUT> text field?
I need this for a virtual keyboard done in HTML5 and it only needs to work in Webkit browsers.
Notes:
createEvent/initTextEvent/dispatchEvent with charcode 8 (backspace) is being ignored (that seems to work only for printable characters)
changing manually the value using substr() sort of works, but this way the caret moves to the end of the input field (and I want to be able to delete characters in the middle of the input field, just like when using a normal keyboard).
Alright here you go: http://jsfiddle.net/dan_barzilay/WWAh7/2/
The get caret function is used to know where to delete the character, if you need more explaining comment.
The reset cursor function is used to restore the caret position after the backspacing.
**it's using jquery but you can change it to normal js in secounds
Edit: the below is too complicated to use. According to
https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand,
it's just enough to call document.execCommand("delete");.
Here's my solution using setSelectionRange, which works well on Chrome:
https://github.com/gdh1995/vimium-plus/blob/master/lib/dom_utils.js#L169
simulateBackspace: function(element) {
var start = element.selectionStart, end = element.selectionEnd, event;
if (!element.setRangeText) { return; }
if (start >= end) {
if (start <= 0 || !element.setSelectionRange) { return; }
element.setSelectionRange(start - 1, start);
}
element.setRangeText("");
event = document.createEvent("HTMLEvents");
event.initEvent("input", true, false);
element.dispatchEvent(event);
}
Well, the only shortage is that we can not undo the changes it makes.
Add: I find a method to enable undo & redo:
in Javascript textarea undo redo , the both anwsers work well on Chrome

Issue with text area key down event using jQuery

We're having problems trying to implement a word counter similar to the one on twitter which decrements when the user types in the text field. Unfortunately it's quite glitchy as once you've deleted all the characters via backspace it displays that you only have 84 characters left (unless you hit backspace again). If you it the delete button the counter goes down even when it has removed nothing from the screen at the end of the text(I'm guessing it removes the 'invisible' character that is causing it to say 84 instead of 85 in the example before). All I want if for it to operate like the one on twitter
/* Limit textarea for cancelation policy to 85 characters*/
$('.counter').text(85-($('#txtCpolicy').val().length));
$('#txtCpolicy').keydown(function(e) {
var current = $(this).val().length;
$('.counter').text(85 - ($('#txtCpolicy').val().length));
if(current >= 85) {
if(e.which != 0 && e.which != 8) {
e.preventDefault();
}
}
});
Hope you can help
Change your code to keyup instead of keydown. Keydown triggers before the text is added to the textarea. Seems to work once you change it.

Categories

Resources