Das Zustandsmodell auf Parameter einer Webanwendung abbilden

Eine Parameterkontrollstruktur und ein Objekt als Abbild aller Zustände und Übergänge die eine Webanwendung annehmen kann.

Formular zum Umrechnen der Datierungen

Wie Rechnen:
Aktionen:

Erläuterungen zur Anwendung und zum Code

Diese Anwendung funktioniert mit oder ohne JavaScript gleichermaßen: Ist JavaScript aktiv, erfolgt die Formularverarbeitung über AJAX. Ist JavaScript im Browser nicht verfügbar, erfolgt ein ganz normales Submit der Formulardaten. Bei dieser Arbeitsweise sind die Parameter sowohl über JavaScript/AJAX als auch im Legacy-CGI-Betrieb dieselben. In der serverseitigen Parameter-Kontrollstruktur wird jedoch anhand eines Custom-Request-Headers unterschieden, ob ein Submit vorliegt oder ein AJAX-Request. Dementsprechend wird entweder eine komplette Seite gesendet oder es werden nur die berechneten Daten serialisiert für die Response.

Für das Formular gibt es der Arbeitsweise entsprechend auch zwei Templates. Je nach Verfügbarkeit von JavaScript wird entweder das eine oder das andere Template in den Browser geladen. Selbstverständlich bekommt auch im JavaScript-Betriebsmodus der Benutzer die Möglichkeit der Navigation über die Browser-History. Im Betrieb über JS/AJAX werden die Zustände der Anwendung, Benutzereingaben und Übergänge, als Objekt in der History gespeichert

Die gesamte Moduldatei ist als Subklasse der Package main ausgebildet und implementiert die Interface-Methoden init, browse und control. Perlcode sowie HTML+JS sind kompakt in einer Moduldatei vereint. Sowohl für Perl als auch JS gibt es eine eigens entwickelte Template-Engine. Das ermöglicht einen einheitlichen Aufbau der jeweiligen Templates, lediglich die Platzhalter sind anders notiert bzw. gekennzeichnet. Der Grund dafür ist, dass ein Rendern beider Templates konfliktfrei über beide Template-Engines möglich sein muss.

Programmcode Perl und JavaScript

package Public::MayaTec;

use base main;
use strict;
use warnings;
require Scaliger;
require TieMaya;

sub christ2maya{
    my $self    = shift;
    my $christ  = shift;
    my $CN      = shift;
    my $dateart = shift; # gregdate || julidate
    my $sca = Scaliger->new( $dateart => $christ) || do{
        die "Christliches Datum ungültig!\n" if $ENV{HTTP_X_AJAX};
        return $self->errmsg("Christliches Datum ungültig!", $self->{URL});
    };
    tie my $tm, 'TieMaya', day => $sca->jd - $CN;
    return $tm->{LC};
}

sub maya2christ{
    my $self    = shift;
    my $lc      = shift;
    my $CN      = shift;
    my $dateart = shift; # gregdate || julidate

    tie my $tm, 'TieMaya', longcount => $lc or do{
        die "Maya Datum ungültig!\n" if $ENV{HTTP_X_AJAX};
        return $self->errmsg("Maya Datum ungültig!", $self->{URL});
    };
    my $sca = Scaliger->new(jd => $tm->{DAY} + $CN);
    return $sca->$dateart;
}

# Vorbelegung der Formular Templates
sub browse{
    my $self = shift;
    my $sca  = Scaliger->new;
    $self->{STASH}{christ} = $sca->gregdate;
    $self->{STASH}{maya}   = $self->christ2maya($sca->gregdate, 584283, 'gregdate');
    $self->{STASH}{gregchecked} = 'checked';
}

# Parameter Kontrollstruktur
sub control{
    my $self = shift;
    # Lade Eingaben wieder ins Formular
    $self->{STASH}{christ} = $self->ents($self->trim($self->param('christ')));
    $self->{STASH}{maya}   = $self->ents($self->trim($self->param('maya')));

    my $dateart = $self->param('age') || '';
    $self->{STASH}{gregchecked} = 'checked' if $dateart eq 'gregdate';
    $self->{STASH}{julichecked} = 'checked' if $dateart eq 'julidate';
    
    if($self->param('christ2maya')){
        $self->{STASH}{maya} = $self->christ2maya($self->trim($self->param('christ')), 584283, $dateart);
        if($ENV{HTTP_X_AJAX}){
            delete $self->{STASH}{src};
            $self->{CONTENT} = $self->http_query($self->{STASH});
        }
    }
    elsif($self->param('maya2christ')){
        $self->{STASH}{christ} = $self->maya2christ($self->trim($self->param('maya')), 584283, $dateart);
        if($ENV{HTTP_X_AJAX}){
            delete $self->{STASH}{src};
            $self->{CONTENT} = $self->http_query($self->{STASH});
        }
    }
    else{
        die "Unbekannter Parameter!\n";
    }
}

sub init{
    my $self = shift;
    # Source Code zur Ausgabe in den Browser
    my $src  = do{
        local @ARGV = $INC{'Public/MayaTec.pm'};
        local $/ = undef;
        <>;
    };
    $self->{STASH}{src} = $self->ents($src);
}

1;#########################################################################
__DATA__
<script src="/jquery.min.js"></script>
<script src="/request.js"></script>

<h2>Formular zum Umrechnen der Datierungen</h2>

