Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][JavaScript]Case'y w JS w zależności od wartości w bazie
Forum PHP.pl > Forum > Przedszkole
sadistic_son
Cześć.

W JS raczkuję. Mam taki skrypcik poniżej:
[JAVASCRIPT] pobierz, plaintext
  1. const dvdFields = document.getElementById('dvdFields');
  2. const bookFields = document.getElementById('bookFields');
  3. const furnitureFields = document.getElementById('furnitureFields');
  4. const selector = document.getElementById('productType');
  5.  
  6.  
  7. selector.addEventListener("click", () => {
  8. selector.addEventListener("change", () => {
  9. switch (selector.value) {
  10. case "DVD":
  11. dvdFields.style.display = 'block';
  12. bookFields.style.display = 'none';
  13. furnitureFields.style.display = 'none';
  14. break;
  15. case "Book":
  16. bookFields.style.display = 'block';
  17. dvdFields.style.display = 'none';
  18. furnitureFields.style.display = 'none';
  19. break;
  20. case "Furniture":
  21. furnitureFields.style.display = 'block';
  22. dvdFields.style.display = 'none';
  23. bookFields.style.display = 'none';
  24. break;
  25. default:
  26. furnitureFields.style.display = 'none';
  27. dvdFields.style.display = 'none';
  28. bookFields.style.display = 'none';
  29.  
  30. }
  31. });
  32. });
[JAVASCRIPT] pobierz, plaintext


Skrypt wyswietla lub chowa diy w zalezności od tego co mamy wybrane w SELECT. Żadne rocket science. Ale teraz wypadałoby aby wartości book, dvd, furniture nie były wpisane ręcznie, ale żeby ładowały się z bazy. Obecnie w bazie mam 3 rodzaje produktów, ale jak będzie ich 300... ?
Tak więc, jeśli rodzajów produktów będzie więcej to i case'ów powinno być automatycznie więcej. Jesli dodam do bazy rodzaj produktu 'sanki' no to powinien się dodać nowy case gdzie 'sankiFields' jest display:block a reszta ma 'none'.
Oczywiście wiem jak to zrobić w php, ale wrzucanie phpa do pliku js, lub trzymanie skryptu js w pliku *.php to chyba nie jest najlepsza praktyka. Pomóżcie jak to zrobić po bożemu.
Dzięki.
nospor
Generalnei sie zle za to zabrales. Nie tworzy sie dynamicznego switch...case tylko tworzy sie tablice/obiekt z informacjami co dany typ zawiera. I potem napodstawie tej tablicy sobie wyswietlasz/chowasz co tam chcesz.
I tak, taka tablice js buduje sie w php (czy tam systemie szablonow zalezy co masz) i w klada sie normalnie w kod strony html.

I kolejna rzecz, to nie robi sie milion HIDEow tylko swoim elementom nadajesz jakas klase np class="dynamic-elements" i potem chowasz wssystkie elementy z ta klasa i pokazujesz tylko te dla wybranego selecta i juz. Znacznie mniej kodu i dziala zawsze

