Get carat position on focus for an input lement - javascript

I want to get the current cursor position when a user clicks inside a filled input box. But using this.selectionStart; only gives '0' using the following code:
$('.exampleDiv').on('focus', 'input', function() {
console.log(this.selectionStart);
});
Html
<div class="exampleDiv" style="width=300px;"><input value="This is a prefilled value"></div>
My guess is that it gives the value 0 because the .on(focus) code runs before the cursor position is set in the input box.
Is there any other event for input element activation which can be used?
Example: Input box has value: "This is a prefilled value"
User clicks on "pre|filled" so I want to get the number of characters after which the cursor appears. Is there a way to get this?

Your logic is correct. However, your this context in the event listener is not your input element. I recommend either saving the reference to the element in a variable (if you know the ID beforehand) or accessing the element through event.target (you'd also have to add the event parameter to your event listener in that case).
A very basic working example (check your console for output or this fiddle):
var input = document.getElementById('foo');
function caretController() {
var caretPos = input.selectionStart;
console.log('caret position:', caretPos);
}
input.addEventListener('focus', caretController);
<input id="foo" type="text">
And with event.target:
function caretController(event) {
var caretPos = event.target.selectionStart;
console.log('caret position:', caretPos);
}
document.getElementsByTagName('input')[0].addEventListener('focus', caretController);
<input type="text">

Related

Change input to uppercase without the cursor jumping to the end of the text

I'm using the following code to change my input value to uppercase:
<script>
function uppercase(z){
v = z.value.toUpperCase();
z.value = v;
}
</script>
<input type="text" id="example" onkeyup="uppercase(this)">
The problem is that when I type something in the middle of the text, the cursor jumps to the end of it. Searching on Google I tried to following code but it didn't work at all:
function uppercase(z){
document.getElementById(z).addEventListener('input', function (e) {
var target = e.target, position = target.selectionStart; // Capture initial position
target.value = target.value.replace(/\s/g, ''); // This triggers the cursor to move.
v = z.value.toUpperCase();
z.value = v;
target.selectionEnd = position; // Set the cursor back to the initial position.
});
}
The first code is working fine, but I still don't know how to prevent the cursor from jumping.
You can also set the cursor position onkeyup (or whatever you are using, as long you get a reference to the input element)
function withSelectionRange() {
const elem = document.getElementById('working');
// get start position and end position, in case of an selection these values
// will be different
const startPos = elem.selectionStart;
const endPos = elem.selectionEnd;
elem.value = elem.value.toUpperCase();
elem.setSelectionRange(startPos, endPos);
}
function withoutSelectionRange() {
const elem = document.getElementById('notWorking');
elem.value = elem.value.toUpperCase();
}
<div style="display: flex; flex-direction: column">
<label for='working'>Uppercase text with selection range</label>
<input id='working' type='text' onkeyup="withSelectionRange()"></input>
<label for='notWorking'>Uppercase text input without selection range</label>
<input id='notWorking' type='text' onkeyup="withoutSelectionRange()"></input>
</div>
Link to codepen
You can achieve this by simply adding some CSS styling:
#example {
text-transform: uppercase;
}
This will make all the letters in the input field appear as uppercase, but the value would still be the same. If you need the value to be uppercase, transform it to uppercase the moment you need it (right before a submit for example)
I have been searching hours after hours for an solution for this same issue.
Adding CSS did the trick for me, except there is a specific requirement that our backend api only accepts upper-cased string.
So besides:
#example {
text-transform: uppercase;
}
I also added callbacks that listen to onBlur and keydown.enter and converts the input value to upper case when those events get triggered.
P.S.:
No sample code as I'm just sharing my thoughts for people who had the same headaches and doesn't want to hack on HTMLInputElement.setSelectionRange.

Backspace not working correctly

