I have <textarea> where user can type in his message to the world! Below, there are upload buttons... I would love to add link to uploaded file (don't worry, I have it); right next to the text that he was typing in.
Like, he types in 'Hello, world!', then uploads the file (its done via AJAX), and the link to that file is added in next line to the content of <textarea>. Attention! Is it possible to keep cursor (place where he left to type) in the same place?
All that may be done with jQuery... Any ideas? I know that there are method 'append()', but it won't be for this situation, right?
Try
var myTextArea = $('#myTextarea');
myTextArea.val(myTextArea.val() + '\nYour appended stuff');
This took me a while, but the following jQuery will do exactly what you want -- it not only appends text, but also keeps the cursor in the exact same spot by storing it and then resetting it:
var selectionStart = $('#your_textarea')[0].selectionStart;
var selectionEnd = $('#your_textarea')[0].selectionEnd;
$('#your_textarea').val($('#your_textarea').val() + 'The text you want to append');
$('#your_textarea')[0].selectionStart = selectionStart;
$('#your_textarea')[0].selectionEnd = selectionEnd;
You should probably wrap this in a function though.
You may take a look at the following answer which presents a nice plugin for inserting text at the caret position in a <textarea>.
You can use any of the available caret plugins for jQuery and basically:
Store the current caret position
Append the text to the textarea
Use the plugin to replace the caret position
If you want an "append" function in jQuery, one is easy enough to make:
(function($){
$.fn.extend({
valAppend: function(text){
return this.each(function(i,e){
var $e = $(e);
$e.val($e.val() + text);
});
}
});
})(jQuery);
Then you can use it by making a call to .valAppend(), referencing the input field(s).
You could use my Rangy inputs jQuery plugin for this, which works in all major browsers.
var $textarea = $("your_textarea_id");
var sel = $textarea.getSelection();
$textarea.insertText("\nSome text", sel.end).setSelection(sel.start, sel.end);
Related
I have a text contained on a <textarea> like this:
Hi {nom},
We are glad to accept your invitation.
I need it to become
Hi Dolly Parton,
We are glad to accept your invitation.
I don't want to use any plugin, but I have tried developing this simple functionality with no possitive result:
prevContent=$('textarea').val(); //alerts correctly textarea content
content = prevContent.replace('{nom}','Dolly Parton');
In this case, no replacement is made and content has the same value as prevContent.
This is not meant to make a real time replacemet, it has to be replaced before submitting form:
$(document).on('click','.submitMessage', function(){
prevContent=$('textarea').val();
content = prevContent.replace('{nom}','Dolly Parton');
$.post('../actions/newMessage.php',{ms_content:content}).success(
function(data){
alert("yikes");}
);}
});
SOLVED: This was due to a spell mistake on variable. It was sent like {nom1}, not {nom}. Sorry for the inconvenience.
You need use RegExp with g flag, because in your example only first {nom} will be replaced:
var prevContent = $('textarea').val();
var content = prevContent.replace(/\{nom\}/g, 'Dolly Parton');
and to update textarea you can use .val, like so
$('textarea').val(content);
Example
You will just need to assign value of "content" to textarea, as :
$('textarea').val(content);
Consider the following problem:
Have a textarea like so:
<textarea id="body" name="body"></textarea>
Also have some simple JavaScript (jQuery) that inserts some new text into the textarea so a user can embed an image:
$('textarea').val($('textarea').val() + '[img]path to image file[/img]');
The trick is to automatically highlight the text in between the [img][/img] tags after that text is inserted so the user can just copy and paste their image URL in quickly, instead of manually selecting, then copy and pasting.
I've racked my brain and gone all over the internet trying to figure this out, and the best I could do was this popular StackOverflow question Selecting text in an element (akin to highlighting with your mouse) which only addresses the problem of selecting the text inside an ENTIRE element, which is not what is desired here. The problem is to select text that matches a certain string, in this case path to image file, so the user can just copy/paste. (not sure if this is the best way to do it, but that's what I thought of...).
Is this possible? I'm guessing we're going to need getSelection() and createRange() but other than that I have no idea where to go... any JavaScript wizards figured this one out already? I feel like this could be a popular question. Using jQuery is fine, as I'm already using it on the rest of the document.
You could use my jQuery plug-in. It works around browser differences in textarea selection manipulation and has some convenience methods:
https://code.google.com/p/rangyinputs/
For your example, the code would be
var $textarea = $("#body");
var text = "path to image file"
$textarea.replaceSelectedText(text, "select");
$textarea.surroundSelectedText("[img]", "[/img]");
Demo: http://jsfiddle.net/P8Jrh/1/
I actually figured this one out myself... I used the Rangy library https://code.google.com/p/rangy/ and code like this:
// Add text to the reply area at the very end, and move the cursor to the very end.
function insertText(textarea, text) {
textarea = $(textarea);
textarea.focus();
textarea.val(textarea.val() + text);
textarea.focus();
// Trigger the textarea's keyup to emulate typing.
textarea.trigger("keyup");
}
// Add text to the reply area, with the options of wrapping it around a selection and selecting a part of it when it's inserted.
function wrapText(textarea, tagStart, tagEnd, selectArgument, defaultArgumentValue) {
textarea = $(textarea);
// Save the scroll position of the textarea.
var scrollTop = textarea.scrollTop();
// Work out what text is currently selected.
var selectionInfo = textarea.getSelection();
if (textarea.val().substring(selectionInfo.start, selectionInfo.start + 1).match(/ /)) selectionInfo.start++;
if (textarea.val().substring(selectionInfo.end - 1, selectionInfo.end).match(/ /)) selectionInfo.end--;
var selection = textarea.val().substring(selectionInfo.start, selectionInfo.end);
// Work out the text to insert over the selection.
selection = selection ? selection : (defaultArgumentValue ? defaultArgumentValue : "");
var text = tagStart + selection + (typeof tagEnd != "undefined" ? tagEnd : tagStart);
// Replace the textarea's value.
textarea.val(textarea.val().substr(0, selectionInfo.start) + text + textarea.val().substr(selectionInfo.end));
// Scroll back down and refocus on the textarea.
textarea.focus();
// If a selectArgument was passed, work out where it is and select it. Otherwise, select the text that was selected
// before this function was called.
if (selectArgument) {
var newStart = selectionInfo.start + tagStart.indexOf(selectArgument);
var newEnd = newStart + selectArgument.length;
} else {
var newStart = selectionInfo.start + tagStart.length;
var newEnd = newStart + selection.length;
}
textarea.selectRange(newStart, newEnd);
// Trigger the textarea's keyup to emulate typing.
textarea.trigger("keyup");
}
var bbcode = {
bold: function(id) {wrapText($("textarea"), "[b]", "[/b]", "", "bolded text");},
};
Example usage:
bbcode.bold();
Full code (in a larger project I did): https://github.com/wnajar/textarea
I am working on a service which will allow editing of text. To aid the user in the process, I'd like to allow the user to set a text field to overwrite mode, as is possible in Word, etc. How can the behaviour of an HTML text box be changed to overwrite instead of insert text as the user types?
For example, if the textbox had the text:
This is a trst.
The user could click between the r and the t, type a single e and the text would then be
This is a test.
with the cursor between the e and the s. I'm currently using jQuery, so methods using either that or pure javascript would be preferred. I would accept any reasonable solution, however.
That's a bit of crazy but it seems to work somehow :)
Based on this answer and this answer this piece of code was created.
$("textarea").on("keypress", function(e) {
var key = String.fromCharCode(e.which || e.charCode || e.keyCode);
if (/[A-Za-z0-9 ]/.test(key)) {
var text = this.innerHTML;
var caret = getCaret(this);
var output = text.substring(0, caret);
this.innerHTML = output + key + text.substring(caret + 1);
setCaretPosition(this, caret + 1);
return false;
}
return true;
});
DEMO: http://jsfiddle.net/aHSzC/
It works but now I have no time to fix a small bug I found.
If you press Backspace it seems to behave like a forward eraser.
Anyway, here is the code that can be improved. Feel free to edit my answer and do whatever you like.
Input elements have an onkeypress attribute. You could make it call a function that gets rid of the character after the cursor. jQuery has a Caret extension that you could use to find out where the caret is.
$(iframe).bind('keypress', function (e) {
if (e.which == 13) {
var range = iframe.getSelection().getRangeAt(0);
var nodeText = $(range.startContainer, iframe).parent().html();
var leftPart = nodeText.substr(0, range.endOffset);
var rightPart = nodeText.substr(range.endOffset);
$(range.startContainer, iframe).parent().replaceWith('<big>' + leftPart + '</big><p>' + rightPart + '</p>');
return false;
}
});
I've got iframe with some content, e.g:
<p>someText</p>
When i place cursor between "some" and "text", and press enter, i want it to be splitted into this:
<big>some</big><p>Text</p>
everything seems to be working ok, but I also need to change cursor position to the beginnings of this: <p>Text</p>
I know how to set cursor position, but I need to select that element. just $('p', iframe) won't work, because I can have multiply <p> items in iframe. any ideas?
This is an unholy mix of DOM, which considers everything in terms of nodes and offsets, and jQuery-ish HTML-as-strings. The two do not mix well. You've misunderstood the endOffset and startOffset properties of DOM Ranges: they're not offsets within the innerHTML of the container. I suggest looking at MDC or the spec and refactoring your code to only use DOM nodes and not strings of HTML.
Denis ,
Give a common class name to all of them , so that it will effect on the elements.
I would add a dynamic id attribute (or use the metadata plugin) using jQuery to identify the split paragraph. And based on the identified split string place the cursor before the <p> tag. Do make sure to remove the id attribute (or some metadata) once you are done placing the cursor, so that any other splits or a backspace on the same <p> doesn't result in unintended consequences
Hope that helps
I found a nice solution without adding id or class to element. i changed this:
$(range.startContainer, iframe).parent().replaceWith('<big>'+leftPart+'</big><p>'+rightPart+'</p>');
to this:
var leftObject = $('<big>'+leftPart+'</big>');
var rightObject = $('<p>'+rightPart+'</p>');
$(range.startContainer, iframe).parent().replaceWith(leftObject);
leftObject.after(rightObject);
now i got both elements selected in leftObject and rightObject
I want to achieve a python version web regexbuddy,and i encounter a problem,how to highlight match values in different color(switch between yellow and blue) in a textarea,there has a demo what exactly i want on http://regexpal.com,but i was a newbie on js,i didn't understand his code meaning.
any advice is appreciated
To save time you should consider using an existing library for this requirement.
Quote from here:
As textarea elements can’t render HTML, this plugin allows you to highlight text inside textarea elements.
jQuery highlightTextarea.
Demo: Codepen
Usage:
$context.highlightTextarea(options);
There is a pre element over the textarea. So when you type anything it is copying the input on the pre element, applying some filters.
For example:
<pre id="view"></pre>
<textarea id="code"></textarea>
When you type on #code it is copying the value, applying filters and adding the HTML to the #view.
var code = document.getElementById("code");
var pre = document.getElementById("pre");
(code).onkeyup = function (){
val = this.value;
val = YourRegex(val);
(pre).innerHTML = val;
};
YourRegex would be a method to match the regex and return some parsed content to the pre, allowing you to customize the appearance of the textarea (that is actually an element over it).
function YourRegex(val)
{
// This function add colors, bold, whatever you want.
if (/bbcc/i.test("bbcc"))
return "<b>" + val + "</b>";
}
#BrunoLM's solution is excellent, but might require more hacking than you're comfortable with. If you're interested (and if jQuery is already in your stack), the following plugin may be worth taking a look at:
http://garysieling.github.io/jquery-highlighttextarea/