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.
578 lines
18 KiB
578 lines
18 KiB
/*! |
|
* 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; |
|
} |
|
});
|
|
|