Kalkulator budowlany.

0

Cześć, jestem początkującym programistą js i mam problem z zadaniem stworzenia kalkulatora budowlanego. Wytyczne wyglądają w ten sposób:

  1. podaj powierzchnie użytkową z garażem
  2. podaj bryłę budynku (parterowy, z poddaszem, piętrowy)
    a) stan surowy(1350zł; 1010zł; 980zł)
    b) stan deweloperski (1275zł, 960zł,1020zł)
    c) stan pod klucz (720zł, 720zł, 720zł)
  3. podpiwniczenie (TAK, NIE)
    a) stan surowy( 25; 0)
    b) stan deweloperski ( 10 , 0)
    c) stan pod klucz (10 , 0)
  4. dach (płaski, spadzisty)
    a) stan surowy( 0,100 )
    b) stan deweloperski (0,15)
    c) stan pod klucz (0;0)
    Stan surowy, stan deweloperski, stan pod klucz
    I Stan surowy od 1*(2a+3a+4a)
    II Stan deweloperski od 1*(2b+3b+4b)
    III Stan pod klucz od 1*(2c+3c+4c)
    Łącznie od I+II+III = ?

I teraz tak - wybierając np stan surowy z poddaszem trzeba zsumować dwie pierwsze wartości. Wszystko byłoby proste, bo wtedy wyliczam to sobie, sumuje itd ale jest przypadek kiedy wszystkie wartości będą surowe, a jedna deweloperska - np podpiwniczenie i wtedy konieczne będzie podstawienie do wzoru liczby zawartej w piwnicy 3b, ale też pobrać wartość 2b.

Innym wypadkiem jest wybranie wszystkich opcji 'pod klucz' - w tym wypadku nie mogę zsumować tylko tego('pod klucz'), ale muszę też dodać wszystkie 'poprzednie' wartości, czyli 'surowe' i developerskie - bo to są kolejne etapy dotarcia do stanu pod klucz.

Tyle tytułem wstępu.
Kod wygląda tak, że mam formularz z inputami typu radio i wartościami value.
Przykładowy kawałek kodu html:

	   			<div class="options">
					<ul class="input__blocks stan">
						<li class="block">
				    		<input value="parter" type="radio" name="rodzaj" class="ico ico-1">
				    		<label for="parterowy">Parterowy</label>
			    		</li>
			    		<li class="block">
				    		<input value="poddasze" type="radio" name="rodzaj" class="ico ico-4">
				    		<label for="poddasze">Z poddaszem</label>
			    		</li>
			    		<li class="block">
				    		<input value="pietro" type="radio" name="rodzaj" class="ico ico-5">
				    		<label for="klucz">Piętrowy</label>
			    		</li>
		    		</ul>
	   			</div>

a tak wygląda js:

		function calculateTotal(){

			var rozmiar = document.querySelector('input[name="rozmiar"]').value;
			var stan = document.querySelector('input[name="stan"]:checked').value;
			var rodzaj = document.querySelector('input[name="rodzaj"]:checked').value;
			var dach = document.querySelector('input[name="dach"]:checked').value;
			var piwnica = document.querySelector('input[name="piwnica"]:checked').value;

			var base_surowy = 0;
			var base_developer = 0;
			var base_klucz = 0;

			var	piwnica_surowy = 0;
			var	piwnica_developer = 0;
			var	piwnica_klucz = 0;

			var	dach_surowy = 0;
			var	dach_developer = 0;
			var	dach_klucz = 0;

			if (dach == 'spadzisty') {
				if (stan == 'surowy') {dach_surowy = 100;};
				if (stan == 'developerski') {
					dach_surowy = 100;
					dach_developer = 15;
				};
				if (stan == 'klucz') {
					dach_surowy = 100;
					dach_developer = 15;
					dach_klucz = 0;
				};
			};

			if (piwnica == true) {
				if (stan == 'surowy') {piwnica_surowy = 25;};
				if (stan == 'developerski') {
					piwnica_surowy = 25;
					piwnica_developer = 10;
				};
				if (stan == 'klucz') {
					piwnica_surowy = 25;
					piwnica_developer = 10;
					piwnica_klucz = 10;
				};
			};


			document.getElementById("price").innerHTML = calc + 'zł';
		}

Stanąłem na tym etapie, bo zacząłem wpadać w pętle 'miliona' if-ów.
Czy jest jakiś inny, bardziej wydajny sposób niż setka if-ów, który mogę zastosować na poziomie początkującego?

0

A nie lepiej rozdzielić to na osobne funkcje?

3

Wszystko byłoby proste, bo wtedy wyliczam to sobie, sumuje itd ale jest przypadek kiedy wszystkie wartości będą surowe, a jedna deweloperska - np podpiwniczenie

Jesteś pewien, że tego wymaga zadanie? Bo to trochę bez sensu. Stan (surowy/developerski/pod klucz) dotyczy raczej całości (tak wynika z pokazanych wzorów).

Btw, aż się prosi o zastosowanie tablic / literałów obiektowych zamiast tych smutnych zmiennych.

Zakładajac, że jest tak jak mówię, można to sprowadzić np do czegoś takiego:

const cenaZaMetrBryłyWgStanu = {
  parterowy: [1350, 1275, 720],
  zPoddaszem: [1010, 960, 720],
  piętrowy: [980, 1020, 720],
}
 
const dodatekZaPodpiwniczenieWgStanu = [25, 10, 10]
 
const dodatekZaDachSpadzistyWgStanu = [100, 10, 0]
 
