Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][AJAX] Ładowanie kategorii do selecta
Forum PHP.pl > Forum > Przedszkole
d.stp
Próbuje zrobić wybór kategorii zależny od wyboru poprzedniego selecta. Mam formularz:

  1. <select name="cats">
  2. <option value="1">test</option>
  3. <option value="2">test 2</option>
  4. <option value="3">test 3</option>


i ajax:

  1. function showCats(str) {
  2. if (str == "") {
  3. document.getElementById("txtHint").innerHTML = "";
  4. return;
  5. } else {
  6. if (window.XMLHttpRequest) {
  7. // code for IE7+, Firefox, Chrome, Opera, Safari
  8. xmlhttp = new XMLHttpRequest();
  9. } else {
  10. // code for IE6, IE5
  11. xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  12. }
  13. xmlhttp.onreadystatechange = function() {
  14. if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
  15. document.getElementById("cats_join").innerHTML = xmlhttp.responseText;
  16. }
  17. }
  18. xmlhttp.open("GET","select.php?cat_id="+str,true);
  19. xmlhttp.send();
  20. }
  21.  
  22. }


takie coś ładuje mi ładnie podkategorie zależne od wyboru kategorii głównej. Problem w tym, że te podkategorie mają jeszcze swoje podkategorie i wtedy jak pojawi mi się drugi select to już nie ładuje dalej po wyborze jakiejś opcji :/ tak samo drugi select (ten który się pojawił) nie reaguje już naawet na:

  1. //kategorie
  2. $('.cats').on('change', function(){
  3. alert(1);
  4. var cat_id = $(this).val();
  5. showCats(cat_id);
  6.  
  7. });


W select.php tworzę sobie ten select a opcje do niego pobieram z bazy...
freewalker
miałem podobny problem, przy dynamicznym ładowaniu treści, że zdarzenia w nowych polach formularza nie działają.

Sposobem na to jest przypisanie zdarzenia (w twoim przypadku .on ) po załadowaniu pola formularza, należy jednak pamiętać, że podwójne bindowanie zdarzenia spowoduje efekt tzw. podwójnego kliknięcia, później potrójnego itp wink.gif Aż w końcu skrypt się wysypie. Więc najpierw zawsze wywołajmy unbind(). Ja zrobiłbym tak:

  1. function binder_catschange()
  2. {
  3.  
  4. $('.cats').unbind().bind('change', function(){
  5. alert(1);
  6. var cat_id = $(this).val();
  7. showCats(cat_id);
  8. });
  9. }


następnie w twoim kodzie w miejscu:

  1. xmlhttp.onreadystatechange = function() {
  2. if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
  3. document.getElementById("cats_join").innerHTML = xmlhttp.responseText;
  4.  
  5. binder_catschange(); // wywolanie funkcji bindowania
  6. }


mam nadzieję, że to pomoże : )
rad11
Nie rozumiem do eventu change uzywasz jquery a do ajaxu uzywasz sposobu ktorego juz sie nie uzywa(po co sobie komplikowac).
d.stp
@rad11, to jest akurat najmniej ważne. Najważniejsze że działa, później i tak to zmienię

sprytne, działa smile.gif

