Dynamiczny formularz oparty o elementy <select> + JS

Odpowiedz Nowy wątek
2011-12-12 19:02
0

Witam,

Mam kłopocik odnośnie tego, co w temacie. Otóż mam sobie formularz, który jest statyczny oparty na elementach SELECT, natomiast zmieniać się mają elementy <option> w tym "selekcie". Mam 6 selektów, z czego tylko pierwszy jest dostępny, pozostałe mają flagę disabled. Jaki chciałbym efekt?

  1. Wybieram z pierwszego selektu (wygenerowanego przez kod PHP) markę samochodu. Wszystko pobierane jest z bazy danych.
  2. Funkcja w OnChange odblokowuje drugi element (to działa).
  3. Odblokowany drugi selekt ma mieć elementy zależne od pierwszego wybranego (jeśli np. wybiorę Volkswagen, to elementy drugiego selektu mają być pobierane z bazy danych poprzez skrypt PHP "./operations/edit_car/operations.php w którym jest funkcja to robiąca). Chcę to zrobić na zasadzie Javascript (JQuery albo cokolwiek innego) by elementy zostały dynamicznie wstawione, a przy zmianie elementu pierwszego selekta np. na Seat, zostały usuniete wszystkie elementy w drugim i pobrane zostałyby nowe modele. Tutaj zaczynam się zawieszać , bo nie wiem jak podejść do tego kłopotu. mam taki kod:

plik operations.php:

<?php
//ŁADOWANIE MODELI NA PODSTAWIE PODANEJ MARKI
if (isset($_REQUEST['mark']))
{
    include('../open_database.php');
    $query="SELECT model FROM cars WHERE mark='".$_REQUEST['mark']."'";
    $result=mysql_query($query);
    mysql_close($conn);    
    $poprzedni='none';
    if($result==false)
        exit;
    while($res=  mysql_fetch_row($result))
    {
        if ($res['model']!=$poprzedni)
        {
                $poprzedni=$res['model'];
                echo '<option value="'.$res['model'].">".$res['model']."</option>";               
        }           
    }
}

?> 

a teraz plik JS:

function add_option(id,zm,skad)
{
    var selected = document.getElementById(skad).value;
    var str = window.location.pathname;
    var directory = str.replace(/index.php/i,"");
    var zmienna= zm;
    var rootdomain_withouts="http://"+window.location.hostname+directory;
    alert(rootdomain_withouts);
    $('document.getElementById('+id+')').load(rootdomain_withouts+"operations/edit_car/actions.php", { zmienna : selected} );

} 

Czy pomożecie rozwiązać problem?

edytowany 1x, ostatnio: johny_noc, 2011-12-12 19:04

Pozostało 580 znaków

2011-12-12 19:55
0
  1. "Select Distinct" - poczytaj co robi
  2. napisz jeszcze co jest źle w ogóle
  3. zainwestuj (tzn ściągnij za darmo) w firebuga, bądź jakiekolwiek inne narzędzie tego typu (google Ci pomoże) - sprawdzisz sobie np czy ścieżka, z której ładujesz dane jest poprawna.
  4. dopiero teraz zauważyłem ostatnią linijkę w js. WTF? $('document.getElementById('+id+')') zastąp $('#'+id)

Pozostało 580 znaków

2011-12-12 21:49
0
  1. Ok poczytam (piszę pracę inżynierską jednocześnie się ucząc programowania w tych językach)
  2. Źle jest to, że nie wysyła nic do pliku php o ile w ogóle go widzi... nie wiem jakiej metody tu użyć. Mało poradników na necie i są niezrozumiałe.
  3. Ścieżki są ok , bo wyświetliłem sobie alert'em, więc funkcja w ogóle wchodzi ze wszystkimi parametrami.
  4. Poprawiłem zgodnie z zaleceniem, jednak to nie rozwiązało mojego problemu.

PRZEPRASZAM ZA MOJĄ NIEWIEDZĘ I WSZELKIE DZIWACTWA KTÓRE TU WIDAĆ :)
WYJAŚNIAM.
Mam 2 selecty:

MARKA SAMOCHODU | | MODEL SAMOCHODU | <-- ten nieaktywny na dzień dobry :)

