...

View Full Version : Set the priority to all and not to the FIRST found



dododidi
07-23-2009, 10:15 PM
Hi everyone,

Venegal (Thx) wrote the majority of the following script and I must say , he did a great job:thumbsup:.
there are a few extensions to script that are needed.
I hope someone can help(if not himself).

the priority within the searched user words and the found content on the site have been set to "the first found" will be hilited. e.g:

1. the wonderfull holidays
2. Sunny holidays
3. holidays in Spain

No.1 (div) only would be hilited if the user search words were e.g: "sunny holidays in Spain".
So this is where I need help: I need the priority to be set so that all three divs would be hilited if the word "holidays" (for example) were searched for.

I hope I am not asking for too much.

Thx and greets to Venegal and Old Pedant.

the Script:


function toggle(id, status){
document.getElementById(id).style.visibility = status;
}
function populateSearchField(){
var specialChars = "\\.+*?[^]$(){}=!<>|:,-=/";
var ignoreList = ["a", "the"];

var i, j, searchFld, keywords;
if (!(searchFld = document.getElementsByName('formcontent')[0])) return;
if (!(keywords = document.referrer.match(/[pq]=(.*?)&/))) return;
var preg_quote = function(str){return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!<>\|\:])/g, "\\$1");}
keywords = decodeURIComponent(keywords[1]).replace(new RegExp('[' + preg_quote(specialChars) + ']', 'g'), ' ').split(/[\+ ]/);
for (i = 0; i < keywords.length; i++){
for (j = 0; j < ignoreList.length; j++) if (!keywords[i] || (keywords[i] == ignoreList[j])) {
keywords.splice(i--, 1);
break;
}
}
searchFld.value = keywords.join(' ');
}

function keywordMatch(keywords, text) {
var result = 0;
for (var i in keywords) {
if (text.match(new RegExp("(^| )" + keywords[i] + "( |$)", "i"))) {
result++;
};
}
return result;
}

function showTextContent() {
var i, bestMatch, maxNumberOfMatches = 0;
var divs = document.getElementById("ts-1").getElementsByTagName('div');
var keywords = document.getElementsByName('formcontent')[0].value.split(' ');
for (i = 0; i < divs.length; i++) {
var div = divs[i];
var divcontent = div.lastChild.nodeValue;
if ((numberOfMatches = keywordMatch(keywords, divcontent)) > maxNumberOfMatches) {
maxNumberOfMatches = numberOfMatches;
bestMatch = div;
}
}
if (bestMatch)
bestMatch.onmouseover();

else {

toggle('fo-test200','visible');
}
}

window.onload = function(){
populateSearchField();
showTextContent();
}

venegal
07-23-2009, 11:35 PM
Is that really how it works? This part here

if ((numberOfMatches = keywordMatch(keywords, divcontent)) > maxNumberOfMatches) {
maxNumberOfMatches = numberOfMatches;
bestMatch = div;
}

suggests that not the first match is used, but the one where the most words match.

If you want to highlight all the matching divs, try changing the showTextContent function to something like this:


function showTextContent() {
var i, matches = [];
var div, divcontent, divs = document.getElementById("ts-1").getElementsByTagName('div');
var keywords = document.getElementsByName('formcontent')[0].value.split(' ');

for (i = 0; i < divs.length; i++) {
div = divs[i];
divcontent = div.lastChild.nodeValue;
if (keywordMatch(keywords, divcontent)) {
matches.push(div);
}
}
if (matches[0])
for (i = 0; i < matches.length; i++) {
matches[i].onmouseover();
}
else {
toggle('fo-test200', 'visible');
}
}

dododidi
07-24-2009, 12:47 AM
hey Vevegal,
nice to here from you again,


it didn't work, in fact its exactly the same as before, it simply take the first option

kind thx for your help

venegal
07-24-2009, 12:31 PM
Your secrecy doesn't do you much good.

Here's an example of that exact same code you got there, the only changes being that the keywords are coming from a DOM element rather than the referrer, and that there is no highlighting but the results are simply printed out. You can clearly see that it is working as expected:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>keyword matches</title>


