Ajax przekazanie wartości zmiennej do thymeleaf w Spring boot

Ajax przekazanie wartości zmiennej do thymeleaf w Spring boot
AN
  • Rejestracja:prawie 7 lat
  • Ostatnio:około 4 lata
  • Postów:50
0

Cześć,
mam modal, w którym chciałbym wyświetlać produkty z koszyka. Produkty dodaję do koszyka przy pomocy ajaxa, po kliknięciu w button jest uruchamiana funkcja w ajaxie dodajDoKoszyka().
Mam tutaj zrobioną pętlę, która dodaje produkt do koszyka, a następnie pobiera listę i wyświetla ją w modalu. Jednak chciałbym to zrobić w inny sposób. Zamiast dodawać w ajaxie paragrafy z nazwą produktu chciałbym przekazać całą listę do modala, gdzie znajdowałby się div z th:each i tutaj byłaby zmienna powiedzmy **${listaProduktów} **, przy pomocy której mógłbym wyświetlać sobie co tylko chcę z tej listy. Czy jest możliwe przekazanie całej listy z ajaxa do zmiennej w thymeleafie? Bardzo proszę o pomoc.

Modal:

Kopiuj
<div class="modal fade" id="dodanoDoKoszykaModal" tabindex="-1">
                            <div class="modal-dialog">
                              <div class="modal-content">
                                <div class="modal-header">
                                  <h5 class="modal-title" id="dodanoDoKoszykaModalTitle">Dodano do koszyka</h5>
                                  <button type="button" class="close" data-dismiss="modal">
                                  </button>
                                </div>
                                <div class="modal-body"  id="dodanoDoKoszykaModalBody">
                                    <!-- W ten sposób chciałbym wyświetlać listę produktów z koszyka -->
                                    <div class="listaaaa" th:each="produkt : ${listaProduktow}">
                                        <p th:text="${produkt.nazwaProduktu}"></p>
                                    </div>
                                    
                                    <!-- Tak robię to teraz, w ajaxie dodaję do tego diva paragraf -->
                                    <div id="listaProduktow">
                                    </div>
                                </div>
                                <div class="modal-footer">
                                  <button type="button" class="btn btn-success" data-dismiss="modal">OK</button>
                                </div>
                              </div>
                            </div>
                          </div>

Funkcja dodawania produktu do koszyka w ajaxie:

Kopiuj
function dodajDoKoszyka(nazwaProduktu)
{
    url = "/test" + nazwaProduktu;
    
    $.ajax({
        type: "POST",
        url: url,
        beforeSend: function(xhr){
            xhr.setRequestHeader(csrfHeaderName, csrfValue);
        }
    }).done(function(response)
    {
        $("#dodanoDoKoszykaModalTitle").text("Koszyk");
        $.each(response, function(index, value){
            $("#listaProduktow").append($("<p>").text(value.nazwaProduktu));
        });

        $("#dodanoDoKoszykaModal").modal();
    }).fail(function()
    {
        $("#dodanoDoKoszykaModalTitle").text("Error");
        $("#dodanoDoKoszykaModalBody").text("Źle");
        $("#dodanoDoKoszykaModal").modal();
    });
}
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Rozumiesz ze thymeleaf to server-side-template? I renderuje się przy odpowiedzi z serwera? Jak twój koszyk jest client-side w JS to nijak nie da się to nic zaczarować.
Zrób to moze jak człowiek:

  • dodanie do koszyka wysyła request do serwera z produktami
  • serwer trzyma sobie stan koszyka
  • front wysyła ajaxa z pytaniem o koszyk i dostaje jsona z koszykiem

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
AN
  • Rejestracja:prawie 7 lat
  • Ostatnio:około 4 lata
  • Postów:50
0

Czyli jak rozumiem nie da się zrobić tego w taki sposób jak chciałem?
No ja teraz robię to tak, że kliknięcie buttona wywołuje funkcję w ajaxie, ponieważ nie mogłem wywołać metody z kontrolera. Żeby to zrobić musiałbym zrobić requesta, jednak nie chcę żeby po dodaniu do koszyka produktu przenosiło mnie na jakąś inną podstronę, chcę tylko żeby wyświetlił się modal z listą aktualnych produktów znajdujących się w koszyku.

Tylko jeśli z frontu wywołam funkcję z ajaxa, która ma pobrać listę produktów z koszyka to ja znowu tego nie przekażę do fronta, czy się mylę?

K5
  • Rejestracja:około 6 lat
  • Ostatnio:2 dni
  • Postów:1002
0
annonymouzinho napisał(a):

