[js] data doorzoeken (Arrays, objects)

Pagina: 1
Acties:

  • r0bert
  • Registratie: September 2001
  • Laatst online: 11-08 16:19
Ik ben bezig met een scriptje, waar ik de user de mogelijkheid wil bieden om realtime de data te doorzoeken. De data wordt via php uit een mySQL database gelezen en in de juiste arrays/objecten geplaats, maar om het even duidelijk te houden, wou ik in dit voorbeeldje even gebruik maken van wat (statische) variabelen.

de vorm waarin de data opgeslagen wordt
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
function fnObject(argNaam, argLeeftijd, argPlaats, argId) {
   this.naam = argNaam;
   this.leeftijd = argLeeftijd;
   this.woonplaats = argPlaats;
   this.id = argId;
}

data = new Array();
data[0] = new Array();

data[0][1] = new Array();
data[0][1][1] = new fnObject('Jaap',34,'Amsterdam',1);
data[0][1][2] = new fnObject('Jan',32,'Amsterdam',2);
data[0][1][3] = new fnObject('Jeroen',38,'Amersfoort',3);
data[0][1][4] = new fnObject('Jerommeke',24,'Gouda',4);
data[0][1][5] = new fnObject('Henk',41,'Utrecht',5);

data[0][2] = new Array();
data[0][2][1] = new fnObject('Flip',52,'Zwolle',6);
data[0][2][2] = new fnObject('Frits',23,'Zwolle',7);
data[0][2][3] = new fnObject('Johan',27,'Enkhuizen',8);
data[0][2][4] = new fnObject('Dirk',23,'Dedemsvaart',9);

data[0][3] = new Array();
data[0][3][1] = new fnObject('Pieter',20,'Leeuwaren',10);
data[0][3][2] = new fnObject('Tomas',30,'Den Bosch',11);
data[0][3][3] = new fnObject('Simon',27,'Maastricht',12);

data[1] = new Array();
data[1][1] = new Array();
data[1][1][1] = new fnObject('Klaas',20,'Leeuwarden',13);
data[1][1][2] = new fnObject('Bert',30,'Saaizeg',14);
data[1][1][3] = new fnObject('Willem',24,'Verweg',15);
data[1][1][4] = new fnObject('Karel',25,'Zevenhuizen',16);

data[1][2] = new Array();
data[1][2][1] = new fnObject('Simon',32,'Groningen',17);
data[1][2][2] = new fnObject('Bert',30,'Lutjelollum',18);

data[2] = new Array();
data[2][1] = new Array();
data[2][1][1] = new fnObject('Kees',45,'Moddergat',19);
data[2][1][2] = new fnObject('Sjakie',34,'Beilen',20);

data[2][2] = new Array();
data[2][2][1] = new fnObject('Leo',46,'Weesp',21);
data[2][2][2] = new fnObject('Jacob',32,'Wezep',22);

Nu moet er gezocht kunnen worden op:

- het getal uit de eerste kolom..
- het getal uit de tweede kolom..
- het getal uit de derde kolom..
- het object .naam
- het object .leeftijd
- het object .woonplaats
- het object .id

Het is de bedoeling dat later de mogelijkheid om op meerdere gecombineerde punten kan worden gezocht, maar voor nu maar even 1 tegelijk.

Een volgende stap lijkt me het opzetten van een simpel zoekformuliertje:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<form name="frmZoeken">
  <fieldset><legend>Zoeken</legend>
    kolom 1: 
    <input type="radio" name="radZoekenOp" value="Kolom1" />
    <input type="text" name="txtKolom1" /><br />
    
    kolom 2:
    <input type="radio" name="radZoekenOp" value="Kolom2" />
    <input type="text" name="txtKolom2" /><br />
    
    kolom 3:
    <input type="radio" name="radZoekenOp" value="Kolom3" />
    <input type="text" name="txtKolom3" /><br />
    
    naam:
    <input type="radio" name="radZoekenOp" value="Naam" />
    <input type="text" name="txtNaam" /><br />
    
    leeftijd:
    <input type="radio" name="radZoekenOp" value="Leeftijd" />
    <input type="text" name="txtLeeftijd" /><br />

    woonplaats:
    <input type="radio" name="radZoekenOp" value="Woonplaats" />
    <input type="text" name="txtWoonplaats" /><br /><br />
    
    id:
    <input type="radio" name="radZoekenOp" value="Id" />
    <input type="text" name="txtId" /><br /><br />

    <input type="button" name="btnZoek" value="Nu zoeken.." 
         onClick="fnSearch(data, document.forms['frmZoeken'].elements['radZoekenOp'].value);" />
  </fieldset>
