ugrás a tartalomhoz

Select elemeinek újra betöltése egy listán belül

stan · 2010. Dec. 22. (Sze), 14.20
Sziasztok!

Probléma leírása:
Van egy szűrőm, amivel a MySql adatbázisomban tárolt adatokat lehet szűrni. Az egyik szűrési feltétel a HELYSZÍN, amelyet a felhasználó kiválaszthat a szűrőben. Választhat megyét, vagy települést. A baj ott kezdődik, hogy hazánkban 3152 település van, így ha ezt beteszem egy select listába, akkor nagyon körülményes kiválasztani a megfelelőt. Ezért arra gondoltam, hogyha kiválasztok egy megyét, akkor ugyanabba a listába töltse be a kiválasztott megye településeit, így megyénként átlagosan már csak 150 település lesz a listában, ami már kezelhetőbb.

Feltételek:
- a helyszín kiválasztására 1 db select elem használható fel
- lehessen megadni olyat is, hogy csak megye, tehát nem kell feltétlenül konkrét települést megadni, hanem lehet megyénként is szűrni
- lehessen meadni olyat is, hogy az egész ország, tehát összes megye
- oldal újratöltése nélkül kéne megoldani, hogy a lista újra betöltse a kiválasztott megye településeit
- működjön a legnépszerűbb böngészőkben, és lehetőleg validálható legyen a kód (W3C)
- minél gyorsabban működik, annál jobb, fontos a sebesség

Meglévő tulajdonságok:
- A települések és a megyék már fel vannak töltve a MySql adatbázisba két küldön táblába
- A települések táblánál jelezve van, hogy az adott település melyik megyéhez tartozik

Eddigi ötleteim:
Már sok időt töltöttem a megoldás keresésével, de csak hasonlókat találtam, nem olyat ami nekem kell. Javascript kell hozzá, de nem tudom, hogy az adatbázist közben kell-e használnia (ajax), vagy elég ha az elején betölti az egész adathalmazt egy tömbbe (sebesség).

Sajnos meghaladja tudásomat a kivitelezés, kérem a segítségeteket!
 
1

Én a helyedben kitennék egy

rrd · 2010. Dec. 22. (Sze), 14.29
Én a helyedben kitennék egy input mezőt ami autocomplete kiegészül ahogy a user elkezdi beírni a település nevét.
Itt egy leírás: http://webmania.cc/amit-a-scriptaculousrol-tudni-erdemes-5/
4

Nekem nem ez kell

stan · 2010. Dec. 22. (Sze), 14.47
Nekem nem ez kell, mert arra a kérdésre, hogy "helyszín", nem egyértelmű mindenkinek, hogy a válasz egy település vagy egy megye. (rendezvényt kereső szisztémáról van szó)

Mert elkezdi beírni pl. hogy A38 hajó.... aztán elindítja a keresést. Hát erre nem ad ki semmit... Akkor erre az a reakció, hogy ez a szűrő vacak, aztán már le is lépett a felhasználó.

A lényeg itt az, hogy egy konkrétan megadott adatra szűrök, tehát konkrét listából kell, hogy válasszak, mert ellenkező esetben nem lesz egyértelmű. Én személy szerint abból indulok ki, hogy a felhasználó intelligenciája nagyon alacsony, szóval ami nekem egyértelmű, azt ő biztosan félreérti. De egy listát nem lehet félreérteni, mert annak meghatározott elemei vannak, tehát a felhasználó nem adhat meg olyan szűrő feltételt, ami nincs is.
2

jquery?

ironwill · 2010. Dec. 22. (Sze), 14.42
3

Kiválasztás

