RejectedSoftware Forums

Sign up

Basic form validation

I have a post create method:

void gönderiyiOluştur(HTTPServerRequest istek, HTTPServerResponse yanıt)
{
    render!("gönderiler/oluştur.dt")(yanıt);
}

and a post store method like this:

void gönderiyiKaydet(HTTPServerRequest istek, HTTPServerResponse yanıt)
{
    auto başlık = istek.form["baslik"];
    auto içerik = istek.form["icerik"];

    bool yayınla = false;

    if (başlık.length > 0)
    {

        Gönderi gönderi = Gönderi(başlık, içerik);

        gönderi.kaydet();
        yanıt.redirect("/");
    }
    else
    {
        yanıt.redirect("/gönderiler/oluştur");
    }
}

I'd like to make basic form validation. For example if input fields are empty it redirects to previous page.

I suppose I should pass some error message to the create method like "baslik field should not be empty" etc..

But since I am quite new to framework I shouldn't figure out. Are there any facilities does the framework offer for form validation.

Erdem

Re: Basic form validation

On Mon, 25 Sep 2017 14:30:54 GMT, Erdem wrote:

I have a post create method:

void gönderiyiOluştur(HTTPServerRequest istek, HTTPServerResponse yanıt)
{
    render!("gönderiler/oluştur.dt")(yanıt);
}

and a post store method like this:

void gönderiyiKaydet(HTTPServerRequest istek, HTTPServerResponse yanıt)
{
    auto başlık = istek.form["baslik"];
    auto içerik = istek.form["icerik"];

    bool yayınla = false;

    if (başlık.length > 0)
    {

        Gönderi gönderi = Gönderi(başlık, içerik);

        gönderi.kaydet();
        yanıt.redirect("/");
    }
    else
    {
        yanıt.redirect("/gönderiler/oluştur");
    }
}

I'd like to make basic form validation. For example if input fields are empty it redirects to previous page.

I suppose I should pass some error message to the create method like "baslik field should not be empty" etc..

But since I am quite new to framework I shouldn't figure out. Are there any facilities does the framework offer for form validation.

Erdem

This is the realm of the vibe.web.web module. Using form parameters and the @errorDisplay annotation, the example can be reduced to this:

import vibe.http.router;
import vibe.http.server;
import vibe.web.web;

class MyWebApp {
    @method(HTTPMethod.get)
    void gönderiyiOluştur(string _error = "")
    {
        // should display _error's contents appropriately if not empty
        render!("gönderiler/oluştur.dt", _error);
    }

    // this causes any exception or parameter validation error to get rendered using gönderiyiOluştur, setting _error appropriately
    @errorDisplay!gönderiyiOluştur
    // "baslik" and "icerik" are automatically read from req.form. They can also be other types, such as integers, and will be validated and converted automatically.
    // Note: the HTTP method defaults to POST here. @method or one of the prefixes like "get" can be used to change this.
    void gönderiyiKaydet(NonEmptyString baslik, string icerik)
    {
        Gönderi gönderi = Gönderi(başlık, içerik);
        gönderi.kaydet();
        yanıt.redirect("/");
    }
}

auto router = new URLRouter;
router.registerWebInterface(new MyWebApp);
listenHTTP(":8080", router);

The validation logic is in the type NonEmptyString, which does not exist in vibe.d itself (there are some predefined validation schemes in vibe.web.validation, though), but can be user defined:

struct NonEmptyString {
pure nothrow @safe:
    private string m_value;
    private this(string value) { m_value = value; }
    string toString() const { return m_value; }
    alias toString this;

    static Nullable!NonEmptyString fromStringValidate(string str, string* error)
    {
        Nullable!ValidPassword ret;
        if (str.length == 0) *error = "Input must not be empty.";
        else ret = NonEmptyString(str);
        return ret;
    }
}

Disclaimer: This was written off the top of my head. If anything doesn't work, please let me know.

Re: Basic form validation

On Mon, 25 Sep 2017 18:31:00 GMT, Sönke Ludwig wrote:

Disclaimer: This was written off the top of my head. If anything doesn't work, please let me know.

After using [vibe.web.web][web-interface-generator] module the program looked like this:

import vibe.vibe;

struct Gönderi
{
    string başlık_, içerik_;

    this (string başlık, string içerik)
    {
        this.başlık_ = başlık;
        this.içerik_ = içerik;
    }

    void kaydet()
    {
        import mysql;
        string mysqlAyarları = "host=localhost;port=3306;user=root;pwd=;db=gunluk";
        Connection bağlantı = new Connection(mysqlAyarları);
        scope(exit)
            bağlantı.close();

        import std.algorithm;

        auto zaman = Clock
                 .currTime
                 .toISOExtString()
                 .replace("T", " ")
                 .findSplit(".")[0];


        auto başlık = this.başlık_.replace("'",`''`);
        auto içerik = this.içerik_.replace("'",`''`);

        logInfo("%s %s", başlık, içerik);

        auto sqlKomutu = "INSERT INTO gonderiler (kullanici_no, baslik, icerik, created_at, updated_at) VALUES (1, '"
                         ~ başlık ~
                         "', '"
                         ~içerik ~
                         "', '"
                         ~ zaman ~
                         "', '"
                         ~ zaman ~
                         "');";

        logInfo(sqlKomutu);
        auto eklenenSatır = exec(bağlantı, sqlKomutu);
        logInfo("%s satır eklendi", eklenenSatır);
    }

    string toString() const
    {
        string dönen;
        dönen ~= "Başlık = " ~ this.başlık_;
        dönen ~= "\nİçerik = " ~ this.içerik_;
        return dönen;
    }
}

// struct NonEmptyString {
// pure nothrow @safe:
//     private string m_value;
//     private this(string value) { m_value = value; }
//     string toString() const { return m_value; }
//     alias toString this;

//     static Nullable!NonEmptyString fromStringValidate(string str, string* error)
//     {
//         Nullable!ValidPassword ret;
//         if (str.length == 0) *error = "Input must not be empty.";
//         else ret = NonEmptyString(str);
//         return ret;
//     }
// }


class Günlük
{

    @method(HTTPMethod.GET)
    @path("/")
    void index()
    {
        render!("yerleşimler/ana.dt");
    }

    @method(HTTPMethod.GET)
    @path("/gönderiler/oluştur") // /posts/create - create a post
    void gönderiyiOluştur(string _error = "")
    {
        logInfo("%s", _error);
        render!("gönderiler/oluştur.dt", _error);
    }

    @errorDisplay!gönderiyiOluştur

    @method(HTTPMethod.POST)
    @path("/gönderiler")  // /posts - save a post
    void gönderiyiKaydet(string baslik, string icerik)
    {

        Gönderi gönderi = Gönderi(baslik, icerik);

        gönderi.kaydet();
        redirect("/");
    }
}

void main()
{
    import vibe.core.log, vibe.core.core, vibe.http.router;
    auto yönlendirici = new URLRouter;
    yönlendirici.registerWebInterface(new Günlük);

    yönlendirici.get("*", serveStaticFiles("public"));

    auto sunucu_ayarları = new HTTPServerSettings;
    sunucu_ayarları.port = 8080;
    sunucu_ayarları.bindAddresses = ["::1", "127.0.0.1"];

    listenHTTP(sunucu_ayarları, yönlendirici);

    logInfo("Lütfen tarayıcıda http://127.0.0.1:8888/ adresini açın.");

    runApplication();

}

Still I can't figure out how do we use @errorDisplay attribute. Also NonEmptyString struct does not compile.