I have built a calculator where a user can either click on the buttons or s/he can select the variables from the drop down. Insertion using keyboard is denied. Now when I click on the highlighted back arrow button which has been put for backspace functionality, only the character present at the right most position is deleted even if my cursor is placed in between the expression using mouse. Is there a workaround to remove the character right before the position where I place my cursor? I am using the below condition on left arrow click:
formulaText.value = formulaText.value.slice(0, formulaText.value.lastIndexOf("("));
You can use the selectionStart property on the input element. More information is on this MDN page. A working example is below.
function getCursorPosition(id) {
return document.getElementById(id).selectionStart;
}
function checkCursorPosition() {
alert(getCursorPosition('testInput'));
}
function backspace() {
var element = document.getElementById('testInput');
var cursorPosition = getCursorPosition('testInput');
element.value = element.value.substring(0, cursorPosition - 1) + element.value.substring(cursorPosition);
element.selectionStart = element.selectionEnd = cursorPosition - 1;
}
<input type="text" id="testInput" value="Example text" />
<button onclick="checkCursorPosition()">Check Cursor Position</button>
<button onclick="backspace()">Backspace</button>

Unable to get value of input field, even through text() and val() methods

I want to get the value of an input field that a user will type into, then do things with it. I've tried the two ways to get value , text() and val(), on the input fields, but neither work.
Kindly advise on what it could be that I'm missing here.
What happens exactly in the code below is that after hovering a button, the value of an input field would be shown through an alert() function. But the alert is constantly blank.
HTML
<div id="collection_name">
collection name
</div>
<input type="text" id="collection_title" placeholder="Midnight in New York">
<div id="collection_button"></div>
jQuery
var collection_title = $('#collection_title').text();
var collection_button = $('#collection_button');
collection_button.on({
mouseover: function() {
alert(collection_title); // the alert comes out blank
}
});
You need to call the text()/val() methods within the handler itself
var collection_title = $('#collection_title');
var collection_button = $('#collection_button');
collection_button.on({
mouseover: function() {
alert(collection_title.val()); //or .text() depending on the element type
}
});
The reason it was blank before is at the time of initializing
var collection_title = $('#collection_title').text();
it had no text value
Demo Fiddle
var collection_title = $('#collection_name').text();
var collection_button = $('#collection_button');
collection_button.on({
mouseover: function () {
alert(collection_title); // the alert comes out blank
}
});

Hiding Text inside of an input element

I have a text input, and I want to hide the text inside, on a given event(I disable the input, when it is not needed). I would like to display the hidden text, when the given event is reversed.
I know I can store the value and retrieve as needed. I'd like to avoid moving data, since this is a purely cosmetic operation.
Can the input text be hidden, or is manipulating the data in the input the only way? I would like the simplest solution.y?
I can use pure JS and jQuery.
I would use "value" attribute of the same input object, since the attribute is the default value. In this case you don't even need any additional variables. The idea of this approach comes from the difference between properties and attributes. It means that if you change value property of the object, the attribute value remains the same as it was before.
var input = document.querySelector('input');
function hide() {
input.value = "";
}
function show() {
input.value = input.getAttribute('value');
}
<input type="text" value="Some text">
<button onclick="hide()">Hide</button>
<button onclick="show()">Show</button>
An example on how to store the value of an input element inside the dataset of the element.
and show/hide it on hover.
var hello = document.getElementById('hello');
hello.dataset.value = hello.value;
hello.value = '';
hello.addEventListener('mouseover', function() {
hello.value = hello.dataset.value;
});
hello.addEventListener('mouseout', function() {
hello.value = '';
});
<input id="hello" value="Hello World" />

How to check over what element my mouse is when I lose focus on input element

Let's say I have this:
<body>
<input type="text" onblur="myFunction()" />
<... rest of page ...>
</body>
<script type="text/javascript">
function myFunction()
{
//this function alerts over what element your mouse is when the input loses focus
}
</script>
Does someone know how to implement this?
You could track what element your mouse if hovering over, like this:
<input type="text" id="myInput" onblur="myFunction()" />
var input = document.getElementById('myInput'), // Get the input element
focus;
input.onmouseover = input.onfocus = function(){focus = true;}; // Set focus to true if the input gains focus
input.onmouseout = input.onblur = function(){focus = false}; // Set focus to false if the input loses focus
document.body.onmousemove = function(e){
if(!focus){ // Only log the target is the input doesn't have focus
console.log(e.target); //Log the current element the mouse is hovering over.
}
};
As far as I know, there's no accurate way to check the mouse's current target on the "mouseleave" or "blur" events, since the event.target of those functions will point to the element the mouse just left, not to the element the mouse is currently hovering over.
Edit:
I added some code so it only logs when the input doesn't have focus.

Categories