Set input cursor to proper position after javascript regex - javascript

After regex is called cursor goes to end. So I tried that fix, that also did not work properly. How can that be fixed? My target: if field empty and digits is typed > cursor at end, if back to add or delete any digit > cursor at proper position(not at end)
document.getElementById('target').addEventListener('input', function (e) {
var target = e.target,
position = target.selectionStart; // Capture initial position
target.value = target.value.replace(/\B(?=(\d{3})+(?!\d))/g, "-");// This triggers the cursor to move.
target.selectionEnd = position; // Set the cursor back to the initial position.
});
Fiddle

Set the selection range to "position" that you created, and if you include a "-" you increment the position, like that:
document.getElementById('target').addEventListener('input', function (e) {
var target = e.target,
position = target.selectionStart; // Capture initial position
var old = target.value;
target.value = target.value.replace(/\B(?=(\d{3})+(?!\d))/g, "-");
if(old != target.value)
position++;
target.setSelectionRange(position, position);
});

Try setSelectionRange().
Your fiddle: **http://jsfiddle.net/ku8bg0c9/2/
I put 10000 for length as I don't think 10000 characters will ever be inputted. But you can set the length based on length of the input string.
document.getElementById('target').addEventListener('input', function (e) {
var target = e.target,
position = target.selectionStart; // Capture initial position
target.value = target.value.replace(/\B(?=(\d{3})+(?!\d))/g, "-"); // This triggers the cursor to move.
target.selectionEnd = position; // Set the cursor back to the initial position.
target.setSelectionRange(10000, 10000);
});

Related

Function param causing cursor to jump on .keyup

