Dynamiczne menu rozwijane

0

Cześć.
Chciałbym się dowiedzieć jak wykorzystać ajaxa i php do wykonania zależnego menu rozwijanego, tzn. jeżeli wybiorę w pierwszym menu jakąś opcję, to zawęzi mi się lista w drugim, po wybraniu elementu z drugiego menu rozwijanego chciałbym, aby z bazy, z tej samej tabeli pobrały się dwie inne wartości i pokazały w inputach po to, żeby to wszystko zapisać do tabeli zbiorczej.
Na yt jest kilka tutoriali jak zrobić coś podobnego ale zawsze kończy się to na jednym inpucie a ja chciałbym 2 lub więcej.
screenshot-20220402205139.png

Przykład na potrzeby przedstawienia problemu.

index.php

<select name="submenu" id="submenu" class="form-control action">
		<option value="">Select submenu</option>
		<?php echo $submenu; ?>
	</select>
	<br />
	<select name="name" id="name" class="form-control action">
		<option value="">Select name</option>
	</select>
	<br />
	<select name="budget" id="budget" class="form-control">
		<option value="">Select budget</option>
</select>

<script>
$(document).ready(function(){
	$('.action').change(function(){
		if($(this).val() !='')
		{
			var action = $(this).attr("id");
			var query = $(this).val();
			var result = '';
			if(action == "submenu")
			{
				result = 'name';
			}
			else
			{
				result = 'budget';
			}
			$.ajax({
				url: "f.php",
				method:"POST",
				data:{action:action, query:query},
				success:function(data){
					$('#'+result).html(data);
				}
			})
		}
	});
});
</script>

f.php

<?php
include ("db.php");

if(isset($_POST["action"]))
{
	$output='';
	if($_POST["action"] === "submenu")
	{
		$result=sqlsrv_query($conn, "SELECT name FROM blog_categories_submenu where submenu = '".$_POST["query"]."'GROUP BY name", 
  array(), array( "Scrollable" => 'keyset' ));
		$output .= '<option value="">Select name</option>';
		while($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)){
			$output .='<option value="'.$row["name"].'">'.$row["name"].'</option>';
		}
	}
	
	if($_POST["action"] === "name")
	{
		$result=sqlsrv_query($conn, "SELECT budget FROM blog_categories_submenu where name = '".$_POST["query"]."'", 
  array(), array( "Scrollable" => 'keyset' ));
		while($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)){
			$output .='<option value="'.$row["budget"].'">'.$row["budget"].'</option>';
		}
	}
echo $output;
}
0

Jakieś 2-3 dni temu był praktycznie identyczny wątek - Wyświetlanie opcji listy rozwijanej zależne od poprzednich. Przejrzałeś go, zanim zadałeś pytanie? :P

Na yt jest kilka tutoriali jak zrobić coś podobnego ale zawsze kończy się to na jednym inpucie a ja chciałbym 2 lub więcej.

Co do tego fragmentu - za bardzo nie rozumiem, co fakt posiadania kilku inputów zmienia. Znaczy - jeśli rozumiesz i wiesz, jak zrobić to dla jednego inputa, to potem jedynie trzeba dodać logikę, która będzie w stanie działać na kilku polach/listach. Więc pytanie - czy umiesz na razie zrobić, żeby takie dopasowywanie treści listy działało dla jednego inputa, masz chociaż to ogarnięte? Bo napisałeś jedynie, że znalazłeś jakieś filmy na YT, ale wcale to nie oznacza, że zrobiłeś cokolwiek poza znalezienie tutoriali :P

0

To mój wątek sprzed kilku dni, jednakże teraz chcę osiągnąć coś innego.
Cały czas się uczę, od wczoraj kombinuje z tymi polami i mi nie wychodzi dlatego piszę i pytam, nie potrafię dodać logiki do reszty..

0

Rzeczywiście, nie zauważyłem, że to Twój :D

