• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Skrypt liczący sumę w formularzu

Object Storage Arubacloud
0 głosów
1,298 wizyt
pytanie zadane 13 lipca 2019 w HTML i CSS przez Hardwell Dyskutant (8,980 p.)
Witam, posiadam formularz, w którym mam inputy typu checkbox:

<input type="checkbox"  name="car">
<input type="checkbox"  name="car_two">

potrzebował bym jakiś kalkulator, (input car ma wartość np 100, a car_two 150).

i teraz jak sie domyślacie chciał bym żeby po wybraniu jednego z dwóch pokazywała się suma w <p id="suma">
(jeśli zaznaczy dwa to sie sumuje itd)

jakieś słowa kluczowe?
komentarz 13 lipca 2019 przez lateM Pasjonat (17,660 p.)
Javascript :D

1 odpowiedź

0 głosów
odpowiedź 13 lipca 2019 przez Chess Szeryf (76,710 p.)
edycja 13 lipca 2019 przez Chess
<form method="get" action="">
  <input type="checkbox" name="ch1"/>
  <input type="hidden" name="ch1-1" value="100"/>

  <input type="checkbox" name="ch2"/>
  <input type="hidden" name="ch2-1" value="200"/>

  <input type="submit"/>
</form>
<?php
$ch1 = isset($_GET['ch1']) ? $_GET['ch1-1'] : 0;
$ch2 = isset($_GET['ch2']) ? $_GET['ch2-1'] : 0;

echo "Result " . ((int)$ch1 + $ch2);
?>

lub

<form method="get" action="">
  <input type="checkbox" name="ch1" value="100"/>

  <input type="checkbox" name="ch2" value="200"/>

  <input type="submit"/>
</form>
<?php

$ch1 = $_GET['ch1'] ?? 0;
$ch2 = $_GET['ch2'] ?? 0;

echo "Result " . ((int)$ch1 + $ch2);

?>

Pozwolę sobie z'edytować post.

Skopiuj HTML z drugiego przykładu i napisz tak.

let sum = 0;

for(let i=0;i<document.querySelectorAll('form input[type=checkbox]').length;i++) {
  console.log(1);
  document.querySelectorAll('form input[type=checkbox]')[i].addEventListener('change', function(e) {
    
    if(document.querySelectorAll('form input[type=checkbox]')[i].checked) {
      sum+=(document.querySelectorAll('form input[type=checkbox]')[i].value|0);
    } else {
      sum-=(document.querySelectorAll('form input[type=checkbox]')[i].value|0);
    }
    console.log(sum);
  }
  , false)
};

document.querySelectorAll('form input[type=checkbox]')..., możesz przypisać do zmiennej.

2
komentarz 13 lipca 2019 przez Tomek Sochacki Ekspert (227,510 p.)
a nie lepiej w js :)? wg mnie nie ma sensu robic tu requesta, dopiero dla ostatecznego submita.
komentarz 13 lipca 2019 przez Hardwell Dyskutant (8,980 p.)
Jak to uzyskać w js?
komentarz 15 lipca 2019 przez Chess Szeryf (76,710 p.)

@Hardwell:

Witam, szukam prostego skryptu który policzy mi wartości z formularza, jakieś słowa kluczowe ? kiedyś takowy posiadałem ale nie mogę znaleźć, zależy mi na tym aby na bieżąco pobierał zaznaczone wartości i wyświetlał w divie

@Chess:

Napisz może, co Ci nie działa w moim rozwiązaniu, OK? Teraz nie wiem, o co chodzi, ponieważ myślę, że wszystko działa prawidłowo. Jeśli chodzi o moje rozwiązanie, naciśnij F12 i wejdź w zakładkę "Console" i po naciśnięciu na checkbox'a ujrzysz odpowiednie wartości.

@Hardwell:

chodzi o to że w ogóle nie działa, może ja to źle po prostu podpinam, ciężko mi powiedzieć bo w technologii JS jestem cienki

@Chess:

F12 i podaj błąd z zakładki "Console", jeśli jakieś są.