<!-- Template für das Legacy Formular -->
<form id="out" onsubmit="return control()">
    <fieldset><legend><strong><label for="christ">Christliches Datum:</label></strong></legend>
        <input id="christ" name="christ" value="%christ%" style="width:100%">
    </fieldset>
    <fieldset><legend><strong><label for="maya">Maya Datum:</label></strong></legend>
        <input id="maya" name="maya" value="%maya%" style="width:100%">
    </fieldset>
    <fieldset><legend><strong>Wie Rechnen:</strong></legend>
        <input type="radio" name="age" value="julidate" %julichecked% id="julichecked"><label for="julichecked">Julianisch</label>
        <input type="radio" name="age" value="gregdate" %gregchecked% id="gregchecked"><label for="gregchecked">Gregorianisch</label>
    </fieldset>

    <fieldset><legend><strong>Aktionen:</strong></legend>
        <button name="christ2maya" value="1" onclick="return control('christ2maya')">Christliches Datum in Maya Datum</button>
        <button name="maya2christ" value="1" onclick="return control('maya2christ')">Maya Datum in Christliches Datum</button>
    </fieldset>
</form>

<!-- Template für das JS Formular -->
<script id="tt" type="text/html">
    <fieldset><legend><strong><label for="christ">Christliches Datum:</label></strong></legend>
        <input id="christ" name="christ" value="@christ@" style="width:100%">
    </fieldset>
    <fieldset><legend><strong><label for="maya">Maya Datum:</label></strong></legend>
        <input id="maya" name="maya" value="@maya@" style="width:100%">
    </fieldset>
    <fieldset><legend><strong>Wie Rechnen:</strong></legend>
        <input type="radio" name="age" value="julidate" @julichecked@ id="julichecked"><label for="julichecked">Julianisch</label>
        <input type="radio" name="age" value="gregdate" @gregchecked@ id="gregchecked"><label for="gregchecked">Gregorianisch</label>
    </fieldset>

    <fieldset><legend><strong>Aktionen:</strong></legend>
        <button name="christ2maya" value="1" onclick="return control('christ2maya')">Christliches Datum in Maya Datum</button>
        <button name="maya2christ" value="1" onclick="return control('maya2christ')">Maya Datum in Christliches Datum</button>
    </fieldset>
</script>



<script>

// History wird geschrieben
function control(key){
    var param_object = input4form(0, key, '1');
    history.pushState(param_object, '', '%url%');
    calc(param_object);
    return false;
}

// Ereignis zur Benutzeraktion Vor/Zurück
$(window).on('popstate', function() {
    if(this.history.state == null) return;
    calc(this.history.state);
});

// Das Parameter-Objekt wird übergeben und gesendet
function calc(param){
    var xhr = new XMLHttpRequest();
    xhr.open('POST','%url%');
    xhr.setRequestHeader('x-ajax','1');
    xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
    xhr.onload = function(){
        if( this.status != 200 ) return pretext(this.response);
        var param = qparse(this.response);
        $('#out').html(xr($('#tt').html(),{
            christ:      param.christ[0],
            maya:        param.maya[0],
            gregchecked: param.gregchecked != null ? param.gregchecked[0] : '',
            julichecked: param.julichecked != null ? param.julichecked[0] : ''
        }));
    };
    xhr.send(query4request(param));
}

</script>

<h2>Erläuterungen zur Anwendung und zum Code</h2>

<p>Diese Anwendung funktioniert mit oder ohne JavaScript gleichermaßen: Ist JavaScript aktiv, erfolgt die Formularverarbeitung über AJAX. Ist JavaScript im Browser nicht verfügbar, erfolgt ein ganz normales Submit der Formulardaten. Bei dieser Arbeitsweise sind die Parameter sowohl über JavaScript/AJAX als auch im Legacy-CGI-Betrieb dieselben. In der serverseitigen Parameter-Kontrollstruktur wird jedoch anhand eines Custom-Request-Headers unterschieden, ob ein Submit vorliegt oder ein AJAX-Request. Dementsprechend wird entweder eine komplette Seite gesendet oder es werden nur die berechneten Daten serialisiert für die Response.</p>

<p>Für das Formular gibt es der Arbeitsweise entsprechend auch zwei Templates. Je nach Verfügbarkeit von JavaScript wird entweder das eine oder das andere Template in den Browser geladen. Selbstverständlich bekommt auch im JavaScript-Betriebsmodus der Benutzer die Möglichkeit der Navigation über die Browser-History. Im Betrieb über JS/AJAX werden die Zustände der Anwendung, Benutzereingaben und Übergänge, als Objekt in der History gespeichert</p>

<p>Die gesamte Moduldatei ist als Subklasse der Package main ausgebildet und implementiert die Interface-Methoden init, browse und control. Perlcode sowie HTML+JS sind kompakt in einer Moduldatei vereint. Sowohl für Perl als auch JS gibt es eine eigens entwickelte Template-Engine. Das ermöglicht einen einheitlichen Aufbau der jeweiligen Templates, lediglich die Platzhalter sind anders notiert bzw. gekennzeichnet. Der Grund dafür ist, dass ein Rendern beider Templates konfliktfrei über beide Template-Engines möglich sein muss.</p>

<h2>Programmcode Perl und JavaScript</h2>

<pre>
%src%
</pre>

Anbieter: nmq​rstx-18­@yahoo.de, die Seite verwendet funktionsbedingt einen Session-Cookie und ist Bestandteil meines nach modernen Aspekten in Perl entwickelten Frameworks.