On IE cursor is comming always at start in textarea - javascript

I am dealing with textarea, and on click of this I am calling one replace function which will remove some specified string in textarea, this is the basic operation.
Expected behavior after clicking on textarea
1) At first click :
It should remove specified string from textarea
Cursor should come at end of string
2) more than one click :
- Cursor should come at where ever user clicks in text area
Below is my replace function....
function replace(id,transFromDb) {
newStr = $("#"+id).val();
var len = null;
if(transFromDb == '') {
newStr = newStr.replace(Lang.Message27,'');
newStr = newStr.replace(Lang.Message28,'');
}
else {
newStr = newStr.replace(Lang.Message28,'');
newStr = newStr.replace(Lang.Message27,'');
}
/* change font weight as bold. */
$("#"+id).css({"fontWeight":"bold"});
$("#"+id).val(newStr);
}
Assume that Lang.Message is specified string.
It's working above behavior with FF.
Facing issue on IE, it always keep cursor position at first.
Please provide any solution....
Thanks in Adavance
Pravin

$("#idOfTextarea").focus(function() {
replace($(this).attr("id"), "");
});
I'm not sure what the second parameter of replace is receiving, so I've just put an empty string in, you'll have to fill that in yourself.
There's clean and easy code for moving the cursor to the end of the textarea here.

Related

How to hide text in input field as you type each character?

I have an input field, that basically takes a confirmation code(alphanumerical) while logging into an application. I want to implement the below functionality:
when you type each character, it appears in the text field for a fraction of time(say 1 second), and then it becomes an asterisk.
The reason I want this? This helps the user know what character he/she is typing in the input field and doesn't compromise on the security aspects.
What I have tried? I tried to make the input field type as "password" but that makes the character typed into an asterisk instantly. I don't want this, I want it to show for 1s then become an asterisk.
<input type=password placeholder="Please enter your alphanumerical code" />
Note: I don't want a display/hide toggle button implementation of the above, as I already am aware of that, and have seen answers about that, but it's not my intended implementation
I am working on a reactJS application, so an implementation based on react, JS, JSX, HTML, etc. would be preferred. Thanks :)
P.S This is my first question on stack overflow and I am very new to react, so please pardon me for any mistakes. Feel free to ask any doubts/queries you have regarding the question.
There is a ready-made solution for github: https://karaggeorge.github.io/react-better-password/
Consider the following algorithm:
On input:
get the caret position,
get the number of characters added or deleted
If added,
get the added characters
insert them in the shaddow string
// to do
after a defined time, or on next input, replace
added characters with asterisks (*)
If deleted
delete number deleted to the right of character pos
in the shadow string
Masking the characters runs on a timeout. If something is entered before the timeout runs, the timeout is cancelled and the characters masked immediately. If you type really quickly, multiple characters are visible for a very short time. If multiple characters are pasted, they are all displayed for the timeout lag.
Here's an implementation:
let maskInput = (function() {
// Keep reference to timeout
let timeoutRef = null;
// Set field to all asterisks, keep cursor at current position
function blankField(el) {
// Cancel timeout if there is one
if (timeoutRef) {
clearTimeout(timeoutRef);
timeoutRef = null;
}
// Get cursor position
let cursorPos = el.selectionStart;
// Mask values
el.value = el.value.replace(/./g, '*');
// Put cursor back in position
el.setSelectionRange(cursorPos, cursorPos);
}
return function (el) {
// Get the shaddow element
let inp = document.getElementById('i1');
// Get current cursor position
let cursorPos = el.selectionStart;
// Get number of characters added
let numAdded = el.value.length - inp.value.length;
// If characters were added
if (numAdded > 0) {
// Get characters added
let charsAdded = el.value.slice(cursorPos - numAdded, cursorPos);
// Insert characaters in inp
let insertIdx = cursorPos - numAdded;
inp.value = inp.value.substring(0, insertIdx) +
charsAdded +
inp.value.substring(insertIdx, inp.value.length);
timeoutRef = setTimeout(() => blankField(el), 250);
// If characters were deleted, delete numAdded characters
// to the right of the current cursor position in inp
} else if (numAdded < 0) {
inp.value = inp.value.substring(0, cursorPos) +
inp.value.substring(cursorPos - numAdded, inp.value.length);
}
}
}());
<input id="i0" oninput="maskInput(this)">Enter text<br>
<input id="i1" readonly>Shaddow text
This assumes that the listener is on an input element, plus the ID of the shadow input and masking character are hard coded. Both can easily be dynamic or set in a parameter object or similar.

Get start index of selected text in entire html page

