I have two <textarea>s. One with id="input" and the other with id="selection".
<textarea id="input"> will contain some HTML. The user will select some text in this textarea, click a button and the selected text will be copied to <textarea id="selection">.
I can use jQuery or just vanilla JavaScript and I'd like it to work in IE7+, Safari and Firefox.
There's only one way I've been able to do it. The problem you're running into, as you may be aware, is that when you click the button (thus firing the event to copy the selection), the textarea loses focus, and thereby there's no text selected.
So as a workaround, I styled a div to look (kinda) like a textarea. That seems to work:
<style type="text/css">
.textarea {
border:1px solid black;
width:200px;
height:100px;
overflow-y: auto;
float:left;
}
</style>
The markup then looks like this:
<div id="input" class="textarea">This is a test</div>
<textarea id="selection"></textarea>
<button id="theButton">Copy</button>
And finally, the script:
var selText = "";
$( document ).ready( function() {
$( '#theButton' ).mousedown( function() {
$( '#selection' ).val( getSelectedText() );
});
});
function getSelectedText(){
if ( window.getSelection ) {
return window.getSelection().toString();
}
else if ( document.getSelection ) {
return document.getSelection();
} else if ( document.selection ) {
return document.selection.createRange().text;
}
}
To give full credit where it's due, I got the getSelectedText() method from http://esbueno.noahstokes.com/post/92274686/highlight-selected-text-with-jquery
The following will do it:
See it in action: http://www.jsfiddle.net/QenBV/1/
function getSelectedText(el) {
if (typeof el.selectionStart == "number") {
return el.value.slice(el.selectionStart, el.selectionEnd);
} else if (typeof document.selection != "undefined") {
var range = document.selection.createRange();
if (range.parentElement() == el) {
return range.text;
}
}
return "";
}
function copySelected() {
var srcTextarea = document.getElementById("input");
var destTextarea = document.getElementById("selection");
destTextarea.value = getSelectedText(srcTextarea);
}
<input type="button" onclick="copySelected()" value="copy selected">
with jquery you can do as below
$('#selection').val($('#input').val());
http://api.jquery.com/val/
Related
Here is a simple script function getSelectedText() that is working on button click. It means that when we select any text and click on the button, the function is creating a new NEWCLASS div successfully. But now I want to use a shortcut key, like CTRL+W to get selected text in the NEWCLASS div.
I tried this code but it doesn't work. Please, check it and let me know what mistake I am making here.
var input = document.getElementsByTagName("body")[0];
input.addEventListener("keyup", function(event) {
if (event.keyCode === 37) {
event.preventDefault();
document.getElementById("myBtn").click();
}
});
My code:
// Function to get the Selected Text
function getSelectedText() {
var selectedText = '';
// #### create a new element with variable (nw) #### //
var nw = document.createElement("div"); // Element's tag
nw.className = "NEWCLASS"; // Element's class name
// some applied style
// window.getSelection
if (window.getSelection) {
selectedText = window.getSelection();
}
// document.getSelection
else if (document.getSelection) {
selectedText = document.getSelection();
}
// document.selection
else if (document.selection) {
selectedText =
document.selection.createRange().text;
} else return;
// #### get the Selected text appended to body #### //
nw.innerHTML = selectedText;
document.getElementsByClassName('maintitle')[0].prepend(nw); // Append element to body
}
<button id="mybtn" onclick="getSelectedText()">Button</button>
<p>Select any part of this sentence and press the button. Select any part of this sentence and press the button. Select any part of this sentence and press the button</p>
<div class="maintitle"> </div>
the ctrl key with w will close the chrome browser so I used "Z" key for that you can replace the key code with whatever you want.
Find the keycodes here
const keySelected = new Set();
document.addEventListener('keydown', (e) => {
keySelected.add(e.which);
if(keySelected.has(17) && keySelected.has(90)){
getSelectedText();
}
});
document.addEventListener('keyup', (e) => {
keySelected.delete(e.which);
});
/*
//jquery code if anyone want
$(document).ready(function(){
const keySelected = new Set();
$(document).keydown(function (e) {
keySelected.add(e.which);
if(keySelected.has(17) && keySelected.has(90)){
getSelectedText()
}
});
$(document).keyup(function (e) {
keySelected.delete(e.which);
});
});
*/
// Function to get the Selected Text
function getSelectedText() {
var selectedText = '';
// #### create a new element with variable (nw) #### //
var nw = document.createElement("div"); // Element's tag
nw.className = "NEWCLASS"; // Element's class name
// some applied style
// window.getSelection
if (window.getSelection) {
selectedText = window.getSelection();
}
// document.getSelection
else if (document.getSelection) {
selectedText = document.getSelection();
}
// document.selection
else if (document.selection) {
selectedText =
document.selection.createRange().text;
} else return;
// #### get the Selected text appended to body #### //
nw.innerHTML = selectedText;
document.getElementsByClassName('maintitle')[0].prepend(nw); // Append element to body
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="mybtn" onclick="getSelectedText()">Button</button>
<p>
Select any part of this sentence
and press the button. Select any part of this sentence
and press the button. Select any part of this sentence
and press the button
</p>
<div class="maintitle"> </div>
You don't need to recall the event on the button, you should be capable of detect the press of the key you want and call the function, like:
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.code === 'keyW') {
getSelectedText();
}
});
Ctrl+W is not such a good choice, as on Windows it is a common shortcut key for closing the current Window or document, so your script will not even get the key event.
But I'll pick Ctrl+Y instead.
You should not use the deprecated keyCode property -- nor the which property which another answer suggests -- notice the red notice in the MDN documentation.
It is even easier with the key property. And you can use the ctrlKey property to know whether the control key is down.
I would use the keydown instead of the keyup event, as you can then cancel any default effect of the key, with a call to cancelDefault.
document.addEventListener("keydown", (event) => {
if (event.ctrlKey && event.key == "y") {
event.preventDefault();
getSelectedText();
}
});
// Your original code:
function getSelectedText() {
var selectedText = '';
var nw = document.createElement("div"); // Element's tag
nw.className = "NEWCLASS"; // Element's class name
if (window.getSelection) {
selectedText = window.getSelection();
} else if (document.getSelection) {
selectedText = document.getSelection();
} else if (document.selection) {
selectedText = document.selection.createRange().text;
} else return;
nw.innerHTML = selectedText;
document.getElementsByClassName('maintitle')[0].prepend(nw);
}
<button id="mybtn" onclick="getSelectedText()">Button</button>
<p>Select any part of this sentence and press the button or enter Ctrl+Y.
Select any part of this sentence and press the button or enter Ctrl+Y.
Select any part of this sentence and press the button or enter Ctrl+Y.
</p>
<div class="maintitle"> </div>
This should work
var input = document.getElementsByTagName("body")[0];
input.keypress("w", function(event) {
if (event.ctrlKey) {
event.preventDefault();
document.getElementById("myBtn").click();
}
});
I have simple javascript rich text editor consiting only of bold button that has following onclick:
document.execCommand('bold', false)
And simple html...
<div contenteditable="true">
My problem is that when I click the bold button, text area loses it's focus, is there some solution for that?
Well the focus moves to the button so you need to cancel the click action so the focus is not lost in the content editable element.
document.querySelector(".actions").addEventListener("mousedown", function (e) {
var action = e.target.dataset.action;
if (action) {
document.execCommand(action, false)
//prevent button from actually getting focused
e.preventDefault();
}
})
[contenteditable] {
width: 300px;
height: 300px;
border: 1px solid black;
}
<div class="actions">
<button data-action="bold">bold</button>
<button data-action="italic">italic</button>
</div>
<div contenteditable="true"></div>
ANSWER UPDATE
Taking a look to this answer you can save and restore current contenteditable position adding the blur event listener to your contenteditable
An example:
//
// restore position after click
//
document.getElementById('btn').addEventListener('click', function(e) {
restoreSelection(cpos);
})
//
// save position on blur
//
document.querySelector('div[contenteditable="true"]').addEventListener('blur', function(e) {
cpos = saveSelection();
})
function saveSelection() {
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange();
}
return null;
}
function restoreSelection(range) {
if (range) {
if (window.getSelection) {
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (document.selection && range.select) {
range.select();
}
}
}
var cpos = -1;
<button id="btn">Make bold</button>
<div contenteditable="true">
this is the text
</div>
Im currently building a very simple inline-editor, for content editable areas within a website. I have managed to do the basics (Bold, Italic etc) and now I have hit a pitfall.
I'm allowing the user to create links, by highlighting text and creating the link via text input. My problem is if the highlighted/selected text is already wrapped in tags I wish the text input to display the current link. Thus giving the user the ability to terminate the link or update/edit it.
My code for creating a link by highlighting selected text HTML:
<div contenteditable='TRUE' class="editable">This Contenteditable text</div>
<!-- Add Url to Highlighted Text -->
<div class="text-button" unselectable="on" onmousedown="event.preventDefault();" onclick="displayUrlInserter();">Add Url</div>
<!-- Show URL Input and Submit -->
<div class="text-button-panel" id="text-button-panel">
<input type="text" id="url" placeholder="Paste or Type your link">
<div class="text-panel-done" onmousedown="event.preventDefault();" onclick="doneUrl()">Done</div>
<div class="text-panel-cancel" onmousedown="event.preventDefault();" onclick="cancelUrl()">Cancel</div>
</div>
Javascript :
function saveSelection() {
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange();
}
return null;
}
function restoreSelection(range) {
if (range) {
if (window.getSelection) {
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (document.selection && range.select) {
range.select();
}
}
}
var selRange;
function displayUrlInserter() {
selRange = saveSelection();
// Display
document.getElementById("text-button-panel").style.display = "block";
// Focus
document.getElementById("url").focus();
}
function doneUrl() {
var url = document.getElementById("url").value;
// No Url
if (url === "") {
return false;
}
// Check for HTTP
if (!url.match("^(http|https)://")) {
url = "http://" + url;
}
restoreSelection(selRange);
**// THIS IS WHERE I NEED TO CHECK FOR EXISTING A TAGS**
document.execCommand("CreateLink", false, url);
// Hide Panel
document.getElementById("text-button-panel").style.display = "none";
// Reset Input
document.getElementById("url").value = "";
}
function cancelUrl() {
document.getElementById("text-button-panel").style.display = "none";
}
The saveSelection and restoreSelection saves the currently selected text and allows me to create the link within doneUrl() via the execCommand.
This all works fine, all i need is to be able check and get the if it is present. Any guidance would be appreciated.
Try : Grande.js
https://github.com/mduvall/grande.js
Look like this when you selected texts
Live : http://mattduvall.com/grande.js/
Here is a function to check if the current selection is a link.
function itemIsLinked(){
if(window.getSelection().toString() != ""){
var selection = window.getSelection().getRangeAt(0);
if(selection){
if (selection.startContainer.parentNode.tagName === 'A' || selection.endContainer.parentNode.tagName === 'A') {
return [true, selection];
} else { return false; }
} else { return false; }
}
}
Then you can run something like
var isLink = itemIsLinked();
If it is linked it will return :
isLink[0] -> true
isLink[1] -> the link object.
To then get the HREF from that selection use:
isLink[1].startContainer.parentNode.href
That's worked really well for me. Good luck.
I can't seem to figure this out. I have a div with some text in it. When the user selects pieces of it (totally at random, whatever they want), I want a small popup to occur with the text inside of it.
To initiative the popup, can I just do this? ...
$('#textdiv').click(function() {
But then how do I get only the selected/highlighted text?
jQuery isn't going to be of much use here, so you'll need pure JS to do the selection grabbing part (credit goes to this page):
function getSelected() {
if(window.getSelection) { return window.getSelection(); }
else if(document.getSelection) { return document.getSelection(); }
else {
var selection = document.selection && document.selection.createRange();
if(selection.text) { return selection.text; }
return false;
}
return false;
}
You were on the right track with the mouseup handler, so here's what I got working:
$('#test').mouseup(function() {
var selection = getSelected();
if (selection) {
alert(selection);
}
});
And a live demo: http://jsfiddle.net/PQbb7/7/.
Just updated first answer.
Try this
function getSelected() {
if(window.getSelection) { return window.getSelection(); }
else if(document.getSelection) { return document.getSelection(); }
else {
var selection = document.selection && document.selection.createRange();
if(selection.text) { return selection.text; }
return false;
}
return false;
}
/* create sniffer */
$(document).ready(function() {
$('#my-textarea').mouseup(function(event) {
var selection = getSelected();
selection = $.trim(selection);
if(selection != ''){
$("span.popup-tag").css("display","block");
$("span.popup-tag").css("top",event.clientY);
$("span.popup-tag").css("left",event.clientX);
$("span.popup-tag").text(selection);
}else{
$("span.popup-tag").css("display","none");
}
});
});
.popup-tag{
position:absolute;
display:none;
background-color:#785448d4;
color:white;
padding:10px;
font-size:20px;
font-weight:bold;
text-decoration:underline;
cursor:pointer;
-webkit-filter: drop-shadow(0 1px 10px rgba(113,158,206,0.8));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Select any text :<br>
<textarea type="text" id="my-textarea" style="width:100%; height:200px;" >
While delivering a lecture at the Indian Institute of Management Shillong, Kalam collapsed and died from an apparent cardiac arrest on 27 July 2015, aged 83. Thousands including national-level dignitaries attended the funeral ceremony held in his hometown of Rameshwaram, where he was buried with full state honours.
</textarea>
<span class="popup-tag"></span>
see: https://jsfiddle.net/arunmaharana123/kxj9pm40/
We've just released an jQuery plugin called highlighter.js that should allow you to do this flexibly. The code is https://github.com/huffpostlabs/highlighter.js, feel free to ask any questions on the github page.
You can get it from the base DOM element likeso:
var start = $('#textdiv')[0].selectionStart;
var end = $('#textdiv')[0].selectionEnd;
var highlight = $('#textdiv').val().substring(start, end);
// Note the [0] part because we want the actual DOM element, not the jQuery object
At this point, you just need to bind it to a click event. I think in this case mouseup is the event you'd want to bind to, since a user clicks and holds the mouse and then releases it after they're done highlighting text.
The problem is this would not trigger users that use only the keyboard to highlight text. For that you'd want to use keyup on the element and filter for the right keystrokes.
You need a event listener that listen to mouseup event.
var bubbleDOM = document.createElement('div');
bubbleDOM.setAttribute('class', 'selection_bubble');
document.body.appendChild(bubbleDOM);
// Lets listen to mouseup DOM events.
document.addEventListener('mouseup', function (e) {
var selection = window.getSelection().toString();
if (selection.length > 0) {
renderBubble(selection);
}
}, false);
// Close the bubble when we click on the screen.
document.addEventListener('mousedown', function (e) {
bubbleDOM.style.visibility = 'hidden';
}, false);
// Move that bubble to the appropriate location.
function renderBubble(selection) {
bubbleDOM.innerHTML = selection;
bubbleDOM.style.visibility = 'visible';
}
I have a page with couple of DIV elements. When user presses the CTRL+ENTER button combo, I need to display (via alert()) the text, that user previously selected. I found the solution and it works like a charm, but there is still one thing left.
I need to make event trigger, only when selected text is inside a DIV with class "main_content". I've tried to assign keyup to $('DIV.main_content'), but it does not work.
Is there a way to make event trigger only if text inside $('DIV.main_content') selected?
Here is a working code that triggers on the whole document:
// Get user selection text on page
function getSelectedText() {
if (window.getSelection) {
return window.getSelection();
}
else if (document.selection) {
return document.selection.createRange().text;
}
return '';
}
$(document).ready(function(){
$(document).keydown(function(e) {
if(e.which == 13 && e.ctrlKey) {
alert(getSelectedText());
return false;
}
});
});
See the code with markup in jsFiddle
You have an error in the getSelectedText() function: window.getSelection() returns a Selection object, not a string. The fact you're passing the result of this to alert() is masking this, because alert() implicitly converts the argument passed to it into a string.
Here's some code to check whether the selection is completely contained within a <div> element with a particular class. It works in all major browsers.
Live example: http://www.jsfiddle.net/cVgsy/1/
// Get user selection text on page
function getSelectedText() {
if (window.getSelection) {
return window.getSelection().toString();
}
else if (document.selection) {
return document.selection.createRange().text;
}
return '';
}
function isSelectionInDivClass(cssClass) {
var selContainerNode = null;
if (window.getSelection) {
var sel = window.getSelection();
if (sel.rangeCount) {
selContainerNode = sel.getRangeAt(0).commonAncestorContainer;
}
} else if (document.selection && document.selection.type != "Control") {
selContainerNode = document.selection.createRange().parentElement();
}
if (selContainerNode) {
var node = selContainerNode;
while (node) {
if (node.nodeType == 1 && node.nodeName == "DIV" && $(node).hasClass(cssClass)) {
return true;
}
node = node.parentNode;
}
}
return false;
}
$(document).ready(function(){
$(document).keydown(function(e) {
if(e.which == 13 && e.ctrlKey && isSelectionInDivClass("main_content")) {
alert(getSelectedText());
return false;
}
});
});
It is interesting question. I have the following idea: you need to catch mouseup event on div.
For example:
So, in your case you can do something like this:
var selectedText = "";
$(".yourdiv").mouseup(function(){
if (window.getSelection)
selectedText = window.getSelection();
else if (document.selection)
selectedText = document.selection.createRange().text;
alert(selectedText)
});
And variable selectedText will be store selected text.