Choopernickel
06-26-2003, 04:49 PM
Still got some quirks to work out, but it's pretty effective. I hate that I had to use innerHTML ("considered harmful!") but it does get the job on. Any suggestions?
Assumes this document extension:
document.getElement = function (anElementID) {
return document.getElementById ? document.getElementById(anElementID) : document.all ? document.all[anElementID] : document.layers ? document.layers[anElementID] : 'undefined';
}
here's the meat of it:
// constructor
function FindInText() {
if (arguments.length) {
// set up properties
this.originalSource = null; // must be filled with document.innerHTML later, on first search
this.formVar = arguments[0];
this.highlightBackColor = arguments[1] ? arguments[1] : "#ffff66";
this.highlightTextColor = arguments[2] ? arguments[2] : "#000000";
this.caseSensitive = arguments[3] ? arguments[3] : false;
this.completeWord = arguments[4] ? arguments[4] : false;
this.searchStringLength = 0;
this.stringComponents = {
startHighlight: "<span style='background-color: " + this.highlightBackColor + ";color=" + this.highlightTextColor + "'>",
endHighlight: "</span>"
}
if (document.getElement('DOT_findTextInPageForm') == null) {
// draw form
document.write('<form id="DOT_findTextInPageForm" action="#" onsubmit="' + this.formVar + '.runSearch(this.elements.searchFormText.value);return false;">' +
'Search Text: <input type="text" name="searchFormText" id="searchFormText">' +
'<input type="submit" value="Search"><br>' +
'<font size=-1>' +
'<input type="checkbox" onclick="' + this.formVar + '.setCaseSensitivity(this.checked)"');
if (this.caseSensitive) document.write(" checked");
document.write('>Match Case?' +
'<input type="checkbox" onclick="' + this.formVar + '.setCompleteWord(this.checked)"');
if (this.completeWord) document.write(" checked");
document.write('>Match Complete Word?' +
'</font>' +
'<input type="reset" onclick="' + this.formVar + '.clearResults()" value="Clear">' +
'</form>');
}
} else return; // if no arguments are passed, we're just setting up the prototype
}
new FindInText();
// FindInText methods
FindInText.prototype.validate = function (toValidate) {
if (toValidate.length == 0) return false;
toValidate.replace(/&/g, "&");
toValidate.replace(/"/g, """);
toValidate.replace(/</g, "<");
toValidate.replace(/>/g, ">");
toValidate.replace(/\\/g, "\\");
toValidate.replace(/\+/g, "\+");
toValidate.replace(/\*/g, "\*");
toValidate.replace(/\?/g, "\?");
toValidate.replace(/\./g, "\.");
toValidate.replace(/\[/g, "\[");
toValidate.replace(/\]/g, "\]");
toValidate.replace(/\^/g, "\^");
toValidate.replace(/\$/g, "\$");
toValidate.replace(/\(/g, "\(");
toValidate.replace(/\)/g, "\)");
toValidate.replace(/\{/g, "\{");
toValidate.replace(/\}/g, "\}");
toValidate.replace(/\|/g, "\|");
toValidate.replace(/\&/g, "\&");
return toValidate;
}
FindInText.prototype.setCaseSensitivity = function (bool) {
if (bool && bool == true || bool == false)
this.caseSensitive = bool;
return;
}
FindInText.prototype.setCompleteWord = function (bool) {
if (bool && bool == true || bool == false)
this.completeWord = bool;
return;
}
FindInText.prototype.clearResults = function () {
document.body.innerHTML = this.originalSource;
return;
}
FindInText.prototype.runSearch = function (argTextToFind) {
var highlightedText, j, k;
var results = new Array();
if (typeof this.originalSource == 'undefined' || this.originalSource == null) {
this.originalSource = document.body.innerHTML;
} else {
this.clearResults();
}
var highlightedText = textToSearch = this.originalSource;
textToFind = this.validate(argTextToFind);
if (!textToFind) return false;
this.searchStringLength = textToFind.length;
var atts = "g";
if (this.completeWord)
textToFind = "(!| )" + textToFind + "( |$)"; // avoid text inside tags
if (!this.caseSensitive)
atts += "i";
var regexToFind = new RegExp(textToFind, atts);
while ((result = regexToFind.exec(textToSearch)) != null) { //> IDE parsing bug
if (result.index > textToSearch.indexOf(">", textToSearch.lastIndexOf("<", result.index)) && result.index < textToSearch.indexOf("<", textToSearch.lastIndexOf(">", result.index))) {
results[results.length] = result.index;
}
}
k = results.length;
if (!k) {
var msg = "term '" + argTextToFind + "' was not found in the text.";
if (this.completeWord) msg = "complete " + msg;
if (this.caseSensitive) msg = "case-sensitive " + msg;
msg = "The " + msg;
alert(msg);
return false;
}
while (k--) { // this loop only works right with DECREMENTS not INCREMENTS to the iterator
thisPosition = results[k];
// close highlight
tmpHighlight = highlightedText.substring(thisPosition + this.searchStringLength);
highlightedText = textToSearch.substring(0, thisPosition + this.searchStringLength) + this.stringComponents.endHighlight + tmpHighlight;
// open highlight
tmpHighlight = highlightedText.substring(thisPosition);
highlightedText = textToSearch.substring(0, thisPosition) + this.stringComponents.startHighlight + tmpHighlight;
}
document.body.innerHTML = highlightedText;
return;
}
here's the super-easy implementation.
<body>
<script type="text/javascript">
ECD_findInPage = new FindInText('ECD_findInPage');
</script>
<noscript>Please use CTRL+F to find text in this page.</noscript>...</body>
script src="" it, or just paste it in the header, no matter.
arguments:
0. Variable name you're using when you call the constructor. Required.
1. Highlight background color, defaults to #ffff66
2. Highlight foreground color, defaults to #000000
3. Case sensitive, defaults to false
4. Complete word, defaults to false
I'll check up on this here thread periodically, hopefully some suggestions will be made!
edited to turn those tabs into 3 spaces
Assumes this document extension:
document.getElement = function (anElementID) {
return document.getElementById ? document.getElementById(anElementID) : document.all ? document.all[anElementID] : document.layers ? document.layers[anElementID] : 'undefined';
}
here's the meat of it:
// constructor
function FindInText() {
if (arguments.length) {
// set up properties
this.originalSource = null; // must be filled with document.innerHTML later, on first search
this.formVar = arguments[0];
this.highlightBackColor = arguments[1] ? arguments[1] : "#ffff66";
this.highlightTextColor = arguments[2] ? arguments[2] : "#000000";
this.caseSensitive = arguments[3] ? arguments[3] : false;
this.completeWord = arguments[4] ? arguments[4] : false;
this.searchStringLength = 0;
this.stringComponents = {
startHighlight: "<span style='background-color: " + this.highlightBackColor + ";color=" + this.highlightTextColor + "'>",
endHighlight: "</span>"
}
if (document.getElement('DOT_findTextInPageForm') == null) {
// draw form
document.write('<form id="DOT_findTextInPageForm" action="#" onsubmit="' + this.formVar + '.runSearch(this.elements.searchFormText.value);return false;">' +
'Search Text: <input type="text" name="searchFormText" id="searchFormText">' +
'<input type="submit" value="Search"><br>' +
'<font size=-1>' +
'<input type="checkbox" onclick="' + this.formVar + '.setCaseSensitivity(this.checked)"');
if (this.caseSensitive) document.write(" checked");
document.write('>Match Case?' +
'<input type="checkbox" onclick="' + this.formVar + '.setCompleteWord(this.checked)"');
if (this.completeWord) document.write(" checked");
document.write('>Match Complete Word?' +
'</font>' +
'<input type="reset" onclick="' + this.formVar + '.clearResults()" value="Clear">' +
'</form>');
}
} else return; // if no arguments are passed, we're just setting up the prototype
}
new FindInText();
// FindInText methods
FindInText.prototype.validate = function (toValidate) {
if (toValidate.length == 0) return false;
toValidate.replace(/&/g, "&");
toValidate.replace(/"/g, """);
toValidate.replace(/</g, "<");
toValidate.replace(/>/g, ">");
toValidate.replace(/\\/g, "\\");
toValidate.replace(/\+/g, "\+");
toValidate.replace(/\*/g, "\*");
toValidate.replace(/\?/g, "\?");
toValidate.replace(/\./g, "\.");
toValidate.replace(/\[/g, "\[");
toValidate.replace(/\]/g, "\]");
toValidate.replace(/\^/g, "\^");
toValidate.replace(/\$/g, "\$");
toValidate.replace(/\(/g, "\(");
toValidate.replace(/\)/g, "\)");
toValidate.replace(/\{/g, "\{");
toValidate.replace(/\}/g, "\}");
toValidate.replace(/\|/g, "\|");
toValidate.replace(/\&/g, "\&");
return toValidate;
}
FindInText.prototype.setCaseSensitivity = function (bool) {
if (bool && bool == true || bool == false)
this.caseSensitive = bool;
return;
}
FindInText.prototype.setCompleteWord = function (bool) {
if (bool && bool == true || bool == false)
this.completeWord = bool;
return;
}
FindInText.prototype.clearResults = function () {
document.body.innerHTML = this.originalSource;
return;
}
FindInText.prototype.runSearch = function (argTextToFind) {
var highlightedText, j, k;
var results = new Array();
if (typeof this.originalSource == 'undefined' || this.originalSource == null) {
this.originalSource = document.body.innerHTML;
} else {
this.clearResults();
}
var highlightedText = textToSearch = this.originalSource;
textToFind = this.validate(argTextToFind);
if (!textToFind) return false;
this.searchStringLength = textToFind.length;
var atts = "g";
if (this.completeWord)
textToFind = "(!| )" + textToFind + "( |$)"; // avoid text inside tags
if (!this.caseSensitive)
atts += "i";
var regexToFind = new RegExp(textToFind, atts);
while ((result = regexToFind.exec(textToSearch)) != null) { //> IDE parsing bug
if (result.index > textToSearch.indexOf(">", textToSearch.lastIndexOf("<", result.index)) && result.index < textToSearch.indexOf("<", textToSearch.lastIndexOf(">", result.index))) {
results[results.length] = result.index;
}
}
k = results.length;
if (!k) {
var msg = "term '" + argTextToFind + "' was not found in the text.";
if (this.completeWord) msg = "complete " + msg;
if (this.caseSensitive) msg = "case-sensitive " + msg;
msg = "The " + msg;
alert(msg);
return false;
}
while (k--) { // this loop only works right with DECREMENTS not INCREMENTS to the iterator
thisPosition = results[k];
// close highlight
tmpHighlight = highlightedText.substring(thisPosition + this.searchStringLength);
highlightedText = textToSearch.substring(0, thisPosition + this.searchStringLength) + this.stringComponents.endHighlight + tmpHighlight;
// open highlight
tmpHighlight = highlightedText.substring(thisPosition);
highlightedText = textToSearch.substring(0, thisPosition) + this.stringComponents.startHighlight + tmpHighlight;
}
document.body.innerHTML = highlightedText;
return;
}
here's the super-easy implementation.
<body>
<script type="text/javascript">
ECD_findInPage = new FindInText('ECD_findInPage');
</script>
<noscript>Please use CTRL+F to find text in this page.</noscript>...</body>
script src="" it, or just paste it in the header, no matter.
arguments:
0. Variable name you're using when you call the constructor. Required.
1. Highlight background color, defaults to #ffff66
2. Highlight foreground color, defaults to #000000
3. Case sensitive, defaults to false
4. Complete word, defaults to false
I'll check up on this here thread periodically, hopefully some suggestions will be made!
edited to turn those tabs into 3 spaces