A w takim razie - czy możesz napisać jaśniej, w czym masz problem/czego nie wiesz, jak zrobić? Bo wrzuciłeś wprawdzie jakiś kod (swoją drogą - czemu używasz jquery? Wprawdzie nie tego dotyczy wątek, ale przy okazji zaznaczę, że to jest mocno odradzane rozwiązanie od jakiegoś czasu), ale nie wiem, w czym jest problem.

Patrząc na Twój rysunek - ja bym zrobił tak, że wybierasz kraj - po jego wybraniu wysyłasz AJAX'em zapytanie o treść drugiej listy, czyli województw. Potem analogicznie - jak wybierzesz województwo to przesyłasz AJAX'em do serwera pytanie o miasta, które są w kraju X i województwie Y. Po zapełnieniu listy miast czekasz, aż user coś wybierze. I po wybraniu miasta przesyłasz do serwera ostateczne pytanie - o miasto A, leżące w województwie B i kraju C. W odpowiedzi na to zapytanie dostajesz dane, które umieszczasz w 3 ostatnich polach.

Jeszcze zwróć uwagę, że wysyłając zapytanie dawaj zawsze pełen zestaw informacji. Bo w Polsce masz wiele miast zduplikowanych, więc województwo jest istotne. Tak samo kraj - jest opcja, że w różnych krajach będzie miasto o takiej samej nazwie. Samo przesłanie zapytania dot. informacji o mieście może albo zawierać 3 wybrane przez usera informacje, albo podczas przesyłania listy miast można razem z ich nazwami przekazać jakieś ID każdego miasta. I wtedy - w zależności od tego, co wybierzesz, po stronie serwera wykonasz albo SELECT populacja, numer, rok FROM dane_miast WHERE kraj=A AND wojewodztwo=B AND miasto=C lub SELECT populacja, numer, rok FROM dane_miast WHERE miasto_id = 3324

0

Mam trzy tabele w bazie - państwo, województwo, miasto - w ostatniej nie tylko jest miasto zapisane ale także wartości populacja, rok założenia, strefa numeracyjna.
Tak jak jest na screenie rozpisane - mam trzy listy wybierane, potem 3 inputy, po kolei wybieram wartości z list wybieranych, jeżeli wybiorę ostatnią to mają mi się uzupełnić inputy zgodnie z wartością wybraną w ostatnim inpucie i które są zapisane w bazie razem w tabeli i to wszystko ma mi się zapisać do jednej wspólnej tabeli, bo przy insercie daje również datę zapisu.

Problem mam z tym, że jak wybieram wszystkie trzy listy to potrafię okodować tylko jeden input, żeby się wyświetlał a pozostałe dwa nie potrafię do tego dołączyć.
Chciałbym, aby mi ktoś pomógł sprawić, że wszystkie 3 wartości będą się pokazywać po wybraniu ostatniej listy rozwijanej a nie tylko jedna jak do tej pory.

0

A możesz gdzieś to wrzucić do netu i dać link, żebym mógł sam sobie to co już masz przeklinać i zobaczyć jak to aktualnie działa?

1

<select id="country_id"> .... </select>

<script>
$('#country_id').on('change', function() {
  ...tutaj ładujesz do "voivodship_container" kolejny select/option -> dla województw...
  ...dla skryptu PHP przekazujesz jedynie parametr country_id = $('#country_id').val()...
  
  data:{country_id:$('#country_id').val()}
  
});
</script>

<div id="voivodship_container">
</div>

<div id="city_container">
</div>

<div id="data_container">
</div>

Jak widać wyżej, na początek pokazujesz pierwszy input, robisz dla niego w js zdarzenie, które ładuje do wnętrza voivodship_container kolejny select/option razem z JS który go obsłuży np.:

<select id="voivodship_id"> .... </select>


<script>
$('#voivodship_id').on('change', function() {
  ...tutaj ładujesz do "city_container" kolejny select/option -> dla miast...
  data:{voivodship_id:$('#voivodship_id').val()}
});
</script>

I tak dalej, a zdarzenie polegające na wyborze miasta ładuje już ostateczne dane.

