You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
579 lines
18 KiB
579 lines
18 KiB
![]()
11 years ago
|
/*!
|
||
|
* a-tools 1.4.1
|
||
|
*
|
||
|
* Copyright (c) 2009 Andrey Kramarev(andrey.kramarev[at]ampparit.com), Ampparit Inc. (www.ampparit.com)
|
||
|
* Licensed under the MIT license.
|
||
|
* http://www.ampparit.fi/a-tools/license.txt
|
||
|
*
|
||
|
* Basic usage:
|
||
|
|
||
|
<textarea></textarea>
|
||
|
<input type="text" />
|
||
|
|
||
|
// Get current selection
|
||
|
var sel = $("textarea").getSelection()
|
||
|
|
||
|
// Replace current selection
|
||
|
$("input").replaceSelection("foo");
|
||
|
|
||
|
// Count characters
|
||
|
alert($("textarea").countCharacters());
|
||
|
|
||
|
// Set max length without callback function
|
||
|
$("textarea").setMaxLength(7);
|
||
|
|
||
|
// Set max length with callback function which will be called when limit is exceeded
|
||
|
$("textarea").setMaxLength(10, function() {
|
||
|
alert("hello")
|
||
|
});
|
||
|
|
||
|
// Removing limit:
|
||
|
$("textarea").setMaxLength(-1);
|
||
|
|
||
|
// Insert text at current caret position
|
||
|
$("#textarea").insertAtCaretPos("hello");
|
||
|
|
||
|
// Set caret position (1 = beginning, -1 = end)
|
||
|
$("#textArea").setCaretPos(10);
|
||
|
|
||
|
// Set Selection
|
||
|
$("#textArea").setSelection(10,15);
|
||
|
|
||
|
*/
|
||
|
var caretPositionAmp;
|
||
|
|
||
|
jQuery.fn.extend({
|
||
|
getSelection: function() { // function for getting selection, and position of the selected text
|
||
|
var input = this.jquery ? this[0] : this;
|
||
|
var start;
|
||
|
var end;
|
||
|
var part;
|
||
|
var number = 0;
|
||
|
input.onmousedown = function() { // for IE because it loses caret position when focus changed
|
||
|
if (document.selection && typeof(input.selectionStart) != "number") {
|
||
|
document.selection.empty();
|
||
|
} else {
|
||
|
window.getSelection().removeAllRanges();
|
||
|
}
|
||
|
}
|
||
|
if (document.selection) {
|
||
|
// part for IE and Opera
|
||
|
var s = document.selection.createRange();
|
||
|
var minus = 0;
|
||
|
var position = 0;
|
||
|
var minusEnd = 0;
|
||
|
var re;
|
||
|
var rc;
|
||
|
if (input.value.match(/\n/g) != null) {
|
||
|
number = input.value.match(/\n/g).length;// number of EOL simbols
|
||
|
}
|
||
|
if (s.text) {
|
||
|
part = s.text;
|
||
|
// OPERA support
|
||
|
if (typeof(input.selectionStart) == "number") {
|
||
|
start = input.selectionStart;
|
||
|
end = input.selectionEnd;
|
||
|
// return null if the selected text not from the needed area
|
||
|
if (start == end) {
|
||
|
return { start: start, end: end, text: s.text, length: end - start };
|
||
|
}
|
||
|
} else {
|
||
|
// IE support
|
||
|
var firstRe;
|
||
|
var secondRe;
|
||
|
re = input.createTextRange();
|
||
|
rc = re.duplicate();
|
||
|
firstRe = re.text;
|
||
|
re.moveToBookmark(s.getBookmark());
|
||
|
secondRe = re.text;
|
||
|
rc.setEndPoint("EndToStart", re);
|
||
|
// return null if the selectyed text not from the needed area
|
||
|
if (firstRe == secondRe && firstRe != s.text) {
|
||
|
return this;
|
||
|
}
|
||
|
start = rc.text.length;
|
||
|
end = rc.text.length + s.text.length;
|
||
|
}
|
||
|
// remove all EOL to have the same start and end positons as in MOZILLA
|
||
|
if (number > 0) {
|
||
|
for (var i = 0; i <= number; i++) {
|
||
|
var w = input.value.indexOf("\n", position);
|
||
|
if (w != -1 && w < start) {
|
||
|
position = w + 1;
|
||
|
minus++;
|
||
|
minusEnd = minus;
|
||
|
} else if (w != -1 && w >= start && w <= end) {
|
||
|
if (w == start + 1) {
|
||
|
minus--;
|
||
|
minusEnd--;
|
||
|
position = w + 1;
|
||
|
continue;
|
||
|
}
|
||
|
position = w + 1;
|
||
|
minusEnd++;
|
||
|
} else {
|
||
|
i = number;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (s.text.indexOf("\n", 0) == 1) {
|
||
|
minusEnd = minusEnd + 2;
|
||
|
}
|
||
|
start = start - minus;
|
||
|
end = end - minusEnd;
|
||
|
|
||
|
return { start: start, end: end, text: s.text, length: end - start };
|
||
|
}
|
||
|
input.focus ();
|
||
|
if (typeof(input.selectionStart) == "number") {
|
||
|
start = input.selectionStart;
|
||
|
} else {
|
||
|
s = document.selection.createRange();
|
||
|
re = input.createTextRange();
|
||
|
rc = re.duplicate();
|
||
|
re.moveToBookmark(s.getBookmark());
|
||
|
rc.setEndPoint("EndToStart", re);
|
||
|
start = rc.text.length;
|
||
|
}
|
||
|
if (number > 0) {
|
||
|
for (var i = 0; i <= number; i++) {
|
||
|
var w = input.value.indexOf("\n", position);
|
||
|
if (w != -1 && w < start) {
|
||
|
position = w + 1;
|
||
|
minus++;
|
||
|
} else {
|
||
|
i = number;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
start = start - minus;
|
||
|
return { start: start, end: start, text: s.text, length: 0 };
|
||
|
} else if (typeof(input.selectionStart) == "number" ) {
|
||
|
start = input.selectionStart;
|
||
|
end = input.selectionEnd;
|
||
|
part = input.value.substring(input.selectionStart, input.selectionEnd);
|
||
|
return { start: start, end: end, text: part, length: end - start };
|
||
|
} else { return { start: undefined, end: undefined, text: undefined, length: undefined }; }
|
||
|
},
|
||
|
|
||
|
// function for the replacement of the selected text
|
||
|
replaceSelection: function(inputStr) {
|
||
|
var input = this.jquery ? this[0] : this;
|
||
|
//part for IE and Opera
|
||
|
var start;
|
||
|
var end;
|
||
|
var position = 0;
|
||
|
var rc;
|
||
|
var re;
|
||
|
var number = 0;
|
||
|
var minus = 0;
|
||
|
var mozScrollFix = ( input.scrollTop == undefined ) ? 0 : input.scrollTop;
|
||
|
if (document.selection && typeof(input.selectionStart) != "number") {
|
||
|
var s = document.selection.createRange();
|
||
|
|
||
|
// IE support
|
||
|
if (typeof(input.selectionStart) != "number") { // return null if the selected text not from the needed area
|
||
|
var firstRe;
|
||
|
var secondRe;
|
||
|
re = input.createTextRange();
|
||
|
rc = re.duplicate();
|
||
|
firstRe = re.text;
|
||
|
re.moveToBookmark(s.getBookmark());
|
||
|
secondRe = re.text;
|
||
|
rc.setEndPoint("EndToStart", re);
|
||
|
if (firstRe == secondRe && firstRe != s.text) {
|
||
|
return this;
|
||
|
}
|
||
|
}
|
||
|
if (s.text) {
|
||
|
part = s.text;
|
||
|
if (input.value.match(/\n/g) != null) {
|
||
|
number = input.value.match(/\n/g).length;// number of EOL simbols
|
||
|
}
|
||
|
// IE support
|
||
|
start = rc.text.length;
|
||
|
// remove all EOL to have the same start and end positons as in MOZILLA
|
||
|
if (number > 0) {
|
||
|
for (var i = 0; i <= number; i++) {
|
||
|
var w = input.value.indexOf("\n", position);
|
||
|
if (w != -1 && w < start) {
|
||
|
position = w + 1;
|
||
|
minus++;
|
||
|
|
||
|
} else {
|
||
|
i = number;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
s.text = inputStr;
|
||
|
caretPositionAmp = rc.text.length + inputStr.length;
|
||
|
re.move("character", caretPositionAmp);
|
||
|
document.selection.empty();
|
||
|
input.blur();
|
||
|
}
|
||
|
return this;
|
||
|
} else if (typeof(input.selectionStart) == "number" && // MOZILLA support
|
||
|
input.selectionStart != input.selectionEnd) {
|
||
|
|
||
|
start = input.selectionStart;
|
||
|
end = input.selectionEnd;
|
||
|
input.value = input.value.substr(0, start) + inputStr + input.value.substr(end);
|
||
|
position = start + inputStr.length;
|
||
|
input.setSelectionRange(position, position);
|
||
|
input.scrollTop = mozScrollFix;
|
||
|
return this;
|
||
|
}
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
//Set Selection in text
|
||
|
setSelection: function(startPosition, endPosition) {
|
||
|
startPosition = parseInt(startPosition);
|
||
|
endPosition = parseInt(endPosition);
|
||
|
|
||
|
var input = this.jquery ? this[0] : this;
|
||
|
input.focus ();
|
||
|
if (typeof(input.selectionStart) != "number") {
|
||
|
re = input.createTextRange();
|
||
|
if (re.text.length < endPosition) {
|
||
|
endPosition = re.text.length+1;
|
||
|
}
|
||
|
}
|
||
|
if (endPosition < startPosition) {
|
||
|
return this;
|
||
|
}
|
||
|
if (document.selection) {
|
||
|
var number = 0;
|
||
|
var plus = 0;
|
||
|
var position = 0;
|
||
|
var plusEnd = 0;
|
||
|
if (typeof(input.selectionStart) != "number") { // IE
|
||
|
re.collapse(true);
|
||
|
re.moveEnd('character', endPosition);
|
||
|
re.moveStart('character', startPosition);
|
||
|
re.select();
|
||
|
return this;
|
||
|
} else if (typeof(input.selectionStart) == "number") { // Opera
|
||
|
if (input.value.match(/\n/g) != null) {
|
||
|
number = input.value.match(/\n/g).length;// number of EOL simbols
|
||
|
}
|
||
|
if (number > 0) {
|
||
|
for (var i = 0; i <= number; i++) {
|
||
|
var w = input.value.indexOf("\n", position);
|
||
|
if (w != -1 && w < startPosition) {
|
||
|
position = w + 1;
|
||
|
plus++;
|
||
|
plusEnd = plus;
|
||
|
} else if (w != -1 && w >= startPosition && w <= endPosition) {
|
||
|
if (w == startPosition + 1) {
|
||
|
plus--;
|
||
|
plusEnd--;
|
||
|
position = w + 1;
|
||
|
continue;
|
||
|
}
|
||
|
position = w + 1;
|
||
|
plusEnd++;
|
||
|
} else {
|
||
|
i = number;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
startPosition = startPosition +plus;
|
||
|
endPosition = endPosition + plusEnd;
|
||
|
input.selectionStart = startPosition;
|
||
|
input.selectionEnd = endPosition;
|
||
|
return this;
|
||
|
} else {
|
||
|
return this;
|
||
|
}
|
||
|
}
|
||
|
else if (input.selectionStart) { // MOZILLA support
|
||
|
input.focus ();
|
||
|
input.selectionStart = startPosition;
|
||
|
input.selectionEnd = endPosition;
|
||
|
return this;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// insert text at current caret position
|
||
|
insertAtCaretPos: function(inputStr) {
|
||
|
var input = this.jquery ? this[0] : this;
|
||
|
var start;
|
||
|
var end;
|
||
|
var position;
|
||
|
var s;
|
||
|
var re;
|
||
|
var rc;
|
||
|
var point;
|
||
|
var minus = 0;
|
||
|
var number = 0;
|
||
|
var mozScrollFix = ( input.scrollTop == undefined ) ? 0 : input.scrollTop;
|
||
|
input.focus();
|
||
|
if (document.selection && typeof(input.selectionStart) != "number") {
|
||
|
if (input.value.match(/\n/g) != null) {
|
||
|
number = input.value.match(/\n/g).length;// number of EOL simbols
|
||
|
}
|
||
|
point = parseInt(caretPositionAmp);
|
||
|
if (number > 0) {
|
||
|
for (var i = 0; i <= number; i++) {
|
||
|
var w = input.value.indexOf("\n", position);
|
||
|
if (w != -1 && w <= point) {
|
||
|
position = w + 1;
|
||
|
point = point - 1;
|
||
|
minus++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
caretPositionAmp = parseInt(caretPositionAmp);
|
||
|
// IE
|
||
|
input.onmouseup = function() { // for IE because it loses caret position when focus changed
|
||
|
if (document.selection && typeof(input.selectionStart) != "number") {
|
||
|
input.focus();
|
||
|
s = document.selection.createRange();
|
||
|
re = input.createTextRange();
|
||
|
rc = re.duplicate();
|
||
|
re.moveToBookmark(s.getBookmark());
|
||
|
rc.setEndPoint("EndToStart", re);
|
||
|
caretPositionAmp = rc.text.length;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (document.selection && typeof(input.selectionStart) != "number") {
|
||
|
s = document.selection.createRange();
|
||
|
if (s.text.length != 0) {
|
||
|
return this;
|
||
|
}
|
||
|
re = input.createTextRange();
|
||
|
textLength = re.text.length;
|
||
|
rc = re.duplicate();
|
||
|
re.moveToBookmark(s.getBookmark());
|
||
|
rc.setEndPoint("EndToStart", re);
|
||
|
start = rc.text.length;
|
||
|
if (caretPositionAmp > 0 && start ==0) {
|
||
|
minus = caretPositionAmp - minus;
|
||
|
re.move("character", minus);
|
||
|
re.select();
|
||
|
s = document.selection.createRange();
|
||
|
caretPositionAmp += inputStr.length;
|
||
|
} else if (!(caretPositionAmp >= 0) && textLength ==0) {
|
||
|
s = document.selection.createRange();
|
||
|
caretPositionAmp = inputStr.length + textLength;
|
||
|
} else if (!(caretPositionAmp >= 0) && start ==0) {
|
||
|
re.move("character", textLength);
|
||
|
re.select();
|
||
|
s = document.selection.createRange();
|
||
|
caretPositionAmp = inputStr.length + textLength;
|
||
|
} else if (!(caretPositionAmp >= 0) && start > 0) {
|
||
|
re.move("character", 0);
|
||
|
document.selection.empty();
|
||
|
re.select();
|
||
|
s = document.selection.createRange();
|
||
|
caretPositionAmp = start + inputStr.length;
|
||
|
} else if (caretPositionAmp >= 0 && caretPositionAmp == textLength) {
|
||
|
if (textLength != 0) {
|
||
|
re.move("character", textLength);
|
||
|
re.select();
|
||
|
} else {
|
||
|
re.move("character", 0);
|
||
|
}
|
||
|
s = document.selection.createRange();
|
||
|
caretPositionAmp = inputStr.length + textLength;
|
||
|
} else if (caretPositionAmp >= 0 && start != 0 && caretPositionAmp >= start) {
|
||
|
minus = caretPositionAmp - start;
|
||
|
re.move("character", minus);
|
||
|
document.selection.empty();
|
||
|
re.select();
|
||
|
s = document.selection.createRange();
|
||
|
caretPositionAmp = caretPositionAmp + inputStr.length;
|
||
|
} else if (caretPositionAmp >= 0 && start != 0 && caretPositionAmp < start) {
|
||
|
re.move("character", 0);
|
||
|
document.selection.empty();
|
||
|
re.select();
|
||
|
s = document.selection.createRange();
|
||
|
caretPositionAmp = caretPositionAmp + inputStr.length;
|
||
|
} else {
|
||
|
document.selection.empty();
|
||
|
re.select();
|
||
|
s = document.selection.createRange();
|
||
|
caretPositionAmp = caretPositionAmp + inputStr.length;
|
||
|
}
|
||
|
s.text = inputStr;
|
||
|
input.focus();
|
||
|
|
||
|
return this;
|
||
|
} else if (typeof(input.selectionStart) == "number" && // MOZILLA support
|
||
|
input.selectionStart == input.selectionEnd) {
|
||
|
position = input.selectionStart + inputStr.length;
|
||
|
start = input.selectionStart;
|
||
|
end = input.selectionEnd;
|
||
|
input.value = input.value.substr(0, start) + inputStr + input.value.substr(end);
|
||
|
input.setSelectionRange(position, position);
|
||
|
input.scrollTop = mozScrollFix;
|
||
|
return this;
|
||
|
}
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
|
||
|
// Set caret position
|
||
|
setCaretPos: function(inputStr) {
|
||
|
|
||
|
var input = this.jquery ? this[0] : this;
|
||
|
var s;
|
||
|
var re;
|
||
|
var position;
|
||
|
var number = 0;
|
||
|
var minus = 0;
|
||
|
var w;
|
||
|
input.focus();
|
||
|
if (parseInt(inputStr) == 0) {
|
||
|
return this;
|
||
|
}
|
||
|
//if (document.selection && typeof(input.selectionStart) == "number") {
|
||
|
if (parseInt(inputStr) > 0) {
|
||
|
inputStr = parseInt(inputStr) - 1;
|
||
|
if (document.selection && typeof(input.selectionStart) == "number" && input.selectionStart == input.selectionEnd) {
|
||
|
if (input.value.match(/\n/g) != null) {
|
||
|
number = input.value.match(/\n/g).length;// number of EOL simbols
|
||
|
}
|
||
|
if (number > 0) {
|
||
|
for (var i = 0; i <= number; i++) {
|
||
|
w = input.value.indexOf("\n", position);
|
||
|
if (w != -1 && w <= inputStr) {
|
||
|
position = w + 1;
|
||
|
inputStr = parseInt(inputStr) + 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (parseInt(inputStr) < 0) {
|
||
|
inputStr = parseInt(inputStr) + 1;
|
||
|
if (document.selection && typeof(input.selectionStart) != "number") {
|
||
|
inputStr = input.value.length + parseInt(inputStr);
|
||
|
if (input.value.match(/\n/g) != null) {
|
||
|
number = input.value.match(/\n/g).length;// number of EOL simbols
|
||
|
}
|
||
|
if (number > 0) {
|
||
|
for (var i = 0; i <= number; i++) {
|
||
|
w = input.value.indexOf("\n", position);
|
||
|
if (w != -1 && w <= inputStr) {
|
||
|
position = w + 1;
|
||
|
inputStr = parseInt(inputStr) - 1;
|
||
|
minus += 1;
|
||
|
}
|
||
|
}
|
||
|
inputStr = inputStr + minus - number;
|
||
|
}
|
||
|
} else if (document.selection && typeof(input.selectionStart) == "number") {
|
||
|
inputStr = input.value.length + parseInt(inputStr);
|
||
|
if (input.value.match(/\n/g) != null) {
|
||
|
number = input.value.match(/\n/g).length;// number of EOL simbols
|
||
|
}
|
||
|
if (number > 0) {
|
||
|
inputStr = parseInt(inputStr) - number;
|
||
|
for (var i = 0; i <= number; i++) {
|
||
|
w = input.value.indexOf("\n", position);
|
||
|
if (w != -1 && w <= (inputStr)) {
|
||
|
position = w + 1;
|
||
|
inputStr = parseInt(inputStr) + 1;
|
||
|
minus += 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} else { inputStr = input.value.length + parseInt(inputStr); }
|
||
|
} else { return this; }
|
||
|
// IE
|
||
|
if (document.selection && typeof(input.selectionStart) != "number") {
|
||
|
s = document.selection.createRange();
|
||
|
if (s.text != 0) {
|
||
|
return this;
|
||
|
}
|
||
|
re = input.createTextRange();
|
||
|
re.collapse(true);
|
||
|
re.moveEnd('character', inputStr);
|
||
|
re.moveStart('character', inputStr);
|
||
|
re.select();
|
||
|
caretPositionAmp = inputStr;
|
||
|
|
||
|
return this;
|
||
|
} else if (typeof(input.selectionStart) == "number" && // MOZILLA support
|
||
|
input.selectionStart == input.selectionEnd) {
|
||
|
input.setSelectionRange(inputStr, inputStr);
|
||
|
return this;
|
||
|
}
|
||
|
return this;
|
||
|
|
||
|
},
|
||
|
|
||
|
countCharacters: function(str) {
|
||
|
var input = this.jquery ? this[0] : this;
|
||
|
if (input.value.match(/\r/g) != null) {
|
||
|
return input.value.length - input.value.match(/\r/g).length;
|
||
|
}
|
||
|
return input.value.length;
|
||
|
},
|
||
|
|
||
|
setMaxLength: function(max, f) {
|
||
|
this.each(function() {
|
||
|
var input = this.jquery ? this[0] : this;
|
||
|
var type = input.type;
|
||
|
var isSelected;
|
||
|
var maxCharacters;
|
||
|
// remove limit if input is a negative number
|
||
|
if (parseInt(max) < 0) {
|
||
|
max=100000000;
|
||
|
}
|
||
|
if (type == "text") {
|
||
|
input.maxLength = max;
|
||
|
}
|
||
|
if (type == "textarea" || type == "text") {
|
||
|
input.onkeypress = function(e) {
|
||
|
var spacesR = input.value.match(/\r/g);
|
||
|
maxCharacters = max;
|
||
|
if (spacesR != null) {
|
||
|
maxCharacters = parseInt(maxCharacters) + spacesR.length;
|
||
|
}
|
||
|
// get event
|
||
|
var key = e || event;
|
||
|
var keyCode = key.keyCode;
|
||
|
// check if any part of text is selected
|
||
|
if (document.selection) {
|
||
|
isSelected = document.selection.createRange().text.length > 0;
|
||
|
} else {
|
||
|
isSelected = input.selectionStart != input.selectionEnd;
|
||
|
}
|
||
|
if (input.value.length >= maxCharacters && (keyCode > 47 || keyCode == 32 ||
|
||
|
keyCode == 0 || keyCode == 13) && !key.ctrlKey && !key.altKey && !isSelected) {
|
||
|
input.value = input.value.substring(0,maxCharacters);
|
||
|
if (typeof(f) == "function") { f() } //callback function
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
input.onkeyup = function() {
|
||
|
var spacesR = input.value.match(/\r/g);
|
||
|
var plus = 0;
|
||
|
var position = 0;
|
||
|
maxCharacters = max;
|
||
|
if (spacesR != null) {
|
||
|
for (var i = 0; i <= spacesR.length; i++) {
|
||
|
if (input.value.indexOf("\n", position) <= parseInt(max)) {
|
||
|
plus++;
|
||
|
position = input.value.indexOf("\n", position) + 1;
|
||
|
}
|
||
|
}
|
||
|
maxCharacters = parseInt(max) + plus;
|
||
|
}
|
||
|
if (input.value.length > maxCharacters) {
|
||
|
input.value = input.value.substring(0, maxCharacters);
|
||
|
if (typeof(f) == "function") { f() }
|
||
|
return this;
|
||
|
}
|
||
|
}
|
||
|
} else { return this; }
|
||
|
})
|
||
|
return this;
|
||
|
}
|
||
|
});
|