Przy wybraniu z listy jakiejś marki, pierwsza pozycja z tego menu (o treści wybierz samochód) zostaje usunięta zdarzeniem OnChange i funkcją napisaną w JS, więc jest si. Kolejna funkcja w tym samym zdarzeniu OnChange aktywuje kontrolkę obok (selecta) no i jest trzecia funkcja (wlasnie ta gdzie znalazles krzaki w ostatniej linijce)... od tej funkcji oczekuję, że gdy przekażę parametry: id_aktywnej kontrolki z której wybieram obecnie, nazwa zmiennej (w pliku php będę ją uzależniał np. jeśli marka jest przekazywana to będzie wybierany model, jeśli model, to rocznik trzeba będzie pobrać z bazy danych itp) oraz nazwa docelowej kontrolki w której mają zostać wpisane dane, to ta funkcja odpowiednio manipulując swoimi argumentami (manipulację pomijam bo do tego już doszedłem i zrobiłem poprawnie) wyśle zmienną mark='nazwa_marki' do pliku operations.php w którym to dojdzie do pobrania danych z bazy danych i jednocześnie wklejenia kodu <option value="wartość">wartość</option>. A więc w JS muszę użyć chyba funkcji innerHtml aby wkleić ten kod właśnei do elementu docelowego i żeby wewnątrz tego innerHtml było odwołanie do pliku php który przecież generuje kod HTML.

Nie wiem czy dosyć jasno to opisałem, to zagmatwane :) wybacz.

PS. Select Distinct sie do czegoś przyda? :) już zrobiłem funkcję która eliminuje powtórzenia, chyba że ona obciąża serwer. Z tym, że to, co robię to panel Admina, więc jak już tylko jedna osoba (właściciel autokomisu) ma wgląd do edycji samochodu dostępnego na jego terenie... proszę zatem o poradę :)

edytowany 1x, ostatnio: johny_noc, 2011-12-12 21:52

Pozostało 580 znaków

2011-12-13 08:47
0

Select distinct jak najbardziej! Od tego masz bazę danych, żeby dane filtrować na poziomie bazy danych. Przecież równie dobrze można by wybrać wszystkie kolumny i wszystkie wiersze i następnie przefiltrować to w php - ale to bez sensu.

druga rzecz:
robisz coś takiego { zmienna: selected } -- wbrew pozorom - "kluczem" nie będzie tu wartość zmiennej zmienna, a po prostu tekst zmienna.

Czyli:

var dupa = "test";
var dane = { dupa: 3 };
for (key in dane) { alert (key); }

wyświetli dupa, a nie test!

Trzeba zrobić coś takiego np:

var dupa = "test";
var dane = {};
dane[dupa] = 3;
for (key in dane) { alert (key); } // tutaj pojawi się "dupa"

Podejrzewam, że dlatego nie dostajesz oczekiwanej zmiennej w php. zrób to tak:

// w ogóle to tworzysz od cholery zmiennych, żeby wykonać na nich jedną operację - bez sensu.
// np jaki sens było robić var zmienna = zm; [?]

function add_option(id,zm,skad) {
    var selected = document.getElementById(skad).value;
    // skoro używasz jQuery to możesz tą linię zastąpić:
    // var selected = $('#'+skad).val();
    var path = "http://" + window.location.hostname + window.location.pathname.replace(/index.php/i,"");
    var path_2 = "operations/edit_car/actions.php";
    var dane = {};
    var dane[zm] = selected;
    $('#'+id).load(path + path_2, dane);
} 

Wydaje mi się, że to powinno wystarczyć.
Zainstaluj Firebuga/cokolwiek jak mówiłem i sobie otwórz zakładkę "Sieć", albo jak to się w Firebugu nazywa - będziesz widział wszystkie zapytania do serwera (i prawdopodobnie odpowiedź serwera na zapytanie - ja używam odpowiednika Firebuga dla Opery i nie wiem)


edytowany 1x, ostatnio: dzek69, 2011-12-13 08:47

Pozostało 580 znaków

2011-12-13 15:31
0

to tworzenie wielu zmiennych (tzn kopii zm ) stworzyłem bo nie wiedziałem dlaczego podkreślało mi zm, a po najechaniu na to, pojawila sie informacja "variable is never used" wiec stwierdzilem, ze podstawienie zmiennej pod nową da jakis efekt. Wiem, to byl moj blad tylko dlatego, ze ucze sie dopiero Jav'y.
Każdy ma prawo na głupotę podczas nauki :) Teraz wiem, że ta zmienna wogóle nie jest przekazywana tylko nazwa zmiennej będzie taka a nie inna :)

A co do PHP to po prostu nie wiedziałem o istnieniu zapytania SELECT DISTINCT. Teraz skoro wiem, to zastosuję to.
Już się zabieram za poprawę skryptu :) dam znać o wynikach za jakąś chwilkę w edycji postu :) pozdrawiam

javascriptu! nie javy! - dzek69 2011-12-13 16:20