I want to be able to obtain the character(s) that come before the text that the user has highlighed, and i need to include html in this. When the example below is rendered, the user will only see "word". When a user highlights this i want to be able to figure out that there is an angle bracket (or any other char)
<span>word</span>
The following will give me the selection and it gives me a start and an end index, but these are relative to the node that this text belongs to. It is also dom related and doesn't include html.
selectedText= childwindow.getSelection();
To get around this i have tried to get the indexOf value for this piece of text on the html string of the page and this works.
childwindow.document.documentElement.innerHTML.indexOf(selectedText)
The issue with this is that if I highlight something like "the", a word that appears on the page several times, the index is not correct. I can understand why, but I dont know what else to do. I would imagine i need to get this from the dom somehow as this knows the exact piece of text that I have obtained.
Even if this is not possible, is there anything i can grab from the dom that will help me make the indexOf request more reliable. I can add extra data under the hood to make sure it matches the value I want.
This ought to do the trick:
function textSelected() {
if (window.getSelection) {
t = window.getSelection().toString() || "";
} else if (document.selection && document.selection.type != "Control") {
t = document.selection.createRange().text || "";
}
return t;
}
Main thing is window's function getSelection which:
Returns a Selection object representing the range of text selected by
the user or the current position of the caret.
Once you have it, just get what you wanna from Selection obj.
The else part is in case you have selected across elements. Then you need to use selection range. More on document.selection:
docs

How to select a sentence in a generic HTML file with Javascript only

I need to select a complete sentence in a HTML text in which I cannot write any placeholder.
When the user selects a piece of text, I want the selection to extend from point to point. The problem I'm facing is that if I extend my sentence over the "tag limit" I'm not able to get it with the standard methods.
This is what I'm trying to do:
Attach a selection changed method:
document.addEventListener('selectionchange', TextSelected);
Extend get my "range"
function ExpandSelection()
{
//get the next "." (end of the sentence)
var last = window.getSelection().focusOffset;
while(window.getSelection().focusNode.textContent.charAt(last) != '.')
{
last++;
}
//get the previous "." (beginning of the sentence" !!! NOT WORKING
var first = window.getSelection().anchorOffset;
while(window.getSelection().focusNode.textContent.charAt(first) != '.')
{
first--;
}
first++;
return { start: first, end : last }
}
My problem is, right now, that my selection is working in "moving forward" but when I try to move backward I'm not able to get the previous characters.
Does anybody has another way to do it?
Summarizing: if somebody is selecting something (also a single letter) I want the selection to expand to the complete sentence.

get the new added characters to an input by js