<script type = "text/javascript">
function toggle(id, status){
document.getElementById(id).style.visibility = status;
}
function populateSearchField(){
var specialChars = "\\.+*?[^]$(){}=!<>|:,-=/";
var ignoreList = ["a", "the"];

var i, j, searchFld, keywords;
if (!(searchFld = document.getElementsByName('formcontent')[0])) return;
//if (!(keywords = document.referrer.match(/[pq]=(.*?)&/))) return;
keywords = ['', document.getElementById('keywords').value];
var preg_quote = function(str){return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!<>\|\:])/g, "\\$1");}
keywords = decodeURIComponent(keywords[1]).replace(new RegExp('[' + preg_quote(specialChars) + ']', 'g'), ' ').split(/[\+ ]/);
for (i = 0; i < keywords.length; i++){
for (j = 0; j < ignoreList.length; j++) if (!keywords[i] || (keywords[i] == ignoreList[j])) {
keywords.splice(i--, 1);
break;
}
}
searchFld.value = keywords.join(' ');
}

function keywordMatch(keywords, text) {
var result = 0;
for (var i in keywords) {
if (text.match(new RegExp("(^| )" + keywords[i] + "( |$)", "i"))) {
result++;
};
}
return result;
}

function showTextContent() {
var i, bestMatch, maxNumberOfMatches = 0;
var divs = document.getElementById("ts-1").getElementsByTagName('div');
var keywords = document.getElementsByName('formcontent')[0].value.split(' ');
for (i = 0; i < divs.length; i++) {
var div = divs[i];
var divcontent = div.lastChild.nodeValue;
if ((numberOfMatches = keywordMatch(keywords, divcontent)) > maxNumberOfMatches) {
maxNumberOfMatches = numberOfMatches;
bestMatch = div;
}
}
if (bestMatch)
// bestMatch.onmouseover();
document.getElementById('result').innerHTML = 'best match: "' + bestMatch.innerHTML + '" with ' + maxNumberOfMatches + ' matches';

else {

// toggle('fo-test200','visible');
document.getElementById('result').innerHTML = 'no matches';
}
}

window.onload = function(){
populateSearchField();
showTextContent();
}

</script>

</head>

<body>

Keywords:<br />
<input type="text" id="keywords" value="the sunny holidays in Spain" /><br /><br />

Keywords without ignored words:<br />
<input type="text" name="formcontent" /><br /><br />


The divs:<br />
<div id="ts-1">
<div>the wonderful holidays</div>
<div>Sunny holidays</div>
<div>holidays in Spain</div>
</div>
<br />
<div id="result"></div>
</body>

</html>

So, whatever isn't working, it's not to be found in the snippet you posted, and unless you are willing to show some more there's nothing more I can do.

dododidi
07-24-2009, 09:24 PM
Hi Venegal,
thx for the help...

the second script that you sent me works well see below.

function showTextContent() {
var i, matches = [];
var div, divcontent, divs = document.getElementById("ts-1").getElementsByTagName('div');
var keywords = document.getElementsByName('formcontent')[0].value.split(' ');

for (i = 0; i < divs.length; i++) {
div = divs[i];
divcontent = div.lastChild.nodeValue;
if (keywordMatch(keywords, divcontent)) {
matches.push(div);
}
}
if (matches[0])
for (i = 0; i < matches.length; i++) {
matches[i].onmouseover(toggle('fo-test2000','visible')); //--------------------mistake here
}
else {
toggle('fo-test200', 'visible');
}
}
All divs are hilited
How can I integrate the:

document.getElementById('fo-test2000').innerHTML = maxNumberOfMatches + " matches"; //-------------------------output code
into the script ?

thx a bunch

venegal
07-24-2009, 09:59 PM
Well how do you want it to be integrated? When only the best match was highlighted, it showed the number of matched keywords of that best match. Now that you highlight a bunch of divs, what dou you want to be shown?

dododidi
07-24-2009, 10:14 PM
in the first script that you sent me, the green Div at the top of the page of showed for example " 3 Matches"
the second script doesn't do that, and as the divs are only hilited, i would also like to show the user why they are hilited.

added:

if you take a look again at the vid6back1.html and the vid6bak10.html then you will see what I mean

