So I found this awesome possum that makes it possible to select_all the text in a span tag:
<script type="text/javascript">
function select_all(el) {
if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.selection != "undefined" && typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.select();
}
}
</script>
<span class="select-all" onclick="select_all(this)">This text becomes selectable</span>
Here's the fiddle
My question is, how might I be able to dynamically add the inline javascript to all span tags with the select-all class? I'm still a newbie with javascript and so I couldn't seem to find anything that mentioned how to do this (that or it confused me).
This is how you create a click event handler for all the existent elements having select-all class:
$(".select-all").click(function() {
//do something
});
This is how you define an event handler for all the existent spans having select-all class:
$("span.select-all").click(function() {
//do something
});
This is how you define an event handler for all the existent and future elements having select-all class:
$("body").on("click", ".select-all", function(e) {
//do something
});
This is how you define an event handler for all the existent and future spans having select-all class:
$("body").on("click", "span.select-all", function(e) {
//do something
});
If you want a specific event handler for all existent and future spans having select-all class inside a container, having a selector, then this is how you do it:
$(selector).on("click", "span.select-all", function(e) {
//do something
});
Note, that selector is "body" in the worst case.
You can do something like this
$('document').ready(function(){
$('.select-all').click(function (el) {
if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.selection != "undefined" && typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.select();
}
});
});
Happy Coding.
Related
Please tell how to use Ctrl+Enter↵ as Enter↵ using Jquery. I need it for chatting application.
How to create by using div "<div id="divChatMessage" contenteditable="true"></div>')"
Follwing shows as my code
$('divChatMessage').bind('keyup',function(ev){
if(ev.keyCode == 13 && ev.ctrlKey){
if(document.selection && document.selection.createRange){
this.focus();
var range = document.selection.createRange();
range.text = "\r\n";
range.collapse(false);
range.select();
}else if(window.getSelection){
//i don't know what to do?
}
}
})
there is a JS framework called mousetrap.js which you can use to solve your problem. you simply have to do the following.
add mousetrap.js to your page.
add mousetrap class to you div
<div id="divChatMessage" class="mousetrap" contenteditable="true" ></div>
this tells moustrap to handle ctrl+enter events generated by the div.
Add this script to your page
script
var $div = $('#divChatMessage');
Mousetrap.bind('ctrl+enter', function(e) {
if(e.target === $div[0])
{
$('label').append($div.html()+'<br/>');
$div.html('');
}
else{
e.preventDefault();
}
});
heres a JSFiddle Demo
hint: use ctrl+enter after typing something
update: Ok, I got it now, you want the cursor to go to a new line inside the div when the user presses ctrl+enter. and when user presses only enter the message will be sent.
so, you need to bind both enter and ctrl+enter.
script
var $div = $('#divChatMessage');
Mousetrap.bind('ctrl+enter', function (e) {
if (e.target === $div[0]) {
$div.html($div.html() + '<br/><br/>');
var el = $div[0];
var range = document.createRange();
var sel = window.getSelection();
range.setStart(el.childNodes[el.childNodes.length - 1], el.childNodes[el.childNodes.length - 1].length - 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
el.focus();
} else {
e.preventDefault();
}
});
Mousetrap.bind('enter', function (e) {
if (e.target === $div[0]) {
$('label').append($div.html() + '<br/>');
$div.html('');
} else {
e.preventDefault();
}
});
Demo
I have a contenteditable div and trying to replace <font> tag with <span> tag but after replacing the html using jQuery replaceWith() function cursor defaults to the beginning of the text however I want it at the end of the replacing html.
Here is the DEMO to reproduce the issue. Let me know if there is any problem reproducing the issue.
Here is demo code gist
<div id="test" contenteditable=true>
<p> <font color="blue">Text to be replaced</font> </p>
</div>
<a id="replace" href="javascript:void(null);">replace</a>
JS code
$('#test').focus();
$('#replace').on({
mousedown: function (event) {
event.preventDefault();
},
click: function () {
$('#test').find('font').replaceWith(function () {
return '<span style="color:red">' + 'New Text' + '</span>'
});
}
});
EDIT: Here the problem may sound duplicate but it is indeed different as you see the content gets replaced. I might be replacing the part of that text selected by user and not the entire text. So I need to place the cursor at the end of the html which is replacing the original html.
You can use this function
function placeCaretAtEnd(el) {
el.focus();
if (typeof window.getSelection != "undefined"
&& typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}
call it as follows
placeCaretAtEnd( document.getElementById("content") );
EXAMPLE
If you create the <span> element by hand using document.createElement() and keep a reference to it, you can easily place the caret immediately after it.
Demo: http://jsfiddle.net/Gaqfs/10/
Code:
function placeCaretAfter(el) {
el.focus();
if (typeof window.getSelection != "undefined"
&& typeof document.createRange != "undefined") {
var range = document.createRange();
range.setStartAfter(el);
range.collapse(true);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}
$('#test').focus();
$('#replace').on({
mousedown: function (event) {
event.preventDefault();
},
click: function () {
var span = document.createElement("span");
span.style.color = "red";
span.innerHTML = "New Text";
$('#test').find('font').replaceWith(span);
placeCaretAfter(span);
}
});
I have the following fiddle: http://jsfiddle.net/sxAss/
By using the solution posted here I was able to move the caret to the end of the input. The problem that I have is that the input does not refresh to actually show the caret. Instead it shows the beginning of the input. What should I do to actually move the view to the end of the input. I am using Chrome.
function moveCaretToEnd(el) {
if (typeof el.selectionStart == "number") {
el.selectionStart = el.selectionEnd = el.value.length;
} else if (typeof el.createTextRange != "undefined") {
el.focus();
var range = el.createTextRange();
range.collapse(false);
range.select();
}
}
First focus your input element then call your moveCaretToEnd function
like
$('#button').click(function() {
$('#input').focus();
$('#input').val($('#input').val() + 'StackOverflowTest');
moveCaretToEnd(document.getElementById('input'));
});
Working fiddle
editor.focus();
Sets the focus fine in Chrome.
But in Firefox, the focus is set on the beginning on the line. I want it to be set on the end of the line. I tried this:
moveCaretToEnd(ed);
function moveCaretToEnd(el) {
if (typeof el.selectionStart == "number") {
el.selectionStart = el.selectionEnd = el.value.length;
} else if (typeof el.createTextRange != "undefined") {
el.focus();
var range = el.createTextRange();
range.collapse(false);
range.select();
}
}
And stupid FF doesn't work again. The focus is gone.
I used the following hack for firefox:
var value = editor.val();
editor.val("");
editor.focus();
editor.val(value);
Here is working fiddle: http://jsfiddle.net/vyshniakov/p37ax/
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.