Disable click event on text selection - javascript

I have the following jQuery, when a user clicks on a td, it reads the text of the td and then does a redirect. How can I disable the click event if the user is selecting the text instead clicking on the td?
$("td").click(function() {
var brand = $(this).closest("tr").attr("data-brand");
var url = window.btoa(window.location.toString());
window.location = "?page=sku&action=brand&brand=" + brand + "&b=" + url;
});

Here we go, I was able to figure it out using a function found here to get the page's selected text, if no selection was found follow link otherwise do nothing.
$("td").click(function() {
var sel = getSelected();
if (sel === "") {
var brand = $(this).closest("tr").attr("data-brand");
var url = window.btoa(window.location.toString());
window.location = "?page=sku&action=brand&brand=" + brand + "&b=" + url;
}
});
function getSelected() {
if (window.getSelection) {
return window.getSelection().toString();
} else if (document.getSelection) {
return document.getSelection().toString();
} else {
var selection = document.selection && document.selection.createRange();
if (selection.text) {
return selection.text.toString();
}
}
return "";
}

You can just do this
function getSelected() {
return (window.getSelection) ? window.getSelection().toString() : document.getSelection().toString();
}

Related

Get start and end of a selection using javascript

i have an html string like this:
<div id="div">Hi how are<span>you?</span> Fine</div>
The text will appear "Hi how are you? Fine".
I would like to select a part of the string using mouse and get the beginning and the end
of the selection looking from the full text string.
For example, if i select "you", i would like to obtain start=11 and end=14;
if i select "are you?", i would like to obtain start=7 and end=15.
I wrote this to obtain the selection:
function getSel() {
console.log(navigator.appCodeName);
if (window.getSelection) {
return window.getSelection();
} else if (document.getSelection) {
return document.getSelection();
} else if (document.selection) {
return document.selection.createRange().text;
}
}
And this code to obtain start and end, but it doesn't work:
$("#div").on('mouseup', function(e){
var text=getSel();
if(text.anchorNode === text.focusNode){
var n = {
node: text.anchorNode.parentNode.id,
start: text.anchorOffset,
end: text.focusOffset
}
//selection from right to left
if(n.start>=n.end) {
var tmp;
tmp=n.start;
n.start=n.end;
n.end=tmp;
}
}
else console.log("error in selection");
});
Your selector is wrong. $('#div') actually selects for any elements that have id='div'.
I have made an example of how it's done. If I am not mistaken of what you're trying to achieve.
function getSelectionText() {
var text = "";
if (window.getSelection) {
text = window.getSelection().toString();
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
}
return text;
}
$(function(){
$("#div").on('mouseup', function(e){
var thisText = $(this).text();
var selectedText = getSelectionText();
var start = thisText.indexOf(selectedText);
var end = start + selectedText.length;
if (start >= 0 && end >= 0){
console.log("start: " + start);
console.log("end: " + end);
}
});
});
Fiddle

Append input with defined text in textfield