No i na koniec:
selector.addEventListener("click", () => {
selector.addEventListener("change", () => {
co to jest?? w clicku dodajesz event change? Po grzyba? Czemu poprostu nie zdefiniiujesz tego even change i juz. Pomijajac bezsens obecnej logiki, to na dodatek za kazdym razem jak klikasz w element to tworzysz kolejny event change i ostattecznie skonczysz z tysiacem eventow na stronie wink.gif
sadistic_son
Cytat(nospor @ 3.01.2023, 12:27:07 ) *
(...) I tak, taka tablice js buduje sie w php (czy tam systemie szablonow zalezy co masz) i w klada sie normalnie w kod strony html.

ok, ale czy wrzucanie JS w html, zamiast w <head><script scr"skrypt.js" ... to nie jest zła praktyka? Normalnie miałbym to gdzieś, ale przy moim obecnym zadaniu best-practices są ważne.


Cytat(nospor @ 3.01.2023, 12:27:07 ) *
I kolejna rzecz, to nie robi sie milion HIDEow tylko swoim elementom nadajesz jakas klase np class="dynamic-elements" i potem chowasz wssystkie elementy z ta klasa i pokazujesz tylko te dla wybranego selecta i juz. Znacznie mniej kodu i dziala zawsze

Dobra, czyli zamist id="dvdFields", id="bookFields" wszystkim im nadaję class="dynamicFields" oraz display:none, a potem tylko temu który mam wybrany w select nadaję display:block. Dobrze rozumiem? W takim razie jak odróżnię te wszystkie co mają być niewidoczne od tego jednego co jest wybrany w select?



Cytat(nospor @ 3.01.2023, 12:27:07 ) *
selector.addEventListener("click", () => {
selector.addEventListener("change", () => {
co to jest?? w clicku dodajesz event change? Po grzyba? Czemu poprostu nie zdefiniiujesz tego even change i juz. Pomijajac bezsens obecnej logiki, to na dodatek za kazdym razem jak klikasz w element to tworzysz kolejny event change i ostattecznie skonczysz z tysiacem eventow na stronie wink.gif

Ok, zrezygnowałem z tego, zostawiłem tylko change. Click było mi potrzebne po to, że pierwotnie chciałem aby przy pierwszym kilknięciu w select już wybierało mi wartość domyślną, ale ostatecznie dodałem dodatkowy option z wartością 'please choose' i jest gituś.
nospor
Cytat
ok, ale czy wrzucanie JS w html, zamiast w <head><script scr"skrypt.js" ... to nie jest zła praktyka? Normalnie miałbym to gdzieś, ale przy moim obecnym zadaniu best-practices są ważne.

JA ci nie karze trzymac calego kodu js w pliku html. Ja ci tylko mowie, bys to co jest dynamiczne tylko wrzucil do html. Tak sie wlasnie robi.

Cytat
Dobra, czyli zamist id="dvdFields", id="bookFields" wszystkim im nadaję class="dynamicFields" oraz display:none, a potem tylko temu który mam wybrany w select nadaję display:block. Dobrze rozumiem? W takim razie jak odróżnię te wszystkie co mają być niewidoczne od tego jednego co jest wybrany w select?

Id mozesz zostawic bo po ID bedziesz przeciez pokazywal wybrane pola. Klasa sluzy glownie do chowania wssytkiego naraz. Oczywiscie chowasz za kazdym razem gdy w select wybor sie zmieni.

Cytat
W takim razie jak odróżnię te wszystkie co mają być niewidoczne od tego jednego co jest wybrany w select?

Noto mowie przeciez: chowasz zawsze wszystko co ma te klase, a pokazujesz tylko ten jeden co masz wybrany (po id)
sadistic_son
No dobra, rozumiem co masz na mysli.

A więc tak wygląda fragmencik źródła strony:
  1. <select id="productType" name="productType">
  2. <option value="Book">Book</option>
  3. <option value="DVD">DVD</option>
  4. <option value="Furniture">Furniture</option>
  5.  
  6.  
  7. <div class="dynamicFields" id="Book">
  8. Weight (kg)<input type="text" name="weight" id="weight" />
  9. </label><br />
  10. <div class="productPropertyDescription">Please provide the weight of book in kg.</div>
  11. </div>
  12.  
  13. <div class="dynamicFields" id="DVD">
  14. Size (MB)<input type="text" name="size" id="size" />
  15. </label><br />
  16. <div class="productPropertyDescription">Please provide size of DVD in MB.</div>
  17. </div>

elementy 'dynamicFields' mają w css ustawione 'display:none' domyslnie, bo chcemy je wyświetlić tylko jeśli są wybrane w selekcie (zdeterminujemy to po ich ID).

Do tego taki skrypcik:
[JAVASCRIPT] pobierz, plaintext
  1. const selector = document.getElementById('productType');
  2. const visible = document.getElementById(selector.value);
  3. const dynamicFields = document.getElementsByClassName('dynamicFields');
  4.  
  5. console.log(selector);
  6. console.log(visible);
  7.  
  8. selector.addEventListener("change", () => {
  9. visible.style.display = 'block';
  10. dynamicFields.style.display = 'none';
  11. })
[JAVASCRIPT] pobierz, plaintext

Niestety w konsoli JS dostaję:
Kod
Uncaught TypeError: Cannot read properties of null (reading 'style')
    at HTMLSelectElement.<anonymous> (scripts.js:7:13)
Czemu nie widzi tego elementu?
nospor
Jesli zrobisz
console.log(dynamicFields);
a mocno mnie rozczarowales ze jeszcze nei zrobiles,tongue.gif
to zobaczysz ze to jest teraz tablica (ewentualnie NULL) a nie jeden element wiec nie mozesz zrobic
dynamicFields.style.display = 'none';
sadistic_son
Mam tych console logów tutaj pełno, z value, bez value, z dupami i bez biggrin.gif No ale takich rzeczy przecież się na forum nie wkleja. No dobra - nie wiedziałem, że nie można masowo zmienić stylu dla wielu elementów. Zaraz... mozna. Nie można dla tablicy. No dobra, skoro nie dynamicFields.style.display = 'none'; to co? sad.gif Pętlą mam to jechać ?
nospor
skoro dynamicFields to tablica to lecisz po tablicy przy uzycui chocby FOR i zmieniasz style display dla kazdego elementtu tablicy. Tylko sie upewnij ze to tablica bo komunikat bledu jakby mowil ze to null?
sadistic_son
Ok, zaraz polecę pętlą, ale tymczasem dlaczego nawet w obecnej formie, po zmianie selecta na dowolną wartość cały czas jedynie wyświetla element o ID takim jak pierwsza wartość z option?
[JAVASCRIPT] pobierz, plaintext
  1. let selector = document.getElementById('productType');
  2. let visible = document.getElementById(selector.value);
  3. let dynamicFields = document.getElementsByClassName('dynamicFields');
  4.  
  5. console.log(selector);
  6. console.log(selector.value);
  7. console.log(visible);
  8. console.log(dynamicFields);
  9.  
  10. selector.addEventListener("change", () => {
  11. // dynamicFields.style.display = 'none';
  12. visible.style.display = 'block';
  13. })
[JAVASCRIPT] pobierz, plaintext

Tak jak by change zadziałał tylko jeden raz na początku.



EDIT:
oraz pętelka:
[JAVASCRIPT] pobierz, plaintext
  1. let selector = document.getElementById('productType');
  2. let visible = document.getElementById(selector.value);
  3. let dynamicFields = document.getElementsByClassName('dynamicFields');
  4.  
  5. console.log(selector);
  6. console.log(selector.value);
  7. console.log(visible);
  8. console.log(dynamicFields);
  9.  
  10. selector.addEventListener("change", () => {
  11. for (var i = 0; i < dynamicFields.length; i++) {
  12. let c = dynamicFields[i];
  13. c.style.display = 'none';
  14.  
  15. }
  16.  
  17. visible.style.display = 'block';
  18. })
[JAVASCRIPT] pobierz, plaintext
Nic to niestety nie zmieniło sad.gif
nospor
No przeciez visible masz ustawic w change() a nie kilometr wczesniej
sadistic_son
Cytat(nospor @ 3.01.2023, 14:19:25 ) *
No przeciez visible masz ustawic w change() a nie kilometr wczesniej

Aaaaaa, no taaak biggrin.gif
Działa dzięki biggrin.gif

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.