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:
<!DOCTYPE HTML>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <form action="">
    <p>
      <label for="edit-megye">Megye</label>
      <select name="megye" id="edit-megye">
        <option value="0">Egész ország</option>
        <option value="1">Bács-Kiskun</option>
        <option value="2">Baranya</option>
        <!-- ide jön a többi megye -->
      </select>
    </p>
    <p>
      <label for="edit-telepules">Település</label>
      <select name="telepules" id="edit-telepules">
        <option value="1-1">Kecskemét</option>
        <option value="1-2">Kiskőrös</option>
        <!-- ide jön az összes település -->
      </select>      
    </p>
  </form>
</body>
</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:

function valt(megye)
{
  var telepul=document.getElementById('edit-telepules')
  var valaszt=megye.options[megye.selectedIndex].value
  var valexpr=new RegExp('^'+valaszt+'-')
  for (i=0,l=telepul.options.length;i<l;i++)
    telepul.options[i].style.display=valaszt==0 || valexpr.test(telepul.options[i].value)?'block':'none'
}
Méghozzá így:

<select name="megye" id="edit-megye" onchange="valt(this)">
13

Megvalósítás

Poetro · 2010. Dec. 22. (Sze), 21.57
<!DOCTYPE HTML>
<html lang="hu-HU">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <form action="">
    <p>
      <label for="edit-megye">Megye</label>
      <select name="megye" id="edit-megye">
        <option value="0">Egész ország</option>
        <option value="1">Bács-Kiskun</option>
        <option value="2">Baranya</option>
        <!-- ide jön a többi megye -->
      </select>
    </p>
    <p>
      <label for="edit-telepules">Település</label>
      <select name="telepules" id="edit-telepules">
        <option value="0">Minden település</option>
        <option value="1-1">Kecskemét</option>
        <option value="1-2">Kiskőrös</option>
        <option value="2-1">Mohács</option>
        <option value="2-2">Pécs</option>
        <!-- ide jön az összes település -->
      </select>
    </p>
  </form>
  <script type="text/javascript">
    (function (megye, telepules) {
      var telepulesek = {}, defaultItem, ol, i, option, frag, fr;
      if (megye && telepules) {
        for (i = 0, ol = telepules.options.length; i < ol; i += 1) {
          option = telepules.options[i];
          frag = option.value && option.value.split('-', 2);
          if (frag.length === 2) {
            fr = frag[0];
            if (!(frag in telepulesek)) {
              telepulesek[fr] = [];
            }
            telepulesek[fr].push({value: option.value, text: option.text});
          }
          if (option.value === '0') {
            defaultItem = {value: option.value, text: option.text};
          }
        }
        megye.selectedIndex = 0;
        megye.onchange = function () {
          var options, i, ol, option;
          telepules.parentNode.style.display = megye.value === '0' ? 
            'none' : 
            'block';
          if (telepulesek[megye.value]) {
            telepules.innerHTML = '';
            option = document.createElement('option');
            option.value = defaultItem.value;
            option.text = defaultItem.text;
            option.selected = true;
            telepules.add(option, null);
            options = telepulesek[megye.value];
            for (ol = options.length, i = 0; i < ol; i += 1) {
              option = document.createElement('option');
              option.value = options[i].value;
              option.text = options[i].text;
              telepules.add(option, null);
            }
            telepules.focus();
          }
        };
        telepules.parentNode.style.display = 'none';
      }
    }(document.getElementById('edit-megye'),
      document.getElementById('edit-telepules')));
  </script>
</body>
</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.

<!DOCTYPE HTML>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <title></title>
<script>
var orszag=[
  [
    '23752','Bács-Kiskun',
    '13631','Kecskemét',
    '31479','Kiskőrös'
  ],
  [
    '352','Baranya',
    '10117','Mohács',
    '12054','Pécs'
  ]
]
var mindlab,mindsel,most=0
function init()
{
  mindlab=document.getElementById('mindlab')
  mindsel=document.getElementById('mindsel')
  valt()
}
function valt()
{
  var valaszt=most?mindsel.options[mindsel.selectedIndex].value:''
  if (most==0 || valaszt=='-1') {
    mindlab.innerHTML='Megye'
    while (mindsel.options.length) mindsel.options[mindsel.options.length-1]=null
    mindsel.options[mindsel.options.length]=new Option('Egész ország','-2')
    for (var i=0,l=orszag.length;i<l;i++)
      mindsel.options[mindsel.options.length]=new Option(orszag[i][1],orszag[i][0])
    most=1
  } else if (most==1) {
    mindlab.innerHTML='Település'
    while (mindsel.options.length) mindsel.options[mindsel.options.length-1]=null
    mindsel.options[mindsel.options.length]=new Option('<Vissza a megyékhez<','-1')
    for (var i=0,l=orszag.length;i<l;i++)
      if (orszag[i][0]==valaszt) {
        for (var j=2,l2=orszag[i].length;j<l2;j+=2)
          mindsel.options[mindsel.options.length]=new Option(orszag[i][j+1],orszag[i][j])
        break
      }
    most=2
  }
}
window.addEventListener('load',init,false)
</script>
</head>
<body>
  <form action="">
    <p>
      <label for="mindsel" id="mindlab"></label>
      <select name="mindegymi" id="mindsel" onchange="valt()">
      </select>
    </p>
  </form>
</body>
</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:

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):

$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');
$orszag=array();
$megye=''; $megyenr=-1;
while ($row=mysql_fetch_assoc($res)) {
  if ($megye!=$row['id']) {
    $megye=$row['id'];
    $orszag[++$megyenr]=array($row['id'],$row['nev']);
  }
  $orszag[$megyenr][]=$row['tid'];
  $orszag[$megyenr][]=$row['tnev'];
}
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!