Aantal in winkelwagen aanpassen
Ik ben aan het stoeien met het volgende:
Ik heb een php geschreven winkelwagen waarin men van een specifiek artikel het aantal kan wijzigen naar een positief getal tussen de 1 en de 100. Ik wil dit oplossen m.b.v. ajax/jquery om zo zonder te refreshen de winkelwagen totaalprijs te laten zien.
Wat heb ik op dit moment:
- database tabel genaamd shopping_products (velden zijn: rowid, shoprow_id, prod_id, aantal, sessieid)
Hierin is "rowid" het unieke nummer voor de rij in de tabel.
"shoprow_id" is het unieke nummer uit de winkelwagen tabel (dient als index key).
"sessieid" bevat een unieke sessie waarde om de juiste waarden te bewerken in de database.
prod_id en aantal zijn duidelijk velden.
In het winkelwagen script heb ik een input type='number' veld opgenomen waarin de gebruiker een getal tussen de 1 en 100 kan opgeven (dit wordt gechecked, bij een negatief getal wordt er sowieso 1 positief gebruikt).
Code (php)
1
2
2
// het input veld:
<input type='number' name='changeprodamount' value='$currentamound' class='amountprod' min='1' max='30' id='amountprod' /> <a href='/winkelwagen'>wijzig</a>
<input type='number' name='changeprodamount' value='$currentamound' class='amountprod' min='1' max='30' id='amountprod' /> <a href='/winkelwagen'>wijzig</a>
Vervolgens hangt daar nu een Javascript code achter om de nieuwe waarde voor het aantal producten "aantal" door te sturen naar een php file:
Code (php)
1
2
3
4
5
2
3
4
5
// javascript code:
$('#amountprod').bind('input', function() {
var newprodamount = $(this).val();
$.post( "/savenewamount.php", { newamount:newprodamount } );
});
$('#amountprod').bind('input', function() {
var newprodamount = $(this).val();
$.post( "/savenewamount.php", { newamount:newprodamount } );
});
Deze code stuurt de nieuwe variabele door naar het php script "savenewamount.php" waarin de database wordt aangeroepen en het veld AANTAL wordt aangepast.
In het php script staat het volgende:
Code (php)
1
2
3
4
5
2
3
4
5
$checkamountprod = $_POST['newamount'];
if($checkamountprod <= 1){ $amountprod = 1; }else{ $amountprod = $_POST['newamount']; }
$updatequery = "UPDATE shopping_products SET aantal='$amountprod', WHERE sessieid='". $_SESSION["clientsesid"] ."'";
$queryresult= mysqli_query($verbinding, $updatequery) or die ("Query mislukt: " . mysqli_error($verbinding));
if($checkamountprod <= 1){ $amountprod = 1; }else{ $amountprod = $_POST['newamount']; }
$updatequery = "UPDATE shopping_products SET aantal='$amountprod', WHERE sessieid='". $_SESSION["clientsesid"] ."'";
$queryresult= mysqli_query($verbinding, $updatequery) or die ("Query mislukt: " . mysqli_error($verbinding));
Waar ik tegen aan loop is dat bij meer dan 1 product in de winkelwagen alle velden van dezelfde winkelwagen sessie worden geupdate naar dezelfde waarde in het AANTAL veld.
Ik moet dus op één of andere manier in de INPUT nog een waarde mee sturen die aangeeft om welke "rowid" het gaat en vervolgens deze zal aanpassen.
Op de bovenstaande manier druk ik ook op de link "wijzig" zodat de pagina wordt gerefreshed en daarmee dus de nieuwe totaalprijs in de winkelwagen zichtbaar is. Dit zou ik willen oplossen met Ajax.
Ik zou daar ook het product id bij pakken.
Ja ik zat daar ook al aan te denken, maar hoe...?
Ik heb 1 input veld met daarin de waarde "aantal". Ik dacht misschien kan ik in die input nog een extra attribuut opnemen die de waarde "product id" bevat en deze in het javascript gedeelte afvangen. Maar hoe ga ik dat doen, dat is dus mijn vraag.
Groeten, Johnny
Semi offtopic: alle attributen van HTML-tags dienen tussen "dubbele quotes" te staan.
Dat staat het ook. Ik heb alleen een fragment gekopieerd vanuit een php echo.
Dus de velden staan wel goed verder.
Ik had gehoopt dat er een oplossing was binnengekomen :)))
Code (php)
1
<input type="number" value="1" name="amount" data-product_id="526" data-price="5.99" />
Gewijzigd op 02/02/2015 22:02:27 door Frank Nietbelangrijk
Hartstikke bedankt voor je post. Kun je me allen nog vertellen hoe ik vervolgens dat data- attribuut ga verwerken in mijn Javascript?
Doe ik dat met: document.getElementById('datestart').value; ?
kopieerde ik uit een ander deel van mijn script.
Maar nu raak ik toch in de war.
Op basis van het input veld met de data- attributen. Hoe valideer dan die VAR?
Ik ben zelf namelijk een groentje in javascript/jquery.
Die datestart is van het bekende Datepicker script.
-----------UPDATE-------------
Ik heb het nu tot zover voor elkaar dat hij het aantal aanpast, maar als ik nu een nieuw product toevoeg aan de winkelwagen en vervolgens het aantal wil aanpassen doet hij dat alleen voor het eerste toegevoegde artikel.
De input staat in een while lus... Waarschijnlijk zit daar nog een struikelblok omdat dan de ID van de input vaker voorkomt?
Gewijzigd op 02/02/2015 22:53:12 door Johnny Cash
Deze vraag snap ik even niet?
met document.getElementById('datestart').value krijg je het aantal te zien (1)
aantal = 1
product_id = 526
price = 5.99
Toevoeging op 02/02/2015 22:56:45:
overigens is
document.getElementById('datestart').value
exact hetzelfde als
document.getElementById('datestart').getAttribute('value')
althans in jouw situatie
Toevoeging op 02/02/2015 22:58:34:
>>De input staat in een while lus... Waarschijnlijk zit daar nog een struikelblok omdat dan de ID van de input vaker voorkomt?
Correct. Een id mag slechts één keer in een HTML pagina voorkomen. een class mag zo vaak voorkomen als je wil.
Ik begrijp dat "datestart" is gerelateerd aan data-product_id??
Ik zie de connectie namelijk niet.
Alle aantallen worden ook hetzelfde omdat je geen product id specificeert in je query:
UPDATE shopping_products
SET aantal='$amountprod', <-- wat doet die komma hier?
WHERE sessieid='". $_SESSION["clientsesid"] ."'"
Daarnaast lijkt mij een shopping cart iets tijdelijks, dit zou ik dus eerder opslaan in een sessie dan in een database?
Overigens hoef je geen prijs mee te geven, enkel een product en een hoeveelheid. De prijsberekening zou ik in het PHP script zelf laten plaatsvinden.
Thomas van den Heuvel op 02/02/2015 23:45:54:
Overigens hoef je geen prijs mee te geven, enkel een product en een hoeveelheid. De prijsberekening zou ik in het PHP script zelf laten plaatsvinden.
Dat is helemaal niet nodig. Het kan juist ook prima in javascript. Ik zou (denk ik) niet eens een ajax call maken maar de cart pas bijwerken als de klant op "Volgende" klikt en het formulier dus verzonden wordt.
Die komma staat daar omdat daarachter nog de rowid komt te staan.
De query met data- attribuut werkt nu wel, maar zoals gezegd alleen voor het laatste product in de while lus:
De input field staat dus met die id='amountprod' in een while lus.
------------UPDATE------------
Het is een feit dat het aan het id='amountprod' ligt in de while loop.
Hoe kan ik dit netjes oplossen. Dus een FOR loop constructie in javascript..?
Gewijzigd op 03/02/2015 00:39:24 door Johnny Cash
Frank Nietbelangrijk op 02/02/2015 23:50:45:
Het kan juist ook prima in javascript.
Als je jezelf een korting wilt geven tijdens het boodschappen doen is dat idd een goede manier :).
Maar hoe kan ik nou op een juiste manier de dubbel voorkomende ID afvangen zoals geschetst?
Thomas van den Heuvel op 03/02/2015 00:47:07:
Als je jezelf een korting wilt geven tijdens het boodschappen doen is dat idd een goede manier :).
Wat een onzin! je past enkel de aantallen aan en later reken je in PHP weer opnieuw het totaal uit dus nikste korting!
Bij het posten geef je ENKEL de aantallen terug en de product_id's. De prijzen moeten weer opnieuw uit de database komen en het totaal moet weer opnieuw berekend worden, anders is het niet veilig uiteraard!
Hier een voorbeeld waar je zo mee door kunt:
http://codepen.io/anon/pen/LEzLMw
Toevoeging op 03/02/2015 01:06:47:
HTML:
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<form action="" method="post">
<input type="hidden" name="cart[][product_id]" value="534" />
<input type="number" name="cart[][amount]" value="1" class="amount-input" data-row="row1" data-price="19.20" /> fietsband 19 inch <span class="price" id="row1">19.20</span><br>
<input type="hidden" name="cart[][product_id]" value="535" />
<input type="number" name="cart[][amount]" value="1" class="amount-input" data-row="row2" data-price="19.60" /> fietsband 21 inch <span class="price" id="row2">19.60</span><br>
Totaal: <span id="total"></span><br><br>
<input type="submit" value="Volgende" />
</form>
<input type="hidden" name="cart[][product_id]" value="534" />
<input type="number" name="cart[][amount]" value="1" class="amount-input" data-row="row1" data-price="19.20" /> fietsband 19 inch <span class="price" id="row1">19.20</span><br>
<input type="hidden" name="cart[][product_id]" value="535" />
<input type="number" name="cart[][amount]" value="1" class="amount-input" data-row="row2" data-price="19.60" /> fietsband 21 inch <span class="price" id="row2">19.60</span><br>
Totaal: <span id="total"></span><br><br>
<input type="submit" value="Volgende" />
</form>
CSS:
JQuery:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function getTotal()
{
var total = .0;
$('.price').each(function( index ) {
total += parseFloat($(this).text());
});
$('#total').text(total.toFixed(2));
}
$(function() {
getTotal();
$('.amount-input').change(function() {
var row = $(this).attr('data-row');
var amount = parseFloat($(this).val());
var price = parseFloat($(this).attr('data-price'));
var total = amount * price;
$('#'+row).html(total.toFixed(2));
getTotal();
});
});
{
var total = .0;
$('.price').each(function( index ) {
total += parseFloat($(this).text());
});
$('#total').text(total.toFixed(2));
}
$(function() {
getTotal();
$('.amount-input').change(function() {
var row = $(this).attr('data-row');
var amount = parseFloat($(this).val());
var price = parseFloat($(this).attr('data-price'));
var total = amount * price;
$('#'+row).html(total.toFixed(2));
getTotal();
});
});
Gewijzigd op 03/02/2015 01:22:06 door Frank Nietbelangrijk
Thnx tot zover
Quote:
Waarom zou je 2x hetzelfde doen op 2 verschillende plaatsen (berekening prijs in JS en berekening prijs in PHP)?Bij het posten geef je ENKEL de aantallen terug en de product_id's. De prijzen moeten weer opnieuw uit de database komen en het totaal moet weer opnieuw berekend worden, anders is het niet veilig uiteraard!
Daarmee maak je imo je code alleen maar nodeloos complexer, en dat heeft weer een aantal nadelen (kans op fouten neemt toe, onderhoud kost meer tijd etc.).
K.I.S.S. !
Maar dit is de meest efficiënte methode.
1) geen (langzame) AJAX calls nodig
2) geen nodeloos aanpassen winkelwagentje
3) een validatie in JAVASCRIPT (dus ook opnieuw prijs berekenen) is handig voor de gebruiker omdat er geen refresh van de pagina nodig is MAAR absoluut onveilig dus wordt het door veel mensen, ook op dit board aangeraden om dit in Javascript en PHP te doen.
4) wat is het probleem? Dat je 4 milliseconden trager bent of zo? Als dat de discussie gaat worden dan haak ik af!
Gewijzigd op 03/02/2015 09:44:21 door Frank Nietbelangrijk
Ik heb het volgende nu werkend:
- specifieke productaantallen kunnen worden aangepast (omslachtig maar werkend) *
- men moet drukken op een knop "update winkelwagen" waardoor het totaal dus wordt berekend
- shopping cart wordt in een db tabel opgeslagen omdat daar weer statistieken programma's aanhangen
* Ik doe dit nu met een ID welke in de loop een +1 krijgt. Er kunnen maximaal 10 producten tegelijk worden besteld, komt op de betreffende webshop nooit voor, maar hierdoor heb ik in de javascript gewoon 10 keer een 4 regel code opgenomen... Ik heb het geprobeerd met de CLASS maar ik krijg dat op één of andere manier niet voor elkaar.
Wil geen discussies op een post die ik schrijf, daar is mijn post niet voor bedoelt.