Optisch leider noch immer nicht der Brüller, Codeaufbau auch noch nicht verbessert, dafür ein paar Bugs entfernt und auf REX 4.2 portiert. Rest folgt demnächst, wenn ich etwas mehr Zeit habe. Da jQuery ja im Backend eingebunden ist, werde ich das Script demnächst etwas kompakter anbieten, weil ich durch das Framework schneller auf Elemente zugreifen kann.
Das Modul funktioniert bei mir und 3 weiteren Kunden einwandfrei.
ACHTUNG: NEUE REXNAME-AKTION. MIT DEM ALTEN IST ES NICHT LAUFFÄHIG.
Kurzanleitung:
- Code: Alles auswählen
Schritt 1:
-> Modul
-> Modul anlegen
-> Modulname: DynTable
-> Eingabe einfügen
-> Ausgabe einfügen
-> Speichern
Schritt 2:
-> Aktionen
-> Aktion anlegen
-> Aktionname: Rexname
-> REXNAME-Code in PRESAVE pasten
-> ADD, EDIT, DELETE auswählen
-> Speichern.
Schritt 3:
-> Modul
-> DynTable öffnen
-> unten bei Aktionen Rexname dem Modul hinzufügen
FERTIG!
Viel Spaß & freue mich auf eure Reaktionen.
EINGABE
- Code: Alles auswählen
<style type="text/css">
#tableImgs {
float: left;
width: 40px;
padding-top: 1px;
vertical-align: text-top;
}
table {
vertical-align: text-bottom;
}
table tr {
margin-bottom: 15px;
vertical-align: text-bottom;
}
table td {
padding-right: 10px;
vertical-align: text-bottom;
}
</style>
<?
$rexname = split("~~","REX_VALUE[1]");
$GLOBALS['rexname'] = $rexname;
/**
* --------------------------------------------------------------------
*
* Redaxo Modul: DynTable
*
* Version: 1.2, 20.02.10 (Copyright 2010 Hirbod - info@ideenkreation.de)
*
* Basiert auf der Version von Ulrich Zdebel, uzdebel@web.de (Version 0.2)
* Reloaded Version 1.2 by Hirbod (info@ideenkreation.de) / REX 4.1 / 4.2 kompatibel und um mehrere wichtige und interessante Features erweitert
*
* --------------------------------------------------------------------
* - Neu:
*
* - REX 4.2 portiert
* - Zellen können an beliebiger Stelle eingefügt oder entfernt werden
* - Zellen können beliebig verschoben werden
* - Die 99 Zellen Begrenzung ist raus, aber noch unsauber gelöst. Es wird dran gearbeitet
* - rexname überarbeitet und genügt als "presave"-aktion
* - Viele Bugs entfernt und den Code etwas bereinigt
*
*/
/**
* -----------------------------------------------------------------------------
* Aktionen für das Modul setzen (Presave-Action):
* rexname [PRE|ADD|EDIT]
*
*
* OPTIONEN:
*
* $maxSize:
* Maximal zulässige Breite "eines" Inputfeldes, wenn sich dieses über
* den zulässigen Bildschirmbereich erstrecken würde.
*
* $headline:
* Mögliche Tabellenüberschrift
*
* $colChooserAllowed:
* true:eingeschaltet; false:ausgeschaltet
* Anzeigeoption für Selectelement zur Einstellung der Tabellenspalten
*
* $maxColChooserValues:
* Maximal einstellbare Anzahl an Spalten
*
* $colChooserInfo:
* true: einschalten; false: ausschalten
* Einschalten des Infotextes wie die Spaltenzahl verändert wird.
*
* $maxCols:
* Ist aktiv, wenn $colChooserAllowed=false; ist !
* Voreinstellung der maximalen Anzahl an Spalten.
*
* $tableIdChooserAllowed:
* Schaltet das Inputfeld zur Eingabe der Tabel id ein / aus
* Für $tableIdChooserAllowed=false wird stets table class="dyntable" gesetzt !
* ------------------------------------------------------------------------------
*/
// OPTIONEN
$maxSize = 120;
$headline = '';
$colChooserAllowed = true;
$maxColChooserValues = 100;
$maxCols = 100;
$colChooserInfo = true;
$tableIdChooserAllowed = true;
$colChooserInfo=true;
if($maxColChooserValues<=1)
{
$colChooserAllowed = false;
$colChooserInfo=false;
}
if(!$colChooserAllowed) $rexname[1] = $maxCols;
if(!isset($rexname[1]) OR ($rexname[1]==''))
{
$rexname[1] = 1;
$sizeArr = array($maxSize);
} else {
$size = floor($maxSize / $rexname[1]);
for($i=0;$i<$rexname[1];$i++) $sizeArr[] = $size;
}
$tableID = (isset($rexname[3])&&($rexname[3]!=''))?$rexname[3]:'dyntable';
$jsSizeArr = "new Array('".implode("','",$sizeArr)."')";
$script=<<<EOD
<script language="javascript">
function numRows(table_id) {
var rows = document.getElementById(table_id).getElementsByTagName('tr');
return rows.length;
}
function numCols(table_id) {
var cols = document.getElementById(table_id).getElementsByTagName('input');
return cols.length;
}
function createInput(pRow, pCellNum, psize )
{
var row_value = '';
var cell = pRow.insertCell(pCellNum);
var el = document.createElement('input');
el.setAttribute('type', 'text');
el.setAttribute('value', row_value);
el.setAttribute('name', '');
el.setAttribute('size', psize);
cell.appendChild(el);
}
function addRow(r, table_id){
if (!document.getElementById || !document.createElement || !document.createTextNode)
{
alert ("Ihr Browser unterst&tzt die Funktion leider nicht !"); return;
}
var rowIndex;
if(r)
rowIndex = r.parentNode.parentNode.rowIndex + 1;
else
rowIndex = numRows(table_id);
//alert(rowIndex);
var sizeArr = $jsSizeArr;
var table = document.getElementById(table_id);
var lastRow = numRows(table_id);
var rowNum = lastRow+1;
var lastCol = numCols(table_id);
var colCount = lastCol / lastRow;
if (navigator.platform == "MacPPC")
{
rowIndex = rowIndex * 2;
}
var row = table.insertRow(rowIndex);
for(var i=0;i<colCount;i++) createInput(row, i, sizeArr[i]);
createButtons(row, table_id);
setRowColHidden(rowNum, colCount);
updateRexname(table_id);
}
function setRowColHidden( rowNum, colCount )
{
document.getElementById('REX_FORM').elements['rexname[0]'].value = rowNum + ':' + colCount;
}
function createButtons(row, table_id)
{
var cell = row.insertCell(0);
cell.innerHTML = '<a href="#row" onclick="addRow(this, \'' + table_id + '\')";><img src="./media/file_add.gif" /></a>' +
'<a href="#row" onclick="moveUp(this, \'' + table_id + '\')";><img src="./media/file_up.gif" /></a>' +
'<a href="#row" onclick="deleteRow(this, \'' + table_id + '\')";><img src="./media/file_del.gif" /></a>' +
'<a href="#row" onclick="moveDown(this, \'' + table_id + '\')";><img src="./media/file_down.gif" /></a>';
cell.id = 'tableImgs';
}
function moveUp(link, table_id){
var row = link.parentNode.parentNode;
if (0 == row.rowIndex) {
alert('Die erste Zeile kann nicht weiter nach oben verschoben werden!');
} else {
var prevRow = row.previousSibling;
row.parentNode.removeChild(row);
prevRow.parentNode.insertBefore(row, prevRow);
updateRexname(table_id);
}
}
function moveDown(link, table_id){
var row = link.parentNode.parentNode;
if (numRows(table_id) == row.rowIndex + 1) {
alert('Die letze Zeile kann nicht weiter nach unten verschoben werden!');
} else {
var nextRow = row.nextSibling;
row.parentNode.removeChild(nextRow);
row.parentNode.insertBefore(nextRow, row);
updateRexname(table_id);
}
}
function setCol(p)
{
var rowcol = document.getElementById('REX_FORM').elements['rexname[0]'].value;
var rowcol = document.REX_FORM.elements['rexname[0]'].value;
var rowcolArr = rowcol.split(":");
document.getElementById('REX_FORM').elements['rexname[0]'].value = rowcolArr[0] + ':' + p;
}
function deleteRow(r, table_id)
{
var i;
if(r)
i = r.parentNode.parentNode.rowIndex;
else
i = numRows(table_id)-1;
if (i == 0) {
alert('Die erste Zeile kann nicht gelöscht werden');
} else {
document.getElementById(table_id).deleteRow(i);
var lastCol = numCols(table_id);
lastRow = numRows(table_id);
var colCount = lastCol / lastRow;
setRowColHidden( lastRow, colCount );
updateRexname(table_id);
}
}
function updateRexname(table_id)
{
var inputWert = document.getElementById(table_id).getElementsByTagName('input');
for (var k = 0; k < inputWert.length; k++)
{
inputWert[k].name = "rexname[" + (k+4) + "]";
}
}
function setHdl()
{
var hdlValue = document.REX_FORM.elements['rexname[2]'].value;
if(hdlValue==1)
{
document.REX_FORM.elements['rexname[2]'].value=0;
} else {
document.REX_FORM.elements['rexname[2]'].value=1;
}
}
</script>
EOD;
// Script im Backend einfügen
if(!$REX['GG']) echo $script;
echo $headline;
/**
* -----------------------------------------------------------------------------
* Vorgabe der Tabellenkonstruktion mit 1 Zeile
* -----------------------------------------------------------------------------
*/
$rexname_col = (isset($rexname[1])&&($rexname[1]!=''))?$rexname[1]:1;
$table_id = 'tabelle';
$colChooser = true;
// Jetzt generieren wir die erste Spalte mit X Cols, falls noch keine zusätzlichen Spalten angelegt wurden
if( isset($rexname[0]) && ($rexname[0]==''))
{
$colChooser=true;
$rexname_rowcol = '1:'.$rexname[1];
$table = '<table id="'.$table_id.'">';
$table .= '<tr>';
$k=4;
for($i=0;$i<$rexname_col;$i++)
{
$rexname_value = isset($rexname[$k])?$rexname[$k]:'';
$table .= '<td><input type="text" name="rexname['.($k).']" value="'.$rexname_value.'" size="'.$sizeArr[$i].'" /></td>';
$k++;
}
$table .= '</tr>';
$table .= '</table>';
}
// Ende
/**
* -----------------------------------------------------------------------------
* Jetzt werden die restlich angelegten Felder dynamisch generiert
* -----------------------------------------------------------------------------*/
if( isset($rexname[0])&& ereg(':',$rexname[0]) )
{
list($rows, $cols) = split(':',$rexname[0]);
$colChooser = ($rows==1)?true:false;
$rexname_rowcol = ( isset($rexname[0]) && ($rexname[0]!='') ) ? $rows.':'.$rexname_col : '1:'.$rexname_col;
$table = '<table id="'.$table_id.'">';
$k=4;
for($i=0;$i<$rows;$i++)
{
$table .= '<tr><td id="tableImgs">
<a href="#row" onclick="addRow(this, \''.$table_id.'\')";><img src="./media/file_add.gif" /></a>
<a href="#row" onclick="moveUp(this, \''.$table_id.'\')";><img src="./media/file_up.gif" /></a>
<a href="#row" onclick="deleteRow(this, \''.$table_id.'\')";><img src="./media/file_del.gif" /></a>
<a href="#row" onclick="moveDown(this, \''.$table_id.'\')";><img src="./media/file_down.gif" /></a>
</td> ';
for($j=0;$j<$cols;$j++)
{
$rexname_value = (isset( $rexname[$k] ) ) ? $rexname[$k] : '';
$table .= '<td><input type="text" name="rexname['.$k.']" value="'.$rexname_value.'" size="'.$sizeArr[$j].'" /></td>';
$k++;
}
$table .= '</tr>';
}
$table .= '</table>';
}
?>
<?=$table;?>
<input name="rexname[0]" type="hidden" value="<?=$rexname_rowcol;?>" />
<input name="rexname[1]" type="hidden" value="<?=$rexname_col;?>" />
<input name="rexname[2]" type="hidden" value="<?=$rexname[2];?>" />
<br />
<a name="row"></a>
<fieldset style="color:#ff0000">
<a href="#row" onClick="addRow(null, '<?=$table_id;?>')"><img src="./media/file_add.gif" /></a>
<a href="#row" onClick="deleteRow(null, '<?=$table_id;?>')"><img src="./media/file_del.gif" /></a><br />
</fieldset>
<br />
Spaltenanzahl
<select name="rexname[1]" onchange="setCol( this[selectedIndex].value ); document.getElementById('REX_FORM').update.value=1; submit();">
<?
foreach( range(1,$maxColChooserValues) as $value) {
echo '<option value="'.$value.'"';
if ( $rexname[1]=="$value" ) {
echo 'selected="selected" ';
}
echo '>'.$value.'</option>';
}
?>
</select>
<br /><br />
Zeile 1 als Tabellenüberschrift (th) auszeichen?<br />
Ja <input type="radio" name="rexname[2]" value="1" <? if ($rexname[2] == '1') echo 'checked'; ?> /> | Nein <input type="radio" name="rexname[2]" value="0" <? if ($rexname[2] == '0') echo 'checked'; ?> /></div>
<br /><br />
<?if($tableIdChooserAllowed):?>
Der Tabelle eine Klasse vergeben<br />
Keine Eingabe = dyntable<br />
<input type="text" name="rexname[3]" value="<?=(isset($rexname[3])&&($rexname[3]!=''))?$rexname[3]:'dyntable';?>">
<br /><br />
<?endif;?>
<? if($colChooserInfo) { ?>
Informationen<br />
- Textile-Formatierung kann in jeder Zelle verwendet werden.<br />
- <span style="color: #ff0000;">Bei veränderter Spaltenanzahl <strong>zwei mal</strong>, "Block übernehmen" betätigen, damit die Zellen geladen werden</span><br />
<? } ?>
</table>
AUSGABE
- Code: Alles auswählen
<? $rexname = split("~~","REX_VALUE[1]");
$GLOBALS['rexname'] = $rexname; ?>
<?
$styleInfoVisible = true;
?>
<?
$table_id = ( isset($rexname[3]) && ($rexname[3]!='') )?$rexname[3]:'dyntable';
if( isset($rexname[0])&&(ereg(':',$rexname[0])) )
{
list($rows,$cols) = split(':', $rexname[0]);
$k=4;
$c=0;
if ("REX_VALUE[5]" == "1")
{
$activeNoHover = $this->getValue('article_id');
}
$tdStyleArr = array();
$thStyleArr = array();
$table = '<table class="'.$table_id.'">';
for($i=0;$i<$rows;$i++)
{
if ($i == 0 or $i == 1 && $this->getValue('article_id') != $activeNoHover)
{
$table .= '<tr class="noHover">';
} else {
$table .= '<tr>';
}
$tdi=1;
for($j=0;$j<$cols;$j++)
{
$c.=($rexname[$k]!='')?1:0;
$rexname[$k] = str_replace(""", "\"", $rexname[$k]);
$rexname[$k] = str_replace("<", "<", $rexname[$k]);
$rexname[$k] = str_replace(">", ">", $rexname[$k]);
if (empty($rexname[$k]))
{
$rexname[$k] = " ";
}
// Inputfelder mit Textile formatieren (php-code nicht eingerückt, weil das sonst EOT-Fehler verursacht.)
$input =<<<EOT
$rexname[$k]
EOT;
$textile = new Textile;
if ("$rexname[$k]" != "")
$rexname[$k] = $textile->TextileThis($input);
$rexname[$k] = str_replace("###"," ",$rexname[$k]);
// die erste Zeile als Tabellenüberschrift
if( isset($rexname[2]) && ($rexname[2]==1) && ($i==0) ) {
$table .= '<th class="th'.$tdi.'">'.$rexname[$k].'</th>';
#$thStyleArr[] = '#dyntable .th'.$tdi;
$thStyleArr[] = '#'.$table_id.' .th'.$tdi;
$k++; $tdi++;
} else {
//$pos1 = stripos($rexname[$k], ".2008");
//echo $pos1;
//if ($pos1 != false) continue;
$table .= '<td class="td'.$tdi.'">'.$rexname[$k].'</td>';
#$tdStyleArr[] = '#dyntable .td'.$tdi;
$tdStyleArr[] = '#'.$table_id.' .td'.$tdi;
$k++; $tdi++;
}
}
$table .= '</tr>';
}
$table .= '</table>';
// Nur Backendformatierung
if(!$REX['REDAXO'])
{
echo <<<EOD
<style type="text/css">
$tableStyle
$thStyleStr
$tdStyleStr
</style>
EOD;
}
// Nur Backend
if(!$REX['REDAXO']) {
if($c>0) echo $table; else {
echo '<fieldset><legend>Info</legend>';
echo 'Sämtliche Tabellenzellen sind leer !';
echo '</fieldset>';
}
}
// Nur Frontend
if($REX['REDAXO']) {
if($c>0) echo '<!-- colsplit -->'.$table;
}
// StyleInfo: Nur Backend
if((!$REX['REDAXO'])&&($styleInfoVisible)) {
echo '<br /><br />';
$info = '<fieldset>';
$info .= '<legend>Styleangaben</legend>';
$info .= 'Die Anzeige der Styleangaben wird in der Backendausgabe dieses Moduls abgeschaltet durch: $styleInfoVisible = false;';
$info .= '<br /><br />';
$info .= '<b>Tabelle:</b><br />id="'.$table_id.'"<br />';
// CSS Tabellenüberschrift
if(count($thStyleArr)>0) {
$info .= '<br />';
$info .= '<b>Überschrift:</b>';
$info .= '<br />';
$tdi=1;
for($j=0; $j<$cols; $j++) {
$info .= $tdi.'.Spalte: class="th'.$tdi.'"' . '<br />'; $tdi++;
}
$info .= '<br /><b>Andere Zellen:</b><br />';
} else $info .= '<br /><b>Zellen:</b><br />';
// CSS andere Zellen
$tdi=1;
for($j=0; $j<$cols; $j++) {
$info .= $tdi.'.Spalte: class="td'.$tdi.'"' . '<br />'; $tdi++;
}
$info .= '</fieldset>';
}
}
unset($tdStyleArr);
unset($thStyleArr);
?>
neue rexname: (nur als presave, ADD, EDIT, DELETE)
- Code: Alles auswählen
<?php
$rexname = rex_request("rexname","array");
$newname = "";
for ( $c = 0; $c < 9999; $c++ ) {
if (isset($rexname[$c])) { $newname .= $rexname[$c] . '~~'; }
else { $newname .= '~~'; }
}
if ( isset($REX_ACTION['VALUE'][1]) and $REX_ACTION['VALUE'][1] != '') {
$rexname = split('~~', $REX_ACTION['VALUE'][1]);
} else {
$REX_ACTION['VALUE'][1] = $newname;
}
?>
Screenshot


Määääääääääääääääääääääääh!