Hi Ken3141,
Happy to hear my suggestion is acceptable to you! Here are the
results. Anything you want to have changed, or which doesn't work for
you, let me know and we'll take it through the clarifications.
Note there is a simple phrase vs keywords differentiation (try
entering _is a_ versus _"is a"_). Also check the comments for things
that can be easily adapted by you (like the highlight style).
------------ "index.html" file follows below ------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>CSV Search</title>
<style><!--
body
{
background-color: white;
color: black;
font-family: arial, helvetica, sans-serif;
}
/* The result-found highlight style for
a matching string, can be changed.
For example, you could give it a yellow
background-color (see comment).
*/
.hilite
{
color: red;
/* background-color: yellow; */
font-weight: bold;
}
table
{
border-collapse: collapse;
border: 1px solid black;
}
td
{
text-align: left;
vertical-align: top;
padding: 6px;
border: 1px solid black;
width: 120px;
}
/* Two row background-colors
to seperate rows; can be changed:
*/
tr td
{
background-color: #eee;
}
tr.alternateRow td
{
background-color: #ccc;
}
#excel
{
display: none;
}
--></style>
<script type="text/javascript"><!--
// Row and column separator
// characters, can be changed:
var rowSeparator = "~";
var columnSeparator = ";";
var resultsI = 0;
function searchData()
{
var data = getData();
var search = document.getElementById("searchString").value;
var arrRows = data.split(rowSeparator);
var rowsLength = arrRows.length;
var s = "";
search = replaceStr(search, " ", " ");
var phraseSearch = ( search.indexOf("\"") >= 0 );
if (phraseSearch)
{
resultsI = 0;
search = replaceStr(search, "\"", "");
s += getMatchingRows(arrRows, search);
if (s != "")
{
s = "<p>" + resultsI +
" results found for phrase \"" +
search + "\":</p> " +
"<table>" + s + "</table>";
}
}
else
{
var searchWords = search.split(" ");
var wordsLength = searchWords.length;
for (var i = 0; i < wordsLength; i++)
{
resultsI = 0;
if (searchWords[i] != "")
{
var thisS = getMatchingRows(arrRows,
searchWords[i]);
if (thisS != "")
{
thisS = "<p>" + resultsI +
" results found for \"" +
searchWords[i] + "\":</p> " +
"<table>" + thisS + "</table>";
s += thisS;
}
}
}
}
if (resultsI < 1)
{
// No results output
s = "<p><em>No results matching \"" +
search + "\" were found.</em></p>";
}
var outputLayer = document.getElementById("dataOutput");
outputLayer.innerHTML = s;
document.getElementById("h1data").innerHTML = "Results";
searchForm.style.display = "none";
newSearchLink.style.display = "block";
}
function newSearch()
{
var outputLayer = document.getElementById("dataOutput");
outputLayer.innerHTML = "";
searchForm.style.display = "block";
newSearchLink.style.display = "none";
document.getElementById("h1data").innerHTML = "Search Data";
}
function getMatchingRows(arrRows, search)
{
var sRow = "";
var isAlternate = false;
var rowsLength = arrRows.length;
var lowSearch = search.toLowerCase();
for (var i = 0; i < rowsLength; i++)
{
var row = arrRows[i];
if ( row.toLowerCase().indexOf(lowSearch) >= 0 )
{
// Construct a table row with matches
// to display later:
var classString = (isAlternate) ?
" class=\"alternateRow\"" : "";
var rowDisplay = replaceStr(row, search,
"<span class=\"hilite\">" + search +
"</span>");
sRow += "<tr" + classString + "><td>";
sRow += replaceStr(rowDisplay, columnSeparator,
"</td><td>");
sRow += "</td></tr>";
isAlternate = !isAlternate;
resultsI++;
}
}
return sRow;
}
function getData()
{
var excelLayer = document.getElementById("excel");
return excelLayer.firstChild.data;
}
function replaceStr(str, oldStr, newStr)
{
var strPos = str.indexOf(oldStr);
return (strPos >= 0) ?
str.substring(0, strPos) + newStr +
replaceStr( str.substring(strPos +
oldStr.length), oldStr, newStr ) : str;
}
// --></script>
</head>
<body>
<h1 id="h1data">Search Data</h1>
<form id="searchForm">
<p>
Your query:
<input type="text" size="20"
name="searchString" id="searchString" />
<input type="text" name="suppressReturn"
style="display: none;" />
<input type="button" onclick="searchData()"
value="Search" />
</p>
</form>
<div id="dataOutput">
</div>
<div id="newSearchLink" style="display: none;">
<p>[<a href="javascript:newSearch()">New search ...</a>]</p>
</div>
<div id="excel">
d;3;40~this;is a;test~this;is a second;test~testing yet;again;...
</div>
<p>Copyright © 2003 by Ken</p>
</body>
</html> |
Request for Answer Clarification by
ken3141-ga
on
29 Jun 2003 06:59 PDT
OK, we're almost there. I mean, I suppose technically you're done,
but you're fighting for another star!
OK, here're the one issue, and the two requests, and one relatively
unrelated question:
ISSUE: While the searches work great as the "extra" requested while
being case insensitive (very cool), if you use the 'wrong' case, you
don't get the red highlighting. Is that possible to fix?
REQESTS (No need to really answer these if you don't want; if it's
quick for you, go for it. Otherwise no worries):
a. I actually like how the cell width of the delivered table is fixed;
is there a way to fix each cell size as a different width?
b. Is there a way to have a fixed content table headings show up at
the top of the table(s) if something is found?
LASTLY:
I tried it on a PocketPC (iPaq 3955, running 2002 OS) and got no love.
Now, I very explicitly said that this answer is NOT dependent upon it
working on a PocketPC, and that's true! The thing I want to know is:
if I post a second question after this is answered to see if it can be
tweaked to work on a PPC, are you interested? It's entirely possible
it won't EVER work due to some 'PPC sucks at JAVA' thing. (aside: PPC
DOES run one simple HTML javascript that I could show as an example).
|
Clarification of Answer by
j_philipp-ga
on
29 Jun 2003 14:04 PDT
Hello Ken,
Glad you liked it!
The changes I made, as pasted below:
- Highlighting is now case-insensitive.
- The column-width can be set via the style, see comment "Define
column width ...".
- The first data-row provided will now be used as header-text (see
data "Header 1;Header 2 ...").
Now, the highlighting will (case-insensitive) replace matches with the
string as entered by the user (case kept). If you want this to be
shown as entered by your data, I understand and will try to work on
it, as it would certainly require more tweaking. It was more important
to me that you get a speedy reply.
Indeed making this work on a PocketPC would be an entirely different
task. I would suggest to you that you post a new
question asking for anyone's help, referring to the script I prepared
in this question-thread. Then, I might find time to tackle the
problem, but we might have luck and there's a "PocketPC Expert"
amongst the Researchers group!
If there is no such expert, I could do online research on what is
supported on this system. I know different JavaScript implementations
(ECMAScript, JScript, JavaScript, also Java, which is unrelated to
this though, plus I know different the different browser support. E.g.
the "innerHTML" in my script -- Internet Explorer, and Mozilla,
specific -- as well as the new addition of a regular expression,
might cause problems. And e.g. getElementById is also only supported
in IE5+, to the best of my memory. There are possible different
implementations for other browsers.)
However, all that might become very theoretical without me being able
to test anything. So one solution would be that I prepare a set of
test-cases for you. Those would be specific, very small scripts, which
you would need to save as different HTML pages, then telling me "1
works", "2 doesn't work", "3 ...", and so on.
Since I couldn't promise this would be all ending in a working script,
I'm afraid we would have to separate this process by yet another
question, specifically for me to create test cases. That's why maybe
first you should post a question to anyone and see what happens!
Let me know how things work and how you would like to proceed!
--------- New file below ---------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>CSV Search</title>
<style><!--
body
{
background-color: white;
color: black;
font-family: arial, helvetica, sans-serif;
}
/* The result-found highlight style for
a matching string, can be changed.
For example, you could give it a yellow
background-color (see comment).
*/
.hilite
{
color: red;
/* background-color: yellow; */
font-weight: bold;
}
/* Define column width;
Leave out specific column
for auto-sizing depending
on cell-contents:
*/
.column1
{
width: 100px;
}
.column2
{
width: 150px;
}
table
{
border-collapse: collapse;
border: 1px solid black;
}
td
{
text-align: left;
vertical-align: top;
padding: 6px;
border: 1px solid black;
}
/* Two row background-colors
to seperate rows; can be changed:
*/
tr td
{
background-color: #eee;
}
tr.alternateRow td
{
background-color: #ccc;
}
#excel
{
display: none;
}
--></style>
<script type="text/javascript"><!--
// Row and column separator
// characters, can be changed:
var rowSeparator = "~";
var columnSeparator = ";";
var resultsI = 0;
function searchData()
{
var data = getData();
var search = document.getElementById("searchString").value;
var arrRows = data.split(rowSeparator);
var rowsLength = arrRows.length;
var s = "";
search = replaceStr(search, " ", " ");
var phraseSearch = ( search.indexOf("\"") >= 0 );
arrHeader = arrRows[0].split(columnSeparator);
headerLength = arrHeader.length;
header = "";
for (var i = 0; i < headerLength; i++)
{
header += "<th>" + arrHeader[i] + "</th>";
}
header = "<tr>" + header + "</tr>";
if (phraseSearch)
{
resultsI = 0;
search = replaceStr(search, "\"", "");
s += getMatchingRows(arrRows, search);
if (s != "")
{
s = "<p>" + resultsI +
" results found for phrase \"" +
search + "\":</p> " +
"<table>" + header + s + "</table>";
}
}
else
{
var searchWords = search.split(" ");
var wordsLength = searchWords.length;
for (var i = 0; i < wordsLength; i++)
{
resultsI = 0;
if (searchWords[i] != "")
{
var thisS = getMatchingRows(arrRows,
searchWords[i]);
if (thisS != "")
{
thisS = "<p>" + resultsI +
" results found for \"" +
searchWords[i] + "\":</p> " +
"<table>" + header + thisS + "</table>";
s += thisS;
}
}
}
}
if (resultsI < 1)
{
// No results output
s = "<p><em>No results matching \"" +
search + "\" were found.</em></p>";
}
var outputLayer = document.getElementById("dataOutput");
outputLayer.innerHTML = s;
document.getElementById("h1data").innerHTML = "Results";
searchForm.style.display = "none";
newSearchLink.style.display = "block";
}
function newSearch()
{
var outputLayer = document.getElementById("dataOutput");
outputLayer.innerHTML = "";
searchForm.style.display = "block";
newSearchLink.style.display = "none";
document.getElementById("h1data").innerHTML = "Search Data";
}
function getMatchingRows(arrRows, search)
{
var sRow = "";
var isAlternate = false;
var rowsLength = arrRows.length;
var lowSearch = search.toLowerCase();
for (var i = 1; i < rowsLength; i++)
{
var row = arrRows[i];
if ( row.toLowerCase().indexOf(lowSearch) >= 0 )
{
// Construct a table row with matches
// to display later:
var classString = (isAlternate) ?
" class=\"alternateRow\"" : "";
sRow += "<tr" + classString + ">";
arrColumns = row.split(columnSeparator);
var columnLength = arrColumns.length;
for (var j = 0; j < columnLength; j++)
{
var column = arrColumns[j];
sRow += "<td class=\"column" + (j + 1) + "\">";
var rowDisplay = replaceStr(column,
search,
"<span class=\"hilite\">" + search +
"</span>");
sRow += rowDisplay;
sRow += "</td>";
}
sRow += "</tr>";
isAlternate = !isAlternate;
resultsI++;
}
}
return sRow;
}
function getData()
{
var excelLayer = document.getElementById("excel");
return excelLayer.firstChild.data;
}
function replaceStr(str, oldStr, newStr)
{
regExp = new RegExp(oldStr, "gi");
results = str.replace(regExp, newStr);
return results;
}
// --></script>
</head>
<body>
<h1 id="h1data">Search Data</h1>
<form id="searchForm">
<p>
Your query:
<input type="text" size="20"
name="searchString" id="searchString" />
<input type="text" name="suppressReturn"
style="display: none;" />
<input type="button" onclick="searchData()"
value="Search" />
</p>
</form>
<div id="dataOutput">
</div>
<div id="newSearchLink" style="display: none;">
<p>[<a href="javascript:newSearch()">New search ...</a>]</p>
</div>
<div id="excel">
Header 1;Header 2;Header 3~d;3;40~this;is a;test~this;is a
second;test~testing yet;again;...
</div>
<p>Version 2, Copyright © 2003 by Ken</p>
</body>
</html>
|
Request for Answer Clarification by
ken3141-ga
on
29 Jun 2003 22:24 PDT
j_phillipp-
Looks great. Would prefer that the highlighted answers to the search
are in the original case, but it's really not all that important.
We're just trying to get the functionality done.
Anyway, if you want to mod it great, otherwise, don't sweat it. I'm
going to go ahead and rate (and pay!). I'll repost as a question to
see if anyone can get it to work on a PPC. If not, oh well, it was
worth the risk.
Too bad Google Answers won't let us give personal specifics, or I
could tell you what we're doing with it. It's pretty interesting and
novel actually, although it might not seem like it without knowing
more details.
Ken
|
Request for Answer Clarification by
ken3141-ga
on
29 Jun 2003 23:31 PDT
I've now posted the follow up question at
http://answers.google.com/answers/main?cmd=threadview&id=223370
|
Clarification of Answer by
j_philipp-ga
on
30 Jun 2003 03:32 PDT
Hello Ken!
Thanks for rating and tip!
I'll be working on the improved highlightling and keep you updated
here. Also, I'll be checking out your new question.
Now you made me curious what you're doing with your application!
Philipp
|
Clarification of Answer by
j_philipp-ga
on
30 Jun 2003 03:52 PDT
----- New version below: --------------------------
----- Will match and highlight case-insensitive, --
----- keeping old text's case ---------------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>CSV Search</title>
<style><!--
body
{
background-color: white;
color: black;
font-family: arial, helvetica, sans-serif;
}
/* The result-found highlight style for
a matching string, can be changed.
For example, you could give it a yellow
background-color (see comment).
*/
.hilite
{
color: red;
/* background-color: yellow; */
font-weight: bold;
}
/* Define column width;
Leave out specific column
for auto-sizing depending
on cell-contents:
*/
.column1
{
width: 100px;
}
.column2
{
width: 150px;
}
table
{
border-collapse: collapse;
border: 1px solid black;
}
td
{
text-align: left;
vertical-align: top;
padding: 6px;
border: 1px solid black;
}
/* Two row background-colors
to seperate rows; can be changed:
*/
tr td
{
background-color: #eee;
}
tr.alternateRow td
{
background-color: #ccc;
}
#excel
{
display: none;
}
--></style>
<script type="text/javascript"><!--
// Row and column separator
// characters, can be changed:
var rowSeparator = "~";
var columnSeparator = ";";
var resultsI = 0;
function searchData()
{
var data = getData();
var search = document.getElementById("searchString").value;
var arrRows = data.split(rowSeparator);
var rowsLength = arrRows.length;
var s = "";
search = replaceStr(search, " ", " ");
var phraseSearch = ( search.indexOf("\"") >= 0 );
arrHeader = arrRows[0].split(columnSeparator);
headerLength = arrHeader.length;
header = "";
for (var i = 0; i < headerLength; i++)
{
header += "<th>" + arrHeader[i] + "</th>";
}
header = "<tr>" + header + "</tr>";
if (phraseSearch)
{
resultsI = 0;
search = replaceStr(search, "\"", "");
s += getMatchingRows(arrRows, search);
if (s != "")
{
s = "<p>" + resultsI +
" results found for phrase \"" +
search + "\":</p> " +
"<table>" + header + s + "</table>";
}
}
else
{
var searchWords = search.split(" ");
var wordsLength = searchWords.length;
for (var i = 0; i < wordsLength; i++)
{
resultsI = 0;
if (searchWords[i] != "")
{
var thisS = getMatchingRows(arrRows,
searchWords[i]);
if (thisS != "")
{
thisS = "<p>" + resultsI +
" results found for \"" +
searchWords[i] + "\":</p> " +
"<table>" + header + thisS + "</table>";
s += thisS;
}
}
}
}
if (resultsI < 1)
{
// No results output
s = "<p><em>No results matching \"" +
search + "\" were found.</em></p>";
}
var outputLayer = document.getElementById("dataOutput");
outputLayer.innerHTML = s;
document.getElementById("h1data").innerHTML = "Results";
searchForm.style.display = "none";
newSearchLink.style.display = "block";
}
function newSearch()
{
var outputLayer = document.getElementById("dataOutput");
outputLayer.innerHTML = "";
searchForm.style.display = "block";
newSearchLink.style.display = "none";
document.getElementById("h1data").innerHTML = "Search Data";
}
function getMatchingRows(arrRows, search)
{
var sRow = "";
var isAlternate = false;
var rowsLength = arrRows.length;
var lowSearch = search.toLowerCase();
for (var i = 1; i < rowsLength; i++)
{
var row = arrRows[i];
if ( row.toLowerCase().indexOf(lowSearch) >= 0 )
{
// Construct a table row with matches
// to display later:
var classString = (isAlternate) ?
" class=\"alternateRow\"" : "";
sRow += "<tr" + classString + ">";
arrColumns = row.split(columnSeparator);
var columnLength = arrColumns.length;
for (var j = 0; j < columnLength; j++)
{
var column = arrColumns[j];
sRow += "<td class=\"column" + (j + 1) + "\">";
var rowDisplay = replaceStr(column,
search,
"<span class=\"hilite\">" + search +
"</span>");
var rowDisplay = wrapString(column,
search,
"<span class=\"hilite\">",
"</span>");
sRow += rowDisplay;
sRow += "</td>";
}
sRow += "</tr>";
isAlternate = !isAlternate;
resultsI++;
}
}
return sRow;
}
function getData()
{
var excelLayer = document.getElementById("excel");
return excelLayer.firstChild.data;
}
function wrapString(sAll, sFind, sStart, sEnd)
{
var sAllLow = sAll.toLowerCase();
var sFindLow = sFind.toLowerCase();
var strPos = sAllLow.indexOf(sFindLow);
var isThere = (strPos >= 0);
var sNew = "";
if (isThere)
{
var sBefore = sAll.substring(0, strPos);
var sMiddle = sAll.substring(strPos, strPos + sFind.length);
var sAfter = sAll.substring(strPos + sFind.length);
sNew = sBefore + sStart + sMiddle + sEnd + sAfter;
}
else
{
sNew = sAll;
}
return sNew;
}
function replaceStr(str, oldStr, newStr)
{
regExp = new RegExp(oldStr, "gi");
results = str.replace(regExp, newStr);
return results;
}
// --></script>
</head>
<body>
<h1 id="h1data">Search Data</h1>
<form id="searchForm">
<p>
Your query:
<input type="text" size="20"
name="searchString" id="searchString" />
<input type="text" name="suppressReturn"
style="display: none;" />
<input type="button" onclick="searchData()"
value="Search" />
</p>
</form>
<div id="dataOutput">
</div>
<div id="newSearchLink" style="display: none;">
<p>[<a href="javascript:newSearch()">New search ...</a>]</p>
</div>
<div id="excel">
Header 1;Header 2;Header 3~d;3;40~this;is a;test~this;is a
second;test~testing yet;again;...
</div>
<p>Version 2.1, Copyright © 2003 by Ken</p>
</body>
</html>
|