Kamil Michna

Poradnik Koa #6 - Formularze

Podstawowa obsługa formularzy w Koa.

Ostatnio nauczyliśmy się jak na podstawie danych z serwera tworzyć wygląd naszych podstron, dzisiaj nauczymy się komunikacji w drugą stronę - serwer odbierze dane z naszej witryny!

Zacznijmy więc od stworzenia podstrony, z formularzem

Wejdźmy zatem do naszego katalogu views i stwórzmy tam plik o nazwie "forms.pug". Nazwa jest całkowicie dowolna. Zacznijmy więc tworzyć stronę z prostym formularzem:

html
    head
        title=title
    body
        form(action="/sendData" method="POST")
            input(type="text" name="formContent")
            input(type="submit", value="Wyślij dane")

Nasza strona zawiera prosty formularz z dwoma inputami: jeden, o typie text będzie miejscem do którego wprowadzimy tekst który następnie wyślemy do serwera,jego name, czyli formContent będzie nam potrzebny do uzyskania tych konkretnie danych po stronie serwera, a input o typie submit to przycisk, który wyśle dane. Cały formularz ma atrybut action ustawiony pod adres /sendData, oznacza to że wszystkie dane będą wysyłane pod adres http://localhost:3000/sendData. Atrybut method ustawiłem na wartość POST.Na pełne REST API przyjdzie czas niebawem.

Co chcemy osiągnąć?

Wyobraźmy sobie że podstrona z naszym formularzem to coś w rodzaju okienka czatu - chcemy po prostu wpisany tam tekst dostarczyć do serwera. Podobnie będzie to działać z kilkoma polami - jak na przykład w przypadku logowania, gdzie potrzebujemy zarówno hasła jak i loginu.

Zacznijmy więc od podpięcia naszego forms.pug pod / w naszych routes. Zedytujmy więc plik router.js:

const Router = require('koa-router');
const router = new Router();
const views = require('koa-views');


router
    .get('/',async (ctx)=>{
        await ctx.render("forms.pug");
    })


module.exports = router

Póki co dokładnie w ten sposób powinien przedstawiać się nasz plik z routingiem. Usunęliśmy routa wskazującego na /hello, pozostał jedynie ten wskazujący na /, ale teraz renderuje on nasz plik z formularzem. I dokładnie o to nam chodziło. Aby sprawdzić czy wszystko działa poprawnie wejdź pod adres /http://localhost:3000/ i sprawdź czy strona rzeczywiście zawiera nasz prosty formularz. Przypomnę jedynie że Po zedytowaniu naszych plików takich jak main.js albo router.js należy ponownie urochomić serwer poleceniem node main.js.

Reagowanie na wysłane dane

To co teraz chcemy zrobić, to odebrać dane z naszego formularza. Wysłaliśmy je pod adres /sendData metodą POST, dodajmy więc w naszym pliku router.js kod, który pozwoli nam zareagować na wysłane dane. Tym razem nie użyjemy w routerze .get, a .post, ze względu na metodę którą wysłaliśmy dane:

const Router = require('koa-router');
const router = new Router();
const views = require('koa-views');


router
    .get('/',async (ctx)=>{
        await ctx.render("forms.pug");
    })
    .post('/sendData', async (ctx)=>{
        console.log('FORMULARZ ODEBRANY!')
    })


module.exports = router

Jak nietrudno się domyślić, po wysłaniu danych w naszym terminalu powinien wyświetlić się napis FORMULARZ ODEBRANY. Sprawdźmy więc czy tak się dzieje.

Sukces!

Terminal wyświetlił zadany komunikat. To co nam pozostało, to sprawić aby wyświetlił również wartość pola tekstowego. Jako że znajduje się ona w obiekcie ctx.request.body, do jego obsługi potrzebny jest nam kolejny middleware, tym razem jest to bodyparser. Zainstalujemy go poleceniem node install koa-bodyparser. Jeżeli instalacja się powiodła, dodajmy go do naszej aplikacji. Zedytujmy więc plik main.js:

const Koa = require("koa");
const app = new Koa();
const router = require('./router')
const views = require('koa-views');

const bodyparser = require('koa-bodyparser'); //#1

app.use(bodyparser())//#2

app.use(views(__dirname + '/views', {
    map: {
        extension: 'pug' 
    }
  }));
  
app.use(router.routes())
app.listen(3000);
    

#1 to po prostu zaimportowanie naszej biblioteki, natomiast w #2 definiujemy bodyparser jako middleware. Przejdźmy teraz z powrotem do router.js i zedytujmy go odpowiednio: ctx.request.body jest obiektem, który zawiera wszystkie pola wysłane przez nasz formularz, każde z nich jest jednym z właściwości obiektu body. Aby więc dostać się do tekstu który znajdował się w polu tekstowym o atrybucie name="content" musimy użyć ctx.request.body.content. Po edycji nasz plik powinien wyglądać tak:

const Router = require('koa-router');
const router = new Router();
const views = require('koa-views');


router
    .get('/',async (ctx)=>{
        await ctx.render("forms.pug");
    })
    .post('/sendData', async (ctx)=>{
        console.log(`WARTOŚĆ POLA TEKSTOWEGO: ${ctx.request.body.content}`)
    })


module.exports = router

Od teraz przy każdym wysłaniu formularza nasz terminal wyświetli stosowny komunikat, wraz z wartością pobraną z pola tekstowego.

To tyle na dzisiaj, w następnym poradniku dowiemy się w jaki sposób skonfigurować nasz serwer tak, aby serwował pliki statyczne, czyli pliki css oraz zdjęcia

Dzięki za uwagę, Kamil Michna ;)