I have this function that is suppose to pass data through diff textarea's however, the cursor keeps jumping to the end of the text.
function KeepReferencesInSync(referenceInput) {
$(referenceInput).keyup(function () {
$("input[name=Reference]").val($(this).val());
}
)}
I got a solution.
I needed to record the cursor position and set [setSelectionRange] to make sure the cursor doesn't jump. See below.
function KeepReferencesInSync(referenceInput) {
$(referenceInput).on('keyup', function () {
//get selection position
var start = this.selectionStart,
end = this.selectionEnd;
$("input[name=Reference]").val($(this).val());
//set the range
this.setSelectionRange(start, end);
})
}
You can try this approach. It's not state-of-the-art but that works.
// Create a list of zone/input/ele
var zoneList = [$('#zone1'),$('#zone2'),$('#zone3')];
// For each zone
$.each(zoneList, function(index, zoneForEvent){
// Attach keyup event
zoneForEvent.on('keyup',function(){
// Get root zone info who trigger event
var rootZoneId = this.id;
var rootZoneValue = this.value;
// Loop on each zone
$.each(zoneList, function(index, zoneDestination){
// If zone destination is not root zone
if (zoneDestination.id !== rootZoneId) {
// Copy value of root element
zoneDestination.val(rootZoneValue);
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="zone1"></textarea>
<input type="text" id="zone2"></input>
<textarea id="zone3"></textarea>

Clicking outside of textarea loses caret position

I created a textarea and a button. When the button is clicked, I want to add the letter 'a' at the current position of the cursor in the textarea. Below is my current code:
$('button.buttonA').click(function(){
var cursorPos = $('textarea.formInsideMenu').prop('selectionStart');
var textCurrent = $('textarea.formInsideMenu').val();
var textBefore = textCurrent.substring(0, cursorPos);
var textAfter = textCurrent.substring(cursorPos, textCurrent.length);
$('textarea.formInsideMenu').val(textBefore + 'a' + textAfter);
});
The above code works fine, (inserts an 'a' at the correct position), when the focus is on the textarea; but as soon as I click on the button, I lose focus of the textarea and the cursor is no longer showing. If I click on the button again after this, 'a' is appended at the very end of the text, (it seems like the cursor is moved to the end of the text). Is there anyway to keep track of where the cursor is inside the textarea even when something else has been clicked on and the textarea has lost focus?
Once you're done with the insert, you need to focus the textarea and set the caret position back:
$('button.buttonA').click(function() {
var area = $('textarea.formInsideMenu'),
curPos = area.prop('selectionEnd');// at the caret **or after selected text**
area.val( area.val().substring(0, curPos) + 'a' + area.val().substring(curPos) )
.focus()
.prop({'selectionStart': curPos+1, 'selectionEnd': curPos+1});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="buttonA">Add an a</button> <br>
<textarea class="formInsideMenu"></textarea>
This version uses javascript only after returning the dom object from jQuery:
$('button.buttonA').click(function(){
var text = $('textarea.formInsideMenu').get(0);
var start = text.selectionStart;
text.value = text.value.slice(0,start) + 'a' + text.value.slice(start);
text.setSelectionRange(start+1,start+1);
text.focus();
});
Fiddle here
Use setSelectionRange after inserting the 'a'.
$('button.buttonA').click(function(){
var cursorPos = $('textarea.formInsideMenu').prop('selectionStart');
var textCurrent = $('textarea.formInsideMenu').val();
var textBefore = textCurrent.substring(0, cursorPos);
var textAfter = textCurrent.substring(cursorPos, textCurrent.length);
$('textarea.formInsideMenu').val(textBefore + 'a' + textAfter);
var elem = document.getElementsByClassName("formInsideMenu")[0];
elem.setSelectionRange(cursorPos, cursorPos + 1);
});
https://jsfiddle.net/ny82n5kn/
You can make a change event on the textarea, where you sore the position of the cursor, like this:
var cursorPos;
$('textarea.formInsideMenu').on('change', function(){
cursorPos = $(this)).prop('selectionStart');
};
Now it will be avaiable in the clickhandler.

Input not scrolling to the far right like it should

I have an input field where i append data at the cursor position.
after that, i set the selectionStart to the end of the field.
BUT, whenever i add something to the input (by button clicks), i only see the left part of it (until it reaches the right edge). everything more is there (i can select it with the mouse and scroll), but it doesn't automatically show the right edge.
how can i do that?
i want to add something to the input and jump right to the end of the string.
// add 2 digit number
$('button#2digit').on('click', function add2digit() {
addNumberToInput(10, 99);
});
function addNumberToInput(min, max) {
var problemInput = $('input#testProblem');
if (lastCharIsOperation() || problemInput.val().trim() < 1) { // if last char is an operation or first in string, just append the number
addAtCursor(randomNonPrime(min, max));
} else {
addAtCursor('+' + randomNonPrime(min, max));
}
}
function addAtCursor(toAdd) {
var problemInput = $('input#testProblem');
var oldText = problemInput.val();
var cursor = problemInput[0].selectionStart;
var pre = oldText.substring(0,cursor);
var post = oldText.substring(cursor, oldText.length);
//insert at cursor
problemInput.val(pre + toAdd + post);
//put cursor to end
problemInput[0].selectionStart = problemInput.val().length;
}
(it even skips back to the left on blur, i couldn't make a picture with the windows snipping tool, because i had to click it first)
From Set mouse focus and move cursor to end of input using jQuery.
var problemInput = $('input#testProblem');
problemInput.focus();
var t=problemInput.val();
problemInput.val('');
problemInput.val(t);
Here is the start of a full solution: https://jsfiddle.net/michaelgentry/vwm159pt/
This will still cause the scroll to jump back to the left on blur, but does what you are asking:
var elem = document.getElementById('myInput');
elem.focus();
elem.scrollLeft = elem.scrollWidth;

Trigger extra mouse click event in same location as first

I have some html, and want to create an input field when clicking a paragraph. That is no problem, but then I'd also like the text cursor to move where the click occured. This can be done simply by clicking again of course, but I'd like this to happen in a single click.
It would be nice to use the first click event to trigger another right after the input field has been created, which would (hopefully) use the mouse coordinates of the first event to move the text cursor to the correct location. Is this possible?
I'm using jquery, so if that makes it easier, please use it for your answer. Thanks for your help!
Here's an approximate solution. It work by calculating the approximate character offset from the number of characters in the text, the width of the text and the relative mouse-offset.
The function for setting the cursor position (once we calculated it) comes from https://stackoverflow.com/a/841121/1961666
http://jsfiddle.net/4LmZ9/
$.fn.selectRange = function(start, end) {
if(!end) end = start;
return this.each(function() {
if (this.setSelectionRange) {
this.focus();
this.setSelectionRange(start, end);
} else if (this.createTextRange) {
var range = this.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', start);
range.select();
}
});
};
$('span').on('click', function(evt)
{
var left = $(this).offset().left;
var width = $(this).width();
var clen = $(this).text().length;
var offset = parseInt((evt.pageX - left)/width * clen);
$(this).replaceWith($('<input />').val($(this).html()));
$('input').trigger('focus').selectRange(offset);
});
(You can get better precision if you calculate the width of each character and taking that into account, if it's important.)

How can i find out which character gets deleted in a tinymce editor on backspace (before it actually gets deleted)?

Assuming the cursor position in a tinymce editor is inside a paragraph.
When a user hits backspace i need to know which character will get deleted.
It is necessary to know this before the character gets removed (onKeyDown is ok, onKeyUp is too late).
How can i find out which character gets deleted on backspace (before it actually gets deleted)?
The code above doesn't take into account backspacing in the middle of a paragraph, or backspacing a whole selection. Try something like the a-tools plugin (although there are several others like it) in combination with the following event handler:
jQuery('input, textarea').keydown(function(e) {
if(e.keyCode === 8) {
var selection = jQuery(this).getSelection();
var selStart = (selection.length) ? selection.start : selection.start - 1;
var selEnd = selection.end;
alert(jQuery(this).val().slice(selStart, selEnd));
}
});
in one of my plugins i set onKeyDown
ed.onKeyDown.add(function(ed, evt) {
if (paragraph && evt.keyCode == 8 && ed.selection.isCollapsed()) {
//insert special marker char
var value = '<span id="__ircaret" class="ircaret">\u2060</span>';
ed.selection.setContent(value, {format : 'raw', no_events: 1});
// node is the dom node the caret is placed in
var node = ed.selection.getNode();
var node_content = $(node).text();
var position = node_content.search('\u2060');
// this is the character
var char_vor_cursor = position != 0 ? node_content.slice(position - 1, position) : '';
// Test for soft-hyphen
if (char_vor_cursor != '' && char_vor_cursor.charCodeAt(0) == 173) {
// correct innerHTML
var text_after_backspace = node_content.slice(0, position - 1) + '<span id="__ircaret" class="ircaret">\u2060</span>' + node_content.slice(position + 1);
node.innerHTML = text_after_backspace;
}
var caret_node = $(node).find('#__ircaret').get(0);
// select caretnode and remove
ed.selection.select(caret_node);
$(ed.getBody()).find('.ircaret').remove();
}
}

Categories