Poetro · 2010. Dec. 22. (Sze), 14.44
Hogy választasz ki több megyét, ha ugyanabba a listába betöltődik a települések listája? Lehetőleg olyan megoldást kellene választani amihez nem kell JavaScript, különben csökken az elérhetőség. Akár csak azt is megcsinálhatnád, hogy kiraksz 2 mezőt, az egyikben a megyék, a másikban pedig az összes település benne van. Ezután JavaScripttel csinálod meg a szűrést a település listára. Például hogy minden település értékét kiegészíted a megye számával. Tegyük fel, hogy így nézne ki a HTML:
  1. <!DOCTYPE HTML>  
  2. <html lang="en-US">  
  3. <head>  
  4.   <meta charset="UTF-8">  
  5.   <title></title>  
  6. </head>  
  7. <body>  
  8.   <form action="">  
  9.     <p>  
  10.       <label for="edit-megye">Megye</label>  
  11.       <select name="megye" id="edit-megye">  
  12.         <option value="0">Egész ország</option>  
  13.         <option value="1">Bács-Kiskun</option>  
  14.         <option value="2">Baranya</option>  
  15.         <!-- ide jön a többi megye -->  
  16.       </select>  
  17.     </p>  
  18.     <p>  
  19.       <label for="edit-telepules">Település</label>  
  20.       <select name="telepules" id="edit-telepules">  
  21.         <option value="1-1">Kecskemét</option>  
  22.         <option value="1-2">Kiskőrös</option>  
  23.         <!-- ide jön az összes település -->  
  24.       </select>        
  25.     </p>  
  26.   </form>  
  27. </body>  
  28. </html>  
Ezek után JavaScripttel kigyűjtöd az összes települést megyénként egy objektumba, és utána ebből szűrsz, amikor valaki kiválasztott egy megyét, és ezekkel töltöd fel a település listát.
5

Ez egy egyszerűsített kereső

stan · 2010. Dec. 22. (Sze), 14.56
Ez egy egyszerűsített kereső, tehát itt csak 1 db megyét, vagy 1 db települést lehet kiválasztani. Lesz egy külön oldalon egy "speciális keresés", amiben majd ki lehet választani több megyét vagy több települést is. A kérdésem az egyszerűsített keresőre vonatkozik, tehát elég ha csak 1 db megyét vagy 1 db települést lehet kiválasztani.

A két select mező megoldás pedig azért nem tetszik, mert ahogy mondtam, ez egy egyszerűsített kereső, és szeretném az egészet 1 db select listával megoldani. Tudom, hogy nem szokványos, és nem a legegyszerűbb út, viszont az én meglátásom szerint így telesül az a kitétel, hogy legyen a szűrő nagyon egyszerű és egyértelmű.

Valahol már láttam ezt a megoldást (már nem tudom melyik oldalon), és akkor nagyon megtetszett, csak nem tudom, hogyan lehet elkészíteni.
6

Hogy?

Poetro · 2010. Dec. 22. (Sze), 15.07
Hogyan fogsz tudni egy megyében keresni, vagy egy településben, ha nem tudod csak a megyét kiválasztani? És ha lecserélted a listát a településekre, hogyan tudsz másik megyét választani, mert mondjuk eltévesztetted a kiválasztást?

A második select mezőt eltüntetheted JavaScripttel, majd újra megjelenítheted, mondjuk egy link segítségével, ami ekkor mondjuk elrejti a települések listát. és akkor ténylegesen mindig csak egy listát fogsz látni, már ha van JavaScript a böngésződben. Ha nincs, akkor persze láthatod mindet - ezzel azokat segíted, akik valamilyen okból nem tudják bekapcsolni a JavaScriptet a böngészőben (céges szabályozás, a böngészője nem támogatja, biztonsági megfontolások stb.)

Egyáltalán nem bonyolult megvalósítani. Amit leírtam, az kb 20-30 sornyi JavaScript kóddal megvalósítható.
7

De egy listát nem lehet

kuka · 2010. Dec. 22. (Sze), 15.10
De egy listát nem lehet félreérteni
Márpedig én valószínűleg megtenném ha ugyanabban a listában egyszer megyék, máskor települések jelennek meg.

