Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP] Formularz - checkbox.
Forum PHP.pl > Forum > Przedszkole
Goldunube
Witam.

Tworzę stronę internetową, którą zalogowany użytkownik będzie mógł spersonalizować według swoich upodobań.
By tego dokonać, będzie musiał uprzednio wypełnić formularz złożony z checkbox'ów.
Checkbox'y są podzielone następująco:

Warzywa
- Marchew
- Ogórek
- itd...

Owoce
- Jabłko
- Pomarańcz
- itd...

Napisałem skrypt, który dodaje do BD zaznaczone przez użytkownika checkbox'y. Zadbałem również o to by w przypadku ponownego wysłania tego formularza z tymi samymi zaznaczonymi pozycjami, były one w BD nadpisywane, a nie dopisywane.
Dodałem również skrypt pobierający z BD wybrane wcześniej pozycje i wyświetlający te rekordy jako zaznaczone checkbox'y (checked=checked).

Problem z którym nie wiem jak się prawidłowo uporać, pojawia się w momencie, gdy użytkownik chce odznaczyć wybrane / wybrany wcześniej checkbox.
Tu pojawia się moje pytanie.

Czy napisać skrypt, którzy przed każdym ponownym zapisem wybranych checbox'ów do BD usuwałby wszystkie poprzednie wpisy dla tego użytkownika, czy raczej napisać skrypt, który porównywałby ilość rekordów w BD z obecną ilością zaznaczonych checkbox'ów i porównując produkty po ID, usuwałby tylko te przy których nie zaznaczono checbox'a ?


A może w ogóle realizuje się to w zupełni inny sposób na który nie wpadłem? AJAX / JQUERY questionmark.gif
Z góry dziękuję za wszelkie podpowiedzi.

Serdecznie pozdrawiam
Adam K.
lukaskolista
ja bym to zrobil w 1 tabeli, czyli tabeli z polami
ogorek
marchewka
jablko
banan
i za kazdym razem updateowalbym wszystkie pola tabeli (1 zapytanie do bazy mnie o zaznaczone juz checkboxy i 1 petla na przetworzenie tego mnie) w zaleznosci od tego, czy checkbox zostal zaznaczony czy nie.

Cytat
czy raczej napisać skrypt, który porównywałby ilość rekordów w BD z obecną ilością zaznaczonych checkbox'ów i porównując produkty po ID, usuwałby tylko te przy których nie zaznaczono checbox'a ?
to wydaje mi sie lepsze
Goldunube
Dzięki Kolego za odpowiedź.

Widzisz w moim przypadku sprawa z tabelami jest trochę bardziej skomplikowana.

Wymyśliłem sobie to tak:

1. Tabela "uzytkownicy" - wiadomo, przechowuje ID uzytkownika, imie, nazwisko itp.
2. Tabela "produkty" - przechowuje ID produktu, nazwę produktu ("ogórek", "marchewka", itp...) oraz ID grupy produktów
3. Tabela "grupa_produktow" - przechowuje ID grupy produktów, oraz nazwę grupy ("warzywa", "owoce", itd)
4. Tabela "wybrane_produkty" - przechowuje ID uzytkownika, oraz ID Produktu

Tabela numer 4 opisuje tą tak zwaną personalizację w moim projekcie. Otóż każdy użytkownik może sobie wejść do swojego profilu i wybrać produkty, które go interesują. Wybrane produkty przy pomocy checkbox'ów przechowywane są właśnie w tabeli nr. 4.
W przypadku dodawania nowego produktu sprawa jest prosta, każdy checkbox ma z bazy przypisany numer ID produktu, który reprezentuje. Po wysłaniu formularza, numer ten wpada do tabeli numer 4.

Gorzej sytuacja wygląda w momencie gdy użytkownik wchodzi do swojego profilu. Wcześniej zaznaczył produkt "ogórek", dzięki czemu w jego profilu checkbox "ogórek" wyświetlany jest jako "checked". Jednakże użytkownik chciałby teraz odznaczyć pole ogórek i tu pojawia się problem. Gość odznacza checkboxa, wysyła taki formularz i oczekuje, że w jego profilu zostanie ten wpis usunięty.

