Hier mal meine Lösung:
In der ext_tables.php die neue Klasse tx_chvacationindex_tcaSingleBox inludieren:
// class for rendering a singlebox by a user function or class method.
include_once(t3lib_extMgm::extPath($_EXTKEY).'TCA/class.tx_chvacationindex_tcaSingleBox.php');
In der tca.php die user function tx_chvacationindex_tcaSingleBox->singleBox aufrufen:
'config' => Array (
'type' => 'select',
'form_type' => 'user',
'userFunc' => 'tx_chvacationindex_tcaSingleBox->singleBox',
'size' => 10,
'minitems' => 0,
'maxitems' => 100,
'foreign_table' => 'tx_chvacationindex_accommodation',
'foreign_table_where' => 'AND tx_chvacationindex_accommodation.parent_uid=###THIS_UID###',
'MM' => 'tx_chvacationindex_accommodation_mm',
)
Die Klasse "tx_chvacationindex_tcaSingleBox" zum abspeichern:
<?php
/***************************************************************
* Copyright notice
*
* (c) 2006 Chi Hoang (chibox@gmail.com)
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
require_once(PATH_t3lib.'class.t3lib_tceforms.php');
class tx_chvacationindex_tcaSingleBox extends t3lib_TCEforms {
function singleBox($PA, $fobj) {
global $TCA;
// Field configuration from TCA:
$config = $PA['fieldConf']['config'];
// "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. See http://typo3.org/documentation/document-library/doc_core_api/Wizards_Configuratio/.
$specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);
// Getting the selector box items from the system
$selItems = $this->addSelectOptionsToItemArray($this->initItemArray($PA['fieldConf']),$PA['fieldConf'],$this->setTSconfig($PA['fieldConf']['config']['foreign_table'],$PA['row']),$field);
$selItems = $this->addItems($selItems,$PA['fieldTSConfig']['addItems.']);
if ($config['itemsProcFunc']) $selItems = $this->procItems($selItems,$PA['fieldTSConfig']['itemsProcFunc.'],$config,$table,$row,$field);
// Possibly remove some items:
$removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
foreach($selItems as $tk => $p) {
// Checking languages and authMode:
$languageDeny = $TCA[$table]['ctrl']['languageField'] && !strcmp($TCA[$table]['ctrl']['languageField'], $field) && !$GLOBALS['BE_USER']->checkLanguageAccess($p[1]);
$authModeDeny = $config['form_type']=='select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table,$field,$p[1],$config['authMode']);
if (in_array($p[1],$removeItems) || $languageDeny || $authModeDeny) {
unset($selItems[$tk]);
} elseif (isset($PA['fieldTSConfig']['altLabels.'][$p[1]])) {
$selItems[$tk][0]=$this->sL($PA['fieldTSConfig']['altLabels.'][$p[1]]);
}
// Removing doktypes with no access:
if ($table.'.'.$field == 'pages.doktype') {
if (!($GLOBALS['BE_USER']->isAdmin() || t3lib_div::inList($GLOBALS['BE_USER']->groupData['pagetypes_select'],$p[1]))) {
unset($selItems[$tk]);
}
}
}
// Creating the label for the "No Matching Value" entry.
$nMV_label = isset($PA['fieldTSConfig']['noMatchingValue_label']) ? $this->sL($PA['fieldTSConfig']['noMatchingValue_label']) : '[ '.$this->getLL('l_noMatchingValue').' ]';
// Prepare some values:
$maxitems = intval($config['maxitems']);
return $this->getSingleBox($PA['table'],$PA['field'],$PA['row'],$PA,$config,$selItems,$nMV_Label);
}
/**
* Creates a multiple-selector box (two boxes, side-by-side)
* (Render function for getSingleField_typeSelect())
*
* @param string See getSingleField_typeSelect()
* @param string See getSingleField_typeSelect()
* @param array See getSingleField_typeSelect()
* @param array See getSingleField_typeSelect()
* @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience)
* @param array Items available for selection
* @param string Label for no-matching-value
* @return string The HTML code for the item
* @see getSingleField_typeSelect()
*/
function getSingleBox($table,$field,$row,&$PA,$config='',$selItems='',$nMV_label='') {
// Setting this hidden field (as a flag that JavaScript can read out)
$item.= '<input type="hidden" name="'.$PA['itemFormElName'].'_mul" value="'.($config['multiple']?1:0).'" />';
// Set max and min items:
$maxitems = t3lib_div::intInRange($config['maxitems'],0);
if (!$maxitems) $maxitems=100000;
$minitems = t3lib_div::intInRange($config['minitems'],0);
// Register the required number of elements:
$this->requiredElements[$PA['itemFormElName']] = array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field);
// Get "removeItems":
$removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
// Perform modification of the selected items array:
$itemArray = t3lib_div::trimExplode(',',$PA['itemFormElValue'],1);
foreach ($itemArray as $k => $v) {
$tvP = explode('|',$v,2);
$iA[$tvP[0]]=rawurldecode($tvP[1]);
}
foreach ($selItems as $k) {
if (!$iA[$k[1]]) {
$iA[$k[1]] = $k[0];
}
}
$itemArray=array();
foreach ($iA as $k => $v) {
$itemArray[] = $k.'|'.rawurlencode($v);
}
foreach($itemArray as $tk => $tv) {
$tvP = explode('|',$tv,2);
$evalValue = rawurldecode($tvP[0]);
$isRemoved = in_array($evalValue,$removeItems) || ($config['form_type']=='select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table,$field,$evalValue,$config['authMode']));
if ($isRemoved && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
$tvP[1] = rawurlencode(@sprintf($nMV_label, $evalValue));
} elseif (isset($PA['fieldTSConfig']['altLabels.'][$evalValue])) {
$tvP[1] = rawurlencode($this->sL($PA['fieldTSConfig']['altLabels.'][$evalValue]));
} else {
$tvP[1] = rawurlencode($this->sL(rawurldecode($tvP[1])));
}
$itemArray[$tk] = implode('|',$tvP);
}
$size = intval($config['size']);
$size = $config['autoSizeMax'] ? t3lib_div::intInRange(count($itemArray)+1,t3lib_div::intInRange($size,1),$config['autoSizeMax']) : $size;
// Pass to "dbFileIcons" function:
$params = array(
'size' => $size,
'autoSizeMax' => t3lib_div::intInRange($config['autoSizeMax'],0),
'style' => isset($config['selectedListStyle']) ? ' style="'.htmlspecialchars($config['selectedListStyle']).'"' : ' style="'.$this->defaultMultipleSelectorStyle.'"',
'dontShowMoveIcons' => ($maxitems<=1),
'maxitems' => $maxitems,
'info' => '',
'headers' => array(
'selector' => $this->getLL('l_selected').':<br />',
'items' => $this->getLL('l_items').':<br />'
),
'noBrowser' => 1,
'thumbnails' => $itemsToSelect
);
$item .= $this->dbFileIconsSingleBox($PA['itemFormElName'],'','',$itemArray,'',$params,$PA['onFocus']);
$item = $this->renderWizards(array($item,$altItem),$config['wizards'],$table,$row,$field,$PA,$PA['itemFormElName'],$specConf,$RTEwouldHaveBeenLoaded);
return $item;
}
/**
* Prints the selector box form-field for the db/file/select elements (multiple)
*
* @param string Form element name
* @param string Mode "db", "file" (internal_type for the "group" type) OR blank (then for the "select" type)
* @param string Commalist of "allowed"
* @param array The array of items. For "select" and "group"/"file" this is just a set of value. For "db" its an array of arrays with table/uid pairs.
* @param string Alternative selector box.
* @param array An array of additional parameters, eg: "size", "info", "headers" (array with "selector" and "items"), "noBrowser", "thumbnails"
* @param string On focus attribute string
* @return string The form fields for the selection.
*/
function dbFileIconsSingleBox($fName,$mode,$allowed,$itemArray,$selector='',$params=array(),$onFocus='') {
// Sets a flag which means some JavaScript is included on the page to support this element.
$this->printNeededJS['dbFileIcons']=1;
// INIT
$uidList=array();
$opt=array();
$itemArrayC=0;
// Creating <option> elements:
if (is_array($itemArray)) {
$itemArrayC=count($itemArray);
reset($itemArray);
switch($mode) {
case 'db':
while(list(,$pp)=each($itemArray)) {
$pRec = t3lib_BEfunc::getRecord($pp['table'],$pp['id']);
if (is_array($pRec)) {
$pTitle = t3lib_div::fixed_lgd_cs($this->noTitle($pRec[$GLOBALS['TCA'][$pp['table']]['ctrl']['label']]),$this->titleLen);
$pUid = $pp['table'].'_'.$pp['id'];
$uidList[]=$pUid;
$opt[]='<option value="'.htmlspecialchars($pUid).'">'.htmlspecialchars($pTitle).'</option>';
}
}
break;
case 'file':
while(list(,$pp)=each($itemArray)) {
$pParts = explode('|',$pp);
$uidList[]=$pUid=$pTitle = $pParts[0];
$opt[]='<option value="'.htmlspecialchars(rawurldecode($pParts[0])).'">'.htmlspecialchars(rawurldecode($pParts[0])).'</option>';
}
break;
default:
while(list(,$pp)=each($itemArray)) {
$pParts = explode('|',$pp);
$uidList[]=$pUid=$pParts[0];
$pTitle = $pParts[1];
$opt[]='<option value="'.htmlspecialchars(rawurldecode($pUid)).'">'.htmlspecialchars(rawurldecode($pTitle)).'</option>';
}
break;
}
}
// Create selector box of the options
$sSize = $params['autoSizeMax'] ? t3lib_div::intInRange($itemArrayC+1,t3lib_div::intInRange($params['size'],1),$params['autoSizeMax']) : $params['size'];
if (!$selector) {
$selector = '<select size="'.$sSize.'" this-="">insertDefStyle('group').' multiple="multiple" name="'.$fName.'_list" '.$onFocus.$params['style'].'>'.implode('',$opt).'</select>';
}
$icons = array(
'L' => array(),
);
if (!$params['dontShowMoveIcons']) {
if ($sSize>=5) {
$icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$fName.'\',\'Top\'); return false;">'.
'<img'.t3lib_iconworks::skinimg($this->backPath,'gfx/group_totop.gif','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib($this->getLL('l_move_to_top')).' />'.
'</a>';
}
$icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$fName.'\',\'Up\'); return false;">'.
'<img'.t3lib_iconworks::skinimg($this->backPath,'gfx/up.gif','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib($this->getLL('l_move_up')).' />'.
'</a>';
$icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$fName.'\',\'Down\'); return false;">'.
'<img'.t3lib_iconworks::skinimg($this->backPath,'gfx/down.gif','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib($this->getLL('l_move_down')).' />'.
'</a>';
if ($sSize>=5) {
$icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$fName.'\',\'Bottom\'); return false;">'.
'<img'.t3lib_iconworks::skinimg($this->backPath,'gfx/group_tobottom.gif','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib($this->getLL('l_move_to_bottom')).' />'.
'</a>';
}
}
$icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$fName.'\',\'Remove\'); return false;">'.
'<img'.t3lib_iconworks::skinimg($this->backPath,'gfx/group_clear.gif','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib($this->getLL('l_remove_selected')).' />'.
'</a>';
$str='<table border="0" cellpadding="0" cellspacing="0" width="1">
'.($params['headers']?'
<tr>
<td>'.$this->wrapLabels($params['headers']['selector']).'</td>
<td></td>
<td></td>
<td></td>
</tr>':'').
'
<tr>
<td valign="top">'.
$selector.'<br />'.
$this->wrapLabels($params['info']).
'</td>
<td valign="top">'.
implode('<br />',$icons['L']).'</td>
<td valign="top"></td>
<td><img src="clear.gif" width="5" height="1" alt="" /></td>
</tr>
</table>';
// Creating the hidden field which contains the actual value as a comma list.
$str.='<input type="hidden" name="'.$fName.'" value="'.htmlspecialchars(implode(',',$uidList)).'" />';
return $str;
}
}
?>