[jQuery, AJAX] dynamiczny formularz

0

Witam

Mam pewien problem i nie bardzo wiem jak się za to zabrać:

Mam w bazie 2 tabele: kategorie i podkategorie.

W HTMLu mam formularz składający się z dwóch pól rozwijalnych. I chciałbym, aby po wybraniu w pierwszym danej kategorii w drugim pojawiały się przypisane tej kategorii podkategorie.

Czy da się to zrobić samym jQuery (które w miarę ogarniam), czy w AJAXie (jeszcze się za niego nie zabrałem). Jak rozwiązać mój problem w prosty sposób?

Pozdrawiam.

0

Można to zrobić na dwa sposoby.

Sposób 1)
Sam JS i PHP

Przy wchodzeniu na stronę pobierasz sobie za pomocą skryptu PHP (zakładam że tego języka używasz) wszystkie kategorie i podkategorie. Ładujesz że to tablicy w JS. Później przy wybraniu danego elementu z listy wczytujesz sobie z tablicy podkategorii elementy które Cię interesują (te będące dziećmi danej kategorii nadrzędnej) i aktualizujesz drugą listę.

Sposób 2)
AJAX

  1. Wykonaj skrypt php który będzie pobierać Ci listę wszystkich pod kategorii danej kategorii nadrzędnej
  2. W zdarzeniu OnSelect (chyba - sprawdź jakie zdarzenie jest wywoływane przy wybraniu elementu z listy) wywołuj funkcje JS która za pomocą AJAXa odwoła się do tego skryptu przekazując mu jako parametr nazwe, id czy co tam masz kategorii nadrzędnej
  3. Skrypt PHP zwróci Ci listę kategorii którą wpakujesz w drugą listę
0
Buka77 napisał(a)

Witam

Mam pewien problem i nie bardzo wiem jak się za to zabrać:

Mam w bazie 2 tabele: kategorie i podkategorie.

W HTMLu mam formularz składający się z dwóch pól rozwijalnych. I chciałbym, aby po wybraniu w pierwszym danej kategorii w drugim pojawiały się przypisane tej kategorii podkategorie.

Czy da się to zrobić samym jQuery (które w miarę ogarniam), czy w AJAXie (jeszcze się za niego nie zabrałem). Jak rozwiązać mój problem w prosty sposób?

Pozdrawiam.

Można jak najbardziej zrobić to frameworkiem jQuery, mozna zrobić to nawet czystym PHP, Ajaxem tez można ale nie bawiłem się nim to stwierdzam teoretycznie [rotfl]

0
piochu napisał(a)

Sposób 2)
AJAX

  1. Wykonaj skrypt php który będzie pobierać Ci listę wszystkich pod kategorii danej kategorii nadrzędnej
  2. W zdarzeniu OnSelect (chyba - sprawdź jakie zdarzenie jest wywoływane przy wybraniu elementu z listy) wywołuj funkcje JS która za pomocą AJAXa odwoła się do tego skryptu przekazując mu jako parametr nazwe, id czy co tam masz kategorii nadrzędnej
  3. Skrypt PHP zwróci Ci listę kategorii którą wpakujesz w drugą listę

Można prosić o kod jakby to wyglądało w AJAXie?

W PHPie zrobiłem następującą funkcję, która zwraca mi kategorie wraz z podkategoriami:

public function zwroc_kategorie()
{
	  $sql = "SELECT * FROM kategorie ORDER BY id_kategorii ASC";
	  $a_wynik_kategorie = $this->o_db->GetAll($sql);

	  $a_kategorie = array();
		
     foreach($a_wynik_kategorie as $v_klucz=>$v_id)
      { 
            $a_podkategorie = array();
      
             $sql2 = "SELECT id_podkategorii,nazwa_podkategorii,id_kategorii FROM podkategorie WHERE id_kategorii='$v_id[id_kategorii]'";
      $a_wynik = $this->o_db->Execute($sql2);
      
      $a_kategorie[$v_id['id_kategorii']]['nazwa'] = $v_id['nazwa_kategorii'];
      $a_kategorie[$v_id['id_kategorii']]['id_kategorii'] = $v_id['id_kategorii'];
      
      foreach($a_wynik as $v_klucz=>$a_dane)
      { 
        $a_podkategorie[$a_dane['id_podkategorii']]['nazwa']=$a_dane['nazwa_podkategorii'];
        $a_podkategorie[$a_dane['id_podkategorii']]['id_podkategorii']=$a_dane['id_podkategorii'];
      }
      $a_kategorie[$v_id['id_kategorii']]['podkategorie'] = $a_podkategorie;
    }

		return $a_kategorie;
}
0

Zainteresuje się funkcja load z frameworka jQuery

function getChildrenCategories (id) {	
	$("#children_list").load("getChildrenList.php?parentID=" + id);
}

btw:

SELECT * FROM kategorie ORDER BY id_kategorii ASC
Nie wiem jak wygląda struktura Twojej tabeli kategorie ale z reguły dobrze jest unikać gwiazdki w zapytaniach. Lepiej określić konkretnie z których kolumn zapytanie ma wyciągać dane.

  1. Pamiętaj o tym żeby filtrować dane dane które przekazujesz to tej funkcji

Aha i na koniec jeszcze jedno, zastanów się czy na prawdę potrzebujesz AJAXa. Jeśli nie wiesz do czego służy poczytaj o nim i w przyszłości dwa razy zastanów się zanim go użyjesz.

0

Nieco mnie naprowadziłeś, ale nie bardzo wiem, co dalej.

Mam formularz z tymi dwoma selectami w pliku HTML:

 <select name="a_firma[branza]" id="select_kategoria">
      <option value="{$a_pozycja.id_kategorii}">(wybierz)</option>
        {foreach from=$a_pozycje item=a_pozycja}
          <option value="{$a_pozycja.id_kategorii}">{$a_pozycja.nazwa_kategorii}</option>
        {/foreach}
      </select>

<select name="a_firma[podbranza]" id="select_podkategoria">
     <option value="{$a_pozycja.id_kategorii}">(wybierz)</option>
</select>

Nowy plik PHP:

<?php
    $v_id = $_GET['id'];

    $sql = "SELECT id_podkategorii, nazwa_podkategorii FROM podkategorie WHERE id_kategorii='$v_id'";
    $a_podkategorie = $this->o_db->GetAll($sql);
		
    return $a_podkategorie;
?>

Oraz JavaScript

$('#select_podkategoria')
  .load("zwroc_podkategorie.php?id="  + $("#select_kategoria").val());

nie wiem, czy dobrze skumałem i co dalej.

0

wystarczy wykorzystać że PHP wykona się przed jquery

 <?PHP

//przed jQuery
    
     // wczytaj wszystko do tablicy, by było wypelnione w przykładowej strukturze podanej poniżej z 
     //czystej wygody i by nie odklepać całego kodu zrobione statycznie
     
        $tablica[1]= "KategoriaA";
        $tablica[2]= "KategoriaB"; 
         
        $Podtablica[1][1] = "A_Podkateforia_1";  
        $Podtablica[1][]  = "A_Podkateforia_2";   
        $Podtablica[1][]  = "A_Podkateforia_3";   
        
        $Podtablica[2][1] = "B_Podkateforia_1";  
        $Podtablica[2][]  = "B_Podkateforia_2";   
                      
    ?> 
         
// a teraz jQuery 
               
<script language="javascript">

function Zakryj() {
     $("[id=1]").hide();
     $("[id=2]").hide();
};

// jqery go
<php>$(document).ready(function(){
 
 // nie pzoosatje nic innego jak za pomoca PHP wczytać sobie w petli, dla lepszego zrozumienia napisałem to statycznie, jednak powyższy kod pwoinien wygenerować PHP, w petli robionej tyle razy ile jest kategorii

  $("option[name=Kat_1]").click(function(){
       Zakryj();
       $("[id=1]").show();
       return false;
  });
  
   $("option[name=Kat_2]").click(function(){
       Zakryj();
       $("[id=2]").show();
       return false;
  });

    // domyslnie piewrsza kategoria aktywna      
     Zakryj();
     $("[id=1]").show();

});

   

     
      
</script> 
          
  // no a tutaj czesc formularza, by było widoczne lepiej psiane staycznie, tez przerobic zlozenei formularza kodem PHP - chyba bajka

         <select size="20">
             <option name="Kat_1"  selected><? echo $tablica[1]; ?></option>
             <option name="Kat_2"><? echo $tablica[2]; ?></option>
          </select>


          <select size="20">           
             <option id="1" name="1"><? echo $Podtablica[1][1]; ?> </option>
             <option id="1" name="2"><? echo $Podtablica[1][2]; ?> </option>
             <option id="1" name="3"><? echo $Podtablica[1][3]; ?> </option>
             <option id="2" name="1"><? echo $Podtablica[2][1]; ?> </option>
             <option id="2" name="2"><? echo $Podtablica[2][2]; ?> </option>
               
               
          </select>
</php>
0

Poszedłem nieco krótszą i szybszą drogą, ale mam 2 małe pytania.

Mój kod wygląda teraz tak:

Wyciągam z tabeli wszystkie kategorie i podkategorie i ładuje je do formularzy. Każdej z opcji podkategorii nadaję klasę o nazwie takiej do jakiej kategorii dana podkategoria należy (kat1, kat2, ...):

<select name="a_firma[branza]" id="select_kategoria">
      <option value="0">(wybierz)</option>
        {foreach from=$a_kategorie item=a_kategoria}
          <option value="{$a_kategoria.id_kategorii}">{$a_kategoria.nazwa_kategorii}</option>
        {/foreach}
</select>

