I have a textarea input element,
If the user types "#" I want to replace it with #[someTextHere].
I'm using JQuery's keypress event, but I havent been able to get what I want, I keep getting the "#" at the end of the string , I.e. [someTextHere]#.
Is it possible?
My Code:
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
</head>
<body>
<textarea id="post-txt"></textarea>
</body>
</html>
<script>
$('#post-txt').keypress(function(event){
var str = $('#post-txt').val();
if(String.fromCharCode(event.which) == '#'){
$('#post-txt').val(str.substring(0,str.length) + '[TEXT]');
}
})
</script>
Assistance would be appreciated.
that's because he adds the character after the execution of the function.you can prevent the addition of the character and add it in your code.
if(String.fromCharCode(event.which) == '#'){
event.preventDefault()
$('#post-txt').val(str + '#[TEXT]');
}
Here is a wonderful solution from kristofdegrave which takes into account selection and the cursor position.
var replacedChar = '#';
var replacement = '#[SomeTextHere]'
var moveCursorBy = replacement.length - replacedChar.length; //Or 0 if you want the cursor to be after between '#' and '[SomeTextHere]'
$('textarea').keypress(function(e){
if(e.key == replacedChar){
// IE
if(document.selection){
// Determines the selected text. If no text selected, the location of the cursor in the text is returned
var range = document.selection.createRange();
// Place the replacement on the location of the selection, and remove the data in the selection
range.text = replacement;
// Chrome + FF
} else if(this.selectionStart || this.selectionStart == '0') {
// Determines the start and end of the selection.
// If no text selected, they are the same and the location of the cursor in the text is returned
// Don't make it a jQuery obj, because selectionStart and selectionEnd isn't known.
var start = this.selectionStart;
var end = this.selectionEnd;
// Place the replacement on the location of the selection, and remove the data in the selection
$(this).val($(this).val().substring(0, start) + replacement + $(this).val().substring(end, $(this).val().length));
// Set the cursor back at the correct location in the text
this.selectionStart = start + moveCursorBy + 1;
this.selectionEnd = start + moveCursorBy + 1;
} else {
// if no selection could be determined,
// place the replacement at the end.
$(this).val($(this).val() + replacement);
}
return false;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea></textarea>
I took the liberty to make a jquery function out of the function posted by Alexandru Severin:
$.fn.replaceCharOnKeyPress = function(chr, replacement) {
var moveCursorBy = replacement.length - chr.length;
this.each(function() {
$(this).keypress(function(e) {
if (e.key == chr) {
// IE
if(document.selection) {
// Determines the selected text. If no text selected, the location of the cursor in the text is returned
var range = document.selection.createRange();
// Place the replacement on the location of the selection, and remove the data in the selection
range.text = replacement;
}
// Chrome + FF
else if(this.selectionStart || this.selectionStart == '0') {
// Determines the start and end of the selection.
// If no text selected, they are the same and the location of the cursor in the text is returned
// Don't make it a jQuery obj, because selectionStart and selectionEnd isn't known.
var start = this.selectionStart;
var end = this.selectionEnd;
// Place the replacement on the location of the selection, and remove the data in the selection
$(this).val($(this).val().substring(0, start) + replacement + $(this).val().substring(end, $(this).val().length));
// Set the cursor back at the correct location in the text
this.selectionStart = start + moveCursorBy + 1;
this.selectionEnd = start + moveCursorBy + 1;
}
else {
// if no selection could be determined,
// place the replacement at the end.
$(this).val($(this).val() + replacement);
}
return false;
}
});
});
return this;
};
Usage example:
$(form).find('input.price').replaceCharOnKeyPress(',', '.');
Live demo
<script type="text/javascript">
$("#input").on('input keydown paste', function() {
$(this).val($(this).val().replace(/#(?![[])/g, '#[some text]'));
var key = event.keyCode || event.charCode;
if (key == 8 || key == 46) {
this.select();
}
});
</script>
This regex **/#(?![[])/g** makes sure that only a single # is matched not #[ there by running the code only once.
This code also makes sure that even if the user pasted the # symbol they will get #[some text] in the input box.
this.select() makes sure that # will not fire again when the user tries to delete with either the backspace or delete button (when you delete '[' from '#[' the regex is no longer able to differentiate, therefore the code fires #[some text] again this is what this.select() prevents by selecting the entire #[some text] and removing it in on swoop).
Any Questions leave a comment below!
$(document).find('input').keypress(function(evt){
if(evt.which==50){
$(this).val($(this).val()+'[Letter to replace]');
evt.preventDefault();
}
});
Try this...
Related
I'm trying to make a jQuery method that would delete wanted chars from selected elements.
For example:
$("input").disallowChars(/\D/g);// should disallow input of all non-digit elements in input elements
This is how I thought to do it, but it doesn't seem to work:
$.fn.disallowChars = function(regexp){
this.keyup(function(){
var value = $(this).val();
value.replace(regexp, "");
$(this).val(value);
});
return this;
};
$("input").disallowChars(/\D/g);
I'm a total newbie at this, how can I make it work.
Thanks
You could use String.fromCharCode() and keypress event instead:
$.fn.disallowChars = function(regexp){
return this.keypress(function(e){
if(String.fromCharCode(e.which).match(regexp)) return false;
});
};
DEMO
BUT doesn't disable any characters to be paste in input using mouse or paste keyboard shortcut.
On modern browsers, you could use input event, or change keyup paste mouseup (ya mouseup, to handle dropped text too):
$.fn.disallowChars = function(regexp){
return this.on('input', function(){
this.value = this.value.replace(regexp, '');
});
};
BUT then once input value is replaced, text carret is put in end (or start depending browser behaviour) of string input.
DEMO
heres a handy routine I use to sanitize some input fields in a current project:
// REPLACE SELECTOR WITH YOUR ID(S) OR SELECTORS...
$('input').bind("change keyup", function() {
var val = $.trim($(this).val());
// READ UP ON REGEX TO UNDERSTAND WHATS GOING ON HERE... ADD CHARACTERS YOU WANT TO ELIMINATE...
var regex = /[":'/\+;<>&\\/\n]/g;
if (val.match(regex)) {
val = val.replace(regex, "");
$(this).val($.trim(val));
}
});
Heres another version I used recently:
$("#myField").on("keypress", function(event) {
// THIS ONLY ALLOWS A-Z, A-Z, 0-9 AND THE # SYMBOL... just change stuffToAllow to suit your needs
var stuffToAllow = /[A-Za-z0-9# ]/g;
var key = String.fromCharCode(event.which);
if (event.keyCode == 8 || event.keyCode == 37 || event.keyCode == 39 || stuffToAllow.test(key)) {
return true;
}
alert( key + ' character not allowed!');
return false;
});
I came across following code snippet to insert enter into the the text in a textarea where ctrl + enter is pressed.
$("#txtChatMessage").keydown(MessageTextOnKeyEnter);
function MessageTextOnKeyEnter(e) {
console.log(this.selectionEnd);
if (e.keyCode == 13) {
if (e.ctrlKey) {
var val = this.value;
if (typeof this.selectionStart == "number" && typeof this.selectionEnd == "number") {
var start = this.selectionStart;
this.value = val.slice(0, start) + "\n" + val.slice(this.selectionEnd);
this.selectionStart = this.selectionEnd = start + 1;
} else if (document.selection && document.selection.createRange) {
this.focus();
var range = document.selection.createRange();
range.text = "\r\n";
range.collapse(false);
range.select();
}
}
return false;
}
}
What I don't understand is what do selectionStart and selectionEnd mean here ? According to documentation that I read, selectionStart-End contain the start-end of selected text in the input element. However, here no text is explicitly selected. On doing console.log I could see that both these properties always have some value even when the text is not selected. Why is that?
selectionStart specifies the index of the selection/highlighted text within the <textarea>. Similarly, selectionEnd specifies the index where the selection ends. Initially, they are set to 0, and if the <textarea> is focused but no text is selected, the selectionStart and selectionEnd values will be the same, and reflect the position of the caret within the value of the <textarea>. On un-focus or blur of the <textarea>, they will remain at the last value that they were set to before the blur event.
Here's a fiddle you can play with:
http://jsfiddle.net/5vd8pxct/
The if block in question appears to handle cross-browser compatibility. document.selection is for IE. selectionStart and selectionEnd seem to work elsewhere. I don't have IE on my machine to experiment with it, and I'm using Chrome. It appears from my fiddle that the default start/end are 0 when the page loads. If you click into/select in the box, the start end will be as expected. If you click outside the box, the positions within the box are remembered.
document.selection is undefined in Chrome.
Your code does not work. You mix regular JavaScript and JQuery. I would suggest to start with plain JavaScript. Generally, in JavaScript this is a reference to the object on which the code will be executed.
Take a look at the following example:
<html>
<head>
<script type="text/javascript">
window.addEventListener("load", function () {
var chat = document.getElementById('txtChatMessage'); // get textarea
chat.addEventListener('keydown', function (event) { //add listener keydown for textarea
event = event || window.event;
if (event.keyCode === 13) { //return pressed?
event.preventDefault();
if (this.selectionStart != undefined) {
var startPos = this.selectionStart;
var endPos = this.selectionEnd;
var selectedText = this.value.substring(startPos, endPos);
alert("Hello, you've selected " + selectedText);
}
}
})
});
</script>
</head>
<body>
<textarea id="txtChatMessage" cols="40" rows="10"></textarea>
</body>
</html>
At first an event listener "onLoad" has been registered. Within this function we get a reference to the textarea object. On this object a new event listener "onKeyDown" has been registered. Within this function this refers to the textarea (chat) object. With the help of the event object, we can ask for the pressed key event.keyCode === 13. With this (textarea) and its attributes selectionStart and selectionEnd we get the selected text.
I have a jScript function to text search an element in drop down. It used to work fine till ie7. I have a workaround that works cross browsers but is slow in ie7 using jQuery option:contains instead of Regex.
Function:
/// For the dropdown element passed, find the index where the Text matches the passes string
/// and select this option. Returns true if found otherwise false
function selectTextinDropdown(el, sometext) {
// Use REgex instead of option:contains as it it much faster!
$(el).find("option:[text^='" + sometext.trim() + "']").each(function () {
// works ok but SLOW in IE 7!!
// $(el).find("option:contains('" + sometext.trim() + "')").each(function () {
//alert("found|" + this.text + "|" + sometext);
$(this).attr("selected", "selected");
if ($(this).text() == sometext) {
$(this).attr("selected", "selected");
return true; //found and selected!
}
return false; //Not found and Not selected!
});
}
Anybody familiar with a better workaround?
tks for reading!
Try this:
function selectTextinDropdown(selectEle, targetText) {
if(targetText==null){
return false;
}
targetText = targetText.trim();
// Find all options that meet your condition
var $matches = $(selectEle).find('option').filter(function(index){
// only use jquery selector once
var $this = $(this);
// extract text from the option
var text= $this.text();
// determine if it's found
// OPTION A: exact match
var found = (text === targetText);
// OPTION B: partial match
// var found = (text.indexOf(targetText) >= 0);
if(found){ // select item if found
$this.attr("selected", "selected");
}
return found;
});
return ($matches!=null && $matches.length>0);
}
I am trying to implement tagging just like what facebook does with #friendname. I have a textarea and I wanted to detect when a user typed in #. How do I do so using a keyup listener? Is it possible to get the entered text using keyup? Here's what I have now
$("#recommendTextArea").keyup(function () {
var content = $(this).val(); //content Box Data
var go = content.match(start); //content Matching #
var name = content.match(word); //content Matching #friendname
console.log(content[content.length-1]);
//If # available
if(go.length > 0)
{
//if #abc avalable
if(name.length > 0)
{
//do something here
}
}
});
Most importantly what I need is the index of the'#' that the user just entered.
LINK
(function ($, undefined) {
$.fn.getCursorPosition = function() {
var el = $(this).get(0);
var pos = 0;
if('selectionStart' in el) {
pos = el.selectionStart;
} else if('selection' in document) {
el.focus();
var Sel = document.selection.createRange();
var SelLength = document.selection.createRange().text.length;
Sel.moveStart('character', -el.value.length);
pos = Sel.text.length - SelLength;
}
return pos;
}
})(jQuery);
$("#recommendTextArea").on('keypress', function(e){
var key = String.fromCharCode(e.which);
if(key === '*') {
var position = $(this).getCursorPosition();
alert(position); // It is the position
alert($(this).val()); // This is the value
}
});
I made some changes HERE.
To detect a #, you'd do something like :
$("#recommendTextArea").keyup(function (e) {
if (e.which===50) {
alert('you typed #');
}
});
and this.value get's you whatever is typed into the textarea, and you'll need a regex to get what's between # and the first following space, or something similar depending on how you intend to do this ?
To get a name, you can do something like this :
var _name = false;
$("#recommendTextArea").keyup(function (e) {
if (_name) {
$('#name').text('name : ' + this.value.substring( this.value.lastIndexOf('#') ) )
}
if (e.which === 50) {
_name = true;
}
if (e.which === 32) {
_name = false;
}
});
FIDDLE
This is just a quick demo, building something that always works and accounts for every possible outcome will be a lot more work than this.
EDIT:
Most importantly what I need is the index of the'#' that the user just
entered.
that would be this.value.lastIndexOf('#')
EDIT AGAIN:
To get the names typed in the textarea regardless of cursor position, number of names etc. you'll have to use a regex, here's a quick example that gets all and any names typed in, as long as they start with a #, and ends with a blank space :
$("#recommendTextArea").keyup(function (e) {
var names = this.value.match(/#(.*?)\s/g);
$('#name').html('names typed : <br/><br/>' + names.join('<br/>'));
});
FIDDLE
I am working in email CMS using ckeditor.net.
At runtime user can change the body of email, I want to restrict user deleting all special words starting with ## .
Here is example-
Email Alert! :<br />
<br />
**##Comments**<br />
<br />
Please do not reply to this email.
I don't want user to delete "##comments" word and all "##" characters in other email templates .
Can you give any code in JavaScript?
At run time I replace "##" words with some paragraph.
I haven't tested this code (just free-formed it into this response), but here's what I'd do.
On the keydown method of the text input, you need to listen for the backspace key:
var input = document.getElementById('myInput');
input.onkeydown = function() {
var key = event.keyCode || event.charCode;
// Detect Backspace (8) & Delete (46) keys
if( key == 8 || key == 46 ){
var caretPos = getCaretPos(input);
// Read backward from the caret position
// until you hit a space or index 0:
while ( (input.value[caretPos] != " ") && (caretPos > 0) ){
caretPos--;
}
// Once you hit the space or index 0, read forward two characters
// to see if it === "##". If both chars are "#", cancel
// the keydown event. You should probably do some bounds checking
// here. Could also be done with String.subtring
if ( input.value[(caretPos + 1)] == "#" &&
input.value[(caretPos + 2)] == "#" )
{
return false;
}
}
};
function getCaretPos(input) {
// Internet Explorer Caret Position (TextArea)
if (document.selection && document.selection.createRange) {
var range = document.selection.createRange();
var bookmark = range.getBookmark();
var caret_pos = bookmark.charCodeAt(2) - 2;
} else {
// Firefox Caret Position (TextArea)
if (input.setSelectionRange)
var caret_pos = input.selectionStart;
}
return caret_pos;
}
References
Detect Backspace
Get Caret Position
Cancel the keydown event