Javascript – Praktyczny projekcik

article-thumbnail

Tematem dzisiejszego wpisu będzie realizacja praktycznego projektu związanego z obsługą strony internetowej. Dzisiejszy projekt to kalkulator, pobierający informację z tagów input, i renderujący odpowiednią treść na podstawie wybranych obliczeń. Projekt nie jest trudny ale za to bardzo pouczający, gdyż zanim zrealizujemy zadanie, będziemy musieli rozwiązać kilka problemów.

Tworzymy strukturę pliku w HTML

Jak wspomniałem nasza aplikacja internetowa będzie pobierać informacje z inputów, a następnie wykonywać obliczenia matematyczne. W HTML będziemy musieli zamieścić kilka tagów, które JS później obsłuży. Zakładam, że wszyscy czytelnicy tego wpisu, znają podstawy HTML’a i CSS’a. Dlatego nie będę omawiał podanego poniżej kodu.

<!DOCTYPE html>
<html lang="pl">
  <head>
    <meta charset="utf-8">
    <title>Projekt Kalkulator</title>
    <style>
      .container
      {
        margin: 0 auto;
        width: 200px;
        height: 200px;
        border: 1px solid black;
        background-color: lightgrey;
        border-radius: 20px;
        text-align: center;
      }
      input
      {
        border: 1px solid black;
        border-radius: 15px;
        width:150px;
        display: block;
        margin: 30px auto;
      }
      .button-container
      {
        display: flex;
        margin: 30px auto;
        justify-content: space-around;
      }
      button
      {
        width: 30px;
        height: 30px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <input type="number" name="input1" value="Podaj pierwszą liczbe">
      <input type="number" name="input2" value="Podaj drugą liczbe">
      <div class="button-container">
        <button type="button">+</button>
        <button type="button">-</button>
        <button type="button">*</button>
        <button type="button">/</button>
      </div>
    </div>
  </body>
</html>
 

Teraz podepnijmy plik ze skryptami. Użyjemy tagu <script src=””></script> umieszczonego wewnątrz sekcji <head>. Alternatywnie można także zapisać tylko tagi script, bez atrybutu src i wówczas umieścić kod wewnątrz nich. Z tej opcji ja będę korzystał, ponieważ pozwoli to umieszczenie w pełni wykonywalnego kodu w tym wpisie.

Budujemy logikę aplikacji

Pierwszym naszym krokiem, będzie zdefiniowanie funkcji odpowiedzialnej za pobranie wartości z inputów. Aby móc to zrobić, powinniśmy nadać naszym tagom <input> identyfikator czyli id, dzięki któremu JS będzie wiedział do którego elementu ma się odwołać. Następnie użyjemy metody obiektu document, o nazwie getElementById(), dzięki której złapiemy inputy. Omawiana funkcja jako argument przyjmie id poszukiwanego obiektu. Od razu po złapaniu pobierzemy ich wartość i zapiszemy w zmiennej. Wystarczy do tego użycie zapisu:

let pierwszaLiczba = document.getElementById('input1').value
let drugaLiczba = document.getElementById('input2').value

Jednak w naszym wypadku lepiej będzie, żeby omawiana funkcja zwróciła nam te wartości w postaci tablicy. Dzięki temu będziemy mogli skorzystać z nowego zapisu wprowadzonego w ES6. Jak wygląda finalna funkcja.

function pobierzDane()
{
    let dane = [];
    dane.push(document.getElementById('input1').value);
    dane.push(document.getElementById('input2').value);
    return dane;
}

Następnym naszym krokiem, będzie stworzenie funkcji które zostaną wykonane po wciśnięciu odpowiadającego im przycisku. Dlatego każdemu tagowi <button> przypiszemy atrybut onclick=””. Pomiędzy cudzysłowami umieścimy nazwy funkcji które mają zostać wykonane po kliknięciu.

Na początek zdefiniujmy funkcję suma(). Najpierw pobierze ona wartości z funkcji pobierzDane(). Następnie przeliczy wynik i wyśle go do funkcji wyswietlWynik(), którą zaraz utworzymy. Skoro pobierzDane() zawsze zwraca tablicę dwuelementową, możemy skorzystać z nowego zapisu. Wygląda on tak:

let [pierwszaZmienna,drugaZmienna] = pobierzDane()

Taki zapis jest równoznaczny z:

let dane = pobierzDane()
let pierwszaZmienna = dane[0]
let drugaZmienna = dane[1]

Teraz zdefiniujmy zmienną wynik, która przyjmie wartość pierwszaZmienna + drugaZmienna. Tą samą metodą tworzymy funkcje roznica i iloczy. Jednak przy funkcji iloraz musimy wprowadzić pewne zmiany. Otóż jak wszyscy wiedzą NIE WOLNO DZIELIĆ PRZEZ ZERO. Dlatego w funkcji umieścimy instrukcję warunkową, która sprawdzi, czy drugaZmienna nie jest zerem. Moja implementacja wygląda tak:

  function suma()
        {
          [pierwszaLiczba,drugaLiczba] = pobierzDane();
          let wynik = pierwszaLiczba+drugaLiczba;
          wypiszWynik(wynik)
        }

      function roznica()
        {
          [pierwszaLiczba,drugaLiczba] = pobierzDane();
          let wynik = pierwszaLiczba-drugaLiczba;
          wypiszWynik(wynik)
        }

      function iloczyn()
        {
          [pierwszaLiczba,drugaLiczba] = pobierzDane();
          let wynik = pierwszaLiczba*drugaLiczba;
          wypiszWynik(wynik)
        }

      function iloraz()
        {
          let wynik;
          [pierwszaLiczba,drugaLiczba] = pobierzDane();
          if(drugaLiczba!==0)
          {
            wynik = pierwszaLiczba/drugaLiczba;
          }
          else 
          {
            wynik = "Dzielenie przez Zero";
          }
          wypiszWynik(wynik)
        }

Funkcja wypiszWynik() otrzymuje jako parametr wynik działania. My chcemy przekazać użytkownikowi, jaki jest wynik jego działań. W tym celu wygenerujemy napis w div’ie klasy container. Użyjemy do tego parametru innerHTML. Najpierw nadajmy id temu elementowi, a następnie pochwyćmy go tą samą metodą co tagi input. Na końcu polecenia zamiast .value umieszczamy .innerHTML. Przypisujemy wartość w ten sposób:

  
function wyswietlWynik(wynik)
      {
          let kontener = document.getElementById('container')
          kontener.innerHTML = wynik + kontener.innerHTML ;
      }


Dzięki temu napis pojawi się na samej górze kontenera. Pora wypróbować nasz program.

<!DOCTYPE html>
<html lang="pl">
  <head>
    <meta charset="utf-8">
    <title>Projekt Kalkulator</title>
    <script>
      function pobierzDane()
        {
          let dane = [];
          dane.push(document.getElementById('input1').value);
          dane.push(document.getElementById('input2').value);
          return dane;
        }
      function suma()
        {
          [pierwszaLiczba,drugaLiczba] = pobierzDane();
          let wynik = pierwszaLiczba+drugaLiczba;
          wyswietlWynik(wynik)
        }
      function roznica()
        {
          [pierwszaLiczba,drugaLiczba] = pobierzDane();
          let wynik = pierwszaLiczba-drugaLiczba;
          wyswietlWynik(wynik)
        }
      function iloczyn()
        {
          [pierwszaLiczba,drugaLiczba] = pobierzDane();
          let wynik = pierwszaLiczba*drugaLiczba;
          wyswietlWynik(wynik)
        }
      function iloraz()
        {
          let wynik
          [pierwszaLiczba,drugaLiczba] = pobierzDane();
          if(drugaLiczba!==0)
          {
            wynik = pierwszaLiczba/drugaLiczba;
          }
          else
          {
            wynik = "Dzielenie przez Zero";
          }
          wyswietlWynik(wynik)
       }
       function wyswietlWynik(wynik)
       {
        let kontener = document.getElementById('container')
        kontener.innerHTML = wynik + kontener.innerHTML ;      
       }
    </script>
    <style>
      .container
      {
        margin: auto;
        width: 200px;
        height: 200px;
        border: 1px solid black;
        background-color: lightgrey;
        border-radius: 20px;
        text-align: center;
      }
      input
      {
        border: 1px solid black;
        border-radius: 15px;
        width:150px;
        display: block;
        margin: 30px auto;
      }
      .button-container
      {
        display: flex;
        margin: 30px auto;
        justify-content: space-around;
      }
      button
      {
        width: 30px;
        height: 30px;
      }

    </style>
  </head>
  <body>
    <div class="container" id="container">
      <input type="number" name="input1" id="input1" value="Podaj pierwszą liczbe">
      <input type="number" name="input2" id="input2" value="Podaj drugą liczbe">
      <div class="button-container">
        <button type="button" onclick="suma()">+</button>
    	<button type="button" onclick="roznica()">-</button>
        <button type="button" onclick="iloczyn()">*</button>
        <button type="button" onclick="iloraz()">/</button>
      </div>
    </div>
  </body>
</html>

Testowanie aplikacji i korekta błędów

Podczas testowania aplikacji okazuje się, że występują błędy. Jednym z nich jest łączenie się wczytanych wartości zamiast ich sumowania. Jest to związane z tzw. przeciążeniem operatorów. Otóż symbol + nie oznacza tylko dodawania liczb, ale również łączenie napisów. Z tego należy wnioskować, że pobrane dane nie zostają przesłane jako liczby a jako tekst. Aby naprawić ten błąd wystarczy w funkcji wczytaj umieścic polecenie parseInt(). Gdzie się ono znajdzie? Otóż umieścimy je podczas dodawania liczb do tablicy. W taki sposób ma to wyglądać.

function pobierzDane()
    {
      let dane = [];
      dane.push(parseInt(document.getElementById('input1').value));
      dane.push(parseInt(document.getElementById('input2').value));
      return dane;
    }

Funkcja parseInt() zmienia podany w argumencie tekst na liczbę. Umieszczona w takim miejscy sprawia, że metoda push() otrzymuje argument typu liczbowego. Teraz sprawdźmy naszą aplikację. Ok, ten problem naprawiliśmy, jednak teraz zaobserwowałem kolejny. Gdy próbujemy wykonać kolejną operację, aktualny wynik nie jest zastępowany, a dopisuje się do już istniejącego. Aby to naprawić umieścimy w div’ie container tag <span> o id wynik. I to do niego będziemy zapisywać nasze rezultaty. Po wprowadzeniu poprawek całość wygląda tak:

<!DOCTYPE html>
<html lang="pl">
  <head>
    <meta charset="utf-8">
    <title>Projekt Kalkulator</title>
    <script>
      function pobierzDane()
        {
          let dane = [];
          dane.push(parseInt(document.getElementById('input1').value));
          dane.push(parseInt(document.getElementById('input2').value));
          console.log(dane)
          return dane;
        }
      function suma()
        {
          [pierwszaLiczba,drugaLiczba] = pobierzDane();
          let wynik = pierwszaLiczba+drugaLiczba;
          wyswietlWynik(wynik)
        }
      function roznica()
        {
          [pierwszaLiczba,drugaLiczba] = pobierzDane();
          let wynik = pierwszaLiczba-drugaLiczba;
          wyswietlWynik(wynik)
        }
      function iloczyn()
        {
          [pierwszaLiczba,drugaLiczba] = pobierzDane();
          let wynik = pierwszaLiczba*drugaLiczba;
          wyswietlWynik(wynik)
        }
      function iloraz()
        {
          let wynik
          [pierwszaLiczba,drugaLiczba] = pobierzDane();
          if(drugaLiczba!==0)
          {
            wynik = pierwszaLiczba/drugaLiczba;
          }
          else
          {
            wynik = "Dzielenie przez Zero";
          }
          wyswietlWynik(wynik)
       }
      function wyswietlWynik(wynik)
      {
         document.getElementById('wynik').innerHTML = wynik ;
      }
    </script>
    <style>
      .container
      {
        margin: auto;
        width: 200px;
        height: 200px;
        border: 1px solid black;
        background-color: lightgrey;
        border-radius: 20px;
        text-align: center;
      }
      input
      {
        border: 1px solid black;
        border-radius: 15px;
        width:150px;
        display: block;
        margin: 30px auto;
      }
      .button-container
      {
        display: flex;
        margin: 30px auto;
        justify-content: space-around;
      }
      button
      {
        width: 30px;
        height: 30px;
      }

    </style>
  </head>
  <body>
    <div class="container" id="container">
      <span id="wynik"></span>
      <input type="number" name="input1" id="input1" value="Podaj pierwszą liczbe">
      <input type="number" name="input2" id="input2" value="Podaj drugą liczbe">
      <div class="button-container">
        <button type="button" onclick="suma()">+</button>
        <button type="button" onclick="roznica()">-</button>
        <button type="button" onclick="iloczyn()">*</button>
        <button type="button" onclick="iloraz()">/</button>
      </div>
    </div>
  </body>
</html>

Jeżeli chcesz utrwalić zdobytą dzisiaj wiedzę, polecam samodzielnie ulepszyć tą aplikację poprzez dodanie przycisków, przenoszącego wartość wyniku do inputa1 oraz usuwającego wszystkie zmiany z inputów i wyniku.