Function param causing cursor to jump on .keyup - javascript

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>

Related

I am having trouble capturing the vale of a text area, and saving it into local storage

Hi I just wondering if i can get some pointers with my code, I am trying to capture and save the input value of a textarea. I am fairly new to JavaScript and I have been wrecking my brain trying to figure it out. My issue is regarding the saveEntry() function, which isn't complete I have only posted how my code is right now, and isn't causing errors/unwanted effects. Any tips or hints would be fantastic, as I keep getting errors
function addTextEntry(key, text, isNewEntry) {
// Create a textarea element to edit the entry
var textareaElement = document.createElement("textarea");
textareaElement.rows = 5;
textareaElement.placeholder = "(new entry)";
// Set the textarea's value to the given text (if any)
textareaElement.value = text;
// Add a section to the page containing the textarea
addSection(key, textareaElement);
// If this is a new entry (added by the user clicking a button)
// move the focus to the textarea to encourage typing
if (isNewEntry) {
textareaElement.focus();
}
// Create an event listener to save the entry when it changes
// (i.e. when the user types into the textarea)
function saveEntry() {
// Save the text entry:
// ...get the textarea element's current value
var currentValue = document.getElementById('textarea').value;
// ...make a text item using the value
// ...store the item in local storage using the given key
localstroage.setItem(key, item);
}
// Connect the saveEntry event listener to the textarea element 'change' event
textareaElement.addEventListener("change", saveEntry());
}
function addImageEntry(key, url) {
// Create a image element
var imgElement = new Image();
imgElement.alt = "Photo entry";
// Load the image
imgElement.src = url;
// Add a section to the page containing the image
addSection(key, imgElement);
}
/**
* Function to handle Add text button 'click' event
*/
function addEntryClick() {
// Add an empty text entry, using the current timestamp to make a key
var key = "diary" + Date.now();
var text = "";
var isNewEntry = true;
addTextEntry(key, text, isNewEntry);
I was told to utilise something similar to this code below, but not exactly the same as I need to capture the data value of the user input text, not pre-created data.
function createDemoItems() {
console.log("Adding demonstration items to local storage");
var item, data, key;
// Make a demo text item
data =
"Friday: We arrived to this wonderful guesthouse after a pleasant journey " +
"and were made most welcome by the proprietor, Mike. Looking forward to " +
"exploring the area tomorrow.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000001";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo text item
data =
"Saturday: After a super breakfast, we took advantage of one of the many " +
"signed walks nearby. For some of the journey this followed the path of a " +
"stream to a charming village.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000002";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo image item
data = window.DUMMY_DATA_URL;
item = makeItem("image", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000003";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo text item
data =
"Sunday: Following a tip from Mike we drove to a gastropub at the head of " +
"the valley - a great meal and fabulous views all round.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000004";
// Store the item in local storage
localStorage.setItem(key, item);
}
You are very close, you just have to make some adjustments here and there!
Just as a disclaimer, I had to re-create your addSection() function, in order to have it properly working. If you already had one, you could discard mine
When we create a new entry, in order to make it distinguishable, I have assigned it the id of the key. Before, you were trying to call getElemenyById("textarea"), but no element had id textarea, which is in fact the tag name of the textarea element that you created. Read more about getElementByTagName if you want.
I have changed the way the event listener is set to:
textareaElement.addEventListener(
'input',
function () { saveEntry(); },
false
);
The difference between change and input are that change will fire only when you are done with the changes and click outside of the textarea, whilst input will fire everytime that you input something. Now you know, so of course, feel free to change it to what you would like it to behave.
Lastly, I have made the just-created item to be retrieved immediately and logged to console. This will be useful just for testing, you can comment out those lines when you are happy.
Beware that the snippet below is playable, but it won't actually save data to LocalStorage because of SO limitations, so you won't be able to fully test it on this page.
function addSection(key, element) {
element.id = key;
var test = document.querySelector("#test");
test.appendChild(element);
}
function addTextEntry(key, text, isNewEntry) {
// Create an event listener to save the entry when it changes
// (i.e. when the user types into the textarea)
function saveEntry() {
// Save the text entry:
// ...get the textarea element's current value
var currentValue = document.getElementById(key).value;
// ...store the item in local storage using the given key
localStorage.setItem(key, currentValue);
//Testing if we can retrieve the item, comment out when you're happy
var item = localStorage.getItem(key);
console.log(item);
}
// Create a textarea element to edit the entry
var textareaElement = document.createElement("textarea");
textareaElement.rows = 5;
textareaElement.placeholder = "(new entry)";
// Set the textarea's value to the given text (if any)
textareaElement.value = text;
// Add a section to the page containing the textarea
addSection(key, textareaElement);
// If this is a new entry (added by the user clicking a button)
// move the focus to the textarea to encourage typing
if (isNewEntry) {
textareaElement.focus();
}
textareaElement.addEventListener(
'input',
function () { saveEntry(); },
false
);
// Connect the saveEntry event listener to the textarea element 'change' event
//textareaElement.addEventListener("change", saveEntry());
}
function addImageEntry(key, url) {
// Create a image element
var imgElement = new Image();
imgElement.alt = "Photo entry";
// Load the image
imgElement.src = url;
// Add a section to the page containing the image
addSection(key, imgElement);
}
/**
* Function to handle Add text button 'click' event
*/
function addEntryClick() {
// Add an empty text entry, using the current timestamp to make a key
var key = "diary" + Date.now();
var text = "";
var isNewEntry = true;
addTextEntry(key, text, isNewEntry);
}
window.onload = () => addEntryClick();
<html>
<head>
</head>
<body>
<div id="test"></div>
</body>
</html>
There are a number of things wrong with the way you're doing things, but you know that: that's why you're here!
You have a typo: localstroage should be localStorage
You create a text area but don't give it an ID. In your saveData function you attempt to find it, but you're searching for it by tag name. There's no need to search: your event handler will already have this set to the element.
In your event handler you refer to your function as saveData(). This will invoke the function immediately and assign its return value as an event handler. Just pass the function name.
Here's a demonstration of concept for you:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Explore local storage</title>
</head>
<body>
<textarea id="txt" placeholder="Enter text and press TAB"></textarea>
<script>
"use strict";
let txtKey = "someKey"
// Save the data. No need to search for the text area:
// the special value 'this' is already set to it.
function saveEntry() {
localStorage.setItem(txtKey, this.value);
}
// Look fr the previous text and if it exists, put it in the textarea
let storedText = localStorage.getItem(txtKey);
if (storedText) {
document.getElementById('txt').value = storedText;
}
// Now add the event listener.
tArea.addEventListener('change', saveEntry); // Pass just the function name
</script>
</body>
</html>
This code uses a hard-coded value for txtKey. Your code might need to generate and track some value for the key, otherwise you risk overwriting earlier data with later data.

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;

Set input cursor to proper position after javascript regex

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);
});