Én megszívlelném Poetro tanácsát és az ő példa kódjától indulnék el a fejlesztéssel.
8

Bővebben?

stan · 2010. Dec. 22. (Sze), 15.39
Akkor pontosan hogy is nézne ki ez a két lista?
Lenne egy MEGYÉK lista, mondjuk alatt egy TELEPÜLÉSEK lista. Ha kiválasztok egy megyét akkor az ahhoz tartozó településeket betölti a TELEPÜLÉSEK listába?
9

Én ezt a függvényt

kuka · 2010. Dec. 22. (Sze), 16.25
Én ezt a függvényt hívogatnám:
  1. function valt(megye)  
  2. {  
  3.   var telepul=document.getElementById('edit-telepules')  
  4.   var valaszt=megye.options[megye.selectedIndex].value  
  5.   var valexpr=new RegExp('^'+valaszt+'-')  
  6.   for (i=0,l=telepul.options.length;i<l;i++)  
  7.     telepul.options[i].style.display=valaszt==0 || valexpr.test(telepul.options[i].value)?'block':'none'  
  8. }  
Méghozzá így:
  1. <select name="megye" id="edit-megye" onchange="valt(this)">  
13

Megvalósítás

Poetro · 2010. Dec. 22. (Sze), 21.57
  1. <!DOCTYPE HTML>  
  2. <html lang="hu-HU">  
  3. <head>  
  4.   <meta charset="UTF-8">  
  5.   <title></title>  
  6. </head>  
  7. <body>  
  8.   <form action="">  
  9.     <p>  
  10.       <label for="edit-megye">Megye</label>  
  11.       <select name="megye" id="edit-megye">  
  12.         <option value="0">Egész ország</option>  
  13.         <option value="1">Bács-Kiskun</option>  
  14.         <option value="2">Baranya</option>  
  15.         <!-- ide jön a többi megye -->  
  16.       </select>  
  17.     </p>  
  18.     <p>  
  19.       <label for="edit-telepules">Település</label>  
  20.       <select name="telepules" id="edit-telepules">  
  21.         <option value="0">Minden település</option>  
  22.         <option value="1-1">Kecskemét</option>  
  23.         <option value="1-2">Kiskőrös</option>  
  24.         <option value="2-1">Mohács</option>  
  25.         <option value="2-2">Pécs</option>  
  26.         <!-- ide jön az összes település -->  
  27.       </select>  
  28.     </p>  
  29.   </form>  
  30.   <script type="text/javascript">  
  31.     (function (megye, telepules) {  
  32.       var telepulesek = {}, defaultItem, ol, i, option, frag, fr;  
  33.       if (megye && telepules) {  
  34.         for (i = 0ol = telepules.options.length; i < ol; i += 1) {  
  35.           option = telepules.options[i];  
  36.           frag = option.value && option.value.split('-', 2);  
  37.           if (frag.length === 2) {  
  38.             fr = frag[0];  
  39.             if (!(frag in telepulesek)) {  
  40.               telepulesek[fr] = [];  
  41.             }  
  42.             telepulesek[fr].push({value: option.value, text: option.text});  
  43.           }  
  44.           if (option.value === '0') {  
  45.             defaultItem = {value: option.value, text: option.text};  
  46.           }  
  47.         }  
  48.         megye.selectedIndex = 0;  
  49.         megye.onchange = function () {  
  50.           var options, i, ol, option;  
  51.           telepules.parentNode.style.display = megye.value === '0' ?   
  52.             'none' :   
  53.             'block';  
  54.           if (telepulesek[megye.value]) {  
  55.             telepules.innerHTML = '';  
  56.             option = document.createElement('option');  
  57.             option.value = defaultItem.value;  
  58.             option.text = defaultItem.text;  
  59.             option.selected = true;  
  60.             telepules.add(option, null);  
  61.             options = telepulesek[megye.value];  
  62.             for (ol = options.length, i = 0; i < ol; i += 1) {  
  63.               option = document.createElement('option');  
  64.               option.value = options[i].value;  
  65.               option.text = options[i].text;  
  66.               telepules.add(option, null);  
  67.             }  
  68.             telepules.focus();  
  69.           }  
  70.         };  
  71.         telepules.parentNode.style.display = 'none';  
  72.       }  
  73.     }(document.getElementById('edit-megye'),  
  74.       document.getElementById('edit-telepules')));  
  75.   </script>  
  76. </body>  
  77. </html>  