/**
 * Oblicza cenę domu wg zadanych kryteriów
 *
 * @param {number} powierzchnia - w m2
 * @param {number} stan (1 - surowy, 2 - deweloperski, 3 - pod klucz)
 * @param {string} bryła ('parterowy' / 'zPoddaszem' / 'piętrowy')
 * @param {boolean} podpiwniczenie
 * @param {boolean} dachSpadzisty 
 * @returns {number} cena
 */
function obliczCenę (powierzchnia, stan, bryła, podpiwniczenie, dachSpadzisty) {
  const cenaZaMetrBryły = sumujElementyTablicy(cenaZaMetrBryłyWgStanu[bryła].slice(0, stan))
  const dodatekZaPodpiwniczenie = podpiwniczenie
    ? sumujElementyTablicy(dodatekZaPodpiwniczenieWgStanu.slice(0, stan))
    : 0
  const dodatekZaDachSpadzisty = dachSpadzisty
    ? sumujElementyTablicy(dodatekZaDachSpadzistyWgStanu.slice(0, stan))
    : 0
 
  return (cenaZaMetrBryły + dodatekZaPodpiwniczenie + dodatekZaDachSpadzisty) * powierzchnia
}

/**
 * Sumuje elementy tablicy numerycznej
 *
 * @param {number[]} tablica
 * @returns {number} suma
 */
function sumujElementyTablicy (tablica) {
  return tablica.reduce((a, b) => a + b)
}
 
// Przykład
const wynik = obliczCenę(100, 2, 'piętrowy', true, false);
console.log(`Cena: ${wynik}zł`)

CodePen: https://codepen.io/caderek/pen/QMvJKW?editors=0011

PS:
Nie używaj polskich nazw w kodzie :P
I nie mieszaj logiki z operacjami na DOM.

0

Prawie idealnie :)
Nie działają wartości FALSE w funkcji wynikowej, tak czy inaczej zlicza te wartości :)
IF to załatwić czy można bardziej elegancko?

1

A fakt, tak na szybko to if tam nie jest zły, w formie ternary najlepiej - zaktualizowałem.

Albo można wykorzystać koercję false do 0 i zrobić tak:

  const dodatekZaPodpiwniczenie = podpiwniczenie && sumujElementyTablicy(dodatekZaPodpiwniczenieWgStanu.slice(0, stan))
  const dodatekZaDachSpadzisty = dachSpadzisty && sumujElementyTablicy(dodatekZaDachSpadzistyWgStanu.slice(0, stan))
0

Cześć wszystkim, mam trochę podobny problem. Potrzebuję zrobić w sumie to prosty kalkulator obliczający powierzchnię i adekwatną do niej cenę, jednak nie mogę sobie poradzić z przypisaniem odpowiedniej ceny z wyboru listy lub checkbox do wzoru na końcową cenę. ktoś podpowie co robię źle ?

<p></p>
<form id="calculator">
<p>Wysokość maty 1 : <input id="a" max="2" type="text" placeholder="a" /></p>
<p>Długość maty 1 :&nbsp; &nbsp; <input id="b" max="20" type="text" placeholder="b" /></p>
<p>Ilość mat :&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <input id="c" type="text" placeholder="c" />&nbsp;&nbsp;</p>
Rodzaj maty :<select name="grubosc">
  <option disabled selected value style='display: none'>Wybierz</option>
  <option value="58">zwykła</option>
  <option value="60">oczkowana</option>
  </select>
  <div>Cena: <span id='out'></span> zł</div>
<p></p>
<p>Cena mat : <input id="result" disabled="disabled" type="text" placeholder="=" /></p>
<button type="button" onclick="Calculator(this.innerHTML)">x</button></form>
<script>
document.querySelector('select').addEventListener('change'), (e) => {
  console.log(e);
  document.querySelector('#out').innerHTML = e.target.value;
});
</script>
<script>
function Calculator(operator) 
{
    var a = document.getElementById('a').value;
    var b = document.getElementById('b').value;  
    var c = document.getElementById('c').value;
    var d = document.getElementById("out");
var strUser = e.value;
    switch(operator) 
    { 
        case 'x':
             result = parseFloat(a) * parseFloat(b) * parseFloat(c) * parseFloat(d)
        break;  
      
    }

    document.getElementById('result').value = '= ' + result;
}
</script>```

0

Użyj konsoli przeglądarki Luke.

document.querySelector('select').addEventListener('change', (e) => {
0

@Freja Draco: Dziękuję, używałem ale muszę przyznać że nie do końca rozumiem co mogę zrobić z pewnymi błędami, jest lepiej ale jeszcze nie daje liczby tylko NaN

0
lukaszzzzzz napisał(a):

@Freja Draco: Dziękuję, używałem ale muszę przyznać że nie do końca rozumiem co mogę zrobić z pewnymi błędami, jest lepiej ale jeszcze nie daje liczby tylko NaN

Bo inputy i selecty przekazują stringi.
Świczenie rozwojowe na dziś: znajdź jak w JS zamienić zmienną tekstową na liczbę.

0

@Freja Draco: Wyczytałem, że parseFloat(), ponieważ mogą być liczby zmiennoprzecinkowe dlatego też w równaniu użyłem tej funkcji. Cały czas pojawia się w konsoli że "e is not defined" i nie wiem za bardzo co z tym zrobić

2

e jest tutaj obiektem zdarzenia change. Jego właściwości są dostępne jest jedynie wewnątrz funkcji strzałkowej (e) => {...}.
A nawet gdyby były dostępne na zewnątrz, to nie posiada on właściwości e.value, więc nic w taki sposób nie odczytasz.

Podstaw sobie:

var strUser = document.querySelector("SELECT[name='grubosc']").value;

i będzie działać. Tzn, będzie działać przynajmniej do tego etapu, bo później nic z tą zmienną nie robisz.

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