z tym, że dopiero po drugim kliknięciu załapuje, później już normalnie. O co biega questionmark.gif

  1. function binder_catschange() {
  2. $('.cats').unbind().bind('change', function(){
  3. var cat_id = $(this).val();
  4. alert(cat_id);
  5. showCats(cat_id);
  6. });
  7. }
  8.  
  9. $(document).ready(function() {
  10.  
  11. //kategorie
  12. $('.cats').on('change', function(){
  13. binder_catschange();
  14. });
freewalker

nie działa bo binduje zdarzenie dopiero po pierwszej zmianie pola, załaduj to na samym starcie a resztę usuń, jak w poniższym przykładzie : )

  1. $(document).ready(function() {
  2.  
  3. //kategorie
  4. binder_catschange(); //wywolaj tylko to, ponizsze juz nie jest potrzebne
  5. /*
  6. $('.cats').on('change', function(){
  7. binder_catschange();
  8. });
  9. */
  10.  
  11. } //end of $document.ready.function
d.stp
Ogarnąłem już wcześniej, ale i tak dzięki.

Teraz dopiero mam zagadkę...

Zrobiłem tak, że po wybraniu kategorii głównej pokazuje się kolejny select z opcjami gdzie kategoria_glowna == opcja_wybrana, działa. Problem w tym że ten skrypt co mam teraz działa na takiej zasadzie że w miejscu selecta, który pojawił się po wybraniu selecta głównego pokazuje się inny select, a stary znika. Zmieniłem więc kod:

document.getElementById("cats_join").innerHTML = xmlhttp.responseText;

Na:

$('#cats_join').append(xmlhttp.responseText);

i efekt osiągnięty, ale jak wybiorę sobie np. kategorie główną, później jej podkategorie, a następnie jeszcze jedną podkategorie tej wcześniejszej i dalej zmienie np. podkategorie to zamiast chciałbym żeby znikały mi wszystkie selecty które są > kategorii klikniętej, bo teraz za każdym wybraniem kategorii pojawia się kolejny select i tak w kółko..



@rad11, wiem o tym, ale to jest tylko żeby działałol później i tak to będę zmieniał

Jakiś pomysł?
freewalker
no tak, przez appenda dopisujesz ciągle nową treść, w takim przypadku rozwiązałbym to numerowaniem poziomu kategorii w selectach, np:

kategoria główna = lvl 1
podkategoria = lvl 2
podkategoria podkategorii = lvl 3


Zaczynając od założenia zmiennej globalnej w kodzie JS:
var max_levels=1; // 1 jak tylko główna kategoria jest zaladowana, każde rozwinięcie spowoduje inkrementację o +1

wymaga też to zmodyfikowania trochę HTMLa dla znacznika select, dodaj atrybut lvl z najnizszym poziomem (w naszym przypadku 1)
  1. <select class='cats' name='moj_select' lvl='1'>


kazdy kolejny select generowany przez skrypt powinien miec zwiekszany atrybut lvl o 1 (az do poziomu maksymalnego danej kategorii), czyli wstawiamy selecta appendem, odnajdujemy ostatnio dodanego w tym divie i zmieniamy jego atrybut lvl uprzednio zwiększając zmienną max_levels o 1;
u ciebie w kodzie będzie to chyba w tym miejscu:

  1. xmlhttp.onreadystatechange = function() {
  2. if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
  3. $('#cats_join').append(xmlhttp.responseText);
  4.  
  5. max_levels+=1;
  6. $("#cats_join").find("select.cats:last").attr("lvl",max_levels);
  7.  
  8. binder_catschange(); // wywolanie funkcji bindowania
  9. }


modyfikujemy też odpowiednio funkcję binder i dodajemy funkcję usuwającą niepotrzebne podkategorie

  1. function binder_catschange() {
  2. $('.cats').unbind().bind('change', function(){
  3. var cat_id = $(this).val();
  4. category_lvl=$(this).attr('lvl');
  5.  
  6. if(category_lvl < max_levels) remove_unwanted_cats(category_lvl);
  7.  
  8. alert(cat_id);
  9. showCats(cat_id);
  10. });
  11. }
  12.  
  13. function remove_unwanted_cats(actual_lvl)
  14. {
  15. start_removing=actual_lvl+1;
  16. end_removing=max_levels+1;
  17.  
  18. for(i=start_removing;i<end_removing;i++)
  19. {
  20. $("#cats_join").find("select.cats[lvl="+i+"]").remove();
  21. }
  22.  
  23. max_levels=actual_lvl;
  24. }


mam nadzieję, że działa bo tak na sucho ciężko się pisze i nie wiadomo czy gdzieś byka nie postawiłem : ) ale chyba najważniejsze, żebyś załapał logikę a na pewno sobie poradzisz
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.