Programozási Kisokos

Gyakorlati példák a programozási tételek megvalósítására modern C#, PHP és JS környezetben. Válaszd ki a menüből a témakört!

Laravel PHP API Backend

0. Alapvető Terminál Parancsok (Artisan CLI)

A Laravel varázslata a beépített parancssoros eszközében, az Artisan-ban rejlik. Ezekkel a parancsokkal másodpercek alatt legenerálhatod a fájljaidat, ahelyett, hogy kézzel hoznál létre mindent.

1. Projekt Létrehozása és Futtatása

Tipp: Miután létrehoztad a projektet, a terminálban be kell lépned a mappájába (cd projektnev), és csak utána indíthatod el a szervert!

# Új, üres Laravel projekt letöltése és telepítése
composer create-project laravel/laravel projektnev

# Beépített fejlesztői szerver indítása (Általában: localhost:8000)
php artisan serve

# KÖTELEZŐ API-hoz (Laravel 11-től kezdve):
# Alapból nincs 'api.php' fájl. Ez a parancs hozza létre!
php artisan install:api
2. Fájlok Generálása (Make)

A profik trükkje: Nem muszáj külön parancsokat beírni a Modellhez és a Controllerhez. Lásd az utolsó sort a kombinált megoldásért!

# Sima Adatbázis Modell létrehozása (Nagy kezdőbetűvel, egyes számban!)
php artisan make:model ModellNev

# Sima Controller létrehozása
php artisan make:controller ControllerNev




3. Adatbázis kezelés és Debugolás
  • Migrate: Olyan, mintha elküldenéd a tervrajzokat a MySQL-nek, hogy építse fel a táblákat. Ha nem használsz SQL export/import fájlokat, ez építi fel az adatbázisodat.
  • Route:list: A legfontosabb parancs, ha valami nem működik a JS kliensed és a Laravel között. Kilistázza, hogy pontosan milyen URL-eken várja az adatokat a szervered.
# Adatbázis táblák létrehozása a Migrációs fájlok alapján
php artisan migrate

# Az összes regisztrált útvonal (URL) kilistázása a terminálba
php artisan route:list

Egy REST API felépítése Laravelben 3 fő fájl köré összpontosul: az útvonalak, az adatmodellek és a vezérlők (Controllerek) köré.

1. Útvonalak (routes/api.php)

Itt határozzuk meg, hogy a kliens (pl. a JS kódod) milyen URL-en érheti el az adatokat. Fontos: Mindenképp importálni (use) kell a Controllert a fájl tetején!

  • {id} vagy {p}: Ezek dinamikus paraméterek az URL-ben.
  • [Kontrollernev::class, 'fugveny_neve']: Így kötjük össze az útvonalat a Controller megfelelő metódusával.
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
// KÖTELEZŐ: A Controller csatolása az útvonalakhoz!
use App\Http\Controllers\Kontrollernev;

// Sima GET kérés paraméter nélkül
Route::get('/utvonal', [Kontrollernev::class, 'ide jon az a nev ami alapjan meg szeretned hivni a controllerben']);

// GET kérés paraméterrel (Az {id} automatikusan átadódik a kontrollernek)
Route::get('/utvonal/{atadnikivantertek}', [Kontrollernev::class, 'controllerfugvenynev']);

2. Adatbázis Modellek

A Model az adatbázis egy konkrét tábláját reprezentálja. Ahhoz, hogy az Eloquent ORM jól működjön, pontosan be kell állítanunk pár dolgot.

<?php

namespace App\Models;
use Illuminate\Database\Eloquent\Model;

class sofor extends Model
{
    // 1. Csatolás a megfelelő táblához (Ha nem a pluralizált angol nevet használjuk)
    protected $table = "táblanév";

    // 2. Elsődleges kulcs beállítása (Ha nem simán 'id' a neve)
    protected $primaryKey = "tábla elsődleges kulcsa(oszlopnév)";

    // 3. KÖTELEZŐ, ha a tábládban nincs 'created_at' és 'updated_at' oszlop!
    // Enélkül a Laravel hibára futna mentéskor vagy frissítéskor.
    public $timestamps = false;
}

3. Controllerek és Lekérdezések

A Controller végzi el a munkát: lekéri az adatot a Modelleken keresztül, majd visszaküldi a kliensnek JSON formátumban, egy megfelelő HTTP státuszkóddal (pl. 200 OK, 404 Not Found).

⚠️ FONTOS SZABÁLY: A találatok ellenőrzése (if feltételek)

Nagyon nem mindegy, hogy egy lekérdezés után hogyan vizsgálod meg, hogy lett-e eredmény! A titok a ->get() használatában rejlik:

  • Ha NINCS ->get() a parancs végén (pl. ::find($id) vagy ->first()):
    A Laravel vagy visszaad egyetlen konkrét sort (objektumot), vagy ha nincs találat, akkor null értéket ad. Itt tökéletesen működik az egyszerű if($data) ellenőrzés.
  • Ha VAN ->get() a parancs végén (pl. ::all() vagy ::where(...)->get()):
    A Laravel ilyenkor egy Listát (Collection) ad vissza. Ha nincs találat, akkor egy üres listát kapunk. Mivel az üres lista is létezik (tehát nem null), a sima if($data) vizsgálat mindig IGAZ lenne! Ilyenkor a listában lévő elemeket kell megszámolni: if($data->count() > 0).
Alapok: Importálás, Összes adat és Find (Keresés ID alapján)
<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
// KÖTELEZŐ: Az összes használt Modelt be kell húzni a Controllerbe!
use App\Models\modelnev;

    public function fugvenynev(api.php bol)(Request $request)
    {
        // Itt jön a lekérdezés és a válasz logikája
    }

    // ÖSSZES ADAT LEKÉRÉSE (példa)
    public function osszes_adat(api.php ben megadott function név)(Request $request)
    {
        $data = modelnev::all();
        return response()->json($data, 200); // 200 = OK
    }

    // PONTOS EGYEZÉS ID ALAPJÁN (FIND)
    public function adat_kereses(Request $request, $id)
    {
        $data = modelnev::find($id); // A $primaryKey alapján keres ezért fontos beállitani a modellben
        
        if($data) {
            return response()->json($data, 200);
        } else {
            // Hibaüzenet, ha nincs találat, 404-es (Not Found) kóddal
            return response()->json(['message' => 'Nem található adat!'], 404);
        }
    }
Szűrések (Where, Részleges egyezés, Relációs jelek)
    // WHERE: PONTOS EGYEZÉS 
    public function pontos_kereses(Request $request, $p)
    {
        $data = modelnev::where('adatbázis oszlopnév (amiben keresni szeretnenk)', $p)->get();
        
        if($data->count() > 0) {
            return response()->json($data, 200);
        } else {
            return response()->json(['message' => 'Nem található adat!'], 404);
        }
    }

    // WHERE: RÉSZLEGES EGYEZÉS (LIKE)
    public function reszleges_egyezeses_kereses(Request $request, $p)
    {
        // SQL: WHERE nev LIKE '%jancsi%'
        $data = modelnev::where('adatbázis oszlopnév (amiben keresni szeretnenk)', 'like', '%'.$p.'%')->get();
        return response()->json($data, 200);
    }

    // WHERE: OPERÁTORRAL (Nagyobb, kisebb, egyenlő)
    public function operatorral_kereses(Request $request, $p)
    {
        // SQL: WHERE ferohely >= $p + 1
        $data = modelnev::where('adatbázis oszlopnév (amiben keresni szeretnenk)', '>=', $p + 1)->get();
        return response()->json($data, 200);
    }
Többtáblás Lekérdezés (JOIN)

Ha a táblák össze vannak kapcsolva (pl. idegen kulcsokkal), a join() paranccsal szedhetjük ki a komplex adatokat. Itt megadhatjuk azt is a select()-ben, hogy pontosan mely oszlopokra van szükségünk az összekapcsolt táblákból.

    public function tobbtablas(Request $request)
    {
        $data = modelnev::select(
                // ha abbol a modellből választunk oszlopot amiből selectelunk akkor nem kell a tablanevet kulon ki irni (de ha ki irjuk se lesz hiba)
                'oszlopnev#1', 
                'tabla1.oszlopnev1 as tablaoszlop1', // 'as': Átnevezés a kimenetben
                'tabla1.oszlopnev2 as tablaoszlop2', 
                'tabla2.oszlopnev1'
            )
            // INNER JOIN sofor ON muszak.sofor_id = sofor.sofor_id
            //Az elsődleges táblában lévő masodlagos kulcs mezot kapcsoljuk ossze az osszekapcsolni kivant tablában lévő elsodleges kulcs mezovel
            ->join('tabla2', 'tabla1(modelnev).masodlagoskulcs ', '=', 'tabla2.id(elsodlegeskulcs)')
            // INNER JOIN tabla3 ON tabla2.masik_idegen_kulcs = tabla3.elsodleges_kulcs
            ->join('tabla3', 'tabla2(modelnev).masodlagoskulcs ', '=', 'tabla3.id(elsodlegeskulcs)')
            ->get();

        if($data->count() > 0) {
            return response()->json($data, 200);
        } else {
            return response()->json(['message' => 'Nincs műszak!'], 404);
        }
    }