how to get the character based on the position of the cusor [duplicate]

How can I get the caret position from within an input field?
I have found a few bits and pieces via Google, but nothing bullet proof.
Basically something like a jQuery plugin would be ideal, so I could simply do
$("#myinput").caretPosition()
Easier update:
Use field.selectionStart example in this answer.
Thanks to #commonSenseCode for pointing this out.
Old answer:
Found this solution. Not jquery based but there is no problem to integrate it to jquery:
/*
** Returns the caret (cursor) position of the specified text field (oField).
** Return value range is 0-oField.value.length.
*/
function doGetCaretPosition (oField) {
// Initialize
var iCaretPos = 0;
// IE Support
if (document.selection) {
// Set focus on the element
oField.focus();
// To get cursor position, get empty selection range
var oSel = document.selection.createRange();
// Move selection start to 0 position
oSel.moveStart('character', -oField.value.length);
// The caret position is selection length
iCaretPos = oSel.text.length;
}
// Firefox support
else if (oField.selectionStart || oField.selectionStart == '0')
iCaretPos = oField.selectionDirection=='backward' ? oField.selectionStart : oField.selectionEnd;
// Return results
return iCaretPos;
}
Use selectionStart. It is compatible with all major browsers.
document.getElementById('foobar').addEventListener('keyup', e => {
console.log('Caret at: ', e.target.selectionStart)
})
<input id="foobar" />
This works only when no type is defined or type="text" or type="textarea" on the input.
I've wrapped the functionality in bezmax's answer into jQuery if anyone wants to use it.
(function($) {
$.fn.getCursorPosition = function() {
var input = this.get(0);
if (!input) return; // No (input) element found
if ('selectionStart' in input) {
// Standard-compliant browsers
return input.selectionStart;
} else if (document.selection) {
// IE
input.focus();
var sel = document.selection.createRange();
var selLen = document.selection.createRange().text.length;
sel.moveStart('character', -input.value.length);
return sel.text.length - selLen;
}
}
})(jQuery);
Got a very simple solution.
Try the following code with verified result-
<html>
<head>
<script>
function f1(el) {
var val = el.value;
alert(val.slice(0, el.selectionStart).length);
}
</script>
</head>
<body>
<input type=text id=t1 value=abcd>
<button onclick="f1(document.getElementById('t1'))">check position</button>
</body>
</html>
I'm giving you the fiddle_demo
There is now a nice plugin for this: The Caret Plugin
Then you can get the position using $("#myTextBox").caret() or set it via $("#myTextBox").caret(position)
(function($) {
$.fn.getCursorPosition = function() {
var input = this.get(0);
if (!input) return; // No (input) element found
if (document.selection) {
// IE
input.focus();
}
return 'selectionStart' in input ? input.selectionStart:'' || Math.abs(document.selection.createRange().moveStart('character', -input.value.length));
}
})(jQuery);
There are a few good answers posted here, but I think you can simplify your code and skip the check for inputElement.selectionStart support: it is not supported only on IE8 and earlier (see documentation) which represents less than 1% of the current browser usage.
var input = document.getElementById('myinput'); // or $('#myinput')[0]
var caretPos = input.selectionStart;
// and if you want to know if there is a selection or not inside your input:
if (input.selectionStart != input.selectionEnd)
{
var selectionValue =
input.value.substring(input.selectionStart, input.selectionEnd);
}
Perhaps you need a selected range in addition to cursor position. Here is a simple function, you don't even need jQuery:
function caretPosition(input) {
var start = input[0].selectionStart,
end = input[0].selectionEnd,
diff = end - start;
if (start >= 0 && start == end) {
// do cursor position actions, example:
console.log('Cursor Position: ' + start);
} else if (start >= 0) {
// do ranged select actions, example:
console.log('Cursor Position: ' + start + ' to ' + end + ' (' + diff + ' selected chars)');
}
}
Let's say you wanna call it on an input whenever it changes or mouse moves cursor position (in this case we are using jQuery .on()). For performance reasons, it may be a good idea to add setTimeout() or something like Underscores _debounce() if events are pouring in:
$('input[type="text"]').on('keyup mouseup mouseleave', function() {
caretPosition($(this));
});
Here is a fiddle if you wanna try it out: https://jsfiddle.net/Dhaupin/91189tq7/
const inpT = document.getElementById("text-box");
const inpC = document.getElementById("text-box-content");
// swch gets inputs .
var swch;
// swch if corsur is active in inputs defaulte is false .
var isSelect = false;
var crnselect;
// on focus
function setSwitch(e) {
swch = e;
isSelect = true;
console.log("set Switch: " + isSelect);
}
// on click ev
function setEmoji() {
if (isSelect) {
console.log("emoji added :)");
swch.value += ":)";
swch.setSelectionRange(2,2 );
isSelect = true;
}
}
// on not selected on input .
function onout() {
// الافنت اون كي اب
crnselect = inpC.selectionStart;
// return input select not active after 200 ms .
var len = swch.value.length;
setTimeout(() => {
(len == swch.value.length)? isSelect = false:isSelect = true;
}, 200);
}
<h1> Try it !</h1>
<input type="text" onfocus = "setSwitch(this)" onfocusout = "onout()" id="text-box" size="20" value="title">
<input type="text" onfocus = "setSwitch(this)" onfocusout = "onout()" id="text-box-content" size="20" value="content">
<button onclick="setEmoji()">emogi :) </button>
The solution is .selectionStart:
var input = document.getElementById('yourINPUTid');
input.selectionEnd = input.selectionStart = yourDESIREDposition;
input.focus();
If .selectionEnd is not assiged, some text (S-->E) will be selected.
.focus() is required when the focus is lost; when you trigger your code (onClick).
I only tested this in Chrome.
If you want more complicated solutions, you have to read the other answers.