venegal
07-24-2009, 10:35 PM
The second script doesn't do that because I don't know what exactly you want it to show. Say, 3 divs are highlighted. What do you want the green div to show? The number of keyword matches of the one div that matched best? Or the number of matching divs? Or the number of keyword matches of each individual matched div when hovering over them?

And how exactly do you want to show the user why they are highlighted?

dododidi
07-24-2009, 10:42 PM
sorry it appears that I am confusing you.

I only want the number of matching divs to be shown in the green box.
the user can already see directly below that box which words he used

venegal
07-24-2009, 11:17 PM
Oh, that's not too hard:


function showTextContent(){
var i, matches = [];
var div, divcontent, divs = document.getElementById("ts-1").getElementsByTagName('div');
var keywords = document.getElementsByName('formcontent')[0].value.split(' ');

for (i = 0; i < divs.length; i++) {
div = divs[i];
divcontent = div.lastChild.nodeValue;
if (keywordMatch(keywords, divcontent)) {
matches.push(div);
}
}
if (matches[0]) {
document.getElementById('fo-test2000').innerHTML = matches.length + " matches";
for (i = 0; i < matches.length; i++) {
matches[i].onmouseover(toggle('fo-test2000', 'visible'));
}
}
else {
toggle('fo-test200', 'visible');
}
}

Lost a few words during copypasting. Fixed now.

dododidi
07-24-2009, 11:34 PM
hmmm strange,

the green div appears but its empty

dododidi
07-24-2009, 11:50 PM
Brilliant, thx a lot Venegal

I'll be in touch

dododidi
07-25-2009, 12:23 AM
Damm it,
I've been looking at the site in Moz. FF and everthing was just fine, then I had a look in IE7 and nothing works in there.

before using the new addons in the script it was ok

take a look at vid6bak10.html

any ideas? :(

I have seen many complaints about .innerHTML

hier is the complete script:

function disappear(){
window.setTimeout("document.getElementById('gaga').style.display='none';",9000);
window.setTimeout("document.getElementById('ts-1').style.visibility='visible';",9500);
return false;

}

disappear(); {
seeme();{

}
}

function toggle(id, status){
document.getElementById(id).style.visibility = status;
}
function populateSearchField(){
var specialChars = "\\.+*?[^]$(){}=!<>|:,-=/";
var ignoreList = ["a", "the"];

var i, j, searchFld, keywords;
if (!(searchFld = document.getElementsByName('formcontent')[0])) return;
if (!(keywords = document.referrer.match(/[pq]=(.*?)&/))) return;
keywords = ['', document.getElementById('keywords').value];
var preg_quote = function(str){return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!<>\|\:])/g, "\\$1");}
keywords = decodeURIComponent(keywords[1]).replace(new RegExp('[' + preg_quote(specialChars) + ']', 'g'), ' ').split(/[\+ ]/);
for (i = 0; i < keywords.length; i++){
for (j = 0; j < ignoreList.length; j++) if (!keywords[i] || (keywords[i] == ignoreList[j])) {
keywords.splice(i--, 1);
break;
}
}
searchFld.value = keywords.join(' ');
}

function keywordMatch(keywords, text) {
var result = 0;
for (var i in keywords) {
if (text.match(new RegExp("(^| )" + keywords[i] + "( |$)", "i"))) {
result++;
};
}
return result;
}

function showTextContent() {
var i, matches = [];
var div, divcontent, divs = document.getElementById("ts-1").getElementsByTagName('div');
var keywords = document.getElementsByName('formcontent')[0].value.split(' ');

for (i = 0; i < divs.length; i++) {
div = divs[i];
divcontent = div.lastChild.nodeValue;
if (keywordMatch(keywords, divcontent)) {
matches.push(div);
}
}
if (matches[0]) {
document.getElementById('fo-test2000').innerHTML = matches.length + " matches / Treffer";
for (i = 0; i < matches.length; i++) {
matches[i].onmouseover(toggle('fo-test2000', 'visible'));
}
}
else {
toggle('fo-test200', 'visible');
}
}



populateSearchField();
showTextContent();

venegal
07-25-2009, 12:45 AM
For starters