Kipróbálható
14

Na ez így már nem rossz

stan · 2010. Dec. 23. (Cs), 11.21
Na ez így már egész jól néz ki. Köszönöm szépen a példát!
Mivel az én ötletemet egyelőre nem tudom megvalósítani, ezt fogom alkalmazni.
10

Mégis csak így kéne

stan · 2010. Dec. 22. (Sze), 19.56
Két óra keresés után végre találtam valamit, ami hasonlít arra, amit kigondoltam:
http://www.javascriptkit.com/script/script2/2levelcombo.shtml

Én ilyenre gondoltam azzal a különbséggel, hogy nem weboldalakra lehet ugrálni, hanem egy űrlap részeként a kiválasztott település sorszámát (id) továbbküldi egy GET értékben egy feldolgoz.php fájlnak. Tehát van még több másik select elem az űrlapban, és azokat is figyelembe kell vegye amikor GET-ként továbbítja az adatokat.

Illetve még annyi, hogy a MySql adatbázisból generálná a megyéket és azok településeit.

Szóval egy kis segítséget szeretnék kérni a fenti példa kód átalakítására, mert javascriptből még nem vagyok olyan profi, hogy ezt átlássam...
11

Elolvastad?

Poetro · 2010. Dec. 22. (Sze), 20.01
Ugye elolvastad amit eddig írtunk? Csináltál A-B tesztet, hogy a felhasználóknak a te módszered egyértelmű, vagy az amit leírtunk? Meddig jutottál a saját megoldásod megvalósításában? Tudsz mutatni kódot? Vagy valakit meg akarsz fizetni, hogy elkészítse neked?
12

Igen

stan · 2010. Dec. 22. (Sze), 20.12
Elolvastam és továbbra is tartom magam a saját elképzelésemhez, mert meggyőződésem, hogy amit ti írtatok, azt bonyolultabb kezelni, mint amit én javasoltam. De köszönöm a javaslatokat, nyilván nem hagytam figyelmen kívül.

A-B tesztet még nem volt alkalmam csinálni, mivel egy fejlesztés alatt álló projektről van szó. Ha készen lesz, nyilván fogok csinálni A-B tesztet, de először szeretnék egy alapverziót, ahol mindennek van egy A verziója, ami működik.

Kódot a fenti linken tudok mutatni, igaz ahhoz semmi közöm mert nem én csináltam.

Saját megoldásom megvalósításában még semeddig nem jutottam, mivel nem művelem olyan magas szinten a javascriptet, hogy egyedül megvalósítsak egy ilyen volumenű funkciót.

Gondoltam lesz valaki, aki esetleg segít, mert gondolom itt olyan emberek vannak, akik hobbyból is szeretnek programozni. Pénzem nincs arra, hogy megfizessem a munkát. De ha nem segít senki, akkor is megoldom, mert akkor nekiállok és elkezdem felturbózni a javascript tudásomat.

Természetesen ha jutok valamire (ami valószínűleg nem mostanában lesz), és elakadok valahol, akkor beírom ide a kódot ameddig jutottam. Addig is ha van valakinek elképzelése, akkor írja meg, ha nincs akkor köszönöm az eddigi tanácsokat.
15

Ha ragaszkodsz az