W skrypcie PHP odbierającym AJAX rozpoznajesz o którą sekcję do załadowania chodzi w zależności od tego jaki parametr dostajesz: country_id, voivodship_id, city_id - nie musisz przekazywać więcej parametrów, tylko jeden.

0

@TomRZ:
no właśnie mi chodzi o te ostateczne dane
wyżej pokazałem, że sam wybór z list rozwijanych mam ale nie potrafię ostatecznych danych do tego wyświetlić
to po prostu jest zły sposób?

1

Nie wiem do końca na czym polega Twój problem.

Robisz HTML taki jaki Ci pokazałem, czyli pokazujesz listę krajów - rozumiem, że będą inne niż Polska, oraz poniżej trzy kontenery: na regiony, miasta, i ostateczne dane, które są wstępnie puste.

  1. Wybór kraju = odczytanie id kraju, przekazanie AJAXEM do PHP parametru GET country_id = id kraju który jest wybrany w Select/Option
  2. PHP produkuje select/option regionów na podstawie kraju + JS który robi to samo co w pkt 1 -> tylko po wyboerze regionu ładuje miasta

Czego tutaj nie rozumiesz?

0

W dalszym ciągu mnie nie rozumiesz.
Problem mam z wyświetleniem tych trzech ostatnich rzeczy, nie z wyborem z list rozwijanych.
Robię dokładnie tak jak mówisz: wczytuję listę krajów, wybieram kraj, potem wybieram okrojone już województwo do kraju, który wybrałem wcześniej, teraz po wybraniu województwa wybieram miasto, które jest tylko w tym województwie i to działa. Problem jest TYLKO z wyświetleniem sztywnych danych przypisanych do tego miasta.

1

Ładujesz je identycznie jak pozostałe rzeczy - tylko zamiast select/option, po prostu dane z bazy.

2

Ja mam dla Ciebie @MiniBus02 taką radę. Nie mieszaj PHP i JavaScript. Najlepiej byłoby dla Ciebie gdybyś miał tylko pliki .php w który masz tylko kod PHP (ale bez JavaScript i HTML'a) i osobno pliki index.html i script.js, tak żeby się nie mieszały. I tak chcesz robić AJAX'y, więc JS może wczytywać i wysyłać dane AJAX'ami.

MiniBus02 napisał(a):
  $result=sqlsrv_query($conn, "SELECT name FROM blog_categories_submenu where submenu = '".$_POST["query"]."'GROUP BY name", 
  array(), array( "Scrollable" => 'keyset' ));
		$output .= '<option value="">Select name</option>';
		while($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)){
			$output .='<option value="'.$row["name"].'">'.$row["name"].'</option>';
		}
	}

Matko boska, bój się boga!! Przecież tutaj masz XSS i SQLInjection w jednym.

Nie łącz w taki sposób danych i HTML'a/SQL'a! Użyj prepared statements w sqlsrv_query oraz htmlEntities() kiedy łączysz HTML'a i dane:

$output = '';
$result = sqlsrv_query($conn, "SELECT name FROM blog_categories_submenu where submenu = '?' GROUP BY name", [$_POST["query"]]);
$output .= '<option value="">Select name</option>';
while ($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) {
    $output .= '<option value="' . htmlEntities($row["name"]) . '">' . htmlEntities($row["name"]) . '</option>';
}

PS: Poza tym już Ci kiedyś pokazywałem jak oddzielić persystencję od widoku, w najprostszy sposób możesz to zrobić tak:

function names() {
    $result = sqlsrv_query($conn, "SELECT name FROM blog_categories_submenu where submenu = '?' GROUP BY name", [$_POST["query"]]);
    while ($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) {
        yield $row["name"];
    }
}

$output = '<option value="">Select name</option>';
foreach (names() as $name) {
    $output .= '<option value="' . htmlEntities($name) . '">' . htmlEntities($name) . '</option>';
}
1

przy wyborze ostatniego selecta robisz $query = 'Select * from MIASTO' i potem jak fetch zrobisz to dajesz w ajaxie '$('#id_iput1').val($query['populacja']) '$('#id_iput1').val($query['duperele']) i tyle

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