I know this seems a quite easy target. I have an input[type=text], and I want to detect the new added character(s) in it. The normal way is:
$selector.keypress(function(e) {
//do sth here
var newchar = String.fromCharCode(e.which);
});
But the above method not working properly for some browsers on android devices. Typing the android virtual keyboard will not fire the keypress.
Then I found the following method is better:
$selector.on('input', function(e){
//do sth here
});
It works fine for android devices, and also, it can detect cut/paste.
Now the question is, is there a way to know the new added character(s) to the input? Do I need to do the complicated string comparison during inputing each time, i.e. compare the previous string and the new string in the input box? I said it's complicated because you may not always type in char(s) at the end, you may insert some char(s) in the middle of the previous string. Think about this, the previous string in the input box is "abc", the new string after pasting is "abcxabc", how can we know the new pasted string is "abcx", or "xabc"?
The method from keypress is quite simple:
String.fromCharCode(e.which);
So, is there similar way to do this by the on('input') method?
After reading Yeldar Kurmangaliyev's answer, I dived into this issue for a while, and find this is really more complicated than my previous expectation. The key point here is that there's a way to get the cursor position by calling: selectionEnd.
As Yeldar Kurmangaliyev mentioned, his answer can't cover the situation:
it is not working is when you select text and paste another text with
replacing the original one.
Based on his answer, I modified the getInputedString function as following:
function getInputedString(prev, curr, selEnd) {
if (selEnd === 0) {
return "";
}
//note: substr(start,length) and substring(start,end) are different
var preLen = prev.length;
var curLen = curr.length;
var index = (preLen > selEnd) ? selEnd : preLen;
var subStrPrev;
var subStrCurr;
for(i=index; i > 0; i--){
subStrPrev = prev.substr(0, i);
subStrCurr = curr.substr(0, i);
if (subStrCurr === subStrPrev) {
var subInterval = selEnd - i;
var interval = curLen - preLen;
if (interval>subInterval) {
return curr.substring(i, selEnd+(interval-subInterval));
}
else{
return curr.substring(i, selEnd);
}
}
}
return curr.substring(0, selEnd);
}
The code is quite self explanation. The core idea is, no matter what character(s) were added(type or paste), the new content MUST be ended at the cursor position.
There's also one issue for my code, e.g. when the prev is abcabc|, you select them all, and paste abc, the return value from my code will be "". Actually, I think it's reasonable, because for my scenario, I think this is just the same with delete the abc from previous abcabc|.
Also, I changed the on('input') event to on('keyup'), the reason is, for some android browsers, the this.selectionEnd will not work in a same way, e.g., the previous text is abc|, now I paste de and the current string will be abcde|, but depending on different browsers, the this.selectionEnd inside on('input') may be 3, or 5. i.e. some browsers will report the cursor position before adding the input, some will report the cursor position after adding the input.
Eventually, I found on('keyup') worked in the same way for all the browsers I tested.
The whole demo is as following:
DEMO ON JSFIDDLE
Working on the cross-browser compatibility is always difficult, especially when you need to consider the touch screen ones. Hope this can help someone, and have fun.
Important notes:
when a user types in a character, the cursor stands after it
when a user pastes the text, the cursor is also located after the pasted text
Assuming this, we can try to suggest the inputed \ pasted string.
For example, when we have a string abc and it becomes abcx|abc (| is a cursor) - we know that actually he pasted "abcx", but not "xabc".
How do this algorithmically? Lets assume that we have the previous input abc and the current input: abcx|abc (cursor is after x).
The new one is of length 7, while the previous one is of length 4. It means that a user inputed 4 characters. Just return these four characters :)
The only case when it is not working is when you select text and paste another text with replacing the original one. I am sure you will come up with a solution for it yoruself :)
Here is the working snippet:
function getInputedString(prev, curr, selEnd) {
if (prev.length > curr.length) {
console.log("User has removed \ cut character(s)");
return "";
}
var lengthOfPasted = curr.length - prev.length;
if (curr.substr(0, selEnd - lengthOfPasted) + curr.substr(selEnd) === prev)
{
return curr.substr(selEnd - lengthOfPasted, lengthOfPasted);
} else {
console.log("The user has replaced a selection :(");
return "n\\a";
}
}
var prevText = "";
$("input").on('input', function() {
var lastInput = getInputedString(prevText, this.value, this.selectionEnd);
prevText = this.value;
$("#result").text("Last input: " + lastInput);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />
<div id="result">Start inputing...</div>

Two different conditions for auto-tabbing text fields

Good morning,
First of all, thanks in advance for any help you might provide
I'll try and explain myself as clearly as possible:
I have a column of some 30ish equal text fields, with an unmodifiable width and height in a form. The users will have two options when inputting text into the text fields:
a) Type word by word
b) Copy from another souce a chunk of text and paste it into the text field.
Now, what I want is to have two different options for the form to auto-tab to the next text field if the first one has been filled.
These are the two options I have tried up to now, which both work when used on their own, but won't work together:
a) Custom Keystroke script for, lets say, Field.0:
if (event.fieldFull) {
this.getField("Field.1").setFocus();
}
b) Custom on-blur script for Field.0:
var temp = new Array();
temp = this.getField("Field.0").value.split(' ');
var rest = "";
ini = temp[0] + ' ';
var charsRead = temp[0].length + 1;
var index = 1;
while ((charsRead + temp[index].length) < 110){
ini = ini + temp[index] + ' ';
index++;
charsRead = charsRead + temp[index].length + 1;
}
for (var i=index ; i < temp.length-1 ; i++){
rest = rest + temp[i] + ' ';
}
this.getField("Field.0").value = ini;
this.getField("Field.1").value = rest;
this.getField("Field.1").setFocus();
As you might probably have noticed, I am no expert (not even close to one...) scripter, so the code might be inefficient or repetitive.
What the script does is: Store the words of the chunk pasted into an array (so as not to split the text in the middle of a word), and copy the first fitting words up to 110 chars (an arbitrary number which sometimes is too little and sometimes too much), and then takes the rest of the words in the array and pastes them into the next field.
When the user tabs out of the Field.0 the focus is set to Field.1. If the text is still too long, when he tabs out of Field.1, the focus is set to Field.2 with the second remainder of the text pasted into it. So, all he has to do is Ctrl+V and TAB, TAB, TAB until all the text has occupied the necessary fields.
Now, for the solution to point a), Scrolling Long Text has to be disabled, but, it is necessary for the script used to solve problem b).
What I am looking for is a way of, independently on how the user has inputted text, to auto-tab WHEN THE FIELD IS FULL. And by full I mean that the text has reached THE END OF THE VISIBLE AREA.
Be it while typing out the text (I suppose it'd has to be with a keystroke script) or when pasting a long phrase (with an on-blur, since keystroke doesn't work here).
Sorry for the long post and thank you once more for the help.
BTW: Using Adobe Acrobat X Pro.
If you have a monospaced font, you can determine how many characters fit in a text field.
Break the pasted text up into chunks of that size, then distribute these chunks over the fields.
So, using the chunk function found here:
//(On paste)
var brokenUpString = pastedString.chunk(maxInputLengthPerField);
for(var i = 0; brokenUpString[i]; i++){
fields[i]value = brokenUpString[i]
}
Now, if you want to move the cursor to the next text field when a user is typing, something like this may work:
//(On key up)
var currentField = 0;
if(fields[currentField].value.length == maxInputLengthPerField){
currentField++;
fields[currentField].setFocus();
}
The problem is that it's "hard" to detect how many characters are entered when a user keeps a button pressed, but you could just take the whole string, break it up, and distribute it over the fields, if that happens.
(chunk() function from the link:)
String.prototype.chunk = function(size) {
return [].concat.apply([],
this.split('').map(function(x,i){ return i%size ? [] : this.slice(i,i+size) }, this)
)
}

Categories

Resources