Pozostało 580 znaków

2011-12-13 15:44
0

Niestety nie ma pożądanego efektu. Dalej dzieje się to samo. Pokażę formularz generowany funkcją .load() w div'ie:

<h3>Edytuj dane istniejącego samochodu</h3>
<form action="./operations/edit_car.php" method="POST">
    <table style="width: 100%; text-align: right; margin-bottom: 15px;">
        <tr>
           <td style="width: 50%">
                <label>Dostępne marki:</label>
                <select name="mark" class="pole_wyboru" id="mark_list" OnChange="zmien_stan('model_list',false); usun_opcje('mark_list','none'); add_option('model_list','mark','mark_list');">
                    <option value="none">wybierz markę</option>

```php
<?php
                            //DO FUNKCJI JQuery load() NALEŻY PODAĆ W FUNKCJI INCLUDE BEZWZGLĘDĄ ŚCIEŻKĘ DOSTĘPU DO PLIKU PHP
                            $katalog=str_replace('/pages/subpages/edit_car.php', '', $_SERVER['SCRIPT_FILENAME']);
                            include($katalog.'/operations/open_database.php');
                            $query='SELECT DISTINCT mark FROM cars ORDER BY mark ASC';
                            $result=mysql_query($query);
                            mysql_close($conn);                          
                            while ($res=mysql_fetch_assoc($result))
                            {
                                echo '<option value="'.$res['mark'].'">'.$res['mark'].'</option>';
                            }      
                        ?>
                </select>
            <td style="width: 50%">
                <label>Dostępne modele:</label>
                    <select name="model" class="pole_wyboru" id="model_list" disabled="disabled" OnChange="usun_opcje('model_list','none');zmien_stan('year_list',false);">
                        <option value="none">wybierz model</option>
                    </select>
    </table>
    <br/>
    <br/>
    <br/>
    <br/>   
   <button class="btn_login" id="ok" type="submit" style="border: 1px black solid; color:black;" onclick="close_window('box'); return true"><img src="./img/icon-change.png" alt="+"/> &nbsp; Wybierz</button> &nbsp;
   <button class="btn_logout" id="cancel" type="button" style="border: 1px black solid; color: #9f0000;" onclick="close_window('box'); return false"><img src="./img/icon-back.png" alt="-"/> &nbsp; anuluj</button>
</form>; 

Zaś nowy skrypt JS wygląda tak (ze wszystkimi funkcjami):

function add_option(id,zm,skad) 
{
    var selected = $('#'+skad).val();
    var path = "http://" + window.location.hostname + window.location.pathname.replace(/index.php/i,"");
    var path_2 = "operations/edit_car/actions.php";
    var dane = {};
    dane[zm] = selected;
    $('#'+id).load(path + path_2, dane);
} 

function zmien_stan(idobiektu,blokada)
{
    document.getElementById(idobiektu).disabled=blokada;
}

function usun_opcje(idobiektu,opcja)
{
    $("#"+idobiektu+" option[value='"+opcja+"']").remove();
} 

Plik PHP uległ lekkiej zmianie (dodałem SELECT DISTINCT :) zgodnie z zaleceniem). Teraz pytanie odnośnie funkcji .load(). Jeśli przesyłamy szereg parametrów do skryptu php to jak potem je w skrypcie php odczytać? Będzie to w tablicy superglobalnej $_REQUEST['nazwazmiennej'] , czy może w tablicy $_POST['NAZWAZMIENNEJ'] a może w $_GET['...']?? Robię to po raz pierwszy dlatego jestem taki zielonobrunatny :) Dziękuję z góry za pomoc mistrzu :D

edytowany 2x, ostatnio: johny_noc, 2011-12-13 15:48

Pozostało 580 znaków

2011-12-13 16:26
0

czekaj, ty chcesz podmienić tylko zawartość jednego selecta, tak? to dlaczego php zwraca aż tyle tego wszystkiego? Twój php powinien zwracać w takim przypadku tylko parę "optionów" (już nie mówiąc o użyciu json i wysłaniu tylko par wartość/opis - ale to nie będziemy mieszać)

zainteresuj się funkcją $.ajax - łatwiej moim zdaniem prześledzić co się dzieje, niż w przypadku $.load

zmienne będą oczywiście w $_GET w przypadku load (ale zajrzyj do dokumentacji, ja nigdy load nie używałem z ww. powodu - metoda ajax jest bardziej rozbudowana).

o $_REQUEST zapomnij, że istnieje i nigdy nie używaj - może być z tego w skrajnych przypadkach więcej złego niż dobrego.


Pozostało 580 znaków

2011-12-13 18:54
0

teraz mam coś takiego:

function add_option(id,zm,skad) 
{
    //czyścimy całkowicie kolejny element
    var select = document.getElementById(id);
    while(select.hasChildNodes()) 
    {
        select.removeChild(select.firstChild);       
    } 
    var selected = $('#'+skad).val();
    var path = "http://" + window.location.hostname + window.location.pathname.replace(/index.php/i,"");
    var path_2 = "operations/edit_car/actions.php";
    var dane = {};
    dane[zm] = selected;
    //$('#'+id).load(path + path_2, dane);
    $('#'+id).innerHTML=wczytaj_plik(path+path_2,zm,dane[zm]);

}  
    //WCZYTANIE HTML ZA POMOCĄ AJAXA
    var ajax_method = typeof XMLHttpRequest == "undefined"?new ActiveXObject('Microsoft.XMLHttp'):new XMLHttpRequest();
    function wczytaj_plik(nazwa, zmienna, wartosc) 
    {
        ajax_method.onreadystatechange = function(){
                if (ajax_method.readyState == 1) {
                        ladowanie();
                }
                if (ajax_method.readyState == 4) {
                        if (ajax_method.status == 200) {
                                wynik(ajax_method.responseText);
                        }
                        else {
                                blad(ajax_method.status);
                        }
                }
        };
        ajax_method.open( "POST", nazwa, true );
        ajax_method.setRequestHeader('Content-Type',
        'application/x-www-form-urlencoded');
        ajax_method.send(zmienna + "=" + encodeURIComponent(wartosc));  
    } 

Sprawdziłem tym dodatkiem do FF który mi poleciłeś... Nagłówki faktycznie są wysyłane POST zmienna=wartość i są to mark=Volkswagen (przy tym wyborze), ale odpowiedź serwera jest zerowa... Nie ma odpowiedzi ani kodu HTML w odpowiedzi serwera. Serwer tylko odpowiedział nagłówkiem... Sprawdziłem katalogi - są wpisane dobrze jak i nazwa skryptu php. Sprawdzam to na serwerze lokalnym Apache. Nie wiem co robię źle. Ta metoda dała taki sam efekt jak funkcja .load() (takie same nagłówki widzę i 0 odpowiedzi w Firebug) tylko więcej pisania. Masz jakieś jeszcze pomysły? Zaczyna mnie to denerwować... a nie chcę motłochu z bazy danych pobierać :(

edytowany 1x, ostatnio: johny_noc, 2011-12-13 19:26

Pozostało 580 znaków

2011-12-13 23:12
0

skoro używasz już jQuery to zrób sobie zamiast

var select = document.getElementById(id);
    while(select.hasChildNodes()) 
    {
        select.removeChild(select.firstChild);       
    } 

takie:

 $('#'+id).html('');

i do ajaxa też użyj jQuery (google, dokumentacja!)

jeżeli skrypt zwraca pustą treść - to raczej cos jest nie tak z PHP - nie z JS.

używasz $_REQUEST['mark'] - zaprzestań tego. Odwołuj się do $_POST i $_GET.

napisz sobie w swoim pliku php który wywołujesz na samym początku: die('dupa'); - zobacz, czy w JS odbierzesz tę dupę - "debugowanie przez dupczenie" to się nazywa ;) głupie, ale jakże skuteczne. dowiesz się, czy na pewno odwołujesz się do poprawnego skryptu. potem zrób sobie np: print_r($_POST); die(); --- zobaczysz co zwróci serwer, czy widzi Twoje dane z POST - i tak małymi kroczkami dojdziesz do tego, co i gdzie jest źle.


Pozostało 580 znaków

2011-12-14 00:52
0

nie jestem aż tak głupi :) metodę przez "dupczenie" znam i zastosowałem . nawet przy niej mam 0 odpowiedzi :) w tym cały problem.

Pozostało 580 znaków

2011-12-14 09:08
0

To znaczy, że nie umiesz jej zastosować ;) Tak naprawdę ktoś, kto ogarnia debugging - poradzi sobie z każdym skryptem - będzie coś kombinował, ale nigdy nie stanie w miejscu.
Ciężko jest tak zdalnie pomóc, skoro nie mam przed sobą Twojego kodu, w którym mogę grzebać i mojego Dragonflya (Firebuga).

Ale nie odpowiedziałeś nic nt. moich kroków. Czy die('dupa') coś zwraca? itd.


edytowany 1x, ostatnio: dzek69, 2011-12-14 09:08

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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