Moje pytanie jak to sprawnie zrobić...
Sposób z porównywaniem wpisów w Tabeli 4 z obecnie zaznaczonymi checkboxami, wydaje się rozwiązywać ten problem, jednakże nie jestem jakoś przekonany, czy tak to powinno się robić... Żeby to zrealizować musiałbym pobrać wszystkie rekordy z tabeli 4 przypisane danemu użytkownikowi, wrzucić to w tablice po czym musiałbym wykonać tyle IF 'ów ile mam checkbox'ów w formularzu.

Jeżeli się mylę to bardzo proszę o wyprowadzenie mnie z błędu wink.gif

Pozdrawiam
Adam K.
nekomata
Mhmm napisałeś [qoute] wpisów w Tabeli 4 z obecnie zaznaczonymi checkboxami, [/qoute] i [qoute]4. Tabela "wybrane_produkty" - przechowuje ID uzytkownika, oraz ID Produktu[/qoute] myślę że miałeś namyśli porównanie wpisów z tabeli 3 (grupa_produktow) z 4 (wybrane_produkty) chyba możesz to zrobić mysql
  1. <?php
  2. $query = "SELECT * ".
  3. "FROM grupa_produktow LEFT JOIN wybrane_produkty ".
  4. "ON grupa_produktow.id = wybrane_produkty.id_produktu WHERE wybrane_produkty.id_uzytkownika ='".$_SESSION['user']['id']."' OR wybrane_produkty.id_uzytkownika=null";
  5. $result = mysqli_query($dbc,$query)
  6. echo '<pre>';
  7. while($row = mysql_fetch_array($result)){
  8. print_r($row);
  9. }
  10. echo '</pre>';
  11. ?>

coś takiego może ci pomoże , bazowałem na przykładzie z tizag (pisałem z palca i na oko więc prawdopodobnie nie działa haha.gif) URL

