I'd like to add a word counter to a large text box (think blog editor) that increments with every word that I enter. (i.e. after I type "Hello" it would increment from 0 to 1 and after I write "world" after that it would increment to 2). I'd like to do this within a webpage but I'm happy to consider other options.
I have no idea how to do this. I think there would be a way to do this with Javascript but I know next to nothing about Javascript.
Could someone point me in the direction of figuring out how to do this?
I think a good idea to implement this is to check inputed letter (for example, onKeyUp event). If previous character was non-space and current is not a letter, then increment count. Detail: if previous character is non-letter, increasing should not be done (double spaces e t.c.)
When user is pressing Backspace or Delete key, similar check should be done. Key codes you can find here
The difficult thing with this counting 'on the fly' is to check 'non-key' input. For example, user can use Ctrl+Insert combination to copy data from clipboard, or select text in the textbox and then press Del key. That should be handled separately if there is real need to avoid whole value processing (which could be really huge)
Use this functionality on the onkeyup event for the textbox.
document.getElementById("inputbox").addEventListener("keyup",function(e){
// Get the inputs text.
var inputVal = e.srcElement.value;
var counter = 0;
// Check input isn't empty.
if(inputVal){
// Count individual letters.
var wordlist = inputVal.split(" ");
for(var i=0;i<wordlist.length;i++)
if(wordlist[i])
counter = counter+1;
}
// Then set your counter element.
document.getElementById("counter").value = counter;
});
Related
The short version: I work in a hospital and am attempting to create a safer, more efficient downtime version of the forms we send with blood components for transfusion. Currently we handwrite or type the donor identification number (DIN) and the product code of the unit onto this form, but ideally these are scanned, as they are ISBT 128 barcodes on the unit.
Scanning a DIN gives me ~=W11512003927826 - I would like to have the first two characters (non-alphanumeric) removed, and if possible, the last two. I've been able to accomplish the second task by simply limiting the character input of the field, which is standard and should work fine.
This also applies to the product code, which scans as ~=<E0785V00 and does not need the first three characters.
I've tried a few methods including some Javascript that was supposed to limit the field to only alphanumeric characters, which I assume is probably the simplest way to handle all of this, but either the code was not in the correct syntax for Adobe or I implemented it incorrectly. I am not familiar with JS at all and am just learning form creation.
If anyone has any advice I'd appreciate any help at all. Thanks in advance!
Edit: So far I've tried these three. I'm using these as an action (run a javascript) on mouse exit and also tried on blur.
const alphanumeric = /[a-zA-Z0-9]/g;
const string = "abc-ABC-012";
const result = string.match(alphanumeric).join("");
console.log(result); // abcABC012
const nonalphanumeric = /[_\W]/g;
const string = "abc-ABC-012";
const result = string.replace(nonalphanumeric, "");
console.log(result); // abcABC012
const string = "aa-aa";
const result = string.slice(2, -2);
console.log(string); // aa-aa
console.log(result); // -
I recommend you setup "On Blur" event handlers for each field that needs to accept scanned in data. For the DIN field, adjust the value using:
var field = this.getField("DINField");
field.value = field.value.replace(/^~=(.+)..$/, '$1');
The code above assumes the field is named DINField. Change as appropriate. It is important to use logic like a RegExp for modifying the value because the on-blur event can fire multiple times per field. The code above will only remove the ~= app-id and last two characters once.
Likewise, for the product-id, set on "On Blur" handler to:
var field = this.getField("ProductField");
field.value = field.value.replace(/^~=<(.+)$/, '$1');
The code above assumes the field is named ProductField. This reg-ex only removes the app-id (and not the last two characters).
I have an input box in a component. I want to prevent the user from being able to add any input if the value of the input box contains more than 2 decimal places.
E.g. if a user inputs 10.95 I dont want to allow them write anything else after this value. They could still update it to 101.95 but it should prevent any input being added after the final decimal place.
The code I have so far is below.
class inputBox extends Component {
countDecimals(value) {
if(Math.floor(value) === value) return 0;
return value.toString().split(".")[1].length || 0;
}
updateValue(e) {
if(this.countDecimals(e.target.value) > 2) {
//prevent user from inputting into box after the decimal place...
}
}
render() {
return(
<input type='text' onChange={this.updateValue} />
)
}
}
You could use React controlled component and bind a state to the input's value atrribute. Then your onChange event handler will look like.
updateValue(e) {
this.setState({ value: e.target.value.toString().split(".").map((el,i)=>i?el.split("").slice(0,2).join(""):el).join(".")})
}
Worked for me.
document.getElementById("yourinput").oninput=function(){
this.value=this.value.toString().split(".").map((el,i)=>i?el.split("").slice(0,2).join(""):el).join(".");
};
Replace the value with a new value, that is shortened to two chars after each dot.
http://jsbin.com/soretokuse/1/edit
I think you need to save the oldvalue, that should work.
var input=document.getElementById('input'),
countDecimals=function(value) {
if(Math.floor(value) === value) return 0;
if(value.toString().split(".")[1])
return value.toString().split(".")[1].length || 0;
},
updateValue=function(val) {
if(countDecimals(val) > 2) {
input.value=input.getAttribute('oldValue');
}
};
input.oninput=function(){
updateValue(this.value);
input.setAttribute('oldValue',this.value);
}
<input id="input" type="text"/>
As far as my knowledge in Javascript and HTML goes there is no 'easy solution' for this. Working with both 'raw' JS and ExtJs forms has learned me that there are multiple ways to focus and manipulate a field. Which makes it hard to manipulate the inner value at the right time.
So allow me to split your issue in to multiple problems. Which I will attempt to tackle:
Triggering
You want your logic to run at all the times something happens to the field.
The following link provides you with the options:
http://www.w3schools.com/TAGS/ref_eventattributes.asp
When you use onchange it will trigger when someone changes the values after you blur the field (you click or tab away from the field). So that's no good.
You could try the key (up, down, press) events. But that excludes when you paste a value.
Long story short, you could in theory try to implement a function on every event you could think of to make sure you catch the users input and do what you want with it.
My solution is, start a timer when you focus a field and validate the value and do further logic. And finalize everything you wanted to do on blur.
Determining the correctness of the value
You could write some nifty regex or a single line statement that tells you if the value is correct. It's all the same in the end, it should fit your needs.
So something like:
var inputVar = element.value;
var inputFloat = parseFloat(inputVar);
var normalizeInput = Math.round(inputFloat * 100) / 100;
if(inputFloat > 0 && normalizeInput == inputFloat){
#correct value
}else{
#incorrect value
}
Handling correct/incorrect input
Now you want to handle the user input and do something.
Things like setting the field to disabled or read only would prevent further input and changes, but would not let your users do anything to your field.
As what I read is you want the field to not change in function, you want to be able to edit it.
So that leaves you with 2 options:
Editing the field content directly by overriding the element.value with the desired value.
Manipulating key inputs / selection to try and keep the cursor at same position the user left it while correcting the false input.
I would opt for the former as it is a lot less of a hassle, although it might mess with the cursor position (browser dependant).
Final implementation
So what I propose combining all the above:
On focus you start running a setTimeout or setInterval
http://www.w3schools.com/jsref/met_win_settimeout.asp
http://www.w3schools.com/jsref/met_win_setinterval.asp
In the function run then, you check if there is a previous value set.
The first time it is NOT so:
You have to hold this previous value somewhere, you could hold it in a variable within javascript or put it in to the field in the DOM.
http://www.w3schools.com/jsref/met_element_setattribute.asp
var inputElement.setAttribute('old_value', oldValue);
Now you check if this value is correct before saving it, else just default it back to blank (or attempt to normalise the value to something that validates, you could keep cutting away characters at the right for example).
Now on each run you check if the value is correct. If the value is correct, you hold the new value as the 'new' previous value (and calling setTimeout again if you use that method).
If it is not correct you write back the old value or attempt to normalise the input value and if that fails use the last correct value.
On the blur event you clear the setTimeout or setInterval running in the background:
http://www.w3schools.com/jsref/met_win_cleartimeout.asp
http://www.w3schools.com/jsref/met_win_clearinterval.asp
(Alternatively you could check if the document.activeElement is the same as the one that is run on this 'loop' so it knows when to stop).
On blur you check the value one last time and do the same logic to prevent false input.
PLAN B
Use the HTML5 number input field:
HTML 5 input type="number" element for floating point numbers on Chrome
Try <input type="number" step="0.01" /> if you are targeting 2 decimal
places :-).
edited Apr 27 '15 at 18:10
Andre Figueiredo
Which only works on browsers that support it.
I have a web page with a form on it. The "submit" button is supposed to remain deactivated until the user fills in all the necessary fields. When they fill in a field, a checkmark appears next to it. When all the checkmarks are there, we're good to go.
A checkmark might be set by code like this:
if (whatever) checkLocation.innerHTML = CHECKMARK;
Here's the code I'm using to do the final check. It just loops through all the locations where there may be checkmarks. If it finds a location without a mark, it disables the submit button and leaves. If it gets through them all, it activates the button and returns true.
function checkSubmitButton() {
var button = document.getElementById(SUBMIT_BUTTON);
for (var i=0; i<CHECK_LOCATIONS.length; i++) { // should be for-each, but JS support is wonky
var element = document.getElementById(CHECK_LOCATIONS[i]);
console.log(CHECK_LOCATIONS[i] +": " +element.innerHTML);
// if found unchecked box, deactivate & leave
if (element.innerHTML != CHECKMARK) {
button.disabled = true;
return false;
}
}
// all true--activate!
console.log("ACTIVATING BUTTON!");
button.disabled = false;
return true;
}
Here's the problem: this works so long as the const CHECKMARK contains something simple, like "X". But specs call for a special HTML character to be used: in this case ✓, or ✓. When I do the comparison (in the if line) it ends up comparing the string "✓" to the string "✓". Since these two are not equal, it doesn't recognize a valid checkmark and the button never activates. How can I compare the contents of the HTML element my constant? (And hopefully make the code work even if down the road somebody replaces the checkmark with something else.)
Thanks.
There is no problem with the check character and it behaves exactly like the X character. The problem is, that your html have the checkmark character stored as html entity in hex string. If you compare checkmark to checkmark it works just fine: https://jsfiddle.net/m7yoh026/
What you can do in your case is to make sure the CHECKMARK variable is the actuall checkmark character, not the html entity.
Other option is to decode the html entity: https://jsfiddle.net/m7yoh026/3/
var CHECKMARK = '✓'
var decoded_checkmark = $('<textarea />').html(CHECKMARK).text();
console.log($('div')[0].innerHTML)
if ($('div')[0].innerHTML == decoded_checkmark) {
$('body').append('checkmark recognized<br>')
}
You can convert a character to its HTML entity equivalent like so:
var encoded = raw.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
return '&#'+i.charCodeAt(0)+';';
});
Well, here's what I ended up doing: I made a function called encodeHtml() that takes a character or string, writes it to a brand new div, and then returns what's contained in that div:
function encodeHtml(character) {
var element = document.createElement("div");
element.innerHTML = character;
return element.innerHTML;
}
Then I can compare to what it returns, since it automatically changes "✓" to "✓", and will work with any unforeseen changes to that character. It's a bit of a kludge, but it works. (It's still not clear to me why JavaScript does this automatic conversion...but there are many design choices in which JavaScript mystifies me, so there you go.)
Thanks all for the help.
I'm having a trouble when i try to force the user to enter data to a text input. I need to do something like the IP Address input in Windows.
I want to split the text input by dashes having something like this
10 - 10 - 10 - 10
Is there any way to do this ?
http://jsfiddle.net/87dug9oa/1/
function check(text) {
var result = [];
text = text.replace(/[^\d]/g,"");
while (text.length >= 3) {
result.push(text.substring(0, 3));
text = text.substring(3);
}
if(text.length > 0) result.push(text);
$("#ip").val(result.join("-"));
}
$("#ip").on("keyup", function() {
check($(this).val());
});
This creates a function, which adds dashes once 3 characters has been added (and the fourth is written).
Now, this does do what you want, but you need to add some additional stuff, such as checking for length and making the remove part work (because when you press any key, it will change the input's value, which will make the caret move to the last character).
Oh I almost forgot. This can be changed to the length of your choice, of course. Just change the "3" to be something else.
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.