Formularze bez przeładowania strony

0

Witam,
mam listę produktów którą wyświetlam za pomocą php foreach, przy każdym produkcie jest możliwość wyboru rozmiaru jak i sztuk:

<?php foreach ($produkty_w_kategorii as $produkt): ?>

	<input type="hidden" class="id_produktu"  name="id_produktu" value="<?php echo $produkt->id?>">
	<input type="radio" class="rozmiar"  name="rozmiar" value="L" > L
	<input type="radio" class="rozmiar"  name="rozmiar" value="XL"> XL
	<input type="text" class="sztuk"  name="sztuk" placeholder="Ilość szt" value="1">	
			
	<button class="formsubmit">Dodaj</button>
<?php endforeach ?> 

I mam do tego taki kod js:

<script>
	$(document).ready(function(){

	$('.formsubmit').click(function(){
		$.post(" <?php echo base_url('produkty/koszyk'); ?> ", 
			{id_produktu: $('.id_produktu').val(), rozmiar: $('.rozmiar').val(), sztuk: $('.sztuk').val()}, 
			function(data){
				$('#response').html(data);
			}
		);
		
	});

});

</script>

I niestety kod ten działa w ten sposób że odczytuje dane (np wybrany rozmiar) tylko z pierwszego produktu wygenerowanego przez foreach i dodaje go do koszyka
Przy każdym produkcie jest taki formularz i przycisk jednak każdy przycisk tak jak by pobiera dane zawsze pierwszego produktu. Np jeśli zaznaczę inny rozmiar przy produkcie numer 1
a przycisk dodaj kliknę przy produkcie numer 3 to w koszyku jest tylko produkt nr 1 z wybranym rozmiarem.
Procedura samego dodawania do koszyka jest poprawna ponieważ działał poprawnie tylko że z przeładowaniem strony, a chce wyeliminować to przeładowanie.
Mam nadzieję że zrozumiecie o co mi chodzi :)

0

Hmmm wydaje mi się że closest() może Ci pomóc. Klikając na przycisk musisz pobrać wartości dokładnie z tego formularza. Closest pozwoli Ci pobrać najbliższe wartości. Ewentualnie możesz coś z $(this) pokombinować. Poczytaj sobie jak działa closest()

0

Albo zrób dla każdego produktu osobny formularz albo zamiast robić pole <input type="hidden" name="id_produktu"> zrób indeks do każdego pola: name="rozmiar[<?=$id_produktu;?>]", name="sztuk[<?=$id_produktu]".
W tej chwili masz zduplikowane nazwy pól i dlatego wczytuje Ci te pierwsze a pozostałe pomija.

0

Z id w name fajny pomysł, nawet myślałem o takim tylko jak to w php później pobrać, trzeba by pętle po wszystkich możliwych id? Jakiś inny pomysł?

0

$(this).closest('.id_produktu').val() działa coś takeigo ?

0

{id_produktu: $(this).closest('.id_produktu').val(), rozmiar: $(this).closest('.rozmiar').val(), sztuk: $(this).closest('.sztuk').val()},

nie działa, dla żadnego produktu z listy

1
PavlO. napisał(a):

Z id w name fajny pomysł, nawet myślałem o takim tylko jak to w php później pobrać, trzeba by pętle po wszystkich możliwych id? Jakiś inny pomysł?

Możesz zrobić jeszcze w ten sposób:

<input type="radio" name="produkt[<?=$produkt_id;?>][rozmiar]" value="XL">
<input type="number" name="produkt[<?=$produkt_id;?>][sztuk]" value="1">

a później jedziesz:

foreach ($_POST['produkt'] as $id => $info) {
    $rozmiar = $info['rozmiar'];
    $sztuk = (int) $info['sztuk'];
}
0

Okej to działa. Tylko jeszcze jak przenieść w javascript tą tablice produkt[<?=$produkt_id;?>] [rozmiar] // [sztuk] z wartościami z inpuów, bo poprzedni skrypt mój odpada, i nie wiem jak zastąpić w nim tą linijkę z danymi:

{id_produktu: $('.id_produktu').val(), rozmiar: $('.rozmiar').val(), sztuk: $('.sztuk').val()}, 

