Возвращаясь к вопросу привожу пример как это можно сделать, правда предложения к разработчикам по доработке файла Admin_Tools.js в процедуре JCFloatDiv:Show(). Дело в том что при применении в пользовательких таблицах, неверно происходит расчет позиции отображения меню, возможно это и частный случай, в любом случае прошу проанализировать.
//
И сам пример
/test/index.php
/test/scripts/catalog.js
/test/CatalogTree.php
/test/ReportHeader.php
/test/Report.php
Вроде все.
//
| Код |
|---|
this.Show = function(div, left, top, dxShadow)
{
var zIndex = parseInt(div.style.zIndex);
if(zIndex <= 0 || isNaN(zIndex))
zIndex = 10000;
div.style.zIndex = zIndex;
div.style.left = left + "px";
div.style.top = top + "px";
//Сдвигаем точку отображения меню с учетом смещений вложенных уровней таблиц и т.д.
var _div = div.offsetParent;
var _left = left;
var _top = top;
while(_div && _div.tagName!="BODY")
{
_left -= _div.offsetLeft;
_top -= _div.offsetTop;
_div = _div.offsetParent;
}
div.style.left = _left + "px";
div.style.top = _top + "px";
//
if(jsUtils.IsIE())
{
var frame = document.getElementById(div.id+"_frame");
if(!frame)
{
frame = document.createElement("IFRAME");
frame.src = "javascript:''";
frame.id = div.id+"_frame";
frame.style.position = 'absolute';
frame.style.zIndex = zIndex-1;
//Формируем фрейм подложки меню в родительском элементе самого меню, иначе в ИЕ идет перемешывание zIndex
// document.body.appendChild(frame);
div.parentElement.appendChild(frame);
}
frame.style.width = div.offsetWidth + "px";
frame.style.height = div.offsetHeight + "px";
frame.style.left = div.style.left;
frame.style.top = div.style.top;
frame.style.visibility = 'visible';
}
/*shadow*/
if(isNaN(dxShadow))
dxShadow = 5;
if(dxShadow > 0)
{
var img = document.getElementById(div.id+'_shadow');
if(!img)
{
if(jsUtils.IsIE())
{
img = document.createElement("DIV");
img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/bitrix/themes/"+phpVars.ADMIN_THEME_ID+"/images/shadow.png',sizingMethod='scale')";
}
else
{
img = document.createElement("IMG");
img.src = '/bitrix/themes/'+phpVars.ADMIN_THEME_ID+'/images/shadow.png';
}
img.id = div.id+'_shadow';
img.style.position = 'absolute';
img.style.zIndex = zIndex-2;
//Формируем фрейм подложки меню в родительском элементе самого меню, иначе в ИЕ идет перемешывание zIndex
// document.body.appendChild(img);
div.parentElement.appendChild(img);
}
img.style.width = div.offsetWidth+'px';
img.style.height = div.offsetHeight+'px';
img.style.left = parseInt(div.style.left)+dxShadow+'px';
img.style.top = parseInt(div.style.top)+dxShadow+'px';
img.style.visibility = 'visible';
}
}
|
И сам пример
/test/index.php
| Код |
|---|
<?
if (!isset($_REQUEST['mode']) )
{
echo "<script type 'text/javascript' Language='JavaScript' src='/test/scripts/catalog.js'></script>";
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
if (!isset($_SESSION["USR"]))
$APPLICATION->AuthForm(GetMessage("ACCESS_DENIED"));
}
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_before.php"); // первый общий пролог
$CatalogStart = "";
if (!isset($_REQUEST['mode']) )
{
echo($adminPage->ShowScript());
$APPLICATION->SetTitle("Title");
$APPLICATION->SetAdditionalCSS("/test/styles.css"); //Копия стандартного
echo "<table border='1'>";
echo " <tr>";
echo " <td valign='top'>";
require("CatalogTree.php");
echo " </td>";
echo " <td valign='top'>";
echo " <table border='0'>";
echo " <tr>";
echo " <td valign='top'>";
}
require("ReportHeader.php");
if (!isset($_REQUEST['mode']) )
{
echo " </td>";
echo " </tr>";
echo " </table>";
echo " </td>";
echo " </tr>";
echo "</table>";
}
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");
?>
|
/test/scripts/catalog.js
| Код |
|---|
function doOutLine( sCatalogRegNo )
{
var oSrcElement, oTargetElement;
oSrcElement = window.event.srcElement;
oTargetElement = document.all( oSrcElement.id + "_div" );
if ( oTargetElement != null )
if ( oTargetElement.style.display == "none")
{
oSrcElement.src = "/test/images/opened.gif";
oTargetElement.style.display = "";
}
else
{
oSrcElement.src = "/test/images/closed.gif";
oTargetElement.style.display = "none";
}
}
function selectCatalog( sCatalogRegNo )
{
var oSrcElement, oTargetElement;
oSrcElement = document.all( sCatalogRegNo + "" );
oTargetElement = document.all( sCatalogRegNo + "_div" );
if ( oTargetElement != null )
if ( oTargetElement.style.display == "none")
{
oSrcElement.src = "/test/images/opened.gif";
oTargetElement.style.display = "";
}
Reports.GetAdminList('/TEST?catalog='+sCatalogRegNo);
}
|
/test/CatalogTree.php
| Код |
|---|
<?
function ShowCatalogTree($Res)
{
function parse_node($xPath, $sParent, $nSubling=1)
{
global $CatalogStart;
if ($nSubling==1)
$xpresult = xpath_eval($xPath, "/catalogs/item");
else
$xpresult = xpath_eval($xPath, "/catalogs/item[@parent='".$sParent."']");
foreach ($xpresult->nodeset as $node)
{
if( $nSubling==1 )
{
$xpresult = xpath_eval($xPath, "/catalogs/item[@rn='".$node->get_attribute("parent")."']");
if( !empty($xpresult->nodeset) )
continue;
}
if ( empty($CatalogStart) )
$CatalogStart = $node->get_attribute("rn");
echo str_pad("", $nSubling*5, " ");
echo "<img title=''";
if ($nSubling >= 3)
echo " src='/test/images/closed.gif'";
else
echo " src='/test/images/opened.gif'";
echo " border = '0'
id = '".$node->get_attribute("rn")."'
onclick='javascript:doOutLine()'
width='16'
height='16'>";
echo "<a class='catalogInactive'
title=''
id='".$node->get_attribute("rn")."_href'
href='javascript:selectCatalog(".$node->get_attribute("rn").")'>";
echo iconv("UTF-8","windows-1251",$node->get_attribute("name"));
echo "</a><br>";
echo "<div id='".$node->get_attribute("rn")."_div' ";
if ($nSubling >= 3)
echo "style={display:none}";
echo ">";
parse_node($xPath, $node->get_attribute("rn"), $nSubling+2);
echo "</div>";
}
}
if( ($xDoc = domxml_open_mem($Res, DOMXML_LOAD_PARSING, &$ErrArr)) )
{
echo "<div id=CatalogTree>";
$xPath = xpath_new_context($xDoc);
parse_node($xPath, "");
echo "</div>";
}
}
// $Res = QueryGetData("localhost",
// 8090,
// "login.xml",
// "target=catalogs.xml&login=".$_SESSION["USR"]."&password=".$_SESSION["PWD"]);
$Res = "<?xml version=\"1.0\" ?><?xml-stylesheet type=\"text/xsl\" href=\"catalogs.xsl\" ?><catalogs><item rn=\"420211713\" parent=\"418381277\" name=\"TEST\"/></catalogs>";
ShowCatalogTree($Res);
?>
|
/test/ReportHeader.php
| Код |
|---|
<?
require("Report.php");
// выберем отчеты
$cReportData = new CReport();
$sReportTableID = "Reports"; // ID таблицы
$oReportSort = new CAdminSorting($sReportTableID, "NRN", "desc");
$oReportList = new CAdminList($sReportTableID, $oReportSort);
// опишем элементы фильтра
$ReportFilterArr = Array(
"find",
"find_type",
"find_id",
"find_lid",
"find_active",
"find_visible",
"find_auto",
"catalog" => $_REQUEST['catalog']
);
// инициализируем фильтр
$oReportList->InitFilter($ReportFilterArr);
// *********************** CheckFilter ******************************** //
// проверку значений фильтра для удобства вынесем в отдельную функцию
function ReportCheckFilter()
{
global $ReportFilterArr, $oReportList;
foreach ($ReportFilterArr as $f) global $$f;
// В данном случае проверять нечего.
// В общем случае нужно проверять значения переменных $find_имя
// и в случае возниконовения ошибки передавать ее обработчику
// посредством $oReportList->AddFilterError('текст_ошибки').
return count($oReportList->arFilterErrors)==0; // если ошибки есть, вернем false;
}
// если все значения фильтра корректны, обработаем его
if (ReportCheckFilter())
{
// создадим массив фильтрации для выборки CReport::GetList() на основе значений фильтра
$arReportFilter = Array(
"ID" => ($find!="" && $find_type == "id"? $find:$find_id),
"LID" => $find_lid,
"ACTIVE" => $find_active,
"VISIBLE" => $find_visible,
"AUTO" => $find_auto,
"CATALOG" => $catalog,
);
}
$rsReportData = $cReportData->GetList($by, $order, $arReportFilter);
$oReportList->AddHeaders(Array(
// array("id" => "NRN",
// "content" => "NRN",
// "sort" => "NRN",
// "default" => "false"
// ),
array("id" => "SDATE",
"content" => "Дата",
"sort" => "SDATE",
"default" => "true"
),
array("id" => "SFORM",
"content" => "Форма",
"sort" => "SFORM",
"default" => "true"
),
array("id" => "SAGENT",
"content" => "Контрагент",
"sort" => "SAGENT",
"default" => "true"
),
array("id" => "SSTATUS",
"content" => "Статус",
"sort" => "SSTATUS",
"default" => "true"
),
// array("id" => "NKIND",
// "content" => "NKIND",
// "sort" => "NKIND",
// "default" => "false"
// ),
array("id" => "SNOTE",
"content" => "Примечание",
"sort" => "SNOTE",
"default" => "true"
)
));
// сформируем контекстное меню
$arReportActions = Array();
// редактирование элемента
$arReportActions[] = array(
// "ICON"=>"insert",
"DEFAULT"=>false,
"TEXT"=>"Добавить отчет",
"ACTION"=>$oReportList->ActionRedirect("report_insert.php"));
$arReportActions[] = array(
// "ICON"=>"update",
"DEFAULT"=>false,
"TEXT"=>"Исправить отчет",
"ACTION"=>$oReportList->ActionRedirect("report_update.php"));
$arReportActions[] = array(
// "ICON"=>"delete",
"DEFAULT"=>false,
"TEXT"=>"Удалить отчет",
"ACTION"=>$oReportList->ActionRedirect("report_delete.php"));
// вставим разделитель
$arReportActions[] = array("SEPARATOR"=>true);
$arReportActions[] = array(
"ICON"=>"calculate",
"DEFAULT"=>false,
"TEXT"=>"Расчитать отчет",
"ACTION"=>$oReportList->ActionRedirect("report_calculate.php"));
$arReportActions[] = array(
"ICON"=>"check",
"DEFAULT"=>false,
"TEXT"=>"Проверить отчет",
"ACTION"=>$oReportList->ActionRedirect("report_check.php"));
foreach ($rsReportData as $Data)
{
// создаем строку. результат - экземпляр класса CAdminListRow
$row =& $oReportList->AddRow($Data["NRN"],$Data);
// далее настроим отображение значений при просмотре и редаткировании списка
// параметр NAME будет редактироваться как текст, а отображаться ссылкой
// $row->AddViewField("NRN", $Data["NRN"]);
$row->AddViewField("SDATE", $Data["SDATE"]);
$row->AddViewField("SFORM", $Data["SFORM"]);
$row->AddViewField("SAGENT", $Data["SAGENT"]);
$row->AddViewField("SSTATUS", $Data["SSTATUS"]);
// $row->AddViewField("NKIND", $Data["NKIND"]);
$row->AddViewField("SNOTE", $Data["SNOTE"]);
// применим контекстное меню к строке
$row->AddActions($arReportActions);
}
//Итоги и т.д.
$oReportList->AddFooter(
array(
array("title"=>GetMessage("MAIN_ADMIN_LIST_SELECTED"), "value"=>0), // кол-во элементов
array("counter"=>true, "title"=>GetMessage("MAIN_ADMIN_LIST_CHECKED"), "value"=>"0"), // счетчик выбранных элементов
)
);
//групповые операции
$oReportList->AddGroupActionTable(Array(
"delete_report"=>"Удалить отчеты",
"calculate"=>"Расчитать отчеты",
"check"=>"Проверить отчеты"
));
// сформируем меню из одного пункта - добавление
$aReportContext = array(
array(
"TEXT"=>"Insert",
"LINK"=>"report_insert.php?lang=".LANG,
"TITLE"=>"Insert record",
"ICON"=>"btn_new"
),
);
// и прикрепим его к списку
$oReportList->AddAdminContextMenu($aReportContext);
/*
// создадим объект фильтра
$oFilter = new CAdminFilter(
$sReportTableID."_filter",
array(
"NRN",
"SAGENT",
"SFROM",
)
);
echo "<form name='find_form' method='get' action='".$APPLICATION->GetCurPage()."'>";
$oFilter->Begin();
echo "<tr>";
echo " <td>NRN:</td>";
echo " <td><input type='text' name='find_nrn' size='47' value='".htmlspecialchars($find_nrn)."'></td>";
echo "</tr>";
echo "<tr>";
echo " <td>SAGENT:</td>";
echo " <td><input type='text' name='find_sagent' size='47' value='".htmlspecialchars($find_sagent)."'></td>";
echo "</tr>";
echo "<tr>";
echo " <td>SFORM:</td>";
echo " <td><input type='text' name='find_sform' size='47' value='".htmlspecialchars($find_sform)."'></td>";
echo "</tr>";
$oFilter->Buttons(array("table_id"=>$sReportTableID,"url"=>$APPLICATION->GetCurPage(),"form"=>"find_form"));
$oFilter->End();
echo "</form>";
*/
// альтернативный вывод
$oReportList->CheckListMode();
$oReportList->DisplayList();
?>
|
/test/Report.php
| Код |
|---|
<?
class CReport
{
function sortArrayByField($original, $field, $descending)
{
$sortArr = array();
foreach ( $original as $key => $value )
{
$sortArr[ $key ] = $value[ $field ];
}
if ( $descending == "desc" )
{
arsort( $sortArr );
}
else
{
asort( $sortArr );
}
$resultArr = array();
foreach ( $sortArr as $key => $value )
{
$resultArr[ $key ] = $original[ $key ];
}
return $resultArr;
}
function ResultSet($Res)
{
if( ($xDoc = domxml_open_mem($Res, DOMXML_LOAD_PARSING, &$ErrArr)) )
{
$xPath = xpath_new_context($xDoc);
$xpresult = xpath_eval($xPath, "/reports/*");
$Result = Array();
foreach ($xpresult->nodeset as $node)
{
$Row = Array("NRN" => iconv("UTF-8","windows-1251",$node->get_attribute("rn")),
"SDATE" => iconv("UTF-8","windows-1251",$node->get_attribute("date")),
"SFORM" => iconv("UTF-8","windows-1251",$node->get_attribute("form")),
"SAGENT" => iconv("UTF-8","windows-1251",$node->get_attribute("agent")),
"SSTATUS" => iconv("UTF-8","windows-1251",$node->get_attribute("status")),
"SNOTE" => iconv("UTF-8","windows-1251",$node->get_attribute("note")),
"NKIND" => iconv("UTF-8","windows-1251",$node->get_attribute("kind"))
);
$Result[] = $Row;
}
return $Result;
}
}
function GetList($aSortField, $aSortOrder, $aFilter)
{
global $CatalogStart;
// $Res = QueryGetData("localhost",
// 8090,
// "login.xml",
// "target=reports.xml&catalog=".(empty($aFilter["CATALOG"])?$CatalogStart:$aFilter["CATALOG"])."&login=".$_SESSION["USR"]."&password=".$_SESSION["PWD"]);
$Res = "<?xml version=\"1.0\" ?><?xml-stylesheet type=\"text/xsl\" href=\"reports.xsl\" ?><reports><item rn=\"419167080\" date=\"01.01.2008\" form=\"TEST-FORM\" agent=\"TEST-AGENT\" status=\"TEST\" note=\"\" kind=\"0\" calctype=\"\" catalog=\"420211713\"/></reports>";
$Result = $this->ResultSet($Res);
$SortResult = $this->sortArrayByField($Result, $aSortField, $aSortOrder);
return $SortResult;
}
}
?>
|
Вроде все.