<select name="a_firma[podbranza]" id="select_podkategoria">
        <option value="0">(wybierz)</option>
        {foreach from=$a_podkategorie item=a_podkategoria}
          <option value="{$a_podkategoria.id_podkategorii}" class="kat{$a_podkategoria.id_kategorii}">{$a_podkategoria.nazwa_podkategorii}</option>
        {/foreach}
</select>

Załóżmy, że jest 5 kategorii głównych. Wtedy w jQuery robię coś takiego:

$('#select_kategoria')
  .change(function(){
    $('.kat1').hide();
    $('.kat2').hide();
    $('.kat3').hide();
    $('.kat4').hide();
    $('.kat5').hide();
    $('.kat' + $(this).val()).show();
  });

I wszystko działa świetnie tylko jak dynamicznie zliczyć wszystkie kategorie i je ukryć zamiast robić to ręcznie?

0

Czy da się to zrobić samym jQuery (które w miarę ogarniam), czy w AJAXie (jeszcze się za niego nie zabrałem).

Po pierwsze jQuery nie jest osobnym językiem, tylko frameworkiem javascript. Po drugie można to zrobić w AJAXie z wykorzystaniem jQuery - jQuery jako framework udostępnia funkcje pozwalające korzystać w prosty sposób z AJAXa, więc jedno drugiego nie wyklucza.

0

Jeśli kategorii jest mało, to przemyśl wstrzyknięcie ich w kod strony lub pobranie AJAXem w tle jako całej paczki i potem odwoływanie się do lokalnej tablicy. Zależy jak często użytkownik będzie skakał po kategoriach.

PS te kat1, kat2 to raczej nadają się na ID niż na klasę

0

I wszystko działa świetnie tylko jak dynamicznie zliczyć wszystkie kategorie i je ukryć zamiast robić to ręcznie?

może tak


<?PHP

echo '
          $("#select_kategoria")
          .change(function(){


   
              for ($i=1, $i < $liczba_kategorii, $i++)
              $(".kat' .$i '").hide();



    $(".kat" + $(this).val()).show();
  });
'

?>

Pzdr

0

Pewnie, bede musiał tak to zrobić na razie, ale czy nie zna ktoś metody, żeby zrobić to w samym jQuery, bez mieszania języków? Nie ma jakiegoś jQuerowego foreacha, który jechałby po wszystkich optionach w danych selekcie?

0

jak już mówiłem, możesz albo dodać jedną stałą klasę i wtedy:

$('.klasa').hide();

schowa wszystkie

albo:

$('#select_kategoria').find('option').hide();

a foreach jest, ale tu niepotrzebny - tak dla pokazówki:

$('#select_kategoria').find('option').each(function(){$(this).hide();});
0

Może przyda się, zwracanie liczby pasujących elementów

$('element').length();

lub
$('element').size();

http://www.electrictoolbox.com/get-total-number-matched-elements-jquery/

Pzdr.

0

by działało FF i w IE7 (bo przeklete IE nie łapie poprzenich roziwązań)

The JavaScript

function change_fruit(seldd) {     
  var look_for_id=''; var opt_id='';
  $('#obj_id').html("");
  $("#obj_id").append("<option value='0'>-Select Fruit-</option>");
  if(seldd.value=='0') { look_for_id='N'; }   
  if(seldd.value=='1'){ look_for_id='Y';  opt_id='a'; }  
  if(seldd.value=='2'){ look_for_id='Y';  opt_id='b'; }  
  if(seldd.value=='3'){ look_for_id='Y';  opt_id='c'; }

  if(look_for_id=='Y') {
    $("#obj_id_all option[id='"+opt_id+"']").each(function() {
      $("#obj_id").append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>");
    });
  } else {
    $("#obj_id_all option").each(function() {
      $("#obj_id").append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>");
    });
  }  
}


The HTML

<select name="obj_id" id="obj_id">
 <option value="0">-Select Fruit-</option>
 <option value="1" id="a">apple1</option>
 <option value="2" id="a">apple2</option>
 <option value="3" id="a">apple3</option>
 <option value="4" id="b">banana1</option>
 <option value="5" id="b">banana2</option>
 <option value="6" id="b">banana3</option>
 <option value="7" id="c">Clove1</option>
 <option value="8" id="c">Clove2</option>
 <option value="9" id="c">Clove3</option>
</select>

<select name="fruit_type" id="srv_type" onchange="change_fruit(this)">
 <option value="0">All</option>
 <option value="1">Starts with A</option>
 <option value="2">Starts with B</option>
 <option value="3">Starts with C</option>
</select>    

<select name="obj_id_all" id="obj_id_all" style="display:none;">
 <option value="1" id="a">apple1</option>
 <option value="2" id="a">apple2</option>
 <option value="3" id="a">apple3</option>
 <option value="4" id="b">banana1</option>
 <option value="5" id="b">banana2</option>
 <option value="6" id="b">banana3</option>
 <option value="7" id="c">Clove1</option>
 <option value="8" id="c">Clove2</option>
 <option value="9" id="c">Clove3</option>    
</select>

1 użytkowników online, w tym zalogowanych: 0, gości: 1