Többszörös szűrés: ÉS / VAGY kapcsolat (orWhere)

Ha egymás után láncolsz több where parancsot, a Laravel automatikusan ÉS (AND) kapcsolatot feltételez közöttük (mindkét feltételnek igaznak kell lennie).
De ha neked az is jó, ha az egyik VAGY a másik feltétel teljesül, akkor veszed elő az orWhere függvényt!

    // TÖBBSZÖRÖS SZŰRÉS: VAGY (OR) KAPCSOLAT
    public function vagy_kereses(Request $request)
    {
        $data = modelnev::where('oszlop_nev', '>', ertek)
                        ->orWhere('oszlop_nev', 'keresettérték')
                        ->get();
        
        if($data->count() > 0) {
            return response()->json($data, 200);
        } else {
            return response()->json(['message' => 'Nincs ilyen adat!'], 404);
        }
    }
POST

POST-al új hozzáadása


public function neve(Request $request){

    $modelnev = new modelnev();

    $modelnev->keres1 = $request->keres1;
    $modelnev->keres2 = $request->keres2;
    $modelnev->keres3 = $request->keres3;

    $modelnev->save();

    return response()->json([
        'message' => 'Sikeres mentés!'
    ], 201);
}
  
Különlegesség: Szöveges (Varchar) Elsődleges Kulcs

Ha a tábládban az elsődleges kulcs nem egy növekvő szám (pl. ID), hanem egy szöveg (pl. rendszám vagy termékkód), akkor azt külön jelezni kell a Modelben. Két dolgot kell megmondanod a Laravelnek: 1. Ez NEM növekszik automatikusan. 2. A típusa szöveg (string).

<?php

namespace App\Models;
use Illuminate\Database\Eloquent\Model;


    protected $table = "tablanev";

    // 1. A kulcs oszlopának neve
    protected $primaryKey = "elsodlegeskulcs_oszlop";

    // 2. KÖTELEZŐ: Megmondjuk, hogy ez NEM egy automatikusan növekvő szám!
    public $incrementing = false;

    // 3. KÖTELEZŐ: Megmondjuk, hogy a kulcs típusa szöveg (string).
    protected $keyType = 'string';

    // Időbélyeg kikapcsolása (ha nincs created_at/updated_at az adatbázisban)
    public $timestamps = false;
Varchar Elsődleges Kulcs Kezelése a Gyakorlatban

Ha a Modelben mindent jól beállítottál, a keresés ugyanúgy működik! A fő különbség az új adat létrehozásánál és a táblák összekapcsolásánál van.

// 1. KERESÉS (Find) - NINCS KÜLÖNBSÉG!
// A find() függvény most már tudja, hogy szöveget kell keresnie az 'id' helyett.
$valtozo = Modelnev::find('keresendo adat'); 
// Az aposztróf csak akkor kell, ha fix adatra szeretnénk mindig keresni. Ha változóra, akkor ugyanúgy meghívjuk a $valtozot, és tudunk vele keresni.


// 2. ÚJ ADAT MENTÉSE - KÜLÖNBSÉG VAN!
// Mivel a kulcs NEM növekszik magától (Auto Increment), NEKED KELL MEGADNI az értékét mentés előtt!
public function szoveges_adat_mentese(Request $request)
{
    $ujAdat = new Modelnev();
    
    // KÖTELEZŐ megadni a kulcsot, különben hibát kapsz!
    $ujAdat->elsodlegeskulcs_oszlop = $request->bevitt_ertek1; 
    
    $ujAdat->masik_oszlop = $request->bevitt_ertek2;
    $ujAdat->save();
    
    return response()->json(['message' => 'Sikeres mentés!'], 201);
}


// 3. TÁBLÁK ÖSSZEKAPCSOLÁSA (Relációk a Modelben) - KÜLÖNBSÉG VAN!
// Ha egy másik tábla hivatkozik erre a szöveges kulcsra, 
// a Laravel alapból 'modelnev_id'-t keresne. Neked explicit meg kell mondanod az oszlopok neveit!

class MasikModelnev extends Model {
    public function kapcsolodo_adatok()
    {
        // belongsTo(KapcsolódóModel::class, 'idegen_kulcs_ebben_a_tablaban', 'elsodleges_kulcs_a_masik_tablaban')
        return $this->belongsTo(Modelnev::class, 'idegenkulcs_oszlopnev', 'elsodlegeskulcs_oszlop');
    }
}

JavaScript és API Kommunikáció

1. Adatok lekérése: XMLHttpRequest és Fetch API

A Klasszikus módszer (XMLHttpRequest)
const url = "alap URL";

function ajax(parameter, url, callback) {
    const xhttp = new XMLHttpRequest();

    xhttp.onload = function() {
        if(xhttp.status == 200) {
            var respons = JSON.parse(xhttp.responseText);
            callback(respons);
        }
    }
    xhttp.open("GET", url + parameter);
    xhttp.send();
}
A Modern módszer (Fetch API + Async/Await)
const url = "alap URL";

async function fetchAdatok(parameter, url, callback) {
    try {
        const response = await fetch(url + parameter);
        if (!response.ok) throw new Error("Hálózati hiba!");
        const adatok = await response.json();
        callback(adatok);
    } catch (error) {
        console.error("Hiba:", error);
    }
}

2. A Táblázat Dinamikus Generálása (DOM)

function tablaletrehozas(adatok) {
    var tabla = document.getElementById("tablazat");
    tabla.innerHTML = ""; 

    if (Array.isArray(adatok)) {
        adatok.forEach(valtozonev => {
            tabla.innerHTML += `
                <tr>
                    <td>${valtozonev.id}</td>
                    <td>${valtozonev.oszlopnev}</td>
                    .
                    .
                    .
                </tr>
            `;
        });
    } else {
        tabla.innerHTML = `<tr><td colspan="6">Nincs adat</td></tr>`;
    }
}

Adatbázis Kezelés (MySQL / MariaDB)

Az adatbázis a webes és asztali alkalmazások lelke. Itt találod a táblák létrehozásához szükséges parancsokat, típusokat, és a haladó lekérdezéseket.

1. Gyakori Adattípusok (Melyiket mikor használjuk?)

  • INT vagy INTEGER (Egész számok): Például 1, 4500. Leggyakrabban ID-khez vagy darabszámokhoz használjuk.
  • VARCHAR(hossz) (Változó hosszúságú szöveg): A VARCHAR(255) a leggyakoribb (pl. nevek, címek, e-mailek). A 255 azt jelenti, hogy maximum ennyi karakter lehet, de ha csak 5-öt írsz be, akkor csak annyi helyet foglal!
  • CHAR(hossz) (Fix hosszúságú szöveg): Vizsgákon ritkább, de pl. egy rendszámhoz (CHAR(7)) vagy irányítószámhoz (CHAR(4)) tökéletes. Ha rövidebbet írsz, szóközökkel pótolja ki.
  • DATE (Csak dátum): Év-Hónap-Nap formátum, pl. '2023-10-25'. Születési időhöz kötelező.
  • DATETIME (Dátum és időpont egyben): Például '2023-10-25 14:30:00'. Regisztrációkhoz, logoláshoz használjuk.
  • DECIMAL(összes, tizedes) (Pontos tizedestört): A DECIMAL(8, 2) azt jelenti, hogy összesen 8 számjegyből állhat, amiből 2 a tizedesvessző után van (pl. árakhoz, 15000.50).
  • BOOLEAN vagy TINYINT(1) (Logikai érték): Igaz vagy Hamis. Az adatbázisban 1 (Igaz) vagy 0 (Hamis) formájában tárolódik.

2. Megszorítások (Constraints) - Szabályok a táblában

Ezek a parancsok garantálják, hogy ne kerüljön "szemét" vagy hibás adat a táblába.

  • PRIMARY KEY (Elsődleges kulcs): Egyedi azonosító minden sornak (pl. személyi szám, vagy egy sima ID). Ebből csak egy lehet táblánként, és nem lehet üres!
  • AUTO_INCREMENT (Automatikus sorszámozás): Általában az INT PRIMARY KEY mellé tesszük, így az adatbázis magától adja a 1, 2, 3... értékeket.
  • NOT NULL (Kötelező mező): Ha ezt kiírod, a rendszer hibát dob, ha valaki üresen (kitöltetlenül) akarja hagyni ezt az oszlopot.
  • UNIQUE (Egyedi érték): Olyan, mint a Primary Key, de ebből több is lehet a táblában (pl. az email oszlopra rakjuk, hogy ne lehessen kétszer regisztrálni ugyanazzal).
  • DEFAULT 'érték' (Alapértelmezett érték): Ha beszúráskor (INSERT) nem adunk meg semmit, ezt írja be automatikusan (pl. DEFAULT 'aktív').
  • CHECK (feltétel) (Bonyolultabb ellenőrzés): Például CHECK (kor >= 18) - nem enged be 18 évnél fiatalabb adatot.
  • FOREIGN KEY (Idegen kulcs): Két tábla összekapcsolására szolgál (pl. a "vásárlások" táblában a "vevo_id" egy idegen kulcs, ami a "vevők" tábla "id"-jére mutat).

3. Adatbázis és Tábla Létrehozása (CREATE)

1. Adatbázis létrehozása

Vizsgákon a legelső lépés. A karakterkódolás (UTF-8) megadása szinte mindig kötelező, hogy a magyar ékezetek (á, ű, ő) ne "krixkraxként" jelenjenek meg!

CREATE DATABASE adatbazisnev 
DEFAULT CHARACTER SET utf8 
COLLATE utf8_hungarian_ci;

-- Használatba vétel (Kiválasztás)
USE adatbazisnev;
2. Tábla létrehozása (CREATE TABLE)

A megszorításokat és a típusokat itt vetjük be. Figyeld meg az idegen kulcs (Foreign Key) megadásának szintaktikáját a kód alján!

CREATE TABLE tablanev (
    -- Elsődleges kulcs, ami magától nő
    id INT AUTO_INCREMENT PRIMARY KEY,
    
    -- Kötelező szöveges mező
    szoveg VARCHAR(255) NOT NULL,
    
    -- szám ami nem lehet negativ
    szam INT UNSIGNED ,
    
    
    -- Idegen kulcs egy másik táblához
    idegenkulcs INT,
    FOREIGN KEY (oszlopnev) REFERENCES masiktabla(kulcs_oszlop)
);

4. Adatok Felvitele (INSERT INTO)

Az adatok beszúrása. Két dologra kell figyelni: az oszlopok neveit fel kell sorolni, majd a VALUES után ugyanabban a sorrendben megadni az értékeket. Szöveget és dátumot mindig aposztrófok (' ') közé teszünk, a számokat nem!




-- Több adat beszúrása egyszerre (vesszővel elválasztva)
INSERT INTO tablanev (oszlopnev1, oszlopnev2, oszlopnev3) 
VALUES ('szovegesértékbevitel', 123, 1),
  ('szoveg1', szam, szam),
  ('szoveg#2', szam, szam),
  ('szoveg#3', szam, szam);

5. Dupla Select / Belső Lekérdezés (Subqueries)

Van, amikor egy kérdés megválaszolásához egy másik kérdést is fel kell tennünk az adatbázisnak. Például: "Kik keresnek többet, mint az ÁTLAG?" (Ehhez először ki kell számolni az átlagot). Ezek a belső lekérdezések, amik mindig zárójelbe kerülnek.

1. Egyetlen értéket adó (Skaláris) belső select

A belső SELECT mindössze egyetlen cellányi adatot ad vissza (pl. egy maximumot vagy átlagot). Relációs jelekkel (=, >, <) vizsgáljuk.


-- Először a zárójel belseje fut le: megkeresi a max árat (pl. 85000). 
-- A külső rész pedig kiírja azt a nevet, aminek az ára egyenlő ezzel.

SELECT oszlopnev1,oszlopnev2 
FROM tabla1 
WHERE oszlopnev3 = (
    SELECT MAX(oszlopnev3) 
    FROM tabla2
);
-- A belso selectben lekerdezhetjuk ugyan azon tabla masik adatait vagy akar masik tabla adatait is
2. Több értéket adó (Lista) belső select (IN)

A belső SELECT egy egész oszlopnyi adatot (több ID-t) ad vissza. Mivel több érték van, nem használhatunk egyenlőségjelet (=), helyette az IN kulcsszót kell használnunk!



SELECT oszlopnev 
FROM tablanev 
WHERE oszlopnev(legtobbszor id) IN (
    SELECT oszlopnev(legtobbszor id) 
    FROM tablanev 
    WHERE keresettoszlopnev = 'keresettertek'
    -- A keresett ertek ha egy valtozo vagy oszlopnev akkor nem kell aposztrof ('')
);

5. Táblák összekapcsolása (Foreign Key / References)

A „Szülő-Gyerek” kapcsolat: Képzeld el, hogy van egy kategoriak táblád (ő a Szülő) és egy termekek táblád (ő a Gyerek). Az idegen kulcs egy „láthatatlan lánc”, ami összeköti őket.

  • Miért jó ez? Megakadályozza, hogy olyan kategóriába sorolj egy terméket, ami nem is létezik. Ha a kategóriák között csak 1-től 5-ig vannak számok, az adatbázis „leüti a kezed”, ha te a 99-es kategóriát akarod megadni.
  • Szigorú szabály: Az összekapcsolt oszlopoknak hajszálpontosan ugyanaz legyen a típusa! Ha a szülő táblában az ID INT UNSIGNED, akkor a gyerek táblában a rá mutató kulcs is INT UNSIGNED kell, hogy legyen.
-- 1. A SZÜLŐ TÁBLA (Ezt hozzuk létre először)
CREATE TABLE parent_table (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    egyeb_mezo VARCHAR(50) NOT NULL
);

-- 2. A GYEREK TÁBLA (Aki hivatkozik a szülőre)
CREATE TABLE child_table (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    egyeb_mezo VARCHAR(100) NOT NULL,
    -- Ez az oszlop fogja tárolni, a referencia id-ket.
    parent_table_id INT UNSIGNED,

    -- A KAPCSOLAT LÉTREHOZÁSA:
    FOREIGN KEY (parent_table_id) REFERENCES parent_table(id)
    -- "elsonek azt az oszlop mezot kell meg adni ami az aktualis tablaban levo masodlagos kulcs zarojelek kozott"
    -- "A masodik ertek az meg a szulo tabla tehat ahol van az elsodleges kulcs és ott zarojelben meg kell adni a primary key oszlop nevet. (altalaban id vagy tablanev_id)"
    
    -- Opcionális extra: ON DELETE CASCADE
    -- Ez azt jelenti: "Ha torlom a parent elemet torlodik vele az osszes rá hivatkozo child elem is."
    ON DELETE CASCADE
);

C# GUI (Windows Forms)

1. Az Adatbázis kapcsolat osztály

using System;
        using MySql.Data.MySqlClient;


        string server = "server=localhost;user=root;database=adatbazisnev;password=;" EN: diak66 uid diak66 pw XXTQ4E;
        MySqlConnection kapcsolat;
        MySqlCommand parancs;
        MySqlDataReader dr;

        public Konstruktornev(filenev)(string sql)
        {
            kapcsolat = new MySqlConnection(server);
            kapcsolat.Open();
            parancs = new MySqlCommand(sql, kapcsolat);
            Dr = parancs.ExecuteReader();
        }

        public MySqlDataReader Dr { get => dr; set => dr = value; }
        public void lezaras() { kapcsolat.Close(); }
        ~Adatbazis() { kapcsolat.Close(); }

2. Adatátvitel Formok között

Gyakori feladat, hogy egy adatot (például egy kijelölt sor ID-ját) át kell adnunk egyik ablakból a másikba. Íme a három legnépszerűbb megoldás:

1. Konstruktoron keresztül

A legegyszerűbb mód: már az ablak létrehozásakor átadjuk az adatot paraméterként.

// Küldő Form (Form1.cs)
string adat = tx_nev.Text;
Form2 f2 = new Form2(adat);
f2.Show();

// Fogadó Form (Form2.cs)
string megkapott;
public Form2(string bejovo) {
    InitializeComponent();
    megkapott = bejovo;
}
2. Statikus osztály (Global)

Ha sok formnak van szüksége ugyanarra az adatra (pl. bejelentkezett felhasználó).

// Hozz létre egy Global.cs fájlt:
public static class Global {
    public static int UserId;
}

// Bárhol írható/olvasható:
Global.UserId = 5;
int id = Global.UserId;
3. Publikus tulajdonság

Létrehozunk egy változót a cél-formban, amit kívülről beállítunk a megjelenítés előtt.

// Fogadó Form (Form2.cs)
public string AtvittAdat { get; set; }

// Küldő Form (Form1.cs)
Form2 f2 = new Form2();
f2.AtvittAdat = "Szia!";
f2.Show();

2. Adatok Mentése és Módosítása

private void bt_mentes_Click(object sender, EventArgs e)
        {
            if (tx_szovegmezo.Text.Length == 0) 
            {
                MessageBox.Show("Kérjük, töltse ki a szöveges mezőt!", "HIBA", MessageBoxButtons.OK, MessageBoxIcon.Error);
                tx_szovegmezo.Focus();
                return; 
            }

            // 2. Szám mező validálása (különálló try-catch)
            try
            {
                int szamAdat = Convert.ToInt32(tx_szamosmezo.Text);
            }
            catch
            {
                MessageBox.Show("A szám mezőbe csak számot írhat!", "HIBA", MessageBoxButtons.OK, MessageBoxIcon.Error);
                tx_szamosmezo.Text = "";
                tx_szamosmezo.Focus();
                return;
            }

            // 3. Ha ide eljutott a program, minden adat hibátlan! Jöhet a többi konverzió.
            string datumAdat = formdatummezo.Value.ToString("yyyy-MM-dd");
            string datumIdoAdat = formdatummezo.Value.ToString("yyyy-MM-dd HH:mm:ss");
            
            if (rbujfelvitel.Checked)
            { 
                string lekerdezes = "INSERT INTO tablanev (szoveges_oszlop, szamos_oszlop, datum_oszlop, datumido_oszlop, logikai_oszlop) " +
                                    "VALUES (" +
                                    "'" + tx_szovegmezo.Text + "', " + 
                                    szamAdat + ", " + 
                                    "'" + datumAdat + "', " + 
                                    "'" + datumIdoAdat + "', " + 
                                    logikaiAdat + ");";
                
                Adatbazis ab = new Adatbazis(lekerdezes);
                ab.Dr.Read();
                MessageBox.Show("Sikeres mentés!");
            }
            else
            {
                string lekerdezes = "UPDATE tablanev SET " +
                                    "szoveges_oszlop='" + tx_szovegmezo.Text + "', " +
                                    "szamos_oszlop=" + szamAdat + ", " +
                                    "datum_oszlop='" + datumAdat + "', " +
                                    "datumido_oszlop='" + datumIdoAdat + "', " +
                                    "logikai_oszlop=" + logikaiAdat + " " +
                                    "WHERE id_oszlop=" + formazon;
                
                Adatbazis ab = new Adatbazis(lekerdezes);
                ab.Dr.Read();
                MessageBox.Show("Sikeres módosítás!");
            }
        }

3. DataGridView Kezelése (Betöltés, Szűrés, Kattintás)

A DataGridView az egyik leghasznosabb vezérlő, mellyel táblázatos adatokat tudunk megjeleníteni és kezelni. Itt láthatod, hogyan töltsd fel, hogyan csinálj dinamikus szűrést TextBox alapján, és miként nyerj ki adatot rákattintással.

Tábla feltöltése és Dátum formázása

A Clear() használatával megelőzzük az adatok duplikálását, a Convert.ToDateTime pedig lehetővé teszi, hogy egyéni (pl. yyyy-MM-dd) formátumban fűzzük be a dátumot a gridbe.

void tablakitoltes()
          {
              dataGridView1.Rows.Clear();
              string lekerdezes = "select * from tablanev";
              Adatbazis ab = new Adatbazis(lekerdezes);

              while (ab.Dr.Read())
              {
                  DateTime DateTimeValtozo = Convert.ToDateTime(ab.Dr["DateTimeAdat"]);
                  dataGridView1.Rows.Add(ab.Dr["oszlopnev"], DateTimeValtozo.ToString("yyyy-MM-dd"));
              }
          }
Dinamikus Szűrés (LIKE)

Ha a felhasználó gépel a txkereses TextBox-ba, a program hozzáfűz egy WHERE feltételt a lekérdezéshez, így a Grid tartalma valós időben szűrhetővé válik.

void tablabetoltes()
          {
              dataGridView1.Rows.Clear();
              string keresszoveg = "";

              // Ha van beírva szöveg, hozzáfűzzük a szűrést
              if (txkereses.TextLength > 0)
              {
                  keresszoveg = " where KeresettOszlop like '" + txkereses.Text + "%' ";
              }

              string lekerdezes = "select * from táblanév " + keresszoveg;
              Adatbazis ab = new Adatbázis(lekerdezes);

              while (ab.Dr.Read())
              {
                  DateTime datum = Convert.ToDateTime(ab.Dr["datumoszlop"]);
                  dataGridView1.Rows.Add(ab.Dr["oszlopnev1"], ab.Dr["oszlopnev2"], datum.ToString("yyyy-MM-dd"));
              }
          }
Esemény: Kattintás a táblázat egy sorára (CellClick)

Amikor rákkattintasz egy cellára, az adott sor értékeit áttöltheted Labelekbe vagy TextBoxokba.
Tipp: A feltételt e.RowIndex >= 0-ra módosítottam a te kódodhoz képest, mert a 0 index a legelső adatsor! (A -1 lenne a fejléc, azt így tökéletesen kihagyjuk).

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
          {
              // Ellenőrizzük, hogy NEM a fejlécre kattintottak-e (fejléc indexe: -1)
              if (e.RowIndex >= 0)
              {
                  // A kiválasztott sor (Row) objektumának eltárolása
                  DataGridViewRow sor = dgadatok.Rows[e.RowIndex];
                  
                  // Cellák értékének átadása a szövegmezőknek (Oszlop neve alapján)
                  label1.Text = sor.Cells["dataGridViewMezonev1"].Value.ToString();
                  label2.Text = sor.Cells["dataGridViewMezonev2"].Value.ToString();
                  label3.Text = sor.Cells["dataGridViewMezonev3"].Value.ToString();
                  label4.Text = sor.Cells["dataGridViewMezonev4"].Value.ToString();
              }
          }

C# CLI & LINQ Kisokos

0. Szövegformázás és Tagolás (Escape karakterek)

A konzolos kiíratásoknál gyakran van szükségünk sortörésre, behúzásra, vagy olyan speciális karakterek kiírására, amiket a C# amúgy a kód részének gondolna (pl. idézőjel). Ezeket a \ (backslash) jellel tudjuk vezérlő jellé alakítani.

  • \n : Új sor (Sortörés / Enter).
  • \t : Tabulátor (Nagyobb szóköz, pl. oszlopok igazításához).
  • \" : Idézőjel kiírása egy szövegen belül (anélkül, hogy lezárná a stringet).
  • \\ : Backslash (\) kiírása (pl. fájlok elérési útjánál).
// 1. Sortörés és Tabulátor használata (tablazat szeru ki iratas)
Console.WriteLine("Oszlopnev\tOszlopnev\n1.\tTartalom1\n2.\tTartalom2");

// 2. Idézőjel a stringen belül
Console.WriteLine("Azt mondta: \"Szia, hogy vagy?\"");

// 3. Elérési út (Backslash) - Kétféleképpen:
string utvonal1 = "C:\\mappa\\fajl.kiterjesztes";

// VAGY: A @ jellel a string elején a C# figyelmen kívül hagyja a vezérlő karaktereket!
string utvonal2 = @"C:\mappa\fajl.kiterjesztes";

Osztály (Class) létrehozása beolvasáshoz


        // fel kell venni a tulajdonságokat (valtozokat)
        public int ID { get; set; }
        public string Nev { get; set; }
        // A valtozok felvétele utan generalni kell hozza propertiket


        // Konstruktor
        public konstruktornev(class név)(string sor)
        {
            var v = sor.Split(';');
            ID = int.Parse(v[0]);
            Nev = v[1];
            
        }
        
        // ToString override megjelenites
        public override string ToString() => $"Név: {Nev}\nId: {ID} ";
    

2. Főprogram - Fájl Beolvasás és Írás (bin/Debug)

Beolvasás (Fejléc átugrásával)

A fájlt (pl. adatok.txt) a bin/Debug/net... mappában keresi. Az első sort (fejlécet) egy külön ReadLine() paranccsal kiolvassuk a ciklus előtt, így a feldolgozás már a tiszta adatokkal kezdődik.

// Egyedi lista az objektumoknak
List<Osztalynev> osztalylista = new List<Osztalynev>();

FileStream fs = new FileStream("adatok.txt", FileMode.Open);
StreamReader sr = new StreamReader(fs, Encoding.UTF8);

// Fejléc kihagyasa
_  = sr.ReadLine();

while (!sr.EndOfStream)
{
    // Konstruktor hívása az aktuális sorral
    osztalylista.Add(new Osztalynev(sr.ReadLine()));
}

// Fájlfolyamok lezárása (KÖTELEZŐ!)
sr.Close();
fs.Close();
Fájlba írás (StreamWriter)

Eredmények kimentése egy új fájlba. Fontos: a FileMode.Create felülírja a fájlt, ha már létezik. A Close() metódusokat sose felejtsd el, különben a fájl üres maradhat!

// Fájl létrehozása (szintén a bin/Debug mappába)
List<Osztalynev> osztalylista = new List<Osztalynev>();

FileStream fs = new FileStream("kimenet.txt", FileMode.Create);
StreamWriter sw = new StreamWriter(fsIras, Encoding.UTF8);

// Ha szeretnél saját fejlécet írni a fájlba
sw.WriteLine("Név;Statisztika");

foreach (var item in osztalylista)
{
    // Adatok kiírása formázva (pl. pontosvesszővel elválasztva)
    sw.WriteLine($"{item.Nev};{item.Tulajdonsag}");
}

// Lezárás (Enélkül nem kerülnek mentésre az adatok az SSD-re/HDD-re!)
sw.Close();
fs.Close();

2.5. Lista elemeinek elérése és bejárása

Elemek elérése index alapján és a teljes lista kiíratása

A beolvasott adatokat tartalmazó listából az elemeket az indexükkel (0-tól kezdve) érhetjük el. Az utolsó elem indexe mindig a Count - 1.

// 1. Az ELSŐ elem elérése (0. index)
Console.WriteLine($"Első adat: {osztalylista[0].Tulajdonsag}");

// 2. Az UTOLSÓ elem elérése (Count-1)
Console.WriteLine($"Utolsó adat: {osztalylista[osztalylista.Count - 1].Tulajdonsag}");

// 3. A teljes lista bejárása (Minden elem kiíratása)
foreach (var item in osztalylista)
{
    // Az osztályban definiált tulajdonságok vagy a felülírt ToString() hívása
    Console.WriteLine($"{item.Nev} - {item.Tulajdonsag1} - {item.Tulajdonsag2}");
}

3. Dictionary (Szótár) Használata (Gyakoriság statisztika)

Kulcs-Érték párok tárolása (Megszámlálás, Statisztika)

A Dictionary<Kulcs, Érték> a legalkalmasabb eszköz statisztikák készítésére (pl. "Melyik kategóriából hány darab van?"). Az alábbi algoritmus végigmegy a listán, és ha a kulcs (pl. fizetési mód, típus) még nincs a szótárban, felveszi 1-es értékkel. Ha már benne van, akkor megnöveli az értékét.

// 1. Szótár létrehozása (Kulcs: a vizsgált szöveges tulajdonság, Érték: darabszám)
Dictionary<string, int> statisztika = new Dictionary<string, int>();

// 2. Lista bejárása és statisztika építése
for (int i = 0; i < lista.Count; i++)
{
    // Ha a szótár MÉG NEM tartalmazza ezt a kulcsot (pl. ezt a kategóriát)
    if (!statisztika.ContainsKey(lista[i].KeresettTulajdonsag))
    {
        // Felvesszük a szótárba, 1-es induló darabszámmal
        statisztika.Add(lista[i].KeresettTulajdonsag, 1);
    }
    else
    {
        // Ha már benne van, csak megnöveljük a meglévő darabszámot
        statisztika[lista[i].KeresettTulajdonsag]++;
    }
}

// 3. A kész statisztika kiírása a képernyőre
foreach (var item in statisztika)
{
    Console.WriteLine($"\t{item.Key}: {item.Value} db");
}

4. Metódus (Eljárás) vs. Függvény

C#-ban minden egy osztályon belül van, így technikailag mindent metódusnak hívunk. Viszont a működésük alapján (ahogy az iskolában is tanulod) két nagy csoportra osztjuk őket: Eljárásokra (nem adnak vissza adatot a hívónak) és Függvényekre (adnak vissza valamilyen eredményt).

Eljárás / Sima Metódus (void)

A void kulcsszó jelzi, hogy ez a kódblokk elvégez egy feladatot (pl. kiír valamit a képernyőre, vagy beállít egy változót), de nem ad vissza értéket a hívónak. Nincs benne return (vagy csak üresen a kilépéshez).

// Létrehozás: A "void" jelzi, hogy nincs visszatérési érték
public void eljaras_neve(string parameternev)
{
    Console.WriteLine("Ez csak megcsinál valamit: " + parameternev);
    // NINCS return érték!
}

// Meghívás a főprogramban: Nem tudjuk változóba menteni!
eljaras_neve("teszt adat");
Függvény (Visszatérési értékkel)

A void helyett egy konkrét adattípust (pl. int, string, bool) adunk meg. A kód végén kötelező a return kulcsszóval egy ilyen típusú értéket visszaadni, amit aztán a hívó fél egy változóban elmenthet.

// Létrehozás: A "void" helyett pl. "int" van megadva (attol fugg milyen vissza térési értéket szeretnenk)
public int fuggveny_neve(int bevittszamertek1, int bevittszamertek2)
{
    int eredmeny = bevittszamertek1 + bevittszamertek2;
    // KÖTELEZŐ visszaadni a függvény tipusanak megfelelo erteket!
    return eredmeny;
}

// Meghívás a főprogramban: egy változóba MENTJÜK a választ!
int megkapott_ertek = fuggveny_neve(5, 10);

C# Programozási Tételek (Hagyományos)

Ezek az algoritmusok LINQ (beépített függvények) használata nélkül, klasszikus ciklusokkal (for, while) oldják meg az alapvető problémákat. Vizsgákon gyakran kötelező ezt a megközelítést alkalmazni!

Összegzés (Summation)

A lista objektumainak egy adott számszerű tulajdonságát adjuk össze.

int osszeg = 0;
for (int i = 0; i < lista.Count; i++)
{
    // Egy osztálypéldány konkrét tulajdonságát adjuk hozzá
    osszeg += lista[i].Tulajdonsag; 
}
Console.WriteLine($"Az összeg: {osszeg}");
Megszámlálás (Counting)

Hány olyan objektum van, aminek a tulajdonsága megfelel a feltételnek?

int db = 0;
for (int i = 0; i < lista.Count; i++)
{
    if (lista[i].Tulajdonsag == Feltétel)
    {
        db++;
    }
}
Console.WriteLine($"Találatok száma: {db}");
Maximum kiválasztás

Kikeresi a legnagyobb elemet. Mindig indexet tárolunk, nem magát az értéket!

int maxIndex = 0; 
for (int i = 1; i < lista.Count; i++)
{
    // Itt is a tulajdonságokat hasonlítjuk össze
    if (lista[i].Tulajdonsag > lista[maxIndex].Tulajdonsag)
    {
        maxIndex = i;
    }
}
Console.WriteLine($"Legnagyobb elem neve: {lista[maxIndex].Nev}");
Minimum kiválasztás

Kikeresi a legkisebb elemet. A logika pontosan ugyanaz, csak a relációs jel fordul meg.

int minIndex = 0; 
for (int i = 1; i < lista.Count; i++)
{
    if (lista[i].Tulajdonsag < lista[minIndex].Tulajdonsag)
    {
        minIndex = i;
    }
}
Console.WriteLine($"Legkisebb elem neve: {lista[minIndex].Nev}");
Kiválogatás (Filtering)

Amikor nem csak megszámlálni akarjuk a feltételnek megfelelő elemeket, hanem egy új listába ki is másoljuk őket, hogy később dolgozhassunk velük.

List<Osztalynev> eredmenyLista = new List<Osztalynev>();

for (int i = 0; i < lista.Count; i++)
{
    // Ha az objektum tulajdonsága megfelel...
    if (lista[i].Tulajdonsag == Feltétel)
    {
        // ...magát az objektumot adjuk hozzá az új listához
        eredmenyLista.Add(lista[i]);
    }
}

1. Alapvető Programozási Tételek (Matematika)

Összegzés és Átlag (Sum, Average)
var osszegzes = lista.Sum(valtozo => valtozo.tulajdonsag);

var atlag = lista.Average(valtozo => valtozo.tulajdonsag);
Megszámlálás (Count)
var count = lista.Count(valtozo => valtozo.tulajdonsag == "keresett tulajdonsasg");

3. Projekció (Kiválogatás) és Rendezés

// Láncolás (KOMPLEX): Az 5 legöregebb macska lekérése
var komplex = lista
    .Where(valtozo => valtozo.tulajdonsag == "keresett tulajdonsag")
    .OrderByDescending(valtozo => valtozo.tulajdonsag)
    .ToList()[..5];
    // a [..5] azt jelenti hogy az elso 5 elem lesz vissza adva ugyan az mint a .Take(5) itt is 5 elemet veszunk ki
  

4. Csoportosítás (GroupBy)

var csoport = listta
        .GroupBy(valtozo => valtozo.tulajdonsag) // csoportosítás a tulajdonsag alapján
        .Where(valtozo => valtozo.Count() > 1)
        .OrderBy(valtozo => valtozo.Key)
        .ToDictionary(valtozo => valtozo.Key, valtozo => valtozo.Count());

CSS Kisokos (Tulajdonság Szótár)

A CSS (Cascading Style Sheets) felel az oldal kinézetéért. Az alábbi listában megtalálod a leggyakrabban használt formázó tulajdonságokat és azok lehetséges értékeit.

1. Méretezés, Margók és Távolságok

Szélesség, Magasság és a Dobozmodell
.elem {
  /* SZÉLESSÉG ÉS MAGASSÁG */
  width: 100%;          /* Fix szélesség (px, %, vw) */
  max-width: 1200px;    /* Sohasem lesz szélesebb ennél (reszponzív oldalaknál kötelező) */
  min-width: 300px;     /* Ennél sohasem lesz keskenyebb */
  
  height: auto;         /* Magasság (auto: a belső tartalom határozza meg, px, vh) */
  min-height: 100vh;    /* Kitölti a képernyő teljes magasságát (Viewport Height) */

  /* TÁVOLSÁGOK (A 4 érték sorrendje mindig: Fent, Jobb, Lent, Bal) */
  margin: 10px 20px 10px 20px;  /* KÜLSŐ távolság az elemek között */
  margin: 0 auto;               /* Vízszintesen KÖZÉPRE igazítja a blokkot! */
  margin-top: 15px;             /* Csak fentre tesz külső margót */

  padding: 20px;                /* BELSŐ távolság (a keret és a szöveg között) minden irányba */
  padding-left: 10px;           /* Csak balra tesz belső margót */

  /* DOBOZ SZÁMÍTÁS (Aranyat érő szabály!) */
  box-sizing: border-box;       /* A padding és a border befelé vastagodik, nem növeli meg az elem szélességét! */
}

2. Keretek és Árnyékok

.elem {
  /* KERET (Vastagság, Stílus, Szín) */
  border: 2px solid red;        /* Folyamatos keret */
  border: 1px dashed blue;      /* Szaggatott keret */
  border: 3px dotted green;     /* Pöttyözött keret */
  border-bottom: 1px solid #ccc;/* Csak alulra tesz vonalat */

  /* SARKOK LEKEREKÍTÉSE */
  border-radius: 8px;           /* Enyhe lekerekítés */
  border-radius: 50%;           /* Teljesen kerek (kör), ha a szélesség és magasság egyezik! */

  /* ÁRNYÉKOK (X eltolás, Y eltolás, Elmosódás, Méretnövelés, Szín) */
  box-shadow: 2px 4px 10px 0px rgba(0,0,0,0.5); /* Doboz árnyéka (kívül) */
  box-shadow: inset 0px 0px 5px black;          /* Belső árnyék (inset) */
}

3. Szövegformázás és Tipográfia

.szoveg {
  /* BETŰTÍPUS ÉS MÉRET */
  font-family: Arial, sans-serif; /* Betűtípus (ha az első nincs, jön a második) */
  font-size: 16px;                /* Betűméret (px, rem, em) */
  font-weight: bold;              /* Vastagság: normal, bold, vagy 100-tól 900-ig számok */
  font-style: italic;             /* Dőlt betű (normal az alap) */

  /* SZÍNEK ÉS IGAZÍTÁS */
  color: #333333;                 /* Szövegszín (Név, Hexa, RGB, RGBA) */
  text-align: center;             /* Igazítás: left, right, center, justify (sorkizárt) */
  line-height: 1.5;               /* Sorköz (a betűméret másfélszerese) */
  letter-spacing: 1px;            /* Betűk közötti távolság */

  /* DEKORÁCIÓ ÉS ÁTALAKÍTÁS */
  text-decoration: underline;     /* Aláhúzás (linkeknél 'none'-nal lehet levenni) */
  text-transform: uppercase;      /* MINDEN NAGYBETŰ (lowercase: kisbetű, capitalize: Kezdőbetűk) */
  text-shadow: 1px 1px 2px black; /* Magának a szövegnek az árnyéka */
}

4. Hátterek (Backgrounds)

.hatter {
  /* EGYSZERŰ HÁTTÉRSZÍN */
  background-color: #0d6efd;      /* Simán kitölti színnel */

  /* HÁTTÉRKÉP BEÁLLÍTÁSAI */
  background-image: url('kep.jpg'); /* Kép betöltése */
  background-size: cover;           /* Kitölti az egész elemet anélkül, hogy torzulna a kép */
  /* (A 'contain' értéknél a kép teljes egésze látszani fog, de lehet, hogy marad üres hely) */
  
  background-position: center;      /* Középre igazítja a képet (lehet top, bottom, left, right is) */
  background-repeat: no-repeat;     /* Megakadályozza, hogy a kis képek csempeszerűen ismétlődjenek */
  background-attachment: fixed;     /* Parallax hatás: görgetéskor a kép helyben marad */

  /* ÁTMENET (GRADIENS) */
  background: linear-gradient(to right, red, blue); /* Pirosból kékbe tartó átmenet */
}

5. Pozíció és Megjelenés (Block vs. Flex)

A megjelenítés típusai

A display: block lényege: Az ilyen elem (pl. div, p, h1) „önző”. Elfoglalja a rendelkezésre álló teljes szélességet (100%), és mindenképpen új sorban kezdődik. Nem enged maga mellé semmit, hacsak nem kényszerítjük rá (pl. floattal).

.container {
  /* FLEXBOX: A modern elrendezés alapja */
  display: flex;         /* Bekapcsolja a rugalmas elrendezést */
  
  /* IGAZÍTÁS A FLEXEN BELÜL */
  justify-content: center;  /* Vízszintesen középre teszi a gyerek elemeket */
  align-items: center;      /* Függőlegesen középre igazít */
  flex-direction: row;      /* Alapértelmezett: egymás mellé rakja az elemeket */
  flex-wrap: wrap;          /* Ha nem férnek el, új sorba törnek */
}

.block-elem {
  display: block;        /* Teljes szélesség, új sor (alapértelmezett a div-nél) */
}

.pozicionalas {
  position: relative;    /* Marad a helyén, de eltolható */
  position: absolute;    /* Kiszakad a folyamból, a szülőhöz igazodik */
  z-index: 10;           /* Rétegrend (magasabb szám van felül) */
}

6. Reszponzivitás (@media screen)

A reszponzivitás lényege, hogy a weboldal alkalmazkodik a képernyő méretéhez. Ezt a @media szabállyal érjük el, ahol meghatározzuk a „töréspontokat” (breakpoints).

Hivatalos Töréspontok (Eszközméretek)
Eszköz Mérettartomány (Szélesség) @media szabály
Mobil 0px - 767px @media screen and (max-width: 767px)
Tablet 768px - 991px @media screen and (min-width: 768px)
Desktop (Monitor) 992px felett @media screen and (min-width: 992px)
/* ALAPSTÍLUS (Általában Desktopra tervezünk először) */
.doboz { width: 33%; float: left; }

/* MOBIL NÉZET (Ha a képernyő kisebb, mint 768px) */
@media screen and (max-width: 767px) {
  .doboz { 
    width: 100%;   /* Mobilon ne legyenek egymás mellett, töltsék ki a szélességet */
    float: none; 
  }
  body { font-size: 14px; } /* Kisebb betűk mobilon */
}

/* TABLET NÉZET (768px és 991px között) */
@media screen and (min-width: 768px) and (max-width: 991px) {
  .doboz { width: 50%; } /* Tableten ketten legyenek egymás mellett */
}

6. Gyakorlati Példák: Kép és Szöveg (Vizsgafeladatok)

Iskolai feladatokban és vizsgákon szinte mindig előkerül a képek és bekezdések egymáshoz igazítása. Íme a 3 leggyakoribb feladattípus, közvetlenül a HTML tagek (img, p) formázásával!

1. Kép balra, a szöveg jobbról körbefolyja

A trükk: A képre rárakjuk a float: left; tulajdonságot. Hogy a szöveg ne tapadjon rá teljesen a képre, teszünk a kép jobb oldalára és aljára egy kis külső margót.

img {
  float: left;          /* A kép balra "lebeg", a szöveg mellette folyik */
  margin-right: 15px;   /* Távolság a kép jobb oldalán a szövegtől */
  margin-bottom: 10px;  /* Távolság a kép alján a szövegtől */
}

p {
  text-align: justify;  /* Vizsgákon gyakori kérés: sorkizárt bekezdés */
}
2. Kép jobbra, a szöveg balról körbefolyja

A trükk: Pont a fordítottja. A képet jobbra lebegtetjük (float: right;), és most a kép BAL oldalára kérünk margót, hogy a szöveg ne lógjon bele.

img {
  float: right;         /* A kép jobbra kerül */
  margin-left: 15px;    /* Most a bal oldalra kell a távolság! */
  margin-bottom: 10px;  /* Alulra ugyanúgy hagyunk egy kicsit */
}

p {
  text-align: justify;
}
3. Kép pontosan középen (A szöveg felette és alatta van)

A tipikus vizsgacsapda: A képek alapból olyanok, mint a betűk (inline elemek), így a margin: 0 auto; nem működik rajtuk! Először blokk szintűvé (dobozzá) kell alakítani a képet a display: block; segítségével, és csak utána lehet margóval középre tolni. Ilyenkor a szöveg nem futja körbe, hanem szépen alatta folytatódik.

img {
  display: block;       /* 1. lépés: Csináljunk dobozt a képből! (KÖTELEZŐ) */
  margin-left: auto;    /* 2. lépés: Bal oldali margó automatikus */
  margin-right: auto;   /* 3. lépés: Jobb oldali margó automatikus */
  /* (Röviden írva: margin: 0 auto; - ez is tökéletes megoldás) */
  
  margin-top: 20px;     /* Távolság a felette lévő bekezdéstől */
  margin-bottom: 20px;  /* Távolság az alatta lévő bekezdéstől */
}

p {
  text-align: center;   /* Opcionális: A bekezdés is középre legyen igazítva */
}
Jótanács: A Float "ragadásának" eltüntetése (Clear)

Ha körbefuttatod a képet a float segítségével, előfordulhat, hogy a következő feladat (pl. a lábléc vagy egy új címsor) is felcsúszik a kép mellé! Ezt a clear tulajdonsággal lehet letiltani egy másik elemen (pl. a láblécen).

footer {
  clear: both;  /* Visszaállítja a rendet: ez az elem már garantáltan új sorba kerül, a kép alá! */
}

6. Gyakorlati Példák (Tipikus Vizsgafeladatok)

Ezek az elrendezések szinte minden webfejlesztős vizsgán (ágazati, érettségi) előkerülnek. Tisztán, csak HTML tag-ekre (class és ID nélkül) hivatkozva készítettük el őket.

1. Kép balra, a szöveg körbefolyja
img {
  float: left;          /* A kép balra "lebeg" */
  margin-right: 15px;   /* Távolság a kép jobb oldalán */
  margin-bottom: 10px;  /* Távolság a kép alján */
}
p {
  text-align: justify;  /* Sorkizárt bekezdés */
}
2. Kép középre igazítása (Szöveg megszakad)
img {
  display: block;       /* Dobozzá kell alakítani a képet! */
  margin: 0 auto;       /* Bal-jobb margó automatikus (középre húzza) */
  margin-bottom: 20px;  /* Távolság az alatta lévő bekezdéstől */
}
3. Fejléc: Háttérkép és Középre zárt Címsor

A feladat: Van egy <header> taged, amiben van egy <h1>. A headernek egy képet kell kapnia háttérként, a szövegnek pedig középen kell lennie, jól olvashatóan.

header {
  background-image: url('fejlec-hatter.jpg'); /* A kép elérési útja */
  background-size: cover;                     /* Kitölti az egész headert torzulás nélkül */
  background-position: center;                /* A kép közepe látszódjon */
  padding: 100px 0;                           /* Fent-lent nagy belső tér, hogy legyen magassága a fejlécnek! */
}

h1 {
  text-align: center;             /* Címsor középre zárása */
  color: white;                   /* Legyen fehér a betű, hogy elüssön a képtől */
  text-shadow: 2px 2px 5px black; /* Fekete árnyék a betűknek (KÖTELEZŐ, ha a kép színes!) */
  margin: 0;                      /* Alapértelmezett margó levétele */
}
4. Vízszintes Navigációs Menü (Középre igazítva)

A feladat: A menü általában egy <nav>-on belüli <ul> és <li> lista. Ebből kell egy soros, vízszintes, középre zárt, pöttyök nélküli menüt csinálni.

nav {
  background-color: #333; /* Sötét sáv a menü mögött */
}

nav ul {
  list-style-type: none;  /* Eltünteti a lista pöttyöket */
  margin: 0;
  padding: 0;
  text-align: center;     /* A lista elemeit (amiket mindjárt inline-block-ká teszünk) középre tolja! */
}

nav li {
  display: inline-block;  /* ETTŐL LESZ EGY SORBAN! (Egymás mellé teszi a lista elemeit) */
}

nav a {
  display: block;         /* A link kitölti a listaelem helyét */
  padding: 15px 20px;     /* Kényelmesen kattintható nagy gombokat csinálunk */
  color: white;
  text-decoration: none;  /* Leveszi a linkek aláhúzását */
}

nav a:hover {
  background-color: #555; /* Ha ráviszed az egeret, megváltozik a színe */
}
5. A Főtartalom (Main) 80%-os, középre zárt elrendezése

A feladat: A weboldal tartalma ne menjen ki a képernyő legszéléig, hanem alkosson egy középre zárt, jól olvasható "papírlap" hatású oszlopot.

body {
  background-color: #f4f4f4;  /* Világosszürke háttér az egész oldalnak */
}

main {
  width: 80%;                 /* Csak a képernyő 80%-át foglalja el */
  max-width: 1200px;          /* De sosem lesz szélesebb 1200 pixelél (óriás monitorokon is szép marad) */
  margin: 20px auto;          /* 20px távolság fentről/lentről, és AUTO balról/jobbról (EZ TESZI KÖZÉPRE!) */
  
  background-color: white;    /* Legyen fehér a tartalom háttere, hogy kiemelkedjen a body szürkeségéből */
  padding: 30px;              /* Belső margó, hogy a szöveg ne tapadjon rá a fehér doboz szélére */
  box-shadow: 0 0 10px rgba(0,0,0,0.1); /* Egy kis finom árnyék (vizsgán plusz pont járhat érte!) */
}

HTML Kisokos (Ritkább tagek és attribútumok)

A HTML nem csak bekezdésekből (p) és div-ekből áll. A szemantikus tagek és a speciális tulajdonságok (attribútumok) segítik a böngészőket, a keresőmotorokat és a vakok képernyőolvasóit is.

1. Idézetek és Különleges Szövegformázások

Ezekkel a tagekkel sokkal pontosabban írhatod le a szöveged jelentését, mintha csak sima span-eket vagy div-eket használnál.

<!-- Hosszú, blokk szintű idézet (automatikusan beljebb húzza a böngésző) -->
<blockquote cite="https://forras-weboldal.hu">
  A programozás nem arról szól, amit tudsz, hanem arról, amit meg tudsz oldani.
</blockquote>

<!-- Rövid, sorközi idézet (automatikusan idézőjeleket tesz köré) -->
Azt mondta: <q>Szeretem a kávét</q>.

<!-- Mű, könyv vagy cikk címének hivatkozása (általában dőlt betűs) -->
Kedvenc könyvem a <cite>Gyűrűk Ura</cite>.

<!-- Rövidítés megadása (ha fölé viszed az egeret, kiírja a teljes nevet) -->
A <abbr title="HyperText Markup Language">HTML</abbr> nagyon hasznos.

<!-- Kiemelés (alapértelmezetten sárga filces kihúzás) -->
Kérlek, hozd el a <mark>piros mappát</mark>!

<!-- Billentyűzet-parancs jelzése a szövegben -->
A mentéshez nyomd meg a <kbd>Ctrl</kbd> + <kbd>S</kbd> gombot!

2. Interaktív és Szemantikus Tagek