{
seeme();{

}
}

seeme isn't defined. And what about those object literals? That doesn't make much sense.

dododidi
07-25-2009, 12:57 AM
well I was sure you would find something in there that was wrong:)
I wrote thos scripts for the preloader and put them in there without window.onload simply because they loaded after the page, taking up to 20 seconds. So that was just trial and error and it worked perfectly.


seeme();{

}
ok i've taken that out, I seemed to have just forgotten those entries

dododidi
07-25-2009, 01:12 AM
I am also getting this in the ff console:

Fehler: document.getElementById("ts-1") is null
Quelldatei: http://bbccbbccbak10.js
Zeile: 46

what ever that means

venegal
07-25-2009, 02:14 AM
It means that for some reason you changed the code in your first post from running onload to running whenever it feels like. Change that back.

dododidi
07-25-2009, 10:56 AM
Still no change with :confused:



window.onload = function(){
populateSearchField();
showTextContent();
}

venegal
07-25-2009, 12:08 PM
The error is gone; you may have a cache issue.

dododidi
07-25-2009, 12:23 PM
Hello again Venegal,
I am still getting the same screwed up results in IE7, nothing works at all, but in FF it perfect.

1. no matches are found in IE7,or more to the point they are not hilited and the green div does not appear...see vid6bak10.html

2. onmouseover all the divs light up and don't disappear on mouseout

venegal
07-25-2009, 02:11 PM
Well, it's definitely not the same error as before.

The one showing up now is caused by some of your divs not having any text, so keywordMatch is throwing an error. Either give all your divs text, or check if it's null before trying to compare.

dododidi
07-25-2009, 02:41 PM
thx, as always you're right.
I just put some text in there et voila.

Now I don't know if this has to do with my missing Ram, they went defect 2 weeks ago, so I am only running till next week on 1GB :( and in IE7 it is now, (with the new script) running extremely slow on the onmouseover.
my thought are: what if others only have IGB(which I doubt very much, but it is possible)

do you have any ideas how I might speed this up a bit in IE7, FF's reaction is milliseconds and IE7 5-6 seconds longer. it sucks

venegal
07-25-2009, 11:36 PM
Well I can't really tell since it's working alright on my machine, but IE is known to have its issues, and with those hundred flash animations your site is quite the CPU hog.

dododidi
07-26-2009, 12:52 AM
strange that you say its a cpu hog when in FF everything works in milliseconds, those preloaders are "only" 1.9Kb.
Does IE handle the cache or windows and how does ff do it?

I realise that the script is now doing more than it did initially, but the flash preloaders were heavier,about 5Kb so I reduced them today and it was still faster than it is now; I can only presume that the script is stressing the cpu .


ADDED:
I surpose I should wait till I have my ram again, but that wouldn't really be the answere for anyone with e.g 1GB of ram or a weak cpu.

you used .innerhtml and as far as I have read today, going by the dom would take longer to write but I could't find out whether the actual processing would be faster or slower

venegal
07-26-2009, 02:19 AM
You don't have to worry about the size of your scripts; those few kilobytes are peanuts and have nothing to do with CPU load during the execution of your site.

Also, caching has nothing to do with it.

As for the innerHTML: Using DOM methods the code would be cleaner, but seeing all that code duplication and inline event handlers you are using, you probably don't care much about clean code. Also, that innerHTML should be called only once when the page is loaded and the number of matches is shown, so performance wise that's nothing you have to care about either.

Now regarding that "should": I just saw that you are calling showTextContent within the onmouseout handlers of each and every one of your divs. Why would you do that? Every invocation goes through all those hundred divs again and checks them for keyword matches, and there goes your CPU.

If you don't want those initially activated divs to change back to deactivated when hovered, the way to go is remove those handlers when they are being activated, and not check all of them again when one is hovered.

dododidi
07-26-2009, 02:43 AM
should be called only once when the page is loaded

correct, with exeption that if the user would enter a new search whilst on my page, then he could search my site in real time.


Now regarding that "should": I just saw that you are calling showTextContent within the onmouseout handlers of each and every one of your divs. Why would you do that? Every invocation goes through all those hundred divs again and checks them for keyword matches, and there goes your CPU.