</form>


code:
1
2
3
4
5
6
7
8
9
10
fnSearch(parameter 1, parameter 2)

parameter 1 = de datasource waarin hij gaat zoeken.. vb:
          -  data
          of data[1]
          of data[2][1]
parameter 2 = hetgeen waar hij op zoekt.. vb:
          - kolom1
          of woonplaats
          of naam

Vervolgens een lijkt me het een beste om een recursieve functie, of iets wat daar op lijkt te gebruiken, ivm het doorlopen van de data bestaand uit arrays met verschillende lengtes.

Ik ben zelf al erg lang aan het klooien geweest, maar kom er gewoon niet uit en heb het idee dat ik mezelf een beetje aan het vastwerken ben :)

Even een opzetje van mijn kant, voor zover ik kom (misschien is het wel helemaal verkeerd, maar wil toch iets laten zien)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function fnSearch(argDataSource, argSearchFor) {
   
   // ga door iedere 'child'/index van de datasource
   for (strVar in argDataSource) {

    // als het type variabele een Array is, heeft het nog geen objecten. Dus als 
    // we niet op kolom1, kolom2 of kolom3 zoeken, hebben we hier nog nix 
    // aan.. dus moeten we nog 1 level dieper
    if ((argDataSource[strVar].constructor.toString().match('Array') == 'Array') && 
         (!argSearchFor.indexOf('kolom'))) fnSearch(argDataSource[strVar], argSearchFor);
    
    // als we op kolom* zoeken, en de waarde van het textfield is 
    //gelijk aan die van de huidige index >>

    // als we niet op kolom* zoeken, maar op een andere factor
    // vergelijk het bijbehorende object met de waarde van het 
    // bijbehorende textfield >>
      else if (argSearchFor.indexOf('kolom')) {
      if (strVar == document.forms['frmZoek'].elements['txt'+ argSearchFor].value) 
          alert(gevonden: '+ strVar);
    } else if (eval('argDataSource[strVar].' + argSearchFor) == document.forms['frmZoek'].elements['txt'+ argSearchFor].value) 
          alert('gevonden: '+ strVar);
   }
}

Typfouten voorbehouden :)

Het scriptje zou verder niet echt nuttige informatie weergeven WAAR hij de data heeft gevonden, maar het is in ieder geval een begin..

Ik hoor graag ideeën, commentaar, verbeteringen of al het andere wat mij op (de goede :9) weg kan helpen..

Het is volgens mij nog al een lap tekst geworden, dus als je zo behulpzaam bent geweest om alles te lezen! Dankjewel voor de moeite iig :P! Toffe gozer/meid die je bent! :P

  • oh,when?
  • Registratie: April 2000
  • Niet online

oh,when?

...

Wat jij eigenlijk wil is een Hash Table in Javascript ( ook wel Hash mapping genoemd )

:)

"You're only as good, as what you did last week."


  • sjroorda
  • Registratie: December 2001
  • Laatst online: 09:47
Waarom niet, als je toch al met MySQL werkt, eerst de zoekopdracht geven en dan pas de db-entries ophalen? Ofwel niet zelf een zoekfunctie schrijven, maar dit overlaten aan de MySQL-features?

Ook een mogelijkheid is het doorzoeken met PHP dus al serverside.

Dit heeft ook nog andere voordelen: als je op 'pietje' zoekt komt-ie niet ook aandragen met 'jantje', scheelt een hoop codeerwerk, etc..

Of zie ik het te simpel en wil jij iets veel geavanceerders bereiken (want zo te zien heb je er al wel over nagedacht :)).

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 29-08 19:47

Bosmonster

*zucht*

Wat je ook kunt doen is omgekeerde zoek-index maken bij creatie, waarbij je een array vult met als index de zoekwoorden en als inhoud een (array van) object(en).

Wat oh,when? zegt dus, een soort Hashmap. Maar een recursieve functie moet ook niet al te ingewikkeld zijn, alleen zul je voor iedere zoek-eigenschap een losse functie moeten schrijven.

  • r0bert
  • Registratie: September 2001
  • Laatst online: 11-08 16:19
sjroorda:
Waarom niet, als je toch al met MySQL werkt, eerst de zoekopdracht geven en dan pas de db-entries ophalen? Ofwel niet zelf een zoekfunctie schrijven, maar dit overlaten aan de MySQL-features?
[..]
Ik wil 't juist via javascript doen, omdat dat sneller is en minder load veroorzaakt. Ook wil ik de functie(s) direct gaan gebruiken bij het weergeven van data in de interface, dus niet als daadwerkelijk zoekfunctie, maar voor het weergeven voor specifieke data.