// EDIT
Więc tak , z powodu iż moja własna niewiedza mnie trochę boli , użyłem mocy gugle i znalazłem odpowiedź (przetestowałem nawet) , wszystko przedstawie w poniższym kodzie na którym testowałem.
grupa_produktow
  1. SET FOREIGN_KEY_CHECKS=0;
  2. -- ----------------------------
  3. -- Table structure for `grupa_produktow`
  4. -- ----------------------------
  5. DROP TABLE IF EXISTS `grupa_produktow`;
  6. CREATE TABLE `grupa_produktow` (
  7. `id` tinyint(4) NOT NULL AUTO_INCREMENT,
  8. `grupa` varchar(20) DEFAULT NULL,
  9. `produkt` varchar(20) DEFAULT NULL,
  10. PRIMARY KEY (`id`)
  11. ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
  12.  
  13. -- ----------------------------
  14. -- Records of grupa_produktow
  15. -- ----------------------------
  16. INSERT INTO `grupa_produktow` VALUES ('1', 'ziemniory', 'bulwa');
  17. INSERT INTO `grupa_produktow` VALUES ('2', 'ziemniory', 'pestycyd');
  18. INSERT INTO `grupa_produktow` VALUES ('3', 'ziemniory', 'stonki');
  19. INSERT INTO `grupa_produktow` VALUES ('4', 'ogorki', 'zielone');
  20. INSERT INTO `grupa_produktow` VALUES ('5', 'ogorki', 'zolte');
  21. INSERT INTO `grupa_produktow` VALUES ('6', 'pyry', 'kartofel bury');

wybrane_produkty
  1. -- ----------------------------
  2. -- Table structure for `wybrane_produkty`
  3. -- ----------------------------
  4. DROP TABLE IF EXISTS `wybrane_produkty`;
  5. CREATE TABLE `wybrane_produkty` (
  6. `id_uzytkownika` tinyint(4) NOT NULL,
  7. `id_produktu` tinyint(4) NOT NULL
  8. ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
  9.  
  10. -- ----------------------------
  11. -- Records of wybrane_produkty
  12. -- ----------------------------
  13. INSERT INTO `wybrane_produkty` VALUES ('7', '2');
  14. INSERT INTO `wybrane_produkty` VALUES ('7', '1');

plik *.php którym testowałem
  1. <?php
  2. define('DB_USER','neko');
  3. define('DB_PASS','tajnehaslo');
  4. define('DB_HOST','localhost');
  5. define('DB_NAME','warzywa');
  6. $dbc = mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME,3306) or die('cannot connect to mysql');
  7. $_SESSION['user']['id'] = '7';
  8. $query = "SELECT * ".
  9. "FROM grupa_produktow LEFT JOIN wybrane_produkty ".
  10. "ON grupa_produktow.id = wybrane_produkty.id_produktu WHERE wybrane_produkty.id_uzytkownika ='".$_SESSION['user']['id']."' OR wybrane_produkty.id_uzytkownika IS null";
  11. $query = mysqli_query($dbc,$query) or die(mysqli_error($dbc));
  12. echo '<pre>';
  13. while($row = mysqli_fetch_array($query,MYSQLI_ASSOC)){
  14. print_r($row);
  15. }
  16. echo '</pre>';
  17. ?>

Wynik wyglada tak
Kod
Array
(
    [id] => 1
    [grupa] => ziemniory
    [produkt] => bulwa
    [id_uzytkownika] => 7
    [id_produktu] => 1
)
Array
(
    [id] => 2
    [grupa] => ziemniory
    [produkt] => pestycyd
    [id_uzytkownika] => 7
    [id_produktu] => 2
)
Array
(
    [id] => 3
    [grupa] => ziemniory
    [produkt] => stonki
    [id_uzytkownika] =>
    [id_produktu] =>
)
Array
(
    [id] => 4
    [grupa] => ogorki
    [produkt] => zielone
    [id_uzytkownika] =>
    [id_produktu] =>
)
Array
(
    [id] => 5
    [grupa] => ogorki
    [produkt] => zolte
    [id_uzytkownika] =>
    [id_produktu] =>
)
Array
(
    [id] => 6
    [grupa] => pyry
    [produkt] => kartofel bury
    [id_uzytkownika] =>
    [id_produktu] =>
)

Mam nadzieję że pomogłem , jak nie to nie narzekam przy okazji nauczyłem się czegoś nowego happy.gif
Goldunube
Niestety nie o to mi chodzi wink.gif
Sorrki za to, że się naszukałeś niepotrzebnie rozwiązania.

Widzisz, mój formularz jest tworzony przy pomocy skryptu. Skrypt pobiera z bazy danych produkty zapisane w Tabeli nr. 2 "produkty", dzieli je na grupy według Tabeli nr. 3 "grupy_produktow" i w takiej podzielonej postaci wyświetla je w formie checkbox'ów. Z racji tego, że te checkbox'y są tworzone na podstawie rekordów zaciągniętych z bazy danych, nie ma żadnego problemu, żebym przy okazji zaciągał również ID produktu (np. w postaci input "hidden") który jest wyświetlany obok danego checkbox'a. Żeby jeszcze bardziej zobrazować tą sytuację podam przykład.
W tabeli "produkty" przechowuję m. in. rekord: "arbuz", któremu został przydzielony ID = 10. Przy pomocy skryptu pobieram wszystkie rekordy z tej tabeli i wyświetlam pogrupowane na stronie w postaci:

  1. <label><input type="checkbox" value=" <?php echo id_produkt(); // funkcja zwracająca ID produktu, w tym przypadku: 10 ?> " /> <?php echo nazwa_produktu(); //funkcja zwracająca nazwę produktu w tym przypadki: arbuz ?> </label>


Mam nadzieję, że jest to w miarę czytelne.
Teraz gdy mam ileś tam tak zbudowanych checkbox'ów, w momencie gdy wysyłam formularz, skrypt pobiera mi ID produktu wpisanego w checkbox, oraz z sesji pobiera ID użytkownika i taki rekord umieszcza w bazie danych w tabeli "wybrane_produkty". Z tym nie ma problemu.
Dodatkowo strona skonstruowana jest w ten sposób, że w momencie gdy użytkownik chce ponownie dokonać zmian w swoim profilu, to wyświetla mu się formularz z zaznaczonymi wcześniej przez niego produktami. W omawianym przypadku pojawi mu się zaznaczony checkbox "arbuz". To jest proste.
Problem pojawia się w momencie gdy ten użytkownik wchodząc ponownie na swój profil, chce odznaczyć tego durnego arbuza. Odznacza go i wysyła formularz przy pomocy submit'a "ZAPISZ".
I teraz jak mam to zrobić, żeby skrypt wychwycił to, że użytkownik odznaczył tego checkbox'a i na tej podstawie usunął ten i tylko ten konkretny wpis z Tabeli "wybrane_przedmioty" smile.gif

Żeby to zrealizować wymyśliłem dwa sposoby. Mimo tego, iż każdy z tych sposobów jest w stanie zrealizować to czego oczekuję, to wydają mi się one mało "sensowne" / optymalne...

Pierwszy sposób polega na usuwaniu w pierwszym kroku wszystkich produktów przypisanych do danego użytkownika po czym w drugim kroku skrypt by dodawał aktualnie wybrane przy pomocy checkbox'ów produkty. Sposób ten jest bardzo prosty do wykonania, jednakże przy każdej nawet pojedynczej zmianie w profilu, usuwałby wszystkie rekordy przypisane do danego użytkownika i wpisywałby je na nowo nie uwzględniając jedynie tych odznaczonych.

Drugi sposób polega na tym, że pobierałbym wszystkie rekordy z tabeli "wybrane_przedmioty" przypisane do danego użytkownika po czym zapisywałbym je do tablicy. Dla każdego takiego rekordu sprawdzałbym, czy istnieje zaznaczony, odpowiadający mu checkbox. Jeżeli nie istnieje checkbox, którego "value" równa się którejś z wartości w Tablicy, to kasuj ten wpis.

Który sposób jest lepszy? A może w ogóle takie zadania realizuje się przy pomocy innych narzędzi ?
nekomata
mhmm , nie możesz zrobić po prostu akcji "onclick" w jquery?zamiast cały formularz byś wysyłał tylko id zmienionego checkbox'a? a w php byś poprostu napisał (z get'a) że usuwasz albo dodajesz daną pozycje?
Goldunube
Mógłbym, tylko wtedy (o ile dobrze pojmuję technikę korzystania z AJAX'a / JQUERY) przy każdym "onclick" wysyłane by było zapytanie do bazy danych. Wszystko ok gdy testuje taką stronę, ale w momencie gdy zaczyna z niej korzystać ileś tam osób (na przykład 100 jednocześnie) to zapytania do bazy danych latają jak szalone. Boje się, że takie rozwiązanie może strasznie zamulić serwis. Niemniej tak jak powiedziałem wcześniej, nie mam zbyt dużego doświadczenia w programowaniu stąd pytania kieruję do Was. Być może moje obawy dotyczące przeciążenia serwisu są bezpodstawne ?
melkorm
1. Pobierasz dostępne opcje.
2. Pobierasz opcje zaznaczone przez użytkownika (może to być zrobione jednym zapytaniem z LEFT JOIN'em z poprzednim)
3. Sprawdzasz jakie opcje odznaczył, a jakie zaznaczył (array_diff) i czy znajdują się w ogóle na liście dostępnych opcji.
4. Usuwasz te które odznaczył jednym zapytaniem.
5. Dodajesz jednym zapytaniem (multi insert) opcje które zaznaczył ,ale wcześniej nie były zaznaczone.
Goldunube
A widzisz, Array_Diff to jest chyba właśnie to czego szukałem ! smile.gif Idę w takim razie kombinować.
Wszystkim bardzo dziękuję za pomoc i szybkie odpowiedzi na pytania. Mam nadzieję, że kiedyś również i ja się odwdzięczę smile.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.