Próbowałem również w taki sposób, po dopisaniu do inputów class="forminput" ale też nie działa: (wyskakuje alert fali)

    $(document).ready(function(){

        $('.formsubmit').on('click',function(){
            var data = $('.forminput').serialize();
            
            $.ajax({
                type : "POST",
                url  : "<?php echo base_url('produkty/koszyk')?>",
                dataType : "JSON",
                data : {data},
                success:function(data)
                {
                    alert('SUCCESS!!');
                },
                error:function()
                {
                    alert('fail');
                }
            });

        });
    });

Problem teraz leży w odpowiednim przekazaniu w js "data".

1

serialize() używaj dla całego formularza a nie dla buttona. Myślę, że najlepszym dla Ciebie wyjściem jest zrobić dla każdego produktu osobny formularz, dać mu class np. productForm a później:

$('.productForm').submit(function() {
    var formData = $(this).serialize();

    $,ajax({
        data: formData,
        // ...
    });
});

Przy okazji daj <button type="submit">, aby można było formularz wysłać wciskając po prostu ENTER w polu tekstowym.

Jeśli chcesz od razu wysłać całą listę produktów a nie jeden wiersz to oczywiście użyj jednego formularza a po stronie php sprawdzaj czy $sztuk > 0 ;)

0

Zrobiłem tak jak poleciłeś:

    $('.productForm').submit(function() {
    var formData = $(this).serialize();

            $.ajax({
                type : "POST",
                url  : "<?php echo base_url('produkty/koszyk')?>",
                dataType : "JSON",
                data : formData,
                success:function(formData)
                {
                    alert('SUCCESS!!');
                },
                error:function()
                {
                    //alert('fail!'');
                    alert(formData);
       
                }
            });

        });

Po dodaniu <button type="submit"> występuje przeładowanie strony, ale to nie ważne na razie. Ważniejsze jest to że nie wiem czemu ale z js otrzymuje alert 'fail'. Przez co wyświetliłem sobie najpierw w alercie "data" przy tym wyskakiwał pusty alert tak jak by nie było żadnych danych, następnym razem w alercie(tym z errora) wyświetliłem sobie "formData" i tam są już jakieś dane. Więc dlaczego w data nic nie było? i js zwraca błąd, a nie wykonuje funkcji success? Może coś z typem danych nie tak? I jeszcze jedno pytanie w php jak odebrać te dane, w sensie $this->input->post( 'formData' ) one będą pod nazwą formData w post?

1

Aby uniknąć przeładowania, popraw kod na:

$('.productForm').submit(function(e) {
    e.preventDefault();
// ...

Żródło

Żeby sprawdzić, dlaczego dostajesz fail, dodaj handler error do $.ajax

error
Type: Function( jqXHR jqXHR, String textStatus, String errorThrown )

Argument textStatus powinien dać Ci wystarczająco dużo informacji ;) Obstawiam, że nie dostajesz poprawnej odpowiedzi JSON.

0

DZIĘKUJĘ udało się, po niżej dołączam kod z poprawami :) Już dodawanie do koszyka działa bardzo fajnie. Teraz jeszcze pytanie odnośnie komunikatu "Dodano do koszyka" czy tak jak ja to poniżej wykonałem jest akceptowalne? MSG jest generowane w pliku php za pomocą echo. Może jakieś inne pomysły bardziej profesjonalne ;) Docelowo fajnie by było jak by owy komunikat znikał np po 3sekundach.


    $('.productForm').submit(function(e) {
    e.preventDefault();
    var formData = $(this).serialize();

            $.ajax({
                url  : "<?php echo base_url('produkty/koszyk')?>",
           	    type: 'POST',
            	contentType: 'application/x-www-form-urlencoded',
            	data: formData,
            	cache: false,
            	processData:false,
                success:function(msg)
                {
                    $('#msg').html(msg);
       
                    //alert('SUCCESS!!');
                },
                
               	error:function() 
               	{
                	$('#msg').html("Błąd dodawania do koszyka!");
                }
            });

        });

0

jQuery.animate()

Samo przekazywanie komunikatu bezpośrednio z php jest OK dopóki nie przekażesz komunikatu błędu z wrażliwymi danymi ;)

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