kuka · 2010. Dec. 23. (Cs), 12.04
Ha ragaszkodsz az őrültségedhez, legyen.
  1. <!DOCTYPE HTML>  
  2. <html lang="en-US">  
  3. <head>  
  4.   <meta charset="UTF-8">  
  5.   <title></title>  
  6. <script>  
  7. var orszag=[  
  8.   [  
  9.     '23752','Bács-Kiskun',  
  10.     '13631','Kecskemét',  
  11.     '31479','Kiskőrös'  
  12.   ],  
  13.   [  
  14.     '352','Baranya',  
  15.     '10117','Mohács',  
  16.     '12054','Pécs'  
  17.   ]  
  18. ]  
  19. var mindlab,mindsel,most=0  
  20. function init()  
  21. {  
  22.   mindlab=document.getElementById('mindlab')  
  23.   mindsel=document.getElementById('mindsel')  
  24.   valt()  
  25. }  
  26. function valt()  
  27. {  
  28.   var valaszt=most?mindsel.options[mindsel.selectedIndex].value:''  
  29.   if (most==0 || valaszt=='-1') {  
  30.     mindlab.innerHTML='Megye'  
  31.     while (mindsel.options.length) mindsel.options[mindsel.options.length-1]=null  
  32.     mindsel.options[mindsel.options.length]=new Option('Egész ország','-2')  
  33.     for (var i=0,l=orszag.length;i<l;i++)  
  34.       mindsel.options[mindsel.options.length]=new Option(orszag[i][1],orszag[i][0])  
  35.     most=1  
  36.   } else if (most==1) {  
  37.     mindlab.innerHTML='Település'  
  38.     while (mindsel.options.length) mindsel.options[mindsel.options.length-1]=null  
  39.     mindsel.options[mindsel.options.length]=new Option('<Vissza a megyékhez<','-1')  
  40.     for (var i=0,l=orszag.length;i<l;i++)  
  41.       if (orszag[i][0]==valaszt) {  
  42.         for (var j=2,l2=orszag[i].length;j<l2;j+=2)  
  43.           mindsel.options[mindsel.options.length]=new Option(orszag[i][j+1],orszag[i][j])  
  44.         break  
  45.       }  
  46.     most=2  
  47.   }  
  48. }  
  49. window.addEventListener('load',init,false)  
  50. </script>  
  51. </head>  
  52. <body>  
  53.   <form action="">  
  54.     <p>  
  55.       <label for="mindsel" id="mindlab"></label>  
  56.       <select name="mindegymi" id="mindsel" onchange="valt()">  
  57.       </select>  
  58.     </p>  
  59.   </form>  
  60. </body>  
  61. </html>  
Az orszag tömb elemei tömbök, mindegyik egy-egy megye, melyekben az első két elem a megye.id és megye.nev, a következők pedig az illető megyéhez tartozó telepules.id és telepules.nev párok. Az orszag adatokat például ezzel a lekérdezéssel szedném össze:
  1. select m.id,m.nev,t.id,t.nev from megye m left join telepules t on t.megyeid=m.id;  
A fenti lekérdezésből pedig valahogy így gyúrnék JavaScript kódot (vagyis ez a PHP kód része volna, amely az űrlapos HTML-t generálja):
  1. $res=mysql_query('select m.id,m.nev,t.id as tid,t.nev as tnev from megye m left join telepules t on t.megyeid=m.id');  
  2. $orszag=array();  
  3. $megye=''$megyenr=-1;  
  4. while ($row=mysql_fetch_assoc($res)) {  
  5.   if ($megye!=$row['id']) {  
  6.     $megye=$row['id'];  
  7.     $orszag[++$megyenr]=array($row['id'],$row['nev']);  
  8.   }  
  9.   $orszag[$megyenr][]=$row['tid'];  
  10.   $orszag[$megyenr][]=$row['tnev'];  
  11. }  
  12. echo 'var orszag=',json_encode($orszag);  
(A PHP kódot nem teszteltem, a hibák javítását rád bízom.)
16

Köszönöm

stan · 2010. Dec. 23. (Cs), 13.19
Köszönöm a segítséget, pontosan ez az amire gondoltam!