vb:
code:
1
2
3
4
5
6
User klikt op '1' in kolom1
 alle kolom2 items komen te voorschijn onder kolom1
User klikt op '2'in kolom1
 alle kolom2 items komen te voorschijn onder kolom1
  User klikt op '1' in kolom2
    alle kolom3 items komen te voorschijn

Het is een beetje een sterk versimpelt idee, dus misschien niet helemaal 100% duidelijk waarom ik het nou persé via javascript wil. Maar dat werkt gewoon het beste. En het lijkt me uberhaupt niet onmogelijk in javascript, dus waarom zou ik dan mySQL gebruiken ?

  • r0bert
  • Registratie: September 2001
  • Laatst online: 11-08 16:19
Ok.. Ik heb het geheel nu aardig werkend. Heb nog wel naar Hash Tables en mapping gezocht, maar kon er niet echt duidelijk uit worden. (Vond allerlei scriptjes waarvan ik niet wist wat ik er nou mee moest etc :S)

Dit is 't script dat ik nu heb.. schrik niet van de grootte :)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<html>
<head>
<script language="JavaScript" type="text/javascript">
arrResult = new Array();

function fnObject(argNaam, argLeeftijd, argPlaats, argId) {
   this.naam = argNaam;
   this.leeftijd = argLeeftijd;
   this.woonplaats = argPlaats;
   this.id = argId;
}

function fnResult(argKol1, argKol2, argKol3, argRefId) {
    this.kolom1 = argKol1;
    this.kolom2 = argKol2;
    this.kolom3 = argKol3;
    this.refId = argRefId;
}

data = new Array();
data[0] = new Array();

data[0][1] = new Array();
data[0][1][1] = new fnObject('Jaap',34,'Amsterdam',1);
data[0][1][2] = new fnObject('Jan',32,'Amsterdam',2);
data[0][1][3] = new fnObject('Jeroen',38,'Amersfoort',3);
data[0][1][4] = new fnObject('Jerommeke',24,'Gouda',4);
data[0][1][5] = new fnObject('Henk',41,'Utrecht',5);

data[0][2] = new Array();
data[0][2][1] = new fnObject('Flip',52,'Zwolle',6);
data[0][2][2] = new fnObject('Frits',23,'Zwolle',7);
data[0][2][3] = new fnObject('Johan',27,'Enkhuizen',8);
data[0][2][4] = new fnObject('Dirk',23,'Dedemsvaart',9);

data[0][3] = new Array();
data[0][3][1] = new fnObject('Pieter',20,'Leeuwaren',10);
data[0][3][2] = new fnObject('Bert',30,'Den Bosch',11);
data[0][3][3] = new fnObject('Simon',27,'Maastricht',12);

data[1] = new Array();
data[1][1] = new Array();
data[1][1][1] = new fnObject('Klaas',20,'Leeuwarden',13);
data[1][1][2] = new fnObject('Bert',30,'Saaizeg',14);
data[1][1][3] = new fnObject('Willem',24,'Verweg',15);
data[1][1][4] = new fnObject('Karel',25,'Zevenhuizen',16);

data[1][2] = new Array();
data[1][2][1] = new fnObject('Simon',32,'Groningen',17);
data[1][2][2] = new fnObject('Bert',30,'Lutjelollum',18);

data[2] = new Array();
data[2][1] = new Array();
data[2][1][1] = new fnObject('Kees',45,'Moddergat',19);
data[2][1][2] = new fnObject('Sjakie',34,'Beilen',20);

data[2][2] = new Array();
data[2][2][1] = new fnObject('Leo',46,'Weesp',21);
data[2][2][2] = new fnObject('Jacob',32,'Wezep',22);