@Hardwell:

A możesz mi pokazać jak to podłączyć? niestety nie mam pojęcia a na pewno źle to robię

@Chess:

<!-- ... -->
 
<body>
 
<form>
 
<!-- ... -->
 
</form>
 
<script>
 
// ... code JS
 
</script>
 
</body>
 
<!-- ... -->

@Hardwell:

<!-- ... -->
  
<body>
<form method="get" action="">
  <input type="checkbox" name="ch1"/>
  <input type="hidden" name="ch1-1" value="100"/>
  
  <input type="checkbox" name="ch2"/>
  <input type="hidden" name="ch2-1" value="200"/>
  
  <input type="submit"/>
</form>
 
<script>
 
let sum = 0;
  
for(let i=0;i<document.querySelectorAll('form input[type=checkbox]').length;i++) {
  console.log(1);
  document.querySelectorAll('form input[type=checkbox]')[i].addEventListener('change', function(e) {
      
    if(document.querySelectorAll('form input[type=checkbox]')[i].checked) {
      sum+=(document.querySelectorAll('form input[type=checkbox]')[i].value|0);
    } else {
      sum-=(document.querySelectorAll('form input[type=checkbox]')[i].value|0);
    }
    console.log(sum);
  }
  , false)
};
 
 
</script>
  
</body>
  
<!-- ... -->

@Chess:

Wszystko chyba OK. Tylko skopiuj ten drugi formularz i po nim napisz tę linię.

<div id="output"></div>

Wyrzuć "console.log(1);" z kodu i zamiast tej linii "console.log(sum);", napisz.

document.getElementById('output').textContent = sum;

@Hardwell:

ŚMIGA

forum.pasja-informatyki.pl/440415

komentarz 18 lipca 2019 przez Hardwell Dyskutant (8,980 p.)
@Chess A więc piszę problem o który zwracałem się do ciebie w wiadomości prywatnej,
A więc:

Posiadam formularz kontaktowy w PHP/HTML (UPRZEDZAM ŻE SKRYPT POSIADAM Z INTERNETU, BYŁ NA JEDNYM Z FORÓW!)

Skrypt oczywiście działa, możesz pobrać i zobaczyć na własnej skórze, podpinam link do skryptu:

https://www33.zippyshare.com/v/JJYoWlw5/file.html

 

Jeśli dodasz jeszcze jedno albo i więcej "Inputów" ale typu text/number i potem dodasz zmienne w php wszystko jest tak samo ok, problem pojawia się gdy dodam input ale typu checkbox, a mianowicie:

kiedy dodam Checkboxy, oraz dodam zmienne z automatu konsola w przeglądarce wywala błąd połączenia,

pliki z checkboxami:

https://www95.zippyshare.com/v/3q4twiP6/file.html

 

jak to rozwiązać?
komentarz 18 lipca 2019 przez Chess Szeryf (76,710 p.)
Wrzuć tutaj kawałek z kodem, który jest za to odpowiedzialny i wytłumacz, co chcesz osiągnąć.
komentarz 19 lipca 2019 przez Hardwell Dyskutant (8,980 p.)
?¿ Przecież masz napisane up
komentarz 19 lipca 2019 przez Chess Szeryf (76,710 p.)

Nadaj klasę np. "custom_checkbox" dla input[type=checkbox] i później zamiast

document.querySelectorAll('input[type=checkbox]')//...

, napisz

document.querySelectorAll('.custom_checkbox')//...
komentarz 19 lipca 2019 przez Hardwell Dyskutant (8,980 p.)

Tylko nigdzie w kodzie nie ma 


document.querySelectorAll('input[type=checkbox]')//...

 

komentarz 19 lipca 2019 przez Chess Szeryf (76,710 p.)
Masz podmienić wszystkie takie linijki, na tę co podałem powyżej.
komentarz 19 lipca 2019 przez Hardwell Dyskutant (8,980 p.)

