Здраствуйте!
Сегодня решал следующую задачу:
Необходимо создать пользовательское свойство привязки элемента инфоблока к местоположениям из интернет-магазина. Зачем нужна такая привязка я вдаваться в подробности не буду, а покажу как можно сделать привязку к любой выборке из базы данных, которая содержит большое количество записей и не может быть размещена в выпадающем списке. Список местоположений содержит более 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 вставляется в поле свойства и название города припысывается рядом.
А вот как это свойство выглядит в списке:

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