Dariusz Morawski

Dariusz Morawski tłumacz free-lance

Temat: Potrzebuję pomocy ze skryptem...

Cześć wszystkim!

Wiele lat temu miałem nieco pojęcia o JS, ale przez uporczywe nieużywanie wszystko mi się rozlazło i teraz, kiedy potrzebuję rozwiązać prosty wydawałoby się problem, jestem jak dziecko we mgle. Pewne rzeczy udało mi się osiągnąć samodzielnie (szukając na różnych forach programistycznych), ale doszedłem do punktu, z którego samodzielne wyjście kosztowałoby mnie masę czasu i energii - zamiast tego wolę zapytać ludzi, którzy się znają i rozwiążą problem lewą ręką z zamkniętymi oczami... :-)

Mam prosty kalkulator dla 3 produktów (ilość x cena = wartość). Mam również checkboxa, który pokazuje pewną wartość albo nie, zależnie od tego, czy jest zaznaczony. Moim problemem jest to, że nie wiem, jak wyczarować, żeby zmiana statusu checkboxa wpływała na łączny wynik.

Oto kod - jest trochę przydługi, bo on ma robić jeszcze parę innych rzeczy (np. sprawdzanie, czy znaki wprowadzone w polu "Ile" są liczbami całkowitymi) - nie chcę go teraz odchudzać, bo mogę coś zepsuć i nie będzie działać. Jak zobaczycie, dwie części kodu (suma i checkbox) mają niezależne skrypty - nie umiem wyciągnąć z drugiego skryptu wartości uruchamianej zaznaczeniem checkboxa i włączyć jej do sumy z pierwszego skryptu:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dobry obiad</title>

<script language=javascript>

function dm(amount)
{
string = "" + amount;
dec = string.length - string.indexOf('.');
if (string.indexOf('.') == -1)
return string + ',-';
if (dec == 1)
return string + '';
if (dec == 2)
return string + '';
if (dec > 3)
return string.substring(0,string.length-dec+3);
return string;
}

function calculate()
{
QtyA = 0; QtyB = 0; QtyC = 0;
TotA = 0; TotB = 0; TotC = 0;

PrcA = 10; PrcB = 20; PrcC = 15;

if (document.ofrm.qtyA.value > "")
{ QtyA = document.ofrm.qtyA.value };
document.ofrm.qtyA.value = eval(QtyA);

if (document.ofrm.qtyB.value > "")
{ QtyB = document.ofrm.qtyB.value };
document.ofrm.qtyB.value = eval(QtyB);

if (document.ofrm.qtyC.value > "")
{ QtyC = document.ofrm.qtyC.value };
document.ofrm.qtyC.value = eval(QtyC);

TotA = QtyA * PrcA;
document.ofrm.totalA.value = dm(eval(TotA));

TotB = QtyB * PrcB;
document.ofrm.totalB.value = dm(eval(TotB));

TotC = QtyC * PrcC;
document.ofrm.totalC.value = dm(eval(TotC));

Totamt =
eval(TotA) +
eval(TotB) +
eval(TotC) ;

document.ofrm.GrandTotal.value = dm(eval(Totamt));
}

function validNum(theForm)
{
var checkOK = "0123456789";
var checkStr = theForm.qtyA.value;
var allValid = true;
var validGroups = true;
var decPoints = 0;
var allNum = "";
for (i = 0; i < checkStr.length; i++)
{
ch = checkStr.charAt(i);
for (j = 0; j < checkOK.length; j++)
if (ch == checkOK.charAt(j))
break;
if (j == checkOK.length)
{
allValid = false;
break;
}
if (ch == ".")
{
allNum += ".";
decPoints++;
}
else if (ch == "," && decPoints != 0)
{
validGroups = false;
break;
}
else if (ch != ",")
allNum += ch;
}
if (!allValid)
{
alert("W polu 'Ile' znajdują się znaki, które nie są liczbą całkowitą - proszę poprawić.");
theForm.qtyA.focus();
return (false);
}

if (decPoints > 0 || !validGroups)
{
alert("W polu 'Ile' znajdują się znaki, które nie są liczbą całkowitą - proszę poprawić.");
theForm.qtyA.focus();
return (false);
}

var checkOK = "0123456789";
var checkStr = theForm.qtyB.value;
var allValid = true;
var validGroups = true;
var decPoints = 0;
var allNum = "";
for (i = 0; i < checkStr.length; i++)
{
ch = checkStr.charAt(i);
for (j = 0; j < checkOK.length; j++)
if (ch == checkOK.charAt(j))
break;
if (j == checkOK.length)
{
allValid = false;
break;
}
if (ch == ".")
{
allNum += ".";
decPoints++;
}
else if (ch == "," && decPoints != 0)
{
validGroups = false;
break;
}
else if (ch != ",")
allNum += ch;
}
if (!allValid)
{
alert("W polu 'Ile' znajdują się znaki, które nie są liczbą całkowitą - proszę poprawić.");
theForm.qtyB.focus();
return (false);
}

if (decPoints > 0 || !validGroups)
{
alert("W polu 'Ile' powinny znaleźć się jedynie liczby całkowite (całkowite).");
theForm.qtyA.focus();
return (false);
}

var checkOK = "0123456789";
var checkStr = theForm.qtyC.value;
var allValid = true;
var validGroups = true;
var decPoints = 0;
var allNum = "";
for (i = 0; i < checkStr.length; i++)
{
ch = checkStr.charAt(i);
for (j = 0; j < checkOK.length; j++)
if (ch == checkOK.charAt(j))
break;
if (j == checkOK.length)
{
allValid = false;
break;
}
if (ch == ".")
{
allNum += ".";
decPoints++;
}
else if (ch == "," && decPoints != 0)
{
validGroups = false;
break;
}
else if (ch != ",")
allNum += ch;
}
if (!allValid)
{
alert("W polu 'Ile' znajdują się znaki, które nie są liczbą całkowitą - proszę poprawić.");
theForm.qtyC.focus();
return (false);
}

if (decPoints > 0 || !validGroups)
{
alert("W polu 'Ile' powinny znaleźć się jedynie liczby całkowite (całkowite).");
theForm.qtyC.focus();
return (false);
}

calculate();
return (true);
}
</script>

<script type='text/javascript'>
window.onload=function(){
var inputs = document.getElementsByClassName('sum'),
total = document.getElementById('payment-total');

for (var i=0; i < inputs.length; i++) {
inputs[i].onchange = function() {
var add = this.value * (this.checked ? 1 : -1);
total.innerHTML = parseFloat(total.innerHTML) + add
}
}
}
</script>
</head>

<body>

<h3>Składamy obiad:</h3>

<form method="POST" action="submit.html" onsubmit="return Validate(this)" name="ofrm">

<table border="0" cellpadding="0" width="550" id="table2">
<tr>
<td width="350" height="31"><b>Co</b></td>
<td align="center" width="100" height="31"><b>Ile</b></td>
<td align="right" height="31" width="60"><b>Cena</b></td>
<td align="right" height="31" width="40"><b>Razem</b></td>
</tr>
<tr>
<td width="350">Zupa</td>
<td align="center" width="100">
<input type="text" name="qtyA" size="5" tabindex="5" onchange="return validNum(document.ofrm)"></td>
<td align="right" width="60">10,-</td>
<td align="right" width="40"> <input type="text" name="totalA" size="4" tabindex="99" onchange="calculate()"></td>
</tr>
<tr>
<td width="350">Kotlet</td>
<td align="center" width="100">
<input type="text" name="qtyB" size="5" tabindex="5" onchange="return validNum(document.ofrm)"></td>
<td align="right" width="60">20,-</td>
<td align="right" width="40"> <input type="text" name="totalB" size="4" tabindex="99" onchange="calculate()"></td>
</tr>
<tr>
<td width="350">Deser</td>
<td align="center" width="100">
<input type="text" name="qtyC" size="5" tabindex="5" onchange="return validNum(document.ofrm)"></td>
<td align="right" width="60">15,-</td>
<td align="right" width="40"> <input type="text" name="totalC" size="4" tabindex="99" onchange="calculate()"></td>
<tr>
<td width="350">Napiwek dla kelnera?</td>
<td align="center" width="100">TAK    <input value="10" type="checkbox" class="sum" data-toggle="checkbox"></td>
<td align="right" width="60"> </td>
<td align="left" width="40">       <span id="payment-total" name="totalD">0</span>,-</td>
</tr> <tr>
<td width="350"> <p>  </p><p align="right"><b>DO ZAPŁATY:</b></td>
<td align="center" width="100"><p>  </p> </td>
<td align="right" width="60"><p>  </p> </td>
<td align="right" width="40"><p>  </p> <input type="text" name="GrandTotal" size="8" tabindex="99" onchange="calculate()"></td>
</tr>

</table>
</form>
</body>
</html>Ten post został edytowany przez Autora dnia 28.05.14 o godzinie 00:29
Marcin Gościcki

Marcin Gościcki Front-end
webdeveloper

Temat: Potrzebuję pomocy ze skryptem...

Z rana do kawy na rozgrzewkę postanowiłem Ci pomóc.

Tu masz rozwiązanie - http://jsfiddle.net/6ARdN/ - prawie całościowe. W tym momencie checkbox działa na odwrót, ponieważ w złym momencie jest ustawiana wysokość napiwku. To już zadanie dla Ciebie żebyś nie miał za łatwo ;)

Po kolei. Jedyne co wystarczyło zrobić to dodać by funkcja calculate() wywoływała się również po kliknięciu w checkbox'a oraz dodanie wartości napiwku to reszty liczb.

Kilka uwag:
1. Przejedź kod walidatorem - masz niepozamykane niektóre znaczniki (np. 4-ty <tr>)!
2. border="0", cellpadding="0", align="right", itp. - od tego jest CSS
3. Cały skrypt można by zamknąć w kilku linijkach, np. używając wyrażeń regularnych (poszukaj w necie info o RegExp) zamiast dziwacznej iteracji :)
4. Na przyszłość kod wrzucaj na jakiś serwis np. jsfiddle.net, codepen.io, itp. Osobom chcącym pomóc będzie zdecydowanie łatwiej lub chociaz użyj BBCode'owego znacznika [CODE ] Tutaj kod [/CODE ]
Jacek Kozioł

Jacek Kozioł Web Developer,
Webmaster

Temat: Potrzebuję pomocy ze skryptem...

Po pierwsze, kod rzeczywiście odbiega od standardów W3C, po drugie, jeżeli będziesz pisał kod w taki sposób, to więcej czasu stracisz na jego utrzymaniu, niż jest to warte. Ale o tym to się musisz sam przekonać.
natomiast poniżej zamieszczam kod napisany naprędce, który może Ci pomoże (pozwoliłem sobie nieco zmienić html i podmienić funkcje na swoje) - od razu zaznaczam że kod który zamieszczam nie jest doskonały ani optymalny, a zamieszczam go po to aby Cię nakierować.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dobry obiad</title>

<script type="text/javascript">

function addEvent(element, evt, funct){
if(element.addEventListener){
return element.addEventListener(evt, funct, false);
}
if(element.attachEvent){
return element.attachEvent('on'+evt, funct);
}
}

function calculateField(oField){
if(oField['input'].value != ''){
var tempVal = parseInt(oField['input'].value);
if(isNaN(tempVal)){
alert('W polu "Ile" znajdują się znaki, które nie są liczbą całkowitą')
} else{
oField['sum'].value = tempVal * oField['val'];
}
} else {
oField['sum'].value = 0;
}
//console.log(oField['input'].value);
}

function totalPrice(oFields){
var sum = 0;
console.log(sum);
for(el in oFields){
if(oFields[el]['sum']){
var tempSumVal = oFields[el]['sum'].value
if(tempSumVal != '' && typeof parseInt(tempSumVal) == 'number'){
sum += parseInt(oFields[el]['sum'].value);
} else {
sum += 0;
}
}
}
//napiwek
if(oFields.tip.checkbox.checked){
if(sum == 0){
alert('Kwota jest równa 0, nie można doliczyć napiwku')
} else{
sum += parseInt(oFields.tip.checkbox.value);
} }
console.log(sum);
oFields.total.input.value = sum;
}

addEvent(window, 'load', function(){
var fields = {
first : {
input : document.getElementById('input_1'),
val : parseInt(document.getElementById('value_1').innerHTML),
sum : document.getElementById('sum_1')
},
second : {
input : document.getElementById('input_2'),
val : parseInt(document.getElementById('value_2').innerHTML),
sum : document.getElementById('sum_2')
},
third : {
input : document.getElementById('input_3'),
val : parseInt(document.getElementById('value_3').innerHTML),
sum : document.getElementById('sum_3')
},
tip : {
checkbox: document.getElementById('tip'),
val : parseInt(document.getElementById('tip').value)
},
total : {
input: document.getElementById('total')
}
};
//totalPrice(fields);
for(el in fields){
if(fields[el]['input']){
//reset po zaladowaniu
fields[el]['input'].value = '';
if(fields[el]['sum'])
fields[el]['sum'].value = '';
(function(field){
addEvent(fields[el]['input'], 'blur', function(){
calculateField(field);
totalPrice(fields);
});
})(fields[el]);
}
if(fields[el]['checkbox']){
addEvent(fields[el]['checkbox'], 'change', function(){
totalPrice(fields);
});
}
}
});

</script>
</head>

<body>

<h3>Składamy :</h3>

<form method="POST" action="submit.html" onsubmit="return Validate(this)" name="ofrm">

<table border="0" cellpadding="0" width="550" id="table2">
<tr>
<td width="350" height="31"><b>Co</b></td>
<td align="center" width="100" height="31"><b>Ile</b></td>
<td align="right" height="31" width="60"><b>Cena</b></td>
<td align="right" height="31" width="40"><b>Razem</b></td>
</tr>
<tr>
<td width="350">Zupa</td>
<td align="center" width="100">
<input type="text" name="qtyA" size="5" tabindex="5" id="input_1" value="1">
</td>
<td align="right" width="60">
<span id="value_1">10,-</span>
</td>
<td align="right" width="40">
<input type="text" name="totalA" size="4" tabindex="99" id="sum_1">
</td>
</tr>
<tr>
<td width="350"><Kotlet</td>
<td align="center" width="100">
<input type="text" name="qtyB" size="5" tabindex="5" id="input_2">
</td>
<td align="right" width="60">
<span id="value_2">20,-</span>
</td>
<td align="right" width="40">
<input type="text" name="totalB" size="4" tabindex="99" id="sum_2">
</td>
</tr>
<tr>
<td width="350">Deser</td>
<td align="center" width="100">
<input type="text" name="qtyC" size="5" tabindex="5" id="input_3">
</td>
<td align="right" width="60">
<span id="value_3">15,-</span>
</td>
<td align="right" width="40">
<input type="text" name="totalC" size="4" tabindex="99" id="sum_3">
</td>
<tr>
<td width="350">Napiwek dla kelnera?</td>
<td align="center" width="100">
TAK <input value="10" type="checkbox" class="sum" data-toggle="checkbox" id="tip">
</td>
<td align="right" width="60"> </td>
<td align="left" width="40">
<span id="payment-total" name="totalD">0</span>,-</td>
</tr> <tr>
<td width="350"> <p> </p><p align="right"><b>DO ZAPŁATY:</b></td>
<td align="center" width="100"><p> </p> </td>
<td align="right" width="60"><p> </p> </td>
<td align="right" width="40"><p> </p>
<input type="text" name="GrandTotal" size="8" tabindex="99" id="total">
</td>
</tr>

</table>
</form>
</body>
</html>
Dariusz Morawski

Dariusz Morawski tłumacz free-lance

Temat: Potrzebuję pomocy ze skryptem...

Przede wszystkim - chciałem obu Wam BARDZO SERDECZNIE podziękować za pomoc. Oczywiście macie rację: powinienem poczytać - niewykluczone, że sam bym sobie poradził. Niestety, potrzebuję rozwiązania problemu "na już", dlatego po pierwszych samodzielnych próbach jednak postanowiłem poprosić o pomoc. Mam nadzieję, że kiedyś znajdę czas, żeby wrócić do JS (pamiętam, że poprawne napisanie nawet prostych rzeczy dawało mi dużo frajdy). No, ale to "może kiedyś".

Na razie skorzystałem z podpowiedzi Marcina (po prostu była pierwsza), dopasowałem ją do mojego projektu - DZIAŁA! (Fajnie by było kiedyś siąść i porównać to rozwiązanie z propozycją Jacka - może kiedyś...).

Ale mam jeszcze inny problem - tym razem z PHP, o którym nie mam bladego pojęcia. Wymyśliłem sobie, żeby dostawać mejlowo informację o tym, co jest zamawiane. Znalazłem w Necie prosty skrypcik, zastosowałem go u siebie i jest fajnie, ale z jednym wyjątkiem: wiadomość przychodzi jak powinna, ale nie umiem włączyć do niej informacji o napiwku: w linii $razem = sprawdz($_POST['GrandTotal']); zamiast "GrandTotal" próbowałem z "totalD" - nic. Bez względu na to, czy napiwek jest zaznaczony czy nie, przychodzi coś takiego:
Zupa: 0,-
Kotlet: 0,-
Deser: 30,-
Razem:

Jest mi obojętne, czy skrypt poinformuje mnie tylko o fakcie zaznaczenia checkboxa, czy o łącznej wartości rachunku (mając informację o wszystkich 3 pozycjach oraz total, łatwo bym to sobie wyliczył). Skrypcik wygląda tak:

<?php

function sprawdz($zmienna){
$new = htmlspecialchars(stripslashes(strip_tags(trim($zmienna))));
return $new;
}

$zupa = sprawdz($_POST['totalA']);
$kotlet = sprawdz($_POST['totalB']);
$deser = sprawdz($_POST['totalC']);
$razem = sprawdz($_POST['GrandTotal']);


$naglowek = 'MIME-Version: 1.0' . "\r\n";
$naglowek .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$naglowek .= 'From: Kucharz informuje' . "\r\n";

$mail = "Zupa: $zupa <br />";
$mail .= "Kotlet: $kotlet <br />";
$mail .= "Deser: $deser <br />";
$mail .= "Razem: $razem <br />";


if (!mail("mejl@domnie.pl", "Strona Formularz", $mail, $naglowek)){echo "blad";}
else {echo "W przypadku niestrawności polecamy sól gorzką. Zapraszamy znowu!";}

?>


Mam nadzieję, że jakaś litościwa dusza pomoże mi i tym razem. Z góry dziękuję.
Dariusz Morawski

Dariusz Morawski tłumacz free-lance

Temat: Potrzebuję pomocy ze skryptem...

Rozwiązanie problemu podpowiedziano mi na innym forum, więc temat uważam za zamknięty. (Gdyby kiedyś ktoś to analizował: wystarczyło stworzyć name dla checkboxa.)

Jeszcze raz dziękuję za pomoc z wcześniejszym problemem.

Następna dyskusja:

Potrzebuję kodera do pomocy




Wyślij zaproszenie do