the reason for that, is when he leaves the div , his original search words would still be relevant and the div hilited, otherwise by 100 divs he would have problems finding that x-hilited div again.


If you don't want those initially activated divs to change back to deactivated when hovered, the way to go is remove those handlers when they are being activated, and not check all of them again when one is hovered.

I dont believe I understood that last one. the way to go is remove those handlers when they are being activated

venegal
07-26-2009, 03:19 AM
the reason for that, is when he leaves the div , his original search words would still be relevant and the div hilited, otherwise by 100 divs he would have problems finding that x-hilited div again.


That's what I meant above, if you want the highlighted divs to still be highlighted when the user "leaves" them (I suppose by "leaving" you mean triggering the onmouseout event) it would be really silly to go through that whole keyword checking ordeal again. You should just remove that event handler ( = make the onmouseout not work any more for those divs, so they stay highlighted no matter what).

If that's in fact what you mean, why don't go try and do that one yourself and show back with some code you've written.

dododidi
07-26-2009, 03:34 AM
:) :) :) yes that is what I mean.

how cruel can a teacher be.

I'll do my best, but I believe I'll just be waisting my time and yours :( I just don't understand enough about JS

dododidi
07-26-2009, 04:26 AM
ok besides the fact that it 5.15 in the morning and I am pretty tired, I have found this:

function showDiv(obj){
obj.onmouseover=null;
obj.onmouseout=null;
}

but please dont ask me how to integrate it...I havent got a clue... I NEED YOUR HELP,

and time is against me Venegal, believe me, I speak and write 4 languages almost fluently but JS isn't one of them.

dododidi
07-26-2009, 12:29 PM
if I am thinking correctly, then I would have to put this
showDiv(obj)
once again in every relevant div, which isn't tidy at all.


but seeing all that code duplication and inline event handlers you are using, you probably don't care much about clean code

well yes I do care, but if one hasn't got a clue how to do it, there is only improvisation left over.

venegal
07-26-2009, 12:34 PM
Alright, within your showTextContent function, you got that loop here

for (i = 0; i < matches.length; i++) {
matches[i].onmouseover();
}

which highlights the matching divs. Now after highlighting them, you just remove those handlers, so they stay highlighted. It will look something like this:


for (i = 0; i < matches.length; i++) {
matches[i].onmouseover();
matches[i].onmouseover = null;
matches[i].onmouseout = null;
}


Now, if you have any more questions, please feel free to ask, but I might not be the one answering them. I have quite a workload myself, and while I do find it relaxing to help out people eager to learn during work breaks, this feels more like I'm the one responsible for maintaining a buggy application.

dododidi
07-26-2009, 01:27 PM
OK then thx for your help writing this "buggy application".

if I had known that that is how you think about it then I would not have asked for help on this basis, rather I would have asked how one could do it better, but seeing you (as a master of JS) helped me, I was assuming that I was on the right road to getting the project finished.
Never the less, I did learn quite a bit, especially thru your last post.

venegal
07-26-2009, 02:32 PM
That's quite alright; I enjoyed helping you up until now, at the moment I just don't have a lot of time though, so I have to prioritize, and there are problems to be solved that are just a tad more enjoyable than yours. To be perfectly honest, even though that will probably make me look like a karma whore, my status in these forums is important to me, and, for the amount of work put in, there are threads with a better thankedposts/posts ratio to be had.

As for the other stuff: I do think you are on the right road. The scripts look ok; it's the HTML that makes this a bit of a mess. I suppose all those hundred duplicated inline event handlers are generated by your server side code, so it's not really a maintainability issue, but still you'd be better off assigning them in your Javascript.

As for the "buggy": You said yourself that you are not all that proficient in JS and don't have the time to read up, but I think you are losing more time to that game of ping pong we are playing here than it would take you to do the basic reading that would enable you to fix many of the bugs yourself.

dododidi
07-26-2009, 03:07 PM
It will be much easier for me now to mess arround with the script and integrate the messed up HTML part within the script, knowing exactly where I want to go and combined with the Knowledge that you have given to me in this game of Ping Pong.

thx for your time and patience



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum