Здраствуйте!
Сегодня решал следующую задачу:
Необходимо создать пользовательское свойство привязки элемента инфоблока к местоположениям из интернет-магазина. Зачем нужна такая привязка я вдаваться в подробности не буду, а покажу как можно сделать привязку к любой выборке из базы данных, которая содержит большое количество записей и не может быть размещена в выпадающем списке. Список местоположений содержит более 4000 записей, поэтому делать выпадающим списком не представляется возможным. Но в битриксе есть интерфейс выбора значения у свойств типа "привязка к элементе" или "привязка к пользователю" при помощи нового окошка, в котором выводится список записей с постраничной навигацией. Позаимствуем его.
создаем файл /bitrix/admin/loсation_search.php со следующим содержанием:
Копируем содержимое /bitrix/modules/main/tools/user_search.php, правим под свои нужды, там придется поправить поля для фильтрации, заголовки таблицы и собственно заменить выборку пользователей на свою, в моем случае местоположения из таблицы b_sale_location.
Далее создаем файл /bitrix/modules/main/tools/location_search.php и вставляем туда наш код, примерно вот такого содержания:
Форму редактирования значения свойства мы создали, осталось зоздать само свойство, в init.php добавляем свойство:
вот что вышло в итоге:

При двойном клике на любую запись, ее ID вставляется в поле свойства и название города припысывается рядом.
А вот как это свойство выглядит в списке:

Извиняюсь за скудность комментариев в коде. Не люблю я их писать, темболее пятница, рабочий день закончился, а я еще тут.
Всем удачных выходных, по донедельника!
Сегодня решал следующую задачу:
Необходимо создать пользовательское свойство привязки элемента инфоблока к местоположениям из интернет-магазина. Зачем нужна такая привязка я вдаваться в подробности не буду, а покажу как можно сделать привязку к любой выборке из базы данных, которая содержит большое количество записей и не может быть размещена в выпадающем списке. Список местоположений содержит более 4000 записей, поэтому делать выпадающим списком не представляется возможным. Но в битриксе есть интерфейс выбора значения у свойств типа "привязка к элементе" или "привязка к пользователю" при помощи нового окошка, в котором выводится список записей с постраничной навигацией. Позаимствуем его.
создаем файл /bitrix/admin/loсation_search.php со следующим содержанием:
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/tools/location_search.php");?> |
Копируем содержимое /bitrix/modules/main/tools/user_search.php, правим под свои нужды, там придется поправить поля для фильтрации, заголовки таблицы и собственно заменить выборку пользователей на свою, в моем случае местоположения из таблицы b_sale_location.
Далее создаем файл /bitrix/modules/main/tools/location_search.php и вставляем туда наш код, примерно вот такого содержания:
<?
require_once(dirname(__FILE__)."/../include/prolog_admin_before.php");
$FN = preg_replace("/[^a-z0-9_\\[\\]:]/i", "", $_REQUEST["FN"]);
$FC = preg_replace("/[^a-z0-9_\\[\\]:]/i", "", $_REQUEST["FC"]);
if (isset($_REQUEST['JSFUNC']))
{
$JSFUNC = preg_replace("/[^a-z0-9_\\[\\]:]/i", "", $_REQUEST['JSFUNC']);
}
else
{
$JSFUNC = '';
}
$sTableID = "tbl_location_popup";
$oSort = new CAdminSorting($sTableID, "ID", "asc");
$lAdmin = new CAdminList($sTableID, $oSort);
// инициализация фильтра
$arFilterFields = Array( "city_name", "id", "city_id", "country_name");
$lAdmin->InitFilter($arFilterFields);
$arFilter = Array();
$arFilter = Array(
"ID" => $id,
"CITY_ID" => $city_id,
"COUNTRY_NAME" => $country_name,
"CITY_NAME" => $city_name,
"COUNTRY_LID" => "ru",
"CITY_LID" => "ru",
);
// убираем ключи с пустыми значениями
foreach($arFilter as $key=>$value)
{
if(!$value)
unset($arFilter[$key]);
}
/* -------------------------------------- */
CModule::IncludeModule("sale");
// собственно сама выборка, можно выбрать все что угодно.
$rsData = CSaleLocation::GetList(
array(
"SORT" => "ASC",
"COUNTRY_NAME_LANG" => "DESC",
"CITY_NAME_LANG" => "ASC"
),
$arFilter,
false,
false,
array()
);
/* -------------------------------------- */
// постраничная навигация
$rsData = new CAdminResult($rsData, $sTableID);
$rsData->NavStart();
$lAdmin->NavText($rsData->GetNavPrint(GetMessage("PAGES")));
// добавляем заголовки
$lAdmin->AddHeaders(array(
array("id"=>"ID", "content"=>"ID", "sort"=>"id", "default"=>true),
array("id"=>"COUNTRY_NAME", "content"=>"Страна", "sort"=>"id", "default"=>true),
array("id"=>"CITY_ID", "content"=>"CITY_ID", "sort"=>"city_id", "default"=>true),
array("id"=>"CITY_NAME", "content"=>"Название", "sort"=>"name", "default"=>true),
));
// рисуем таблицу с результатами выборки
while($arRes = $rsData->GetNext())
{
$f_ID = $arRes['ID'];
$row =& $lAdmin->AddRow($f_ID, $arRes);
$row->AddViewField("ID", $f_ID);
$row->AddViewField("COUNTRY_NAME_ORIG", $arRes["COUNTRY_NAME"]);
$row->AddViewField("CITY_ID", $arRes["CITY_ID"]);
$row->AddViewField("NAME", $arRes["CITY_NAME"]);
$arActions = array();
$arActions[] = array(
"ICON"=>"",
"TEXT"=>"Выбрать",
"DEFAULT"=>true,
"ACTION"=>"SetValue('".$arRes["ID"]."','".$arRes["CITY_NAME"]."');"
);
$row->AddActions($arActions);
}
$lAdmin->AddFooter(
array(
array("title"=>GetMessage("MAIN_ADMIN_LIST_SELECTED"), "value"=>$rsData->SelectedRowsCount()),
array("counter"=>true, "title"=>GetMessage("MAIN_ADMIN_LIST_CHECKED"), "value"=>"0"),
)
);
$lAdmin->AddAdminContextMenu(array());
$lAdmin->CheckListMode();
$APPLICATION->SetTitle(GetMessage("MAIN_PAGE_TITLE"));
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_popup_admin.php")
?>
<script language="JavaScript">
<!--
function SetValue(id, name)
{
<?if ($JSFUNC <> ''){?>
window.opener.SUV<?=$JSFUNC?>(id);
<?}else{?>
window.opener.document.<?echo $FN;?>["<?echo $FC;?>"].value=id;
window.opener.document.getElementById('div_<?echo $FC;?>').innerHTML= name;
window.close();
<?}?>
}
//-->
</script>
<form name="find_form" method="GET" action="<?echo $APPLICATION->GetCurPage()?>?">
<?
// рисуем табличку фиьтра
$oFilter = new CAdminFilter(
$sTableID."_filter",
array(
"ID",
"CITY_ID",
"Страна",
"Город",
)
);
$oFilter->Begin();
?>
<tr>
<td><b>Найти:</b></td>
<td>Название</td>
<td><input type="text" name="city_name" size="47" value="<?echo htmlspecialchars($city_name)?>"></td>
</tr>
<tr>
<td></td>
<td>ID</td>
<td><input type="text" name="id" size="47" value="<?echo htmlspecialchars($id)?>"></td>
</tr>
<tr>
<td></td>
<td>CITY_ID</td>
<td><input type="text" name="city_id" size="47" value="<?echo htmlspecialchars($city_id)?>"></td>
</tr>
<tr>
<td></td>
<td>Страна</td>
<td><input type="text" name="country_name" size="47" value="<?echo htmlspecialchars($country_name)?>"></td>
</tr>
<input type="hidden" name="FN" value="<?echo htmlspecialchars($FN)?>">
<input type="hidden" name="FC" value="<?echo htmlspecialchars($FC)?>">
<input type="hidden" name="JSFUNC" value="<?echo htmlspecialchars($JSFUNC)?>">
<?
$oFilter->Buttons(array("table_id"=>$sTableID, "url"=>$APPLICATION->GetCurPage(), "form"=>"find_form"));
$oFilter->End();
?>
</form>
<?
//
$lAdmin->DisplayList();
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_popup_admin.php");
?>
|
Форму редактирования значения свойства мы создали, осталось зоздать само свойство, в init.php добавляем свойство:
<?
class Yenisite_RegionSelector
{
function GetUserTypeDescription()
{
return array(
"PROPERTY_TYPE" => "S",
"USER_TYPE" => "CIBlock_types",
"DESCRIPTION" => 'Привязка к местоположению',
"GetPropertyFieldHtml" => Array("Yenisite_RegionSelector", "GetPropertyFieldHtml"),
"ConvertToDB" => Array("Yenisite_RegionSelector", "ConvertToDB"),
"ConvertFromDB" => Array("Yenisite_RegionSelector", "ConvertFromDB"),
"GetAdminListViewHTML" => array("Yenisite_RegionSelector", "GetAdminListViewHTML")
);
}
function GetPropertyFieldHtml($arProperty, $value, $strHTMLControlName)
{
// если значение установлено, делаем выборку местоположения, чтобы вывести название города
if($value["VALUE"])
{
CModule::IncludeModule("sale");
$arFilter = Array(
"ID" => $value["VALUE"],
"COUNTRY_LID" => "ru",
"CITY_LID" => "ru",
);
$rsData = CSaleLocation::GetList(
array(
"SORT" => "ASC",
"COUNTRY_NAME_LANG" => "DESC",
"CITY_NAME_LANG" => "ASC"
),
$arFilter,
false,
false,
array("CITY_NAME", "COUNTRY_NAME")
);
$location = $rsData->GetNext();
}
/*
дальше для каждого поля ввода выводим функцию которая будет открывать окно с нашей формой построенной в файле location.php, функция заимствована у товарища Битрикса
*/
$function_name = str_replace('[','xx',$strHTMLControlName['VALUE']); //заменяем квадратные скобочки, чтобы их небыло в имени функции
$function_name = str_replace(']','xx',$function_name);
$html = "<script>function open_win_".$function_name."(){ window.open('/bitrix/admin/location_search.php?lang=ru&FN=". $strHTMLControlName['FORM_NAME']."&FC=".$strHTMLControlName['VALUE']."', '', 'scrollbars=yes,resizable=yes,width=760,height=500,top='+Math.floor((screen.height - 560)/2-14)+',left='+Math.floor((screen.width - 760)/2-5));}</script>";
// выводим input с id местоположения и рядом подпись в виде названия города
$html .= '<input type="text" name="'.$strHTMLControlName['VALUE'].'" id="'.$strHTMLControlName['VALUE'].'" value="'.$value["VALUE"].'" /><input class="tablebodybutton" type="button" OnClick="open_win_'.$function_name.'()" value="..."> <span id="div_'.$strHTMLControlName['VALUE'].'">';
// проверяем если названия города нет - пишем название страны
if($location["CITY_NAME"])
$html .= $location["CITY_NAME"];
else
$html .= $location["COUNTRY_NAME"];
$html .= '</span>';
return $html;
}
function GetAdminListViewHTML($arProperty, $value, $strHTMLControlName)
{
// вывод местоположений в удобочитаемом виде в списке элементов. со ссылкой на редактирование местоположения
if($value["VALUE"])
{
CModule::IncludeModule("sale");
$arFilter = Array(
"ID" => $value["VALUE"],
"COUNTRY_LID" => "ru",
"CITY_LID" => "ru",
);
$rsData = CSaleLocation::GetList(
array(
"SORT" => "ASC",
"COUNTRY_NAME_LANG" => "DESC",
"CITY_NAME_LANG" => "ASC"
),
$arFilter,
false,
false,
array("CITY_NAME", "COUNTRY_NAME", "ID")
);
$location = $rsData->GetNext();
return $location["CITY_NAME"]."[<a href='/bitrix/admin/sale_location_edit.php?ID=".$location["ID"]."'>".$location["ID"]."</a>]";
}
return;
}
function ConvertToDB($arProperty, $value)
{
return $value;
}
function ConvertFromDB($arProperty, $value)
{
return $value;
}
}
// регистрируем свойство
AddEventHandler("iblock", "OnIBlockPropertyBuildList", Array("Yenisite_RegionSelector", "GetUserTypeDescription"));
?>
|
вот что вышло в итоге:

При двойном клике на любую запись, ее ID вставляется в поле свойства и название города припысывается рядом.
А вот как это свойство выглядит в списке:

Извиняюсь за скудность комментариев в коде. Не люблю я их писать, темболее пятница, рабочий день закончился, а я еще тут.
Всем удачных выходных, по донедельника!