use base qw/Prty::Hash/;
use strict;
our $VERSION = 1.112;
# -----------------------------------------------------------------------------
=encoding utf8
=head1 NAME
Prty::JQuery::DataTable - Erzeuge eine HTML/JavaScript DataTables-Tabelle
=head1 BASE CLASS
L<Prty::Hash>
=head1 SYNOPSIS
=begin html
<p class="sdoc-fig-p">
<img class="sdoc-fig-img" src="https://raw.github.com/s31tz/Prty/master/img/prty_jquery_datatable_example01.png" width="757" height="170" alt="" />
</p>
=end html
Quelltext siehe Abschnitt L</"Beispiel Synopsis">.
=head1 DESCRIPTION
Hompage des DataTables-Plugin:
Die Klasse liefert den HTML- und JavaScript-Code für ein
DataTable-Widget.
=head1 ATTRIBUTES
=over 4
=item arguments => $json (Default: undef)
JSON-Code der das DataTable-Objekt in JavaScript instantiiert. Die
äußeren geschweiften Klammern werden hierbei weggelassen. Die
Kolumnendefinitionen (DataTables-Attribut columns:) wird intern
generiert und zu diesem Code hinzugefügt.
=item class => $class (Default: undef)
CSS-Klasse der DataTable (des Table-Elements).
=item columns => \@columns (Default: [])
Referenz auf eine Liste mit Kolumnen-Spezifikationen. Eine einzelne
Kolumnen-Spezifikation ist ein Hash mit den Komponenten:
{
name=>$name, # interner Name, insbes. f. Wert-Lookup
title=>$title, # Kolumnenüberschrift
type=>$type, # DataTables-Kolumnentyp (s. Link unten)
align=>$align, # 'left'|'center'|'right' (Default: 'left')
orderable=>$bool, # 0|1 (Default: 1)
searchable=>$bool, # 0|1 (Default: 1)
visible=>$bool, # 0|1 (Default: 1)
}
Nicht benötigte Komponenten können weggelassen werden.
Mögliche Werte für $type: 'date', 'num', 'num-fmt', 'html-num',
'html-num-fmt', 'html', 'string'. Siehe
=item id => $id (Default: undef)
DOM-Id der DataTable (des Table-Elements).
=item instantiate => $bool (Default: 0)
Füge die Instantiierung des DataTable-Objektes (JavaScript) zum
HTML-Code der Methode html() hinzu.
=item rowCallback => $sub (Default: s.u.)
Referenz auf eine Subroutine, die für jedes Row-Objekt die
darzustellende Zeileninformation (für tr- und td-Tag) liefert
(siehe Prty::Html::Table::List). Default:
rowCallback => sub {
my ($row,$i,$columnA) = @_;
my @arr;
for my $col (@$columnA) {
my $name = $col->name;
push @arr,$name? $row->get($name): undef;
}
return (undef,@arr);
};
=item rows => \@rows (Default: [])
Liste der Row-Objekte. Für jedes Element wird die Callback-Methode
(Attribut rowCallback) aufgerufen.
=back
=head1 EXAMPLES
=head2 Beispiel Synopsis
Default-Aussehen einer DataTable:
=begin html
<p class="sdoc-fig-p">
<img class="sdoc-fig-img" src="https://raw.github.com/s31tz/Prty/master/img/prty_jquery_datatable_example01.png" width="757" height="170" alt="" />
</p>
=end html
Das Programm
my $tab = Prty::Database::Row::Object->makeTable(
[qw/per_id per_vorname per_nachname per_geburtsdatum/],
qw/1 Rudi Ratlos 1971-04-23/,
qw/2 Erika Mustermann 1955-03-16/,
qw/3 Harry Hirsch 1948-07-22/,
qw/4 Susi Sorglos 1992-10-23/,
);
my $h = Prty::Html::Tag->new('html-5');
my $html = Prty::JQuery::DataTable->html($h,
id=>'personTable',
class=>'compact stripe hover cell-border',
columns=>[
{
name=>'per_id',
title=>'Id',
align=>'right',
},{
name=>'per_vorname',
title=>'Vorname',
},{
name=>'per_nachname',
title=>'Nachname',
},{
name=>'per_geburtsdatum',
title=>'Geburtstag',
align=>'center',
},
],
rows=>scalar $tab->rows,
instantiate=>1,
);
erzeugt den HTML-Code (lange Zeilen umbrochen)
<table id="personTable" class="compact stripe hover cell-border"
cellspacing="0">
<thead>
<tr>
<th>Id</th>
<th>Vorname</th>
<th>Nachname</th>
<th>Geburtstag</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Rudi</td>
<td>Ratlos</td>
<td>1971-04-23</td>
</tr>
<tr>
<td>2</td>
<td>Erika</td>
<td>Mustermann</td>
<td>1955-03-16</td>
</tr>
<tr>
<td>3</td>
<td>Harry</td>
<td>Hirsch</td>
<td>1948-07-22</td>
</tr>
<tr>
<td>4</td>
<td>Susi</td>
<td>Sorglos</td>
<td>1992-10-23</td>
</tr>
</tbody>
</table>
<script type="text/javascript">
jQuery('#personTable').DataTable({
columns: [
{
className: 'dt-right',
},{
className: 'dt-left',
},{
className: 'dt-left',
},{
className: 'dt-center',
},
],
});
</script>
=head2 Mit Instantiierungs-Argumenten (HTML-Seite)
Beispiel für die Angabe von Instantiierungs-Argumenten. Dies
kann bei Aufruf der Methode
L</"instantiate() - Instantiiere Widget in JavaScript">
$dt->instantiate(q~
fixedHeader: true,
stateSave: true,
dom: 't',
~),
oder durch Zuweisung an das Attribut instantiate erfolgen
instantiate=>q~
fixedHeader: true,
stateSave: true,
dom: 't',
~
Die Angabe C<dom: 't'> bewirkt hier, dass das DataTables-Plugin
keine Bedienelemente erzeugt:
=begin html
<p class="sdoc-fig-p">
<img class="sdoc-fig-img" src="https://raw.github.com/s31tz/Prty/master/img/prty_jquery_datatable_example02.png" width="757" height="117" alt="" />
</p>
=end html
Das Programm
my $tab = Prty::Database::Row::Object->makeTable(
[qw/per_id per_vorname per_nachname per_geburtsdatum/],
qw/1 Rudi Ratlos 1971-04-23/,
qw/2 Erika Mustermann 1955-03-16/,
qw/3 Harry Hirsch 1948-07-22/,
qw/4 Susi Sorglos 1992-10-23/,
);
my $h = Prty::Html::Tag->new('html-5');
my $dt = Prty::JQuery::DataTable->new(
id=>'personTable',
class=>'compact stripe hover cell-border',
columns=>[
{
name=>'per_id',
title=>'Id',
align=>'right',
},{
name=>'per_vorname',
title=>'Vorname',
},{
name=>'per_nachname',
title=>'Nachname',
},{
name=>'per_geburtsdatum',
title=>'Geburtstag',
align=>'center',
},
],
rows=>scalar $tab->rows,
);
my $html = Prty::Html::Page->html($h,
styleSheet=>Prty::JQuery::DataTable->stylesheetUrl,
styleSheet=>q|
body {
font-family: sans-serif;
font-size: 12px;
color: black;
background-color: white;
}
|,
body=>$dt->html($h),
javaScript=>[
Prty::JQuery::DataTable->pluginUrl,
$dt->instantiate(q~
fixedHeader: true,
stateSave: true,
dom: 't',
~),
],
);
erzeugt den HTML-Code (lange Zeilen umbrochen)
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css"
<style type="text/css">
body {
font-family: sans-serif;
font-size: 12px;
color: black;
background-color: white;
}
</style>
</head>
<body>
<table id="personTable" class="compact stripe hover cell-border"
cellspacing="0">
<thead>
<tr>
<th>Id</th>
<th>Vorname</th>
<th>Nachname</th>
<th>Geburtstag</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Rudi</td>
<td>Ratlos</td>
<td>1971-04-23</td>
</tr>
<tr>
<td>2</td>
<td>Erika</td>
<td>Mustermann</td>
<td>1955-03-16</td>
</tr>
<tr>
<td>3</td>
<td>Harry</td>
<td>Hirsch</td>
<td>1948-07-22</td>
</tr>
<tr>
<td>4</td>
<td>Susi</td>
<td>Sorglos</td>
<td>1992-10-23</td>
</tr>
</tbody>
</table>
<script type="text/javascript"
<script type="text/javascript"
</script>
<script type="text/javascript">
jQuery('#personTable').DataTable({
fixedHeader: true,
stateSave: true,
dom: 't',
columns: [
{
className: 'dt-right',
},{
className: 'dt-left',
},{
className: 'dt-left',
},{
className: 'dt-center',
},
],
});
</script>
</body>
</html>
=head1 METHODS
=head2 Plugin-Code (Klassenmethoden)
=head3 stylesheetUrl() - URL der DataTables CSS-Definitionen
=head4 Synopsis
$url = $class->stylesheetUrl;
$url = $class->stylesheetUrl($config);
=head4 Description
Liefere den CDN URL der DataTables CSS-Definitionen.
=head4 Example
Prty::JQuery::DataTable->stylesheetUrl;
=>
=cut
# -----------------------------------------------------------------------------
sub stylesheetUrl {
my $class = shift;
my $config = shift || 'dt-1.10.11';
return "https://cdn.datatables.net/t/dt/$config/datatables.min.css";
}
# -----------------------------------------------------------------------------
=head3 pluginUrl() - URL des Plugin
=head4 Synopsis
$url = $class->pluginUrl;
$url = $class->pluginUrl($config);
=head4 Description
Liefere den CDN URL des DataTables Plugin.
=head4 Example
Prty::JQuery::DataTable->pluginUrl;
=>
=cut
# -----------------------------------------------------------------------------
sub pluginUrl {
my $class = shift;
my $config = shift || 'dt-1.10.11';
return "https://cdn.datatables.net/t/dt/$config/datatables.min.js";
}
# -----------------------------------------------------------------------------
=head2 Konstruktor
=head3 new() - Instantiiere Objekt
=head4 Synopsis
$obj = $class->new(@keyVal);
=head4 Description
Instantiiere eine DataTable in Perl und liefere eine Referenz auf
dieses Objekt zurück.
=cut
# -----------------------------------------------------------------------------
sub new {
my $class = shift;
# @_: @keyVal
my $self = $class->SUPER::new(
arguments=>undef,
class=>undef,
columns=>[],
id=>undef,
instantiate=>0,
rowCallback=>undef,
rows=>[],
);
$self->set(@_);
return $self;
}
# -----------------------------------------------------------------------------
=head2 Code-Generierung
=head3 html() - Generiere HTML
=head4 Synopsis
$html = $obj->html($h);
$html = $class->html($h,@keyVal);
=head4 Description
Generiere den HTML-Code des DataTable-Objekts und liefere
diesen zurück. Als Klassenmethode gerufen, wird das Objekt intern
mit den Attributen @keyVal instantiiert.
=cut
# -----------------------------------------------------------------------------
sub html {
my $this = shift;
my $h = shift;
my $self = ref $this? $this: $this->new(@_);
my ($arguments,$class,$id,$instantiate,$rowCallback,$rowA) =
$self->get(qw/arguments class id instantiate rowCallback rows/);
# Liste der Kolumnendefinitionen als Hash-Objekte
my @columns = $self->getColumns;
# HTML generieren
if (!@columns) {
return '';
}
my @titles;
for my $col (@columns) {
push @titles,$col->title;
}
if (!$rowCallback) {
$rowCallback = sub {
my ($row,$i,$columnA) = @_;
my @arr;
for my $col (@$columnA) {
my $name = $col->name;
push @arr,$name? $row->get($name): undef;
}
return (undef,@arr);
};
}
my $html = Prty::Html::Table::List->html($h,
allowHtml=>1,
border=>0,
class=>$class,
empty=>undef,
id=>$id,
rowCallback=>$rowCallback,
rowCallbackArguments=>[\@columns],
rows=>$rowA,
titles=>\@titles,
);
if ($instantiate) {
$html .= $h->tag('script',
$self->instantiate,
);
}
return $html;
}
# -----------------------------------------------------------------------------
=head3 instantiate() - Instantiiere Widget in JavaScript
=head4 Synopsis
$javaScript = $e->instantiate;
$javaScript = $e->instantiate($json);
=head4 Description
Liefere den JavaScript-Code, der das DataTables-Objekt in JavaScript
instantiiert. Aufbau:
jQuery('#ID').DataTable({
<JSON-Code>,
columns: [
<Kolumnen-Definitionen>
]
});
=cut
# -----------------------------------------------------------------------------
sub instantiate {
my ($self,$json) = @_;
my ($id,$arguments) = $self->get(qw/id arguments/);
$arguments = Prty::Unindent->string($arguments);
$arguments .= Prty::Unindent->string($json);
my $columns;
for my $col ($self->getColumns) {
my $keyVals;
if (my $type = $col->type) {
$keyVals .= "type: '$type',\n";
}
if (my $align = $col->align || 'left') {
$keyVals .= "className: 'dt-$align',\n";
}
if (my $searchable = $col->searchable) {
$keyVals .= "searchable: '$searchable',\n";
}
if (my $orderable = $col->orderable) {
$keyVals .= "orderable: '$orderable',\n";
}
if (my $visible = $col->visible) {
$keyVals .= "visible: '$visible',\n";
}
if ($keyVals) {
$keyVals =~ s/^/ /mg;
$columns .= sprintf "{ // %s\n%s},",$col->title,$keyVals;
}
else {
$columns .= sprintf "{ // %s\n},",$col->title;
}
}
$columns =~ s/^/ /mg;
$arguments .= "columns: [\n$columns\n],\n";
$arguments =~ s/^/ /mg;
return sprintf qq|jQuery('#%s').DataTable({\n%s\n});|,$id,$arguments;
}
# -----------------------------------------------------------------------------
=head2 Hilfsmethoden
=head3 getColumns() - Liste der Kolumnendefinitionen
=head4 Synopsis
@columns | $columns = $e->getColumns;
=head4 Description
Liefere die Liste der Kolumnendefinitionen. Die Kolumnen werden
beim Setzen des Objektattributs columns als einfache Hashes
angegeben. Diese Methode liefert die Kolumnen-Definitionen als
Hash-Objekte (vom Typ Prty::Hash).
=cut
# -----------------------------------------------------------------------------
sub getColumns {
my $self = shift;
my ($columnA) = $self->get(qw/columns/);
# Column-Hashes in Objekte wandeln. Die Attributnamen werden
# dabei auf Korrektheit geprüft.
my @columns;
for my $h (@$columnA) {
push @columns,Prty::Hash->new([qw/
name
title
type
align
orderable
searchable
visible
/])->join($h);
}
return wantarray? @columns: \@columns;
}
# -----------------------------------------------------------------------------
=head1 VERSION
1.112
=head1 AUTHOR
Frank Seitz, L<http://fseitz.de/>
=head1 COPYRIGHT
Copyright (C) 2017 Frank Seitz
=head1 LICENSE
This code is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
# -----------------------------------------------------------------------------
1;
# eof