jednak nie chcę żeby po dodaniu do koszyka produktu przenosiło mnie na jakąś inną podstronę, chcę tylko żeby wyświetlił się modal z listą aktualnych produktów znajdujących się w koszyku.

A czemu ma Cię przenosić na inna podstronę? Wiesz co to jest Http Request?

Tylko jeśli z frontu wywołam funkcję z ajaxa, która ma pobrać listę produktów z koszyka to ja znowu tego nie przekażę do fronta, czy się mylę?

????????

Wysyłasz na backend request, dostajesz produkty obecnie znajdujące się w koszyku i je wyświetlasz. Jaki problem?

ps Kto Cię tak skrzywdził podpowiadając, że powinieneś uczyć sie javy webowej korzystając z Thymeleafa i Ajaxa?

edytowany 1x, ostatnio: kixe52
AN
Robię w kontrolerze PostMapping aby móc z poziomu html'a przy pomocy buttona wywołać odpowiednią metodę, ale wtedy przekierowuje mnie na tą podstronę.
K5
Łatwiej będzie jak podzielisz się swoim githubem, bo wyczuwam, że coś poszło nie tak już od samego początku pisania projektu. Nalegam abyś odpowiedział na moje pytanie w post scriptum ;p
AN
Nie mam githuba, mogę wysłać kawałek kodu gdzie wywołuję metodę z kontrolera i tego requesta w kontrolerze. A jeśli chodzi o jave webową, to jest to moja pierwsza styczność z nią, wybrałem sobie taki projekt, z thymeleafem wydaje mi się wszystko prostsze i łatwiejsze. A jeśli chodzi o Ajaxa to nie chciałem w ogóle z niego korzystać, ale no wydawało mi się, że bez niego nie uda mi się wywołać metody, która doda odpowiedni produkt do koszyka a następnie wyświetli modala z listą produktów w koszyku...
AN
  • Rejestracja:prawie 7 lat
  • Ostatnio:około 4 lata
  • Postów:50
0

Poniżej znajduje się kawałek kodu z podstrony produktów. Wyświetlane są tutaj wszystkie produkty znajdujące się w bazie danych.

Kopiuj
<div class="listaProdoktowContainer" th:each="produkt : ${listaProduktowNaStronie}">
                        <div class="col-sm-12">
                        <ul>
                            <li>
                                <button class="zdjecie" th:disabled="${produkt.dostepnosc_produktu}==false"
                                        th:onclick="'window.location.href = \'' + @{/{nazwaProduktu}(nazwaProduktu=${produkt.nazwaProduktu})} + '\''">
                                    <img th:src="@{${produkt.sciezka_zdjecia}}" width="180" height="130"/>
                                </button>
                            </li>
                            <li><span id="nazwaAktualnegoProduktu" th:text="${produkt.nazwaProduktu}"></span></li>
                            <li><span class="cena" th:text="${#numbers.formatDecimal(produkt.cena_brutto_produktu, 0, 2)} + ' zł'"></span></li>
                            <li>
                                <span th:switch="${produkt.dostepnosc_produktu}">
                                    <p class="produktDostepny" th:case="true">&#x2714 Produkt dostępny</p>
                                    <p class="produktNiedostepny" th:case="false">&#10006 Produkt niedostępny</p>
                                </span>
                            </li>
                            <!-- Tutaj wywołuje metodę z kontrolera -->
                            <li><button type="button" class="btn btn-warning dodajDoKoszyka" th:id="${produkt.nazwaProduktu}" th:disabled="${produkt.dostepnosc_produktu}==false" 
                                       th:onclick="'window.location.href = \'' + @{/test/{nazwaProduktu}(nazwaProduktu=${produkt.nazwaProduktu})} + '\''"
                                       >Dodaj do koszyka</button>
                            </li>
                            <li>
                                <div sec:authorize="hasRole('ROLE_ADMIN')">
                                <button type="button" class="btn btn-primary" id="edytujProdukt" th:onclick="'window.location.href = \'' + @{/edytuj_produkt/{id}(id=${produkt.idProduktu})} + '\''">Edytuj</button>
                                <button type="button" class="btn btn-danger" id="usunProdukt">Usuń</button>
                                </div>
                            </li>
                        </ul>
                        </div>
                    </div>

A tutaj jest kod metody z kontrolera, która dodaje produkt do listy, a następnie zwraca wszystkie produkty znajdujące się w koszyku. Jednak tak jak pisałem wyżej, zostaje przekierowany na tą podstronę, a tego nie chcę, chciałbym pozostać na stronie z produktami i żeby po kliknięciu buttona pojawił się modal, gdzie przy pomocy th:each przypisałbym do zmiennej właśnie listę produktów z koszyka i sobie to fajnie wyświetlił.

