Kinek hasznos ez a demó?
Ez az önálló HTML/CSS/JS ártáblázat elsősorban azoknak a vállalkozóknak lehet hasznos, akik gyorsan, szerveroldali fejlesztés nélkül szeretnének bemutatni egy árazási struktúrát. Különösen praktikus, ha Ön:
- szolgáltatásait havi és éves díjjal is értékesíti, és az ügyfelek számára átláthatóvá tenné a különbséget;
- egy landing page vagy termékoldal prototípusát készíti, és vizuálisan ellenőrizné az árkiírás működését;
- vagy csak szeretné megérteni, hogyan épül fel egy ilyen interaktív elem a v0.app dokumentációja alapján.
A demó teljesen helyi működésű, nem igényel semmilyen háttérrendszert, így bármilyen böngészőben azonnal kipróbálható.
Egy konkrét, elképzelt helyzet
Képzelje el, hogy Ön egy kkv-knak szóló szoftveres szolgáltatást értékesít. Az értékesítési anyagban szeretné bemutatni, hogy éves fizetés esetén az ügyfél mennyit takarít meg a havi díjhoz képest. Ebben a demóban beírja a havi díjat (például 12 000 Ft-ot), kiválasztja a „Havi díj” opciót, és a táblázat azonnal mutatja az éves összesített összeget. Az ügyfél ezt látva azonnal érti az ajánlat lényegét.
Hogyan használja a tényleges demót?
A kód egy beágyazott, működő felületet hoz létre. A használata három egyszerű lépésből áll:
- Adja meg az összeget a „Összeg (Ft)” mezőben. Az alapértelmezett érték 12 000 Ft.
- Válassza ki az időtartamot a legördülő menüből: „Havi díj” vagy „Éves díj”.
- Kattintson a „Számítás” gombra, és a táblázat automatikusan megjeleníti a konvertált értékeket.
A „Újratöltés” gomb visszaállítja az alapértékeket (12 000 Ft, havi díj), és törli a táblázatot.
Három pontos teszt a kód alapján
A kód viselkedését az alábbi tesztekkel ellenőrizheti:
- 1. teszt – Havi összeg átváltása: Írjon be 10 000 Ft-ot, hagyja a „Havi díj” opciót, majd kattintson a „Számítás” gombra. Várt eredmény: A táblázatban megjelenik a „Havi díj” sor 10 000 Ft-tal, és az „Éves összesen (12 hónap)” sor 120 000 Ft-tal, a sor kiemelt háttérszínt kap.
- 2. teszt – Éves összeg átváltása: Írjon be 120 000 Ft-ot, válassza az „Éves díj” opciót, majd kattintson a „Számítás” gombra. Várt eredmény: A táblázatban megjelenik az „Éves díj” sor 120 000 Ft-tal, és a „Havi egyenérték” sor 10 000 Ft-tal, szintén kiemeléssel.
- 3. teszt – Hibás bemenet kezelése: Írjon be negatív számot (-5) vagy szöveget („abc”), majd kattintson a „Számítás” gombra. Várt eredmény: A táblázat nem jelenik meg, a visszajelzési sávban pedig hibaüzenet jelenik meg: „Hibás szám: adjon meg nem negatív pénzösszeget.” vagy „Csak számot írhat be (pl. 8500).”
A demó korlátai
Fontos tisztázni, hogy ez a megoldás kizárólag demonstrációs célokat szolgál. Nem végez valós pénznem- vagy árfolyamszámítást, nem tárol adatokat, és nem tartalmaz semmilyen üzleti logikát (például kedvezményeket vagy több összetevős árazást). A táblázat kizárólag a beírt összeg és a választott időtartam közötti matematikai átváltást mutatja be.
Mit igényelne egy éles weboldal?
Egy valódi, éles weboldalon weboldal készítés során ez a demó további kiegészítéseket igényelne:
- Reszponzív megjelenés: Bár a kód tartalmaz alapvető nézetport-beállítást, éles környezetben alaposabban tesztelni kell a mobilos és táblagépes megjelenítést.
- Kiszolgálóoldali ellenőrzés: Ha az árakat űrlapon keresztül küldené be, szerveroldalon is ellenőrizni kell az adatokat, nem csak a böngészőben.
- Kedvezmény- és árfolyamlogika: Az éles megoldásban általában szükség van különböző árszintekre, esetleg kedvezményekre vagy több fizetési periódusra.
- Szerkeszthető adatforrás: Az árakat és a választható opciókat érdemes lenne egy tartalomkezelő rendszerből (például WordPress) vagy egy külön JSON-fájlból betölteni, hogy az üzleti felhasználó módosíthassa őket programozói tudás nélkül.
A demó így is kiváló alapot ad egy gyors ötletvizsgálatra, és jól mutatja, milyen egyszerűen lehet interaktív elemeket létrehozni tiszta kóddal.
Próbáld ki a működő példát
A teljes másolható kód
Teljes, másolható index.html
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ártáblázat – havi és éves nézet</title>
<style>
* { box-sizing: border-box; margin: 0; }
body {
background: #202632;
color: #e6eef8;
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 20px;
}
.card {
background: #283040;
border-radius: 24px;
padding: 28px;
max-width: 860px;
width: 100%;
box-shadow: 0 15px 30px rgba(0,0,0,0.4);
}
h1 {
font-size: 1.7rem;
font-weight: 600;
margin-bottom: 24px;
letter-spacing: -0.3px;
border-left: 6px solid #39a0ff;
padding-left: 16px;
}
.controls {
display: flex;
flex-wrap: wrap;
gap: 16px;
align-items: flex-end;
margin-bottom: 28px;
}
.field {
display: flex;
flex-direction: column;
gap: 8px;
flex: 1 1 200px;
}
label {
font-size: 0.85rem;
font-weight: 500;
opacity: 0.9;
letter-spacing: 0.3px;
}
input, select {
background: #1a202c;
border: 1px solid #2f3b4e;
border-radius: 14px;
padding: 12px 16px;
color: #e6eef8;
font-size: 1rem;
outline: none;
transition: 0.2s;
}
input:focus, select:focus {
border-color: #39a0ff;
box-shadow: 0 0 0 3px rgba(57,160,255,0.2);
}
.actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
button {
background: #39a0ff;
color: #0b1a2a;
border: 0;
border-radius: 12px;
padding: 12px 22px;
font-weight: 700;
font-size: 0.95rem;
letter-spacing: 0.3px;
cursor: pointer;
transition: 0.15s;
box-shadow: 0 4px 0 #1d6cbb;
}
button.clear {
background: #5b6e8c;
box-shadow: 0 4px 0 #3a4a66;
color: #f0f6ff;
}
button:active { transform: translateY(4px); box-shadow: none; }
.table-container {
background: #1e242e;
border-radius: 20px;
padding: 12px;
overflow-x: auto;
margin-top: 8px;
}
table {
width: 100%;
border-collapse: collapse;
font-size: 0.95rem;
}
th, td {
text-align: left;
padding: 12px 10px;
border-bottom: 1px solid #2d3748;
}
th {
color: #9fb3d0;
font-weight: 600;
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 1px;
}
td:last-child, th:last-child { text-align: right; }
td:first-child, th:first-child { font-weight: 500; }
.feedback {
background: #2a3442;
border-radius: 14px;
padding: 14px 18px;
margin-top: 20px;
font-size: 0.9rem;
color: #bdd3f0;
border-left: 4px solid #39a0ff;
min-height: 36px;
}
.year-highlight td {
background: #253041;
}
.summary {
margin-top: 12px;
display: flex;
justify-content: flex-end;
font-size: 0.9rem;
color: #b9d2f0;
}
</style>
</head>
<body>
<main class="card">
<h1>Ártáblázat – havi / éves nézet</h1>
<!-- beviteli mezők -->
<div class="controls">
<div class="field">
<label for="amount">Összeg (Ft)</label>
<input type="number" id="amount" min="0" step="1" value="12000" placeholder="pl. 12000">
</div>
<div class="field">
<label for="unit">Időtartam</label>
<select id="unit">
<option value="month">Havi díj</option>
<option value="year">Éves díj</option>
</select>
</div>
<div class="actions">
<button type="button" id="generate">Számítás</button>
<button type="button" id="reset" class="clear">Újratöltés</button>
</div>
</div>
<!-- táblázat -->
<div class="table-container" id="tableWrap"></div>
<!-- üzenet / visszajelzés -->
<div class="feedback" id="feedback">Adja meg az összeget, majd válasszon nézetet.</div>
</main>
<script>
(function() {
'use strict';
// elemek
const amountInput = document.getElementById('amount');
const unitSelect = document.getElementById('unit');
const genBtn = document.getElementById('generate');
const resetBtn = document.getElementById('reset');
const feedback = document.getElementById('feedback');
const tableWrap = document.getElementById('tableWrap');
// tisztítás segéd
function clearTable() {
tableWrap.innerHTML = '';
}
// sablon használat helyett, textContent mindenhol
function buildTable(amount, unit) {
// ellenőrzés + összeg normalizálás
const numeric = Number(amount);
if (!isFinite(numeric) || numeric < 0) {
feedback.textContent = 'Hibás szám: adjon meg nem negatív pénzösszeget.';
return;
}
if (numeric === 0) {
feedback.textContent = 'Az összeg 0, a táblázat nullákat tartalmaz.';
} else {
feedback.textContent = `Érvényes összeg: ${new Intl.NumberFormat('hu-HU').format(Math.round(numeric))} Ft – nézet: ${unit === 'month' ? 'havi' : 'éves'}.`;
}
let rows = [];
if (unit === 'month') {
// havi összeg → éves (12 hónap)
const yearly = numeric * 12;
rows = [
{ label: 'Havi díj', value: numeric, type: 'base' },
{ label: 'Éves összesen (12 hónap)', value: yearly, type: 'total' }
];
} else {
// éves összeg → havi bontás
const monthly = numeric / 12;
rows = [
{ label: 'Éves díj', value: numeric, type: 'base' },
{ label: 'Havi egyenérték', value: monthly, type: 'total' }
];
}
// táblázat létrehozása DOM használatával (textContent)
const table = document.createElement('table');
const thead = document.createElement('thead');
const headerRow = document.createElement('tr');
const th1 = document.createElement('th');
th1.textContent = 'Megnevezés';
const th2 = document.createElement('th');
th2.textContent = 'Összeg (Ft)';
headerRow.appendChild(th1);
headerRow.appendChild(th2);
thead.appendChild(headerRow);
table.appendChild(thead);
const tbody = document.createElement('tbody');
rows.forEach((row, idx) => {
const tr = document.createElement('tr');
if (row.type === 'total') {
tr.classList.add('year-highlight'); // kiemelés
}
const tdLabel = document.createElement('td');
tdLabel.textContent = row.label;
const tdValue = document.createElement('td');
// kerekítés 2 tizedesre, de kerekítés, mert pénz
const rounded = Math.round(row.value);
tdValue.textContent = new Intl.NumberFormat('hu-HU').format(rounded);
tr.appendChild(tdLabel);
tr.appendChild(tdValue);
tbody.appendChild(tr);
});
table.appendChild(tbody);
tableWrap.innerHTML = ''; // törlés
tableWrap.appendChild(table);
}
// event: generálás
function handleGenerate() {
clearTable();
const amount = amountInput.value.trim();
const unit = unitSelect.value;
// ha üres vagy nem szám
if (amount === '') {
feedback.textContent = 'Adjon meg egy összeget!';
return;
}
const numeric = Number(amount);
if (isNaN(numeric)) {
feedback.textContent = 'Csak számot írhat be (pl. 8500).';
return;
}
if (numeric < 0) {
feedback.textContent = 'Negatív összeg nem lehet.';
return;
}
// megfelelő visszajelzés és táblázat
buildTable(numeric, unit);
}
// reset alapértékekkel
function handleReset() {
amountInput.value = '12000';
unitSelect.value = 'month';
clearTable();
feedback.textContent = 'Alapértékek visszaállítva. Adjon meg új összeget, ha szeretné.';
}
// eseménykezelők (click, nem form)
genBtn.addEventListener('click', handleGenerate);
resetBtn.addEventListener('click', handleReset);
// kezdeti érték – előállítunk egy alap táblázatot is (de marad a teszt kedvéért)
// A felhasználó azonnal látja a mintát
window.addEventListener('load', function() {
const numeric = Number(amountInput.value);
if (!isNaN(numeric)) {
buildTable(numeric, unitSelect.value);
} else {
feedback.textContent = 'Adjon meg összeget, a példabetöltés nem sikerült.';
}
});
})();
</script>
</body>
</html>A weboldalon megjelenő szöveges és vizuális tartalmak előállításához mesterséges intelligenciát (AI) használunk.