What I'm trying to do is to append .com in textfield during user input. Textfield will be empty and .com will be shown during typing domain name. Here is my not working code:
HTML
Enter domain name: <input type="text" id="domain">
Javascript
$(document).ready(function(){
$("input").keypress(function(){
$("#domain").val(this.value + ".com");
});
});
Not working demo:
http://jsfiddle.net/UUzux/25/
Thanks in advance.
I thought this was a great question. For a sleek solution, you could use the following code taken from
Set keyboard caret position in html textbox
to manually set the caret position in the input field:
function setCaretPosition(elemId, caretPos) {
var el = document.getElementById(elemId);
el.value = el.value;
if (el !== null) {
if (el.createTextRange) {
var range = el.createTextRange();
range.move('character', caretPos);
range.select();
return true;
} else {
if (el.selectionStart || el.selectionStart === 0) {
el.focus();
el.setSelectionRange(caretPos, caretPos);
return true;
} else { // fail
el.focus();
return false;
}
}
}
}
And then you'd implement it as follows:
$("input").keyup(function () {
var val = $("#domain").val();
val = val.replace(/\..*/g, ''); // replace this with whatever regex you need to deny whatever input you want.
$("#domain").val(val + ".com");
var caretPos = val.length;
var elemId = "domain";
setCaretPosition(elemId, caretPos);
});
Which will take anything after any . character out of the string, replace it each time with '.com' (you can replace this regex to handle whatever you need), and then set the cursor position to right before the '.com'
JSFiddle Demo
Also, to enable editing in the middle of the string you'd have to get the caret position. There's a stackoverflow question here
Get cursor position (in characters) within a text Input field
With good examples. I modified one of the answers as follows:
getCaretPosition = function (elemId) {
var input = $('#' + elemId);
if (!input) return; // No (input) element found
if ('selectionStart' in input[0]) {
// Standard-compliant browsers
return input[0].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;
}
}
And then your jQuery would look like this:
$("input").keyup(function () {
var val = $("#domain").val();
var elemId = "domain";
var caretPos = getCaretPosition(elemId);
val = val.replace(/\..*/g, '');
$("#domain").val(val + (val ? ".com" : ""));
setCaretPosition(elemId, caretPos);
});
Updated Fiddle with that implementation.
maybe this would help you.
http://jsfiddle.net/naeemshaikh27/UUzux/35/
$(document).ready(function(){
var prevText;
$("input").keyup(function(e){
var str=$("input").val().replace(".com", "");
str=str+'.com'
$("#domain").val( str );
});
});
well here is the updated one: http://jsfiddle.net/naeemshaikh27/UUzux/39/
But still looks aweful without caret moved
You could try this
$(document).ready(function () {
$("input").keyup(function (e) {
var kcode;
if (!e){
var e = window.event;
}
if (e.keyCode){
kcode = e.keyCode;
}
else if (e.which){
kcode = e.which;
}
if (kcode == 8 || kcode == 46){
return false;
}
this.value = this.value.replace('.com', '');
$("#domain").val(this.value + ".com");
var curpos = this.createTextRange();
curpos.collapse(true);
curpos.moveEnd('character', this.value.length - 4);
curpos.select();
});
});
I had to borrow some code from Joel on this post regarding disabling the backspace and delete keys. Just as he states in his post be careful using e.keyCode because not all browsers use it, some use e.Which.
JsFiddle Demo
Update: link to full list of key codes.

Implementing Hashtags using Jquery

What I want to do is basically is that whenever I write anything that starts with a #, the color of the tagged string should change to some other color, say blue, immediately. And when I press space to end the string, the color should change back to black. I tried a logic like this on a contenteditable div:
if (# is pressed)
hashtagging = true
append "<span>" to div
if (space is pressed and hashtagging is true)
hashtagging = false
append "</span>" to div
This is not working as expected.
Something like this should do:
$(function() {
var hashtags = false;
$(document).on('keydown', '#myInputField', function (e) {
arrow = {
hashtag: 51,
space: 32
};
var input_field = $(this);
switch (e.which) {
case arrow.hashtag:
input_field.val(input_field.val() + "<span class='highlight'>");
hashtags = true;
break;
case arrow.space:
if(hashtags) {
input_field.val(input_field.val() + "</span>");
hashtags = false;
}
break;
}
});
});
Now this code checks on keydown if the hashtag or space is pressed and adds a span with a class for styling to it. Reason for checking for keydown instead of keyup is to add the tags before the actual input is added to the textfield. I used a text-field as input, but modify it with whatever you need.
Here's a working example, done by incorporating the solution given by Sondre with the solution by Mr_Green (Set the caret position always to end in contenteditable div) to place the caret at the end.
http://jsfiddle.net/344m4/1/
var hashTagList = [];
function logHashList(){
hashTagList = [];
$('.highlight').each(function(){
hashTagList.push(this.innerHTML);
});
for(var i=0;i<hashTagList.length;i++){
alert(hashTagList[i]);
}
if(hashTagList.length==0){
alert('You have not typed any hashtags');
}
}
$(function() {
var hashtags = false;
$(document).on('keydown', '#example-one', function (e) {
arrow = {
hashtag: 51,
space: 32
};
var input_field = $(this);
switch (e.which) {
case arrow.hashtag:
e.preventDefault();
input_field.html(input_field.html() + "<span class='highlight'>#");
placeCaretAtEnd(this);
hashtags = true;
break;
case arrow.space:
if(hashtags) {
e.preventDefault();
input_field.html(input_field.html() + "</span> ");
placeCaretAtEnd(this);
hashtags = false;
}
break;
}
});
});
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();
}
}

Can getSelection() be applied to just a certain element (not the whole document)?