Tudtad, hogy JavaScript nélkül is készíthetsz lenyíló (harmonika) menüt? Erre való a details és a summary.

<!-- Lenyíló menü (JavaScript nélkül!) -->
<details>
  <summary>Kattints ide a részletekért!</summary>
  <p>Ez a szöveg alapból rejtve van, és csak kattintásra nyílik le.</p>
</details>

<!-- Dátumok és idők gépek számára is értelmezhető formátumban -->
A találkozó <time datetime="2023-10-25T20:00">szerda este 8-kor</time> lesz.

<!-- Alsó index és felső index (Matekhoz vagy kémiához) -->
H<sub>2</sub>O <!-- A 2-es lent lesz (víz) -->
E = mc<sup>2</sup> <!-- A 2-es fent lesz (négyzet) -->

3. Hasznos és Egyedi Attribútumok (Tulajdonságok)

Bizonyos tagek egyedi tulajdonságokkal rendelkeznek, amikkel extra funkciókat adhatunk nekik. Illetve léteznek globális attribútumok (pl. title, hidden, data-*), amiket bármilyen tagen használhatsz.

<!-- LINKEK (A tag) SPECIÁLIS TULAJDONSÁGAI -->
<!-- target="_blank": Új lapon nyitja meg a linket -->
<a href="https://google.com" target="_blank">Kereső</a>

<!-- download: Nem megnyitja, hanem letölti a fájlt (megadhatod a letöltött fájl nevét is) -->
<a href="konyv.pdf" download="Harry_Potter.pdf">Könyv letöltése</a>

<!-- KÉPEK (IMG) SPECIÁLIS TULAJDONSÁGAI -->
<!-- loading="lazy": Csak akkor tölti be a képet, ha a felhasználó odagörget (gyorsítja az oldalt!) -->
<!-- alt="...": KÖTELEZŐ! Ha nem tölt be a kép, ezt írja ki, és a vakok felolvasója is ezt olvassa. -->
<img src="nagy-kep.jpg" alt="Egy szép hegyvidék" loading="lazy">

<!-- INPUT (ŰRLAP MEZŐK) SPECIÁLIS TULAJDONSÁGAI -->
<!-- placeholder: Halvány segítő szöveg a mezőben -->
<!-- required: Kötelező kitölteni űrlapküldés előtt -->
<!-- readonly / disabled: Csak olvasható, nem módosítható -->
<input type="text" placeholder="Írd ide a neved..." required>
<input type="email" value="titkos@email.hu" disabled>

<!-- GLOBÁLIS ATTRIBÚTUMOK (Bármin használhatóak) -->
<!-- title: Kicsi sárga tooltip jelenik meg az egér rávitelekor -->
<div title="Ez egy rejtett üzenet!">Vidd fölém az egeret!</div>

<!-- hidden: Eltünteti az elemet (olyan, mint a CSS display: none;) -->
<p hidden>Ez a bekezdés nem látszik az oldalon.</p>

<!-- data-* attribútumok: Saját, egyedi adatokat tárolhatsz a tagben JavaScript számára! -->
<button data-id="45" data-role="admin" onclick="olvasdKi()">Törlés</button>

0. Alapvető HTML Építőelemek

Minden weboldal két fő részből áll: a Fejrészből (<head>), ami a gépnek és a böngészőnek szól, valamint a Testből (<body>), amibe a tényleges, látogatók által látható tartalom kerül.

A Fejrész (Head) Titkai

A színfalak mögötti tagek

Ezek a tagek nem jelennek meg magán a weboldalon. Információt adnak a keresőknek (Google), betöltik a stílusokat, és beállítják az oldalt.

  • <title>: A weboldal címe. Ez jelenik meg a böngésző fülén és a Google keresési találataiban.
  • <meta charset="UTF-8">: Kötelező! Ez biztosítja, hogy az ékezetes betűk (á, é, ű) helyesen jelenjenek meg.
  • <meta name="viewport">: Felelős azért, hogy a weboldal mobilon is jól nézzen ki, és ne kelljen nagyítani az olvasáshoz.
  • <meta name="description">: A weboldal rövid leírása. Ezt mutatja a Google a cím alatt a keresőben.
  • <link rel="stylesheet">: Ezzel kötheted hozzá a külső CSS fájlodat (vagy pl. a Bootstrapet) az oldalhoz.
  • <style>: Ha nem külső fájlt használsz, ide írhatod a belső CSS kódodat.
  • <script>: JavaScript kódok vagy külső JS fájlok betöltésére szolgál (bár ezt gyakran a <body> aljára teszik a gyorsabb betöltés miatt).
<head>
  <!-- Karakterkódolás és Mobil nézet beállítása -->
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  <!-- FAVICON: A böngésző fülén megjelenő kis ikon -->
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  
  <title>Szuper Weboldal</title>
  <link rel="stylesheet" href="style.css">
</head>

A Test (Body) Építőelemei

Itt található a lényeg. Kategóriákra bontottuk a leggyakrabban használt tageket!

1. Szövegformázás
  • <h1> - <h6>: Címsorok (Heading). A h1 a főcím, h6 a legkisebb.
  • <p>: Bekezdés (Paragraph). Folyószöveghez.
  • <br>: Sortörés (Break). Nincs lezáró párja.
  • <hr>: Vízszintes elválasztó vonal. Nincs lezáró párja.
  • <strong> vagy <b>: Félkövér szöveg.
  • <em> vagy <i>: Dőlt szöveg.
<h1>Üdvözöllek!</h1>
<p>Ez egy <strong>fontos</strong> üzenet.<br>
Itt folyatódik a <em>következő</em> sorban.</p>
<hr>
2. Listák
  • <ul>: Rendezetlen (pöttyös) lista (Unordered List).
  • <ol>: Rendezett (számozott) lista (Ordered List).
  • <li>: Listaelem. Csak ul vagy ol belsejében lehet!
<ul>
  <li>Első pöttyös elem</li>
  <li>Második pöttyös elem</li>
</ul>

<ol>
  <li>Első számozott elem</li>
</ol>
3. Tárolók (Dobozok) és Szemantikus zónák
  • <div>: Egy "üres" doboz. Új sort kezd (blokk szintű). Általában stílusozásra használjuk.
  • <span>: Sorközi (inline) tároló. Nem kezd új sort, csak egy szót/kifejezést fog közre stílusozáshoz.
  • <header>, <footer>: A weboldal (vagy egy szekció) fejléce és lábléce.
  • <main>: Az oldal fő, egyedi tartalma ide kerül.
  • <section>: Egy tematikus blokk (pl. "Rólunk", "Szolgáltatások").
  • <nav>: A navigációs menü tárolója.
<header>
  <nav>Főmenü helye</nav>
</header>

<main>
  <section>
    <div class="doboz">Tartalom <span style="color:red">piros</span> szóval.</div>
  </section>
</main>
4. Hivatkozások és Média
  • <a>: Hivatkozás (Link). A href="" attribútum mondja meg, hova mutasson.
  • <img>: Kép. Az src="" adja meg a kép útvonalát, az alt="" a leírását. Nincs lezáró párja!
  • <iframe>: Másik weboldal (pl. YouTube videó vagy Google Térkép) beágyazása.
  • <video> / <audio>: Videó és hangfájl lejátszása a böngészőben.
<a href="https://google.hu">Kattints ide</a>

<img src="fenykep.kiterjesztes" alt="kep" width="300">

<video controls>
  <source src="film.mp4" type="video/mp4">
</video>
5. Táblázatok
  • <table>: Maga a táblázat tárolója.
  • <tr>: Táblázat sora (Table Row).
  • <th>: Fejléc cella (Table Head). Félkövér és középre zárt alapból.
  • <td>: Sima adat cella (Table Data).
<table border="1">
  <tr>
    <th>Fejlecszoveg#1</th>
    <th>Fejlecszoveg#2</th>
  </tr>
  <tr>
    <td>Kitoltoszoveg#1</td>
    <td>Kitoltoszoveg#2</td>
  </tr>
</table>
6. Űrlapok (Forms)
  • <form>: Az űrlap tárolója.
  • <input>: Beviteli mező (szöveg, jelszó, checkbox, rádiógomb stb. a type alapján).
  • <label>: A mezőhöz tartozó felirat. (Rákattintva belekattint a mezőbe).
  • <select> & <option>: Legördülő lista és az elemei.
  • <button>: Kattintható gomb.
<form>
  <label>Neved:</label>
  <input type="text" placeholder="Ide írj...">
  
  <select>
    <option>Opció 1</option>
    <option>Opció 2</option>
  </select>

  <button type="submit">Küldés</button>
</form>