Get cursor position (in characters) within a text Input field

How can I get the caret position from within an input field?
I have found a few bits and pieces via Google, but nothing bullet proof.
Basically something like a jQuery plugin would be ideal, so I could simply do
$("#myinput").caretPosition()
Easier update:
Use field.selectionStart example in this answer.
Thanks to #commonSenseCode for pointing this out.
Old answer:
Found this solution. Not jquery based but there is no problem to integrate it to jquery:
/*
** Returns the caret (cursor) position of the specified text field (oField).
** Return value range is 0-oField.value.length.
*/
function doGetCaretPosition (oField) {
// Initialize
var iCaretPos = 0;
// IE Support
if (document.selection) {
// Set focus on the element
oField.focus();
// To get cursor position, get empty selection range
var oSel = document.selection.createRange();
// Move selection start to 0 position
oSel.moveStart('character', -oField.value.length);
// The caret position is selection length
iCaretPos = oSel.text.length;
}
// Firefox support
else if (oField.selectionStart || oField.selectionStart == '0')
iCaretPos = oField.selectionDirection=='backward' ? oField.selectionStart : oField.selectionEnd;
// Return results
return iCaretPos;
}
Use selectionStart. It is compatible with all major browsers.
document.getElementById('foobar').addEventListener('keyup', e => {
console.log('Caret at: ', e.target.selectionStart)
})
<input id="foobar" />
This works only when no type is defined or type="text" or type="textarea" on the input.
I've wrapped the functionality in bezmax's answer into jQuery if anyone wants to use it.
(function($) {
$.fn.getCursorPosition = function() {
var input = this.get(0);
if (!input) return; // No (input) element found
if ('selectionStart' in input) {
// Standard-compliant browsers
return input.selectionStart;
} else if (document.selection) {
// IE
input.focus();
var sel = document.selection.createRange();
var selLen = document.selection.createRange().text.length;
sel.moveStart('character', -input.value.length);
return sel.text.length - selLen;
}
}
})(jQuery);
Got a very simple solution.
Try the following code with verified result-
<html>
<head>
<script>
function f1(el) {
var val = el.value;
alert(val.slice(0, el.selectionStart).length);
}
</script>
</head>
<body>
<input type=text id=t1 value=abcd>
<button onclick="f1(document.getElementById('t1'))">check position</button>
</body>
</html>
I'm giving you the fiddle_demo
There is now a nice plugin for this: The Caret Plugin
Then you can get the position using $("#myTextBox").caret() or set it via $("#myTextBox").caret(position)
(function($) {
$.fn.getCursorPosition = function() {
var input = this.get(0);
if (!input) return; // No (input) element found
if (document.selection) {
// IE
input.focus();
}
return 'selectionStart' in input ? input.selectionStart:'' || Math.abs(document.selection.createRange().moveStart('character', -input.value.length));
}
})(jQuery);
There are a few good answers posted here, but I think you can simplify your code and skip the check for inputElement.selectionStart support: it is not supported only on IE8 and earlier (see documentation) which represents less than 1% of the current browser usage.
var input = document.getElementById('myinput'); // or $('#myinput')[0]
var caretPos = input.selectionStart;
// and if you want to know if there is a selection or not inside your input:
if (input.selectionStart != input.selectionEnd)
{
var selectionValue =
input.value.substring(input.selectionStart, input.selectionEnd);
}
Perhaps you need a selected range in addition to cursor position. Here is a simple function, you don't even need jQuery:
function caretPosition(input) {
var start = input[0].selectionStart,
end = input[0].selectionEnd,
diff = end - start;
if (start >= 0 && start == end) {
// do cursor position actions, example:
console.log('Cursor Position: ' + start);
} else if (start >= 0) {
// do ranged select actions, example:
console.log('Cursor Position: ' + start + ' to ' + end + ' (' + diff + ' selected chars)');
}
}
Let's say you wanna call it on an input whenever it changes or mouse moves cursor position (in this case we are using jQuery .on()). For performance reasons, it may be a good idea to add setTimeout() or something like Underscores _debounce() if events are pouring in:
$('input[type="text"]').on('keyup mouseup mouseleave', function() {
caretPosition($(this));
});
Here is a fiddle if you wanna try it out: https://jsfiddle.net/Dhaupin/91189tq7/
const inpT = document.getElementById("text-box");
const inpC = document.getElementById("text-box-content");
// swch gets inputs .
var swch;
// swch if corsur is active in inputs defaulte is false .
var isSelect = false;
var crnselect;
// on focus
function setSwitch(e) {
swch = e;
isSelect = true;
console.log("set Switch: " + isSelect);
}
// on click ev
function setEmoji() {
if (isSelect) {
console.log("emoji added :)");
swch.value += ":)";
swch.setSelectionRange(2,2 );
isSelect = true;
}
}
// on not selected on input .
function onout() {
// الافنت اون كي اب
crnselect = inpC.selectionStart;
// return input select not active after 200 ms .
var len = swch.value.length;
setTimeout(() => {
(len == swch.value.length)? isSelect = false:isSelect = true;
}, 200);
}
<h1> Try it !</h1>
<input type="text" onfocus = "setSwitch(this)" onfocusout = "onout()" id="text-box" size="20" value="title">
<input type="text" onfocus = "setSwitch(this)" onfocusout = "onout()" id="text-box-content" size="20" value="content">
<button onclick="setEmoji()">emogi :) </button>
The solution is .selectionStart:
var input = document.getElementById('yourINPUTid');
input.selectionEnd = input.selectionStart = yourDESIREDposition;
input.focus();
If .selectionEnd is not assiged, some text (S-->E) will be selected.
.focus() is required when the focus is lost; when you trigger your code (onClick).
I only tested this in Chrome.
If you want more complicated solutions, you have to read the other answers.

Categories