function fnSearch(argDataSource, argSearchFor, arg1, arg2, arg3) {

   // ga door iedere 'child'/index van de datasource
   for (strVar in argDataSource) {
   
    // als het type variabele een Array is, heeft het nog geen objecten. Dus als 
    // we niet op kolom1, kolom2 of kolom3 zoeken, hebben we hier nog nix 
    // aan.. dus moeten we nog 1 level dieper

    if ((argDataSource[strVar].constructor.toString().match('Array') == 'Array') && (!argSearchFor.indexOf('Kolom') > -1)) {
        if (arg1) fnSearch(argDataSource[strVar], argSearchFor, arg1, strVar);
        else fnSearch(argDataSource[strVar], argSearchFor, strVar);
    }
    
    // als we op kolom* zoeken, en de waarde van het textfield is 
    // gelijk aan die van de huidige index >>
     
     else if ((argSearchFor.indexOf('Kolom') > -1) && (arg1) && (arg2)) {
         if ((argSearchFor = 'Kolom1') && (arg1 == document.getElementById('txt'+ argSearchFor).value))
            arrResult[++arrResult.length] = new fnResult(arg1, arg2, strVar, eval('argDataSource[strVar]').id);
         else if ((argSearchFor = 'Kolom2') && (arg2 == document.getElementById('txt'+ argSearchFor).value)) 
            arrResult[++arrResult.length] = new fnResult(arg1, arg2, strVar, eval('argDataSource[strVar]').id);
         else if ((argSearchFor = 'Kolom3') && (strVar == document.getElementById('txt'+ argSearchFor).value)) 
            arrResult[++arrResult.length] = new fnResult(arg1, arg2, strVar, eval('argDataSource[strVar]').id);
    
    // als we niet op kolom* zoeken, maar op een andere factor
    // vergelijk het bijbehorende object met de waarde van het 
    // bijbehorende textfield >>
    } else if (eval('argDataSource[strVar].' + argSearchFor.toLowerCase()) == document.getElementById('txt'+ argSearchFor).value) 
           arrResult[++arrResult.length] = new fnResult(arg1, arg2, strVar, eval('argDataSource[strVar]').id);
   }
}

function fnRadioValue(argWhich) {
    for (i = 0; i < document.forms['frmZoeken'].elements[argWhich].length; i++) {
        if (document.forms['frmZoeken'].elements[argWhich][i].checked == true)
            return document.forms['frmZoeken'].elements[argWhich][i].value;
    }
}

function fnSResult(arrResult) {
    for (strIets in arrResult)
            alert('kolom 1: '+ arrResult[strIets].kolom1 +
                '\nkolom 2: '+ arrResult[strIets].kolom2 +
                '\nkolom 3: '+ arrResult[strIets].kolom3 +
                '\nNaam: '+ data[arrResult[strIets].kolom1][arrResult[strIets].kolom2][arrResult[strIets].kolom3].naam);
}

</script>

</head>

<body>

<form name="frmZoeken">
  <fieldset><legend>Zoeken</legend>
    kolom 1: 
    <input type="radio" name="radZoekenOp" value="Kolom1" />
    <input type="text" name="txtKolom1" /><br />
    
    kolom 2:
    <input type="radio" name="radZoekenOp" value="Kolom2" />
    <input type="text" name="txtKolom2" /><br />
    
    kolom 3:
    <input type="radio" name="radZoekenOp" value="Kolom3" />
    <input type="text" name="txtKolom3" /><br />
    
    naam:
    <input type="radio" name="radZoekenOp" value="Naam" />
    <input type="text" name="txtNaam" /><br />
    
    leeftijd:
    <input type="radio" name="radZoekenOp" value="Leeftijd" />
    <input type="text" name="txtLeeftijd" /><br />
    woonplaats:
    <input type="radio" name="radZoekenOp" value="Woonplaats" />
    <input type="text" name="txtWoonplaats" /><br /><br />
    
    id:
    <input type="radio" name="radZoekenOp" value="Id" />
    <input type="text" name="txtId" /><br /><br />

    <input type="button" name="btnZoek" value="Nu zoeken.." 
         
     onClick="arrResult.length = 0; fnSearch(data, fnRadioValue('radZoekenOp')); fnSResult(arrResult);" />
  </fieldset>
</form>

</body>
</html>

Online @ http://www.sovenewmedia.nl/gathering.tweakers.net/voorbeeld.html

Alleen zit er ergens nog 1 lek in.. Als je meerdere keren achter elkaar een zoekactie uit wilt voeren, komt het scriptje in de knoei te zitten. Ik denk dat het komt door dit nogal vage stukje code:
code:
1
arrResult.length = 0;

Op deze manier probeer ik de Array te legen (gevonden via de search), maar ik heb het vermoeden dat dit niet helemaal lekker werkt :S

Weet iemand hoe ik dit op kan lossen.. of als het hier niet aan ligt, waar het dan wel aan (zou kunnen) ligt(/liggen) ?

edit: sorry voor de te lange regels code, maar als ik deze halverwege af ga breken, wordt het er niet echt beter op
Pagina: 1