Kopiuj
@RequestMapping(value = "/test/{nazwaProduktu}", method = RequestMethod.POST)
    public List<Produkt> dodajProduktDoKoszyka(@PathVariable(name = "nazwaProduktu") String nazwaProduktu)
    {
        Optional<Produkt> produkt = produktRepo.findByNazwaProduktu(nazwaProduktu);
        produktService.dodajProduktDoKoszyka(produkt.get());

        List<Produkt> produkty_w_koszyku = produktService.pobierzProduktyZKoszyka();
        return produkty_w_koszyku;
    }
K5
  • Rejestracja:około 6 lat
  • Ostatnio:2 dni
  • Postów:1002
1
annonymouzinho napisał(a):

Poniżej znajduje się kawałek kodu z podstrony produktów. Wyświetlane są tutaj wszystkie produkty znajdujące się w bazie danych.
A jeśli chodzi o jave webową, to jest to moja pierwsza styczność z nią, wybrałem sobie taki projekt, z thymeleafem wydaje mi się wszystko prostsze i łatwiejsze.

Z thymeleafem nic nie jest prostsze. Powtórzę to 20 raz. Po co pchać się na początku przygody z webówką w widoki? Najpierw ogarnij swoje API RESTowe aby było poprawnie napisane, a dopiero potem dodawaj do tego front krok po kroku.

Chociażby w Twoim controllerze:

Kopiuj
@RequestMapping(value = "/test/{nazwaProduktu}", method = RequestMethod.POST)
    public List<Produkt> dodajProduktDoKoszyka(@PathVariable(name = "nazwaProduktu") String nazwaProduktu)
    {
        Optional<Produkt> produkt = produktRepo.findByNazwaProduktu(nazwaProduktu);
        produktService.dodajProduktDoKoszyka(produkt.get());

        List<Produkt> produkty_w_koszyku = produktService.pobierzProduktyZKoszyka();
        return produkty_w_koszyku;
    }

Po co Ci ten Optional skoro potem i tak używasz get() bez żadnego sprawdzania.
Poza tym cała ta 'logika' nie powinna być w controllerze.

edytowany 1x, ostatnio: kixe52
AN
  • Rejestracja:prawie 7 lat
  • Ostatnio:około 4 lata
  • Postów:50
0

No rozumiem, widocznie źle wybrałem ale niestety teraz już tego nie mogę zmienić muszę skończyć to tak jak zacząłem.
Optional jest, ponieważ tak to w repozytorium zrobiłem żeby w innym miejscu sprawdzić czy dany produkt istnieje, a nie chciałem robić drugiej takiej samej metody tylko bez optionala to tak już zostawiłem.
A wracając do mojego pytania, to czy mogę w jakiś sposób zrobić to tak żeby mnie nie przekierowywało na tą podstronę? I przekazać tą listę do modala?
Bo jeśli nie to chyba sobie odpuszczę wyświetlanie koszyka po dodaniu produktu do koszyka i wyświetlę po prostu informację, że produkt został dodany.

Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Myśle że twój problem polega na tym, ze nie wiesz ze jest coś takiego jak @RestController który zwraca "dane" a nie robi żadnych przekierowań na inną stronę ;) Jak używasz @Controller i zwracasz jakieś ModelAndView to niestety wszystko odbywa się na zasadzie request-response i przeładowuje stronę.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
K5
Mi się wydaje, że Autor ma jakiś misz masz. CopyPasta z innych tutoriali i tak wychodzi.
AN
Właśnie używam @RestController
Shalom
Ale jak niby łączysz thymyleaf z rest controllerem? o_O To jakieś pomieszanie z poplątaniem
AN
No może faktycznie nie ma to sensu skoro i tak mnie przekierowuje, więc zmienię adnotację chyba na @Controller
K5
  • Rejestracja:około 6 lat
  • Ostatnio:2 dni
  • Postów:1002
1
  1. Nie pisz po polsku.
  2. Popraw swoje API.
  3. Jakbyś wrzucił to na GH to byłoby prościej.
  4. Wywal tego TL'a.
  5. A jeśli, aż tak bardzo się przy nim upierasz to przeanalizuj co zwracasz z tej metody. Jak już bawisz się w TLa i widoki to powinieneś zwracać te właśnie widoki, a nie listę produktów. Coś w stylu: definiujesz sobie szablon koszyka i po każdej operacji dodaj/usuń zwracasz z API jego model.

NIe powinienem tego wklejać, skoro odradzam Ci TL'a, ale tutaj jest to w miarę OK napisane: https://github.com/reljicd/spring-boot-shopping-cart

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.