tutaj są wszystkie linijki kodu w którym występuje checkbox, tutaj to zmienić?

    $inputs.filter(':checkbox').on('click', function() {
            var $elem = $(this);
            var $row = $(this).closest('.form-row');
            if ($elem.is(':checked')) {
                $elem.removeClass('error');
                hideFieldError($elem);
            } else {
                $elem.addClass('error');
            }
        });
            if (checkFieldsErrors()) {
                var dataToSend = $form.serializeArray();
                dataToSend = dataToSend.concat(
                    $form.find('input:checkbox:not(:checked)').map(function() {
                        return {"name": this.name, "value": this.value}
                    }).get()
                );

 

komentarz 19 lipca 2019 przez Chess Szeryf (76,710 p.)

Input'y, które mają być filtrowane, cokolwiek co masz w kodzie, ale związane z input'ami o typie checkbox zamień na klasę i odwołaj się do nich poprzez tę właśnie klasę.

Napisz tak dla pierwszego przykładu

$inputs.filter('input.your_class:checkbox').on('click', function() {//...

i tak dla drugiego

$form.find('input.your_class:checkbox:not(:checked)').map(function() {//...
<!-- ... -->
<input type="checkbox" class="your_class" <!-- ... -->/>
<!-- ... -->

W HTML wtedy musiałbyś mieć tę klasę przy input[type="checkbox"] zgodnie z powyższym przykładem.

Te komentarze możesz wyrzucić z kodu, oznaczają że dalej coś może się znajdować.

W każdym bądź razie, nie wiem, czy o to chodziło.

Specjalnie nadałem blokowi kodu kolorowanie składni plain-text, ponieważ traktuję to jako pseudokod ze względu takiego, że nie wiem, czy klasa z tej biblioteki/framework'a jest oznaczona jako znak kropki.

komentarz 20 lipca 2019 przez Hardwell Dyskutant (8,980 p.)
Zrobiłem jak wyżej, można powiedzieć że działa, ale nie do końca, a mianowicie:
konsola nadal wywala error, ale wiadomości przychodzą na pocztę, a po 2, kiedy nic nie zaznaczam (ani zielony ani niebieski ani czerwony) to w wiadomości mam napis Array, a kiedy zaznaczę to pokazuje mi się tak samo Array
komentarz 20 lipca 2019 przez Hardwell Dyskutant (8,980 p.)
miałem je zapisane w taki sposób:

    <input class="your_class" type="checkbox" name="zazn[]" value="red"> Czerwony
    <input class="your_class" type="checkbox" name="zazn[]" value="green"> Zielony
    <input class="your_class" type="checkbox" name="zazn[]" value="blue"> niebieski

i konsola wywala błąd, a kiedy dam tylko jeden input bez kwadratowego nawiasu w name to działa, ale jest kolejny problem, kolor wysyła się i kiedy go nie zaznacze i kiedy go zaznaczęa powinien tylko wtedy kiedy jest zaznaczony
komentarz 20 lipca 2019 przez Chess Szeryf (76,710 p.)
Wrzuć może całość (tylko tę część, która odpowiada za te checkbox'y), ale tutaj na forum, a nie jakieś linki.
komentarz 20 lipca 2019 przez Hardwell Dyskutant (8,980 p.)

formularz.html:

<!doctype html>
<html>
<head>
	<meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">    
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>     
</head>
<style>
    * {
        box-sizing: border-box;
    }
	.form {
        margin:3rem auto;
		font-family:sans-serif;
        max-width:40rem;
	}
	.form .form-row {
        margin-bottom:1rem;
    }
    .form .form-row:last-child {
        margin-bottom: 0;
    }
    .form input[type=text],
    .form input[type=email],
    .form textarea,
    .form .checkbox-cnt .state {
        box-shadow:inset 0 1px 5px rgba(0,0,0,0.07);
    }
	.form input[type=text], 
	.form input[type=email],
    .form textarea {
        border-radius:0.2rem;
        font-family:sans-serif;
		padding:0.8rem;
		border:1px solid #aaa;
        display: block;
        width:100%;
        color:#666;
	}
    .form input[type=text]:focus,
    .form input[type=email]:focus,
    .form textarea:focus {
        border-color:#9DC9F5;
        box-shadow:inset 0 0 0 1px #9DC9F5, inset 0 1px 5px rgba(0,0,0,0.07);
        outline:none;
    }
    .form textarea {
        height:10rem;
    }
	.form label {
        font-weight:bold;
		display: block;
		font-size:0.9rem;
		margin-bottom:0.5rem;
	}
    .form .submit-btn {
        font-family: sans-serif;
        padding:1rem 2rem;
        background: #70B81B;
        border:0;
        border-radius:0.2rem;
        color:#fff;
        font-size:1.1rem;
        font-weight: bold;
        transition: 0.3s background-color;
        cursor: pointer;
    }
    .form .submit-btn:hover {
        background: #7EC927;
    }
    .form .checkbox-cnt {
        padding-left:3rem;
        position: relative;
        font-weight: normal;
        font-size:0.85rem;
        line-height: 1.1rem;
        color:#444;
        cursor: pointer;
    }
    .form .checkbox-cnt .state {
        width:2rem;
        height: 2rem;
        display: block;
        position: absolute;
        left:0;
        top:0;
        border:1px solid #aaa;
        border-radius:0.2rem;
    }
    .form .checkbox-cnt .state:before {
        width:1rem;
        height: 1rem;
        border-radius:0.2rem;
        background: #70B81B;
        display: block;
        position: absolute;
        left:50%;
        top:50%;
        content:'';
        transform:translate(-50%, -50%) scale(1);
        opacity:0;
    }
    .form .checkbox-cnt input:checked ~ .state:before {
        animation: checkboxShowAnim 0.5s 1;
        opacity: 1;
    }
    .form .checkbox-cnt input {
        position:absolute;
        top:0; left:0;
        width:2rem;
        height: 2rem;
        z-index: 2;
        cursor:pointer;
        padding:0;
        margin:0;
        opacity: 0;
    }
    .form input[type=text].error,
    .form input[type=email].error,
    .form textarea.error,
    .form .checkbox-cnt input.error ~ .state {
        border-color:#E01546;
    }
    .field-error {
        color:#E01546;
        padding:0.5rem 0;
        font-size:0.8rem;
    }
    @keyframes checkboxShowAnim {
        0%  { border-radius:50%; transform:translate(-50%, -50%) scale(0.2); }
        50% { transform:translate(-50%, -50%) scale(1.2); }
        100% { transform:translate(-50%, -50%) scale(1); }
    }

    .element-is-busy {
        position: relative;
        pointer-events: none;
        opacity:0.5;
    }
    .element-is-busy::after {
        position: absolute;
        left: 50%;
        top: 50%;
        width: 20px;
        height: 20px;
        border-radius: 50%;
        border: 2px solid rgba(0, 0, 0, 0.2);
        border-right-color: rgba(0,0,0,0.7);
        transform: translate(-50%, -50%) rotate(0deg);
        content:'';
        animation: rotateSingleLoading 0.3s infinite linear;
        z-index: 100;
    }
    @keyframes rotateSingleLoading {
        from {
            transform: translate(-50%, -50%) rotate(0deg);
        }
        to {
            transform: translate(-50%, -50%) rotate(360deg);
        }
    }
    .form .send-error {
        display:inline-block;
        font-family: sans-serif;
        font-size:0.9rem;
        padding:1rem 1.5rem;
        color:#E01546;
    }
    .form-send-success {
        font-family: sans-serif;
        text-align:center;
        font-size:2rem;
        font-weight:bold;
        border:1px solid #eee;
        color:#333;
        padding:10rem 0;
        margin:3rem auto;
        max-width:40rem;
    }
    .form-send-success strong {
        display:block;
        margin-bottom:0.5rem;
    }
    .form-send-success span {
        font-size:1rem;
        color:#888;
        font-weight:normal;
        display: block;
    }
    @media screen and (max-width:500px) {
        .form .submit-btn {
            display: block;
            width: 100%;
        }
        .form .send-error {
            text-align:center;
            display: block;
        }
    }
</style>
<body>

<form class="form" id="contactForm" method="post" novalidate action="send-script.php">

	<!--CHECKBOXYDODANE-->
    <input class="your_class" type="checkbox" name="zazn[]" value="red"> Czerwony
    <input class="your_class" type="checkbox" name="zazn[]" value="green"> Zielony
	<input class="your_class" type="checkbox" name="zazn[]" value="blue"> niebieski
	<!--KONIEC-->

    <div class="form-row">
        <label for="field-name">Name*</label>
        <input type="text" name="name" required id="field-name" data-error="Wypełnij to pole" pattern="[a-zA-ZąĄććę곣ńŃóÓśŚżŻŹŹ ]+">
    </div>
    <div class="form-row">
        <label for="field-email">Email*</label>
        <input type="email" name="email" required id="field-email" data-error="Wpisz poprawny email" pattern="[^@\s]+@[^@\s]+\.[^@\s]+">
    </div>
    <div class="form-row">
        <label for="field-message">Message*</label>
        <textarea name="message" required data-error="Musisz wypełnić pole" id="field-message" pattern=".+"></textarea>
    </div>
    <div class="form-row">
        <label class="checkbox-cnt">
            <input class="your_class" type="checkbox" required data-error="Musisz wypełnić pole" name="regulation">
            <i class="state" aria-hidden="true"></i>
            <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In libero arcu, vulputate sit amet mattis sit amet, ultrices in erat. Aenean suscipit arcu ac lorem lacinia ut scelerisque turpis commodo.</span>
        </label>
    </div>
    <div class="form-row">
        <button type="submit" class="submit-btn">
            Wyślij
        </button>
    </div>
</form>

<script>
    $(function() {
        var $inputs = $('form input[required], form textarea[required], select[required]');

        var displayFieldError = function($elem) {
            var $fieldRow = $elem.closest('.form-row');
            var $fieldError = $fieldRow.find('.field-error');
            if (!$fieldError.length) {
                var errorText = $elem.attr('data-error');
                var $divError = $('<div class="field-error">' + errorText + '</div>');
                $fieldRow.append($divError);
            }
        };

        var hideFieldError = function($elem) {
            var $fieldRow = $elem.closest('.form-row');
            var $fieldError = $fieldRow.find('.field-error');
            if ($fieldError.length) {
                $fieldError.remove();
            }
        };

        $inputs.on('input', function() {
            var $elem = $(this);
            if (!$elem.get(0).checkValidity()) {
                $elem.addClass('error');
            } else {
                $elem.removeClass('error');
                hideFieldError($elem);
            }
        });

		
		$inputs.filter('input.your_class:checkbox').on('click', function() {
            var $elem = $(this);
            var $row = $(this).closest('.form-row');
            if ($elem.is(':checked')) {
                $elem.removeClass('error');
                hideFieldError($elem);
            } else {
                $elem.addClass('error');
            }
        });

        var checkFieldsErrors = function() {
            //ustawiamy zmienną na true. Następnie robimy pętlę po wszystkich polach
            //jeżeli któreś z pól jest błędne, przełączamy zmienną na false.
            var fieldsAreValid = true;
            $inputs.each(function(i, elem) {
                var $elem = $(elem);
                //if (new RegExp(pattern).test($elem.val())) {
                if (elem.checkValidity()) {
                    hideFieldError($elem);
                    $elem.removeClass('error');
                } else {
                    displayFieldError($elem);
                    $elem.addClass('error');
                    fieldsAreValid = false;
                }
            });
            return fieldsAreValid;
        };

        $('.form').on('submit', function(e) {
            e.preventDefault();

            var $form = $(this);

            if (checkFieldsErrors()) {
                var dataToSend = $form.serializeArray();
                dataToSend = dataToSend.concat(		
					$form.find('input.your_class:checkbox:not(:checked)').map(function() {
                        return {"name": this.name, "value": this.value}
                    }).get()
                );

                var $submit = $form.find(':submit');
                $submit.prop('disabled', 1);
                $submit.addClass('element-is-busy');

                $.ajax({
                    url : $form.attr('action'),
                    method: $form.attr('method'),
                    dataType : 'json',
                    data : dataToSend,
                    success: function(ret) {
                        if (ret.errors) {
                            ret.errors.map(function(el) {
                                return '[name="'+el+'"]'
                            });
                            checkFieldsErrors($form.find(ret.errors.join(',')));
                        } else {
                            if (ret.status=='ok') {
                                $form.replaceWith('<div class="form-send-success"><strong>Wiadomość została wysłana</strong><span>Dziękujemy za kontakt. Postaramy się odpowiedzieć jak najszybciej</span></div>');
                            }
                            if (ret.status=='error') {
                                $submit.after('<div class="send-error">Wysłanie wiadomości się nie powiodło</div>');
                            }
                        }
                    },
                    error : function() {
                        console.error('Wystąpił błąd z połączeniem');
                    },
                    complete: function() {
                        $submit.prop('disabled', 0);
                        $submit.removeClass('element-is-busy');
                    }
                });
            }
        })
    })
</script>
</body>
</html>

send-script.php:

<?php
$mailToSend = 'EMAIL';
if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
	$name       = $_POST['name'];
	$email      = $_POST['email'];
	$message    = $_POST['message'];
	$regulation = $_POST['regulation'];
	//TUTAJ ZMIENNE Z CHECKBOXOW DODANE
	$zazn = $_POST['zazn'];
	//KONIEC ZMIENNYCH 
	$errors     = Array();
	$return     = Array();
	if ( empty( $name ) ) {
		array_push( $errors, 'name' );
	}
	if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
		array_push( $errors, 'email' );
	}
	if ( empty( $message ) ) {
		array_push( $errors, 'message' );
	}
	if ( empty( $regulation ) ) {
		array_push( $errors, 'regulation' );
	}
	
	
	//TUTAJ JAK WYŻEJ DODANE
	
	if ( empty( $zazn ) ) {
		array_push( $errors, 'zazn' );
	}
	//KONIEC  
	
	
	if ( count( $errors ) > 0 ) {
		$return['errors'] = $errors;
	} else {
		$headers = 'MIME-Version: 1.0' . "\r\n";
		$headers .= 'Content-type: text/html; charset=UTF-8' . "\r\n";
		$headers .= 'From: ' . $email . "\r\n";
		$headers .= 'Reply-to: ' . $email;
		$message = "
			<html>
			<head>
			<meta charset=\"utf-8\">
			</head>
			<style type='text/css'>
				body {font-family:sans-serif; color:#222; padding:20px;}
				div {margin-bottom:10px;}
				.msg-title {margin-top:30px;}
			</style>
			<body>
			<div>Imię: <strong>$name</strong></div>
			<div>Email: <a href=\"mailto:$email\">$email</a></div>
			<div class=\"msg-title\"> <strong>Wiadomość:</strong></div>
			<div>$message</div>
			$zazn
			</body>
			</html>";

		if ( mail( $mailToSend, 'Wiadomość ze strony - ' . date( "d-m-Y" ), $message, $headers ) ) {
			$return['status'] = 'ok';
		} else {
			$return['status'] = 'error';
		}
	}

	header( 'Content-Type: application/json' );
	echo json_encode( $return );
}

 

komentarz 20 lipca 2019 przez Chess Szeryf (76,710 p.)
Napisz może szczegółowo jakie dostajesz błędy, ponieważ u mnie błędów chyba "nie ma".

Podobne pytania

0 głosów
2 odpowiedzi 1,378 wizyt
pytanie zadane 7 października 2017 w HTML i CSS przez Mavimix Dyskutant (8,390 p.)
+1 głos
1 odpowiedź 293 wizyt
0 głosów
1 odpowiedź 315 wizyt
pytanie zadane 21 grudnia 2019 w PHP przez milogab2004 Początkujący (440 p.)

92,579 zapytań

141,432 odpowiedzi

319,664 komentarzy

61,964 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...