Alkalmazások fejlesztése

8. előadás

Horváth Győző
Egyetemi adjunktus
1117 Budapest, Pázmány Péter sétány 1/c., 2.420-as szoba
Tel: (1) 372-2500/1816
horvath.gyozo@inf.elte.hu

Eddig

  • Szerveroldali dinamikus weboldal generálás
  • Kliensoldali webprogramozás
  • Kliensoldali alapfogalmak
  • DOM, jQuery
  • Weboldalak progresszív fejlesztése

Ezen a héten

  • AJAX

AJAX

Aszinkron kommunikáció a szerverrel teljes oldalújratöltés nélkül

Hagyományos oldalkiszolgálás

Hagyományos oldalkiszolgálás

  • Folyamatos újratöltődés
  • Szaggatott használat
  • Csökkentett felhasználói élmény
  • Feleslegesen nagy adattömegek

Megoldás

Kommunikáció a háttérben

Párhuzamosan a betöltött oldallal

AJAX

AJAX

  • Aszinkron JavaScript és XML
  • Aszinkron
    • párhuzamosság
    • eseményvezéreltség
  • JavaScript
    • vezérlési logika
  • XML
    • kommunikációs adatformátum, bármi lehet
    • elsősorban JSON

AJAX jQuery-vel

  • Alacsony szintű metódus
    • $.ajax()
  • Magas szintű metódus
    • $.get()
    • $.post()
    • $.getJSON()
    • $.getScript()
    • $elem.load()

load()

A letöltött tartalmat a kiválasztott elembe helyezi.

// Alap használat
$("#hirek").load("hirlista.html");

// Oldaltöredék betöltése
$("#hirek").load("hirlista.html #content");

// Kérés küldése paraméterekkel
$("#hirek").load("hirlista.php", { honnan: 0, mennyit: 10 });

// Callback függvény hívása a kommunikáció végén
$("#hirek3").load("hirlista.php", { honnan: 0, mennyit: 10 }, function() {
    alert('Betöltöttem a hírlistát!');
});

get, post

// GET kérés a szervernek
$.get("hirlista.php", { honnan: 0, mennyit: 10 });

// POST kérés a szervernek
$.post("hirlista.php", { honnan: 0, mennyit: 10 });

// JSON kommuniáció
$.getJSON("hirlista.php", { formatum: 'json' });

// Dinamikus szkriptbetöltés
$.getScript("jquery_ui.js");

$.ajax()

$.ajax({
    url: 'hirlista.php',
    data: { mettol: 0 },
    type: 'POST',
    dataType: 'html',
});

Válasz feldolgozása

jqXHR objektum metódusai

  • done()
  • fail()
  • always()
$.post("hirlista.php", { honnan: 0, mennyit: 10 })
    .done(function (data) {
        console.log(data);
    })
    .fail(function (error) {
        console.log(error);
    });

Űrlap küldése

serializeArray() metódus

$('#registration form').submit(function(e) {
    // A form elküldésének megakadályozása
    e.preventDefault();
    var $this = $(this);
    $.post('regisztracio.php', $this.serializeArray(), function(data) {
        $this.html(data);
    });
});

Szerveroldali megfontolások

"Hagyományos" HTTP kérés feldolgozása

  1. AJAX végpontok definiálása
  2. A hagyományos végpontok "felokosítása" AJAX kérések kezelésére

AJAX kérés felismerése

  • X-Requested-With: XMLHttpRequest HTTP fejléc felismerése
  • var is_ajax_request = req.xhr; Express-specifikus
  • res.format() használata (Express)
// req.xhr
app.get('/path', function(req, res) {
  var is_ajax_request = req.xhr;
  // ...
});

// res.format
res.format({
  'text/html': function(){
    res.send('<p>hey</p>');
  },

  'application/json': function(){
    res.send({ message: 'hey' });
  },
});

Feladat

Tedd lehetővé a felvett hibák törlését AJAX-szal!

1. lépés

A funkció megvalósítása hagyományos módon

  • sablon (gomb)
  • végpont (/errors/delete/:id)
  • vezérlő
<a class="btn btn-danger btn-sm" href="/errors/delete/{{id}}" role="button">Törlés</a>
router.get('/delete/:id', function(req, res) {
    var id = req.params.id;
    req.app.models.error.destroy({id: id})
        .then(function (deletedErrors) {
            res.redirect('/errors/list');
        });
});

2. lépés

Megvalósítás AJAX-szal (list_delete.js)

  • sablon (szkript felvétele)
  • megírása
    • gombra kattintás
    • alapértelmezett művelet megakadályozása
    • AJAX GET kérés küldése a link URL-jére

3. lépés

Szerveroldal

  • Szerveroldal: más válasz AJAX kérésekre (res.format())
  • Szerveroldal opcionálisan: más válasz AJAX kérésekre (/ajax/errors/delete/:id végpont)
res.format({
    'text/html': function(){
        res.redirect('/errors/list');
    },
    'application/json': function () {
        res.json({ success: true });
    }
});

4. lépés

Kliensoldal

  • Kliensoldal: válasz feldolgozása
  • Táblázatsor eltűntetése

Feladat

Az új hiba felvételét oldd meg felugró ablakban. A felugró ablakhoz használd a Bootstrap modal komponensét, a felugró ablak tartalmához pedig a már kész funkció elemeit!

1. lépés

Felugró ablak sablonja (list.hbs)

<div class="modal fade" id="newErrorModal">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
      </div>
      <div class="modal-body">
        
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

2. lépés

Gombra kattintva jelenjen meg az ablak

var $modal = $('#newErrorModal').modal({show: false});
// ...
$modal.modal('show');

3. lépés

Az új hiba oldal betöltése a felugró ablak megfelelő részébe

4. lépés

A validációs szabályok működtetése

var $form = $('form[data-toggle=validator]');
$form.validator();

5. lépés

Mégsem gombra kattintva a felugró ablak bezárása

$form.on('reset', function(e) {
    $modal.modal('hide');
});

6. lépés

A Mentés gombra kattintva AJAX kérés küldése az űrlap adataival

$.ajax('/errors/new', {
    method: 'post',
    data: $form.serializeArray(),
    dataType: 'json'
})

7. lépés

Szerveroldali logika

  • Meglévő végpont felokosítása
  • ajax végpont írása
  • JSON válasz írása ({success: true})

8. lépés

Válasz feldolgozása kliensoldalon

  • a felugró ablak eltűntetése
  • a lista frissítése

Önálló feladat

Tedd lehetővé a státuszállítást a következőképpen! Tegyél fel egy gombot, majd arra kattintva egy felugró ablakban legyen egy legördülő mező, amiben a státuszt lehet beállítani, és egy többsoros szöveges beviteli mező az üzenetnek. Mentés után frissüljön a táblázatban a státusz!