I was testing out the getSelection() method, and I wanted my program to get the selected text in a certain paragraph of text and display it in a div tag. I used the following code:
var txt = document.getSelection();
document.getElementById("display").innerHTML = "The text you have selected is: " + txt + ".";
However, I want the program to only get selections made in the paragraph itself, not in the entire document. I tried using document.getElementById("id").getSelection(); but it didn't work.
How can I make it so getSelection() only applies to a certain element?
Here's one approach, tested only in Chromium 19 (Which supports textContent, for Internet Explorer innerText would have to be used instead):
function getSelectedText() {
if (window.getSelection) {
return window.getSelection().toString();
} else if (document.selection) {
return document.selection.createRange().text;
}
return '';
}
var b = document.getElementsByTagName('body')[0],
o = document.getElementById('output');
b.onmouseup = function(e){
var selText = getSelectedText(),
targetElem = e.target.tagName.toLowerCase();
if (selText && targetElem == 'p') {
o.textContent = 'You selected the text: "' + selText + '" from a ' + targetElem + ' element.';
}
};​
JS Fiddle demo.
getSelection() is only available as a method of window and document. If you want to get a Range representing just the portion of the user selection that lies within a particular node, here's a function to do that, using my Rangy library (the code to do without the library would be longer and is beyond my enthusiasm to write right now):
function getSelectedRangeWithin(el) {
var selectedRange = null;
var sel = rangy.getSelection();
var elRange = rangy.createRange();
elRange.selectNodeContents(el);
if (sel.rangeCount) {
selectedRange = sel.getRangeAt(0).intersection(elRange);
}
elRange.detach();
return selectedRange;
}
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;
}
written in coffeescript:
getSelected = ->
if window.getSelection
return window.getSelection()
else if document.getSelection
return document.getSelection()
else
selection = document.selection and document.selection.createRange()
return selection.text if selection.text
return false
false
delicious javascript

Can I change the HTML of the selected text?

Can we change the HTML or its attributes of the selected part of the web page using javascript?
For example,
There is a random web page:(A part of it is shown)
with HTML as
...<p>Sample paragraph</p>..
It is possible to get the HTML of the selected text which has already been answered here.
But, is it possible for me change the html of the selected text? Like, add a class or id attribute to the paragraph tag.
The jQuery wrapselection plugin sounds like what you're looking for http://archive.plugins.jquery.com/project/wrapSelection . What you're asking for is not directly possible though, the plugin works by adding in extra nodes around the surrounding text which may not be 100% reliable (particularly in IE6-8)
Here is a working example without a plugin.
http://jsfiddle.net/9HTPw/2/
function getSel() {
var sel = null;
if (
typeof document.selection != "undefined" && document.selection
&& document.selection.type == "Text") {
sel = document.selection;
} else if (
window.getSelection && window.getSelection().rangeCount > 0) {
sel = window.getSelection();
}
return sel;
}
var getSelectionStart = (function () {
function createRangeFromSel(sel) {
var rng = null;
if (sel.createRange) {
rng = sel.createRange();
} else if (sel.getRangeAt) {
rng = sel.getRangeAt(0);
if (rng.toString() == "") rng = null;
}
return rng;
}
return function (el) {
var sel = getSel(),
rng, r2, i = -1;
if (sel) {
rng = createRangeFromSel(sel);
if (rng) {
if (rng.parentElement) {
if (rng.parentElement() == el) {
r2 = document.body.createTextRange();
r2.moveToElementText(el);
r2.collapse(true);
r2.setEndPoint("EndToStart", rng);
i = r2.text.length;
}
} else {
if ( rng.startContainer && rng.endContainer
&& rng.startContainer == rng.endContainer
&& rng.startContainer == rng.commonAncestorContainer
&& rng.commonAncestorContainer.parentNode == el) {
//make sure your DIV does not have any inner element,
//otherwise more code is required in order to filter
//text nodes and count chars
i = rng.startOffset;
}
}
}
}
return i;
};
})();
$("#content").on('mousedown', function () {
$("#content").html(content)
});
var content = $("#content").html();
$("#content").on('mouseup', function () {
var start = getSelectionStart(this);
var len = getSel().toString().length;
$(this).html(
content.substr(0, start) +
'<span style=\"background-color: yellow;\">' +
content.substr(start, len) +
'</span>' +
content.substr(Number(start) + Number(len), content.toString().length));
});
References:
http://bytes.com/topic/javascript/answers/153164-return-selectionstart-div

Categories

Resources