Sfoglia il codice sorgente

Ticket #4575 - Events: Enhancements. Point 5.

AntonLV 2 anni fa
parent
commit
7dd49b037d

+ 15 - 4
inc/classes/BxDolSearch.php

@@ -522,17 +522,19 @@ class BxDolSearchResult implements iBxDolReplaceable
      */
     function processing ()
     {
-        if (defined('BX_API')) {
-            return $this->processingAPI ();
+        if (bx_is_api()) {
+            return $this->processingAPI();
         }
 
         $sCode = $this->displayResultBlock();
         if ($this->aCurrent['paginate']['num'] > 0) {
             $sPaginate = $this->showPagination();
             $sCode = $this->displaySearchBox($sCode, $sPaginate);
-        } else {
-            $sCode = $this->bDisplayEmptyMsg ? $this->displaySearchBox(MsgBox(_t($this->sDisplayEmptyMsgKey ? $this->sDisplayEmptyMsgKey : '_Empty'))) : '';
         }
+        else {
+            $sCode = $this->bDisplayEmptyMsg ? $this->displaySearchBox($this->displayResultBlockEmpty()) : '';
+        }
+
         return $sCode;
     }
 
@@ -597,6 +599,15 @@ class BxDolSearchResult implements iBxDolReplaceable
         return $sCode;
     }
 
+    /**
+     * Get html output of empty search result
+     * @return html code
+     */
+    function displayResultBlockEmpty ()
+    {
+        return MsgBox(_t($this->sDisplayEmptyMsgKey ? $this->sDisplayEmptyMsgKey : '_Empty'));
+    }
+            
     /**
      * Add different code before html output (usually redeclared)
      * no return result

+ 11 - 10
inc/js/jquery.dolPopup.js

@@ -245,21 +245,22 @@
                 }
 
                 setTimeout(function () {
-                	// Don't should popup with pointer if there is no parent. Checking after showing.
-                        if(typeof o.pointer.el == 'string')
-                            o.pointer.el = $(o.pointer.el);
+                    // Don't should popup with pointer if there is no parent. Checking after showing.
+                    if(typeof o.pointer.el == 'string')
+                        o.pointer.el = $(o.pointer.el);
 
-                	if($(o.pointer.el).length > 0 && !$.contains(document, o.pointer.el[0])) {
-                		$el.remove();
-                		return;
-                	}
+                    if($(o.pointer.el).length > 0 && !$.contains(document, o.pointer.el[0])) {
+                        $el.remove();
+                        return;
+                    }
 
-                	if(typeof(o.onShow) == 'function')
-                		o.onShow($el);
+                    if(typeof(o.onShow) == 'function')
+                        o.onShow($el);
                     else if(typeof(o.onShow) == 'string')
                     	eval(o.onShow);
+                    else
+                        $el.find('input[type=text]:first').focus(); //NOTE. Put cursor to the first input element, ONLY IF there is no any custom behaviour for onShow event.
 
-                    $el.find('input[type=text]:first').focus(); // put cursor to the first input element
                 }, o.speed);
 
             }, 100);

+ 64 - 0
modules/base/general/classes/BxBaseModGeneralModule.php

@@ -25,6 +25,8 @@ class BxBaseModGeneralModule extends BxDolModule
     protected $_aSearchableNamesExcept;
     protected $_aFormParams;
 
+    protected $_aBrowsingFiltersKeys;
+
     function __construct(&$aModule)
     {
         parent::__construct($aModule);
@@ -44,6 +46,8 @@ class BxBaseModGeneralModule extends BxDolModule
             'context_id' => 0,
             'custom' => array()
         );
+
+        $this->_aBrowsingFiltersKeys = ['mode'];
     }
 
     // ====== ACTIONS METHODS
@@ -298,6 +302,66 @@ class BxBaseModGeneralModule extends BxDolModule
         echo(json_encode($a));
     }
 
+    public function actionGetBrowsingFilters()
+    {
+        $aParams = $this->_prepareBrowsingFiltersParamsGet();
+
+        $sContent = $this->_oTemplate->getBrowsingFilters($aParams);
+        if(empty($sContent))
+            return echoJson([]);
+
+        echoJson([
+            'code' => 0,
+            'popup' => [
+                'html' => $sContent,
+                'options' => [
+                    'closeOnOuterClick' => false,
+                    'removeOnClose' => false,
+                ]
+            ],
+        ]);
+    }
+
+    public function actionApplyBrowsingFilters()
+    {
+        $aParams = $this->_prepareBrowsingFiltersParamsGet();
+
+        $aBrowseParams = ['mode' => $aParams['mode'], 'empty_message' => true];
+        unset($aParams['mode']);
+        $aBrowseParams['params'] = $aParams;
+
+        $mixedResult = $this->serviceBrowse($aBrowseParams);
+        if(empty($mixedResult))
+            return echoJson([]);
+
+        if(is_array($mixedResult) && isset($mixedResult['content']))
+            $mixedResult = $mixedResult['content'];
+
+        return echoJson([
+            'code' => 0, 
+            'content' => $mixedResult, 
+            'eval' => $this->_oConfig->getJsObject('main') . '.onApplyBrowsingFilter(oData)'
+        ]);
+    }
+
+    protected function _prepareBrowsingFiltersParamsGet($mParams = false)
+    {
+        $aParams = [];
+        $bParams = !empty($mParams) && is_array($mParams);
+
+        foreach($this->_aBrowsingFiltersKeys as $sKey)
+            if($bParams) {
+                if(isset($mParams[$sKey]))
+                    $aParams[$sKey] = $mParams[$sKey];
+            }
+            else {
+                if(($sValue = bx_get($sKey)) !== false)
+                    $aParams[$sKey] = $sValue;
+            }
+
+        return $aParams;
+    }
+
     // ====== SERVICE METHODS
 
     public function serviceIsBadgesAvaliable()

+ 20 - 0
modules/base/general/classes/BxBaseModGeneralSearchResult.php

@@ -218,6 +218,26 @@ class BxBaseModGeneralSearchResult extends BxTemplSearchResult
         return parent::displayResultBlock();
     }
 
+    function displaySearchBox ($sContent, $sPaginate = '')
+    {
+        $aResult = parent::displaySearchBox($sContent, $sPaginate = '');
+
+        if(isset($this->_aParams['filters']) && is_array($this->_aParams['filters']))
+            $aResult['buttons'] = [
+                ['title' => _t('_Filters'), 'href' => 'javascript:void(0)', 'onclick' => 'javascript:' . $this->_aParams['filters']['onclick']]
+            ];
+
+        return $aResult;
+    }
+
+    function applyContainerId()
+    {
+        if(empty($this->aCurrent['name']) || empty($this->_sMode))
+            return parent::applyContainerId();
+
+        return str_replace('_', '-', $this->aCurrent['name'] . '-search-result-block-' . $this->_sMode);
+    }
+
     function decodeDataAPI($a)
     {
         $bExtendedUnits = getParam('sys_api_extended_units') == 'on';

+ 17 - 1
modules/base/general/classes/BxBaseModGeneralTemplate.php

@@ -363,7 +363,23 @@ class BxBaseModGeneralTemplate extends BxDolModuleTemplate
         
         return $this->parseHtmlByName('favorite-list-info.html', array('bx_repeat:items' => $aListsTmpl, 'author' => $oProfile->getUnit()));
     }
-    
+
+    public function getBrowsingFilters($aParams)
+    {
+        if(empty($aParams['mode']))
+            return '';
+
+        $sContent = $this->_getBrowsingFiltersContent($aParams);
+        if(empty($sContent))
+            return '';
+
+        $sPopupId = $this->_oConfig->getHtmlIds('popup_bfilters_' . $aParams['mode']);
+        $sPopupContent = $this->parseHtmlByName('browsing_filters.html', [
+            'content' => $sContent
+    	]);
+
+    	return BxTemplFunctions::getInstance()->transBox($sPopupId, $sPopupContent, true);
+    }
 
     function entryAllActions($sActions)
     {

+ 3 - 0
modules/base/general/template/browsing_filters.html

@@ -0,0 +1,3 @@
+<div class="bx-base-general-browsing-filters">
+    <div class="bx-base-general-browsing-filters-cnt bx-def-padding">__content__</div>
+</div>

+ 72 - 0
modules/base/groups/js/main.js

@@ -18,8 +18,80 @@ function BxBaseModGroupsMain(oOptions) {
     this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
 
     this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+
+    this._oBrowsingFiltersPopupOptions = {};
+    this._oBrowsingFiltersPopupOptionsDefaults = {};
 }
 
+BxBaseModGroupsMain.prototype.changeBrowsingFilters = function(oElement, sSelector, oRequestParams) {
+    if($(sSelector).length)
+        return $(sSelector).dolPopup(this._oBrowsingFiltersPopupOptions);
+
+    var $this = this;
+    var oData = jQuery.extend({mode: ''}, this._getDefaultData());
+    if(oRequestParams != undefined)
+        oData = jQuery.extend({}, oData, oRequestParams);
+
+    this.loadingInButton(oElement, true);
+
+    jQuery.get (
+        this._sActionsUrl + 'get_browsing_filters',
+        oData,
+        function(oResponse) {
+            if(oElement)
+                $this.loadingInButton(oElement, false);
+
+            if(oResponse && oResponse.popup != undefined) {
+                $this._oBrowsingFiltersPopupOptions = jQuery.extend($this._oBrowsingFiltersPopupOptionsDefaults, oResponse.popup.options, {
+                    pointer: { 
+                        el: $(oElement),
+                        align: 'right'
+                    }
+                });
+
+                oResponse.popup.options = $this._oBrowsingFiltersPopupOptions;
+            }
+
+            processJsonData(oResponse);
+        },
+        'json'
+    );
+};
+
+BxBaseModGroupsMain.prototype.applyBrowsingFilter = function(oElement, oRequestParams) {
+    var $this = this;
+
+    var oData = this._getDefaultData();
+    if(oRequestParams != undefined)
+        oData = jQuery.extend({}, oData, oRequestParams);
+
+    this.loadingInButton(oElement, true);
+
+    jQuery.get (
+        this._sActionsUrl + 'apply_browsing_filters',
+        oData,
+        function(oResponse) {
+            $this.loadingInButton(oElement, false);
+
+            $(oElement).parents('.bx-popup-applied:visible:first').dolPopupHide();
+
+            processJsonData(oResponse);
+        },
+        'json'
+    );
+};
+
+BxBaseModGroupsMain.prototype.onApplyBrowsingFilter = function(oData) {
+    if(!oData.content)
+        return;
+
+    var oContainer = $('.bx-db-content').has('#' + $(oData.content).find('.bx-search-result-block:first').attr('id'));
+    if(!oContainer || oContainer.length == 0)
+        return;
+
+    oContainer.html(oData.content).bxProcessHtml();
+};
+
 BxBaseModGroupsMain.prototype.connAction = function(oElement, sObject, sAction, iContentId) {
     var $this = this;
     var oParams = this._getDefaultData();

+ 5 - 4
modules/boonex/english/data/langs/system/en.xml

@@ -49,13 +49,14 @@
 	<string name="_favorite_err_duplicate_favorite"><![CDATA[You already favorited this item.]]></string>
 	<string name="_favorite_err_not_enabled"><![CDATA[The feature is not available right now. Please, try again later.]]></string>
 	<string name="_feature_do_feature"><![CDATA[Feature]]></string>
-    <string name="_feature_do_unfeature"><![CDATA[Unfeature]]></string>
-    <string name="_feature_err_cannot_perform_action"><![CDATA[Cannot perform the action.]]></string>
-    <string name="_feature_err_duplicate_feature"><![CDATA[The item was already added in featured list.]]></string>
-    <string name="_feature_err_not_enabled"><![CDATA[The feature is not available right now. Please, try again later.]]></string>
+        <string name="_feature_do_unfeature"><![CDATA[Unfeature]]></string>
+        <string name="_feature_err_cannot_perform_action"><![CDATA[Cannot perform the action.]]></string>
+        <string name="_feature_err_duplicate_feature"><![CDATA[The item was already added in featured list.]]></string>
+        <string name="_feature_err_not_enabled"><![CDATA[The feature is not available right now. Please, try again later.]]></string>
 	<string name="_Female"><![CDATA[Woman]]></string>
         <string name="_free"><![CDATA[free]]></string>
 	<string name="_From"><![CDATA[From]]></string>
+        <string name="_Filters"><![CDATA[Filters]]></string>
 	<string name="_Header"><![CDATA[Header]]></string>
 	<string name="_Incorrect Captcha"><![CDATA[Incorrect Captcha]]></string>
 	<string name="_Incorrect Email"><![CDATA[Incorrect Email]]></string>

+ 1 - 0
modules/boonex/events/classes/BxEventsConfig.php

@@ -319,6 +319,7 @@ class BxEventsConfig extends BxBaseModGroupsConfig
 
         $sHtmlPrefix = str_replace('_', '-', $this->_sName);
         $this->_aHtmlIds = array_merge($this->_aHtmlIds, [
+            'popup_bfilters_recent' => $sHtmlPrefix . '-popup-bfilters-recent',
             'popup_question' => $sHtmlPrefix . '-popup-question',
             'popup_questionnaire' => $sHtmlPrefix . '-popup-questionnaire',
             'popup_session' => $sHtmlPrefix . '-popup-session'

+ 20 - 3
modules/boonex/events/classes/BxEventsModule.php

@@ -19,13 +19,18 @@ class BxEventsModule extends BxBaseModGroupsModule implements iBxDolCalendarServ
     function __construct(&$aModule)
     {
         parent::__construct($aModule);
-        
+
         $CNF = &$this->_oConfig->CNF;
-        $this->_aSearchableNamesExcept = array_merge($this->_aSearchableNamesExcept, array(
+
+        $this->_aSearchableNamesExcept = array_merge($this->_aSearchableNamesExcept, [
             $CNF['FIELD_TIMEZONE'],
             $CNF['FIELD_JOIN_CONFIRMATION'],
             $CNF['FIELD_REMINDER']
-        ));
+        ]);
+
+        $this->_aBrowsingFiltersKeys = array_merge($this->_aBrowsingFiltersKeys, [
+            'by_date', 'date_start', 'date_end'
+        ]);
     }
 
     public function actionCheckIn()
@@ -409,6 +414,18 @@ class BxEventsModule extends BxBaseModGroupsModule implements iBxDolCalendarServ
         return $this->_serviceBrowse ('upcoming_connected', array_merge($aDefaults, $aParams), BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
     }
 
+    public function serviceBrowseRecentProfiles ($bDisplayEmptyMsg = false, $bAjaxPaginate = true)
+    {
+        $sMode = 'recent';
+
+        $sFilterSelector = '#' . $this->_oConfig->getHtmlIds('popup_bfilters_recent');
+        $aFilterParams = ['mode' => $sMode];
+
+        return $this->_serviceBrowse ($sMode, [
+            'filters' => ['onclick' => $this->_oConfig->getJsObject('main') . ".changeBrowsingFilters(this, '" . $sFilterSelector . "', " . json_encode($aFilterParams) . ")"]
+        ], BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
+    }
+
     /**
      * @page service Service Calls
      * @section bx_events Events

+ 61 - 0
modules/boonex/events/classes/BxEventsSearchResult.php

@@ -83,6 +83,67 @@ class BxEventsSearchResult extends BxBaseModGroupsSearchResult
         $oJoinedProfile = null;
         $bProcessConditionsForPrivateContent = true;
 
+        $iDateStart = $iDateEnd = 0;
+        if(isset($this->_aParams['by_date'])) {
+            switch($this->_aParams['by_date']) {
+                case 'today':
+                    $iDateStart = gmmktime(0, 0, 0, date("m"), date("d"), date("Y"));
+                    $iDateEnd = $iDateStart + 86399;
+                    break;
+
+                case 'tomorrow':
+                    $iDateStart = gmmktime(0, 0, 0, date("m"), date("d") + 1, date("Y"));
+                    $iDateEnd = $iDateStart + 86399;
+                    break;
+
+                case 'weekend':
+                    $iDayOfWeek = date("w");
+                    $iDateStart = gmmktime(0, 0, 0, date("m"), date("d") + ($iDayOfWeek > 0 ? 6 - $iDayOfWeek : -1), date("Y"));
+                    $iDateEnd = $iDateStart + 2 * 86400 - 1;
+                    break;
+
+                case 'this_week':
+                    $iDayOfWeek = date("w");
+                    $iDateStart = gmmktime(0, 0, 0, date("m"), date("d") - ($iDayOfWeek > 0 ? $iDayOfWeek - 1 : 6), date("Y"));
+                    $iDateEnd = $iDateStart + 7 * 86400 - 1;
+                    break;
+
+                case 'next_week':
+                    $iDayOfWeek = date("w");
+                    $iDateStart = gmmktime(0, 0, 0, date("m"), date("d") + ($iDayOfWeek > 0 ? 8 - $iDayOfWeek : 1), date("Y"));
+                    $iDateEnd = $iDateStart + 7 * 86400 - 1;
+                    break;
+
+                case 'this_month':
+                    $iDateStart = gmmktime(0, 0, 0, date("m"), 1, date("Y"));
+                    $iDateEnd = gmmktime(23, 59, 59, date("m") + 1, 0, date("Y"));
+                    break;
+
+                case 'date_range':
+                    if(!empty($this->_aParams['date_start'])) {
+                        list($iDsy, $iDsm, $iDsd,) = explode('-', $this->_aParams['date_start']);
+                        $iDateStart = gmmktime(0, 0, 0, $iDsm, $iDsd, $iDsy);
+                    }
+                    else
+                        $iDateStart = gmmktime(0, 0, 0, date("m"), date("d"), date("Y"));
+
+                    if(!empty($this->_aParams['date_end'])) {
+                        list($iDey, $iDem, $iDed,) = explode('-', $this->_aParams['date_end']);
+                        $iDateEnd = gmmktime(23, 59, 59, $iDem, $iDed, $iDey);
+                    }
+                    else
+                        $iDateEnd = gmmktime(23, 59, 59, date("m"), date("d"), date("Y"));
+                    break;
+            }
+
+            if($iDateStart != 0 && $iDateEnd != 0) {
+                //--- 1. already started or will start in selected date interval
+                $this->aCurrent['restriction']['filter_date_start'] = ['value' => $iDateEnd, 'field' => 'date_start', 'operator' => '<', 'table' => 'bx_events_data'];
+                //--- 2. and didn't finished to the beginning of selected date interval
+                $this->aCurrent['restriction']['filter_date_end'] = ['value' => $iDateStart, 'field' => 'date_end', 'operator' => '>', 'table' => 'bx_events_data'];
+            }
+        }
+
         switch ($sMode) {
             case 'created_entries':
                 if(!$this->_setAuthorConditions($sMode, $aParams, $oJoinedProfile)) {

+ 64 - 0
modules/boonex/events/classes/BxEventsTemplate.php

@@ -84,6 +84,70 @@ class BxEventsTemplate extends BxBaseModGroupsTemplate
 			'date_end_f' => $oDateEnd ? bx_time_js($oDateEnd->getTimestamp(), BX_FORMAT_DATE_TIME, true) : '',
         ));
     }
+
+    protected function _getBrowsingFiltersContent($aParams)
+    {
+        $sJsObject = $this->_oConfig->getJsObject('main');
+
+        $sMode = $aParams['mode'];
+
+        $aForm = [
+            'inputs' => [
+                'by_date' => [
+                    'name' => 'by_date',
+                    'type' => 'radio_set',
+                    'caption' => _t('_bx_events_form_filters_input_by_date'),
+                    'values' => [
+                        ['key' => 'all', 'value' => _t('_bx_events_form_filters_input_by_date_all')],
+                        ['key' => 'today', 'value' => _t('_bx_events_form_filters_input_by_date_today')],
+                        ['key' => 'tomorrow', 'value' => _t('_bx_events_form_filters_input_by_date_tomorrow')],
+                        ['key' => 'weekend', 'value' => _t('_bx_events_form_filters_input_by_date_weekend')],
+                        ['key' => 'this_week', 'value' => _t('_bx_events_form_filters_input_by_date_this_week')],
+                        ['key' => 'next_week', 'value' => _t('_bx_events_form_filters_input_by_date_next_week')],
+                        ['key' => 'this_month', 'value' => _t('_bx_events_form_filters_input_by_date_this_month')],
+                        ['key' => 'date_range', 'value' => _t('_bx_events_form_filters_input_by_date_date_range')],
+                        
+                    ],
+                    'value' => 'all',
+                    'attrs' => ['onchange' => $sJsObject . '.onChangeBrowsingFiltersByDate(this)'],
+                    'dv_thd' => 1
+                ],
+                'date_start' => [
+                    'name' => 'date_start',
+                    'type' => 'datepicker',
+                    'tr_attrs' => ['class' => 'date-range date-start', 'style' => 'display:none']
+                ],
+                'date_end' => [
+                    'name' => 'date_end',
+                    'type' => 'datepicker',
+                    'tr_attrs' => ['class' => 'date-range date-end', 'style' => 'display:none']
+                ],
+                'controls' => [
+                    'name' => 'controls',
+                    'type' => 'input_set',
+                    [
+                        'name' => 'apply',
+                        'type' => 'button',
+                        'value' => _t('_bx_events_form_filters_input_do_apply'),
+                        'attrs' => ['onclick' => $sJsObject . '.applyBrowsingFilter(this, ' . json_encode($aParams) . ')']
+                    ], [
+                        'name' => 'cancel',
+                        'type' => 'button',
+                        'value' => _t('_Cancel'),
+                        'attrs' => [
+                            'class' => 'bx-def-margin-sec-left',
+                            'onclick' => "$('.bx-popup-applied:visible').dolPopupHide()"
+                        ]
+                    ],
+                    
+                ],
+                
+            ]
+        ];
+
+        $oForm = new BxTemplFormView($aForm);
+        return $oForm->getCode(true);
+    }
 }
 
 /** @} */

+ 12 - 0
modules/boonex/events/install/langs/en.xml

@@ -152,6 +152,18 @@
     <string name="_bx_events_form_price_input_sys_do_cancel"><![CDATA[Cancel]]></string>
     <string name="_bx_events_form_price_input_do_cancel"><![CDATA[Cancel]]></string>
 
+    <string name="_bx_events_form_filters_input_by_date"><![CDATA[By date]]></string>
+    <string name="_bx_events_form_filters_input_by_date_all"><![CDATA[Any date]]></string>
+    <string name="_bx_events_form_filters_input_by_date_today"><![CDATA[Today]]></string>
+    <string name="_bx_events_form_filters_input_by_date_tomorrow"><![CDATA[Tomorrow]]></string>
+    <string name="_bx_events_form_filters_input_by_date_weekend"><![CDATA[This weekend]]></string>
+    <string name="_bx_events_form_filters_input_by_date_this_week"><![CDATA[This week]]></string>
+    <string name="_bx_events_form_filters_input_by_date_next_week"><![CDATA[Next week]]></string>
+    <string name="_bx_events_form_filters_input_by_date_this_month"><![CDATA[This month]]></string>
+    <string name="_bx_events_form_filters_input_by_date_date_range"><![CDATA[Custom date range]]></string>
+    <string name="_bx_events_form_filters_input_do_apply"><![CDATA[Apply]]></string>
+
+
     <string name="_bx_events_acl_action_create_profile"><![CDATA[Create Event]]></string>
     <string name="_bx_events_acl_action_use_paid_join"><![CDATA[Use paid join]]></string>
     <string name="_bx_events_acl_action_delete_profile"><![CDATA[Delete Event]]></string>

+ 30 - 1
modules/boonex/events/js/main.js

@@ -10,11 +10,40 @@
 
 function BxEventsMain(oOptions) {
     BxBaseModGroupsMain.call(this, oOptions);
-    
+
     this._sObjName = oOptions.sObjName == undefined ? 'oBxEventsMain' : oOptions.sObjName;
+
+    this._oBrowsingFiltersPopupOptionsDefaults = jQuery.extend(this._oBrowsingFiltersPopupOptionsDefaults,  {
+        onShow: function(oPopup) {
+            $(oPopup).find("[name = 'cancel']").focus();
+        }
+    });   
 }
 
 BxEventsMain.prototype = Object.create(BxBaseModGroupsMain.prototype);
 BxEventsMain.prototype.constructor = BxEventsMain;
 
+BxEventsMain.prototype.onChangeBrowsingFiltersByDate = function(oElement) {
+    var sAction = $(oElement).val() == 'date_range' ? 'show' : 'hide';
+
+    $(oElement).parents('.bx-form-element-wrapper:first').siblings('.date-range').each(function() {
+        $(this).bx_anim(sAction);
+    });
+};
+
+BxEventsMain.prototype.applyBrowsingFilter = function(oElement, oRequestParams)
+{
+    var oFilters = $(oElement).parents('.bx-base-general-browsing-filters:first');
+
+    if(oRequestParams == undefined)
+        oRequestParams = {};
+
+    oRequestParams.by_date = oFilters.find("input[name='by_date']:checked").val();
+    if(oRequestParams.by_date == 'date_range') {
+        oRequestParams.date_start = oFilters.find("input[name='date_start']").val();
+        oRequestParams.date_end = oFilters.find("input[name='date_end']").val();
+    }
+
+    BxBaseModGroupsMain.prototype.applyBrowsingFilter.call(this, oElement, oRequestParams);
+};
 /** @} */

+ 6 - 5
modules/boonex/russian/data/langs/system/ru.xml

@@ -46,14 +46,15 @@
 	<string name="_favorite_err_cannot_perform_action"><![CDATA[Невозможно выполнить действие.]]></string>
 	<string name="_favorite_err_duplicate_favorite"><![CDATA[Вы уже добавляли данный объект в избранное ранее.]]></string>
 	<string name="_favorite_err_not_enabled"><![CDATA[Действие не доступно в данный момент. Пожалуйста, попробуйте позднее.]]></string>
-    <string name="_feature_do_feature"><![CDATA[В продвинутые]]></string>
-    <string name="_feature_do_unfeature"><![CDATA[Из продвинутых]]></string>
-    <string name="_feature_err_cannot_perform_action"><![CDATA[Невозможно выполнить действие.]]></string>
-    <string name="_feature_err_duplicate_feature"><![CDATA[Данный объект уже добавлен в список продвинутых.]]></string>
-    <string name="_feature_err_not_enabled"><![CDATA[Действие не доступно в данный момент. Пожалуйста, попробуйте позднее.]]></string>
+        <string name="_feature_do_feature"><![CDATA[В продвинутые]]></string>
+        <string name="_feature_do_unfeature"><![CDATA[Из продвинутых]]></string>
+        <string name="_feature_err_cannot_perform_action"><![CDATA[Невозможно выполнить действие.]]></string>
+        <string name="_feature_err_duplicate_feature"><![CDATA[Данный объект уже добавлен в список продвинутых.]]></string>
+        <string name="_feature_err_not_enabled"><![CDATA[Действие не доступно в данный момент. Пожалуйста, попробуйте позднее.]]></string>
 	<string name="_Female"><![CDATA[Женщина]]></string>
         <string name="_free"><![CDATA[бесплатно]]></string>
 	<string name="_From"><![CDATA[От]]></string>
+        <string name="_Filters"><![CDATA[Фильтры]]></string>
 	<string name="_Header"><![CDATA[Заголовок]]></string>
 	<string name="_Incorrect Captcha"><![CDATA[Неправильная капча]]></string>
 	<string name="_Incorrect Email"><![CDATA[Введите правильный адрес электронной почты]]></string>

+ 24 - 1
template/scripts/BxBaseSearchResult.php

@@ -59,7 +59,7 @@ class BxBaseSearchResult extends BxDolSearchResult
             foreach ($aData as $aValue)
                 $sCode .= $this->displaySearchUnit($aValue);
 
-            $sHtmlId = 'bx-search-result-block-' . rand(0, PHP_INT_MAX);
+            $sHtmlId = $this->applyContainerId();
             $sClasses = $this->applyContainerClass();
 
             $sAttributes = '';
@@ -91,6 +91,20 @@ class BxBaseSearchResult extends BxDolSearchResult
         return $sCode;
     }
 
+    function displayResultBlockEmpty ()
+    {
+        return BxDolTemplate::getInstance()->parseHtmlByName('search_result_block.html', [
+            'html_id' => $this->applyContainerId(),
+            'class' => 'bx-search-result-block bx-search-result-block-empty',
+            'attrs' => '',
+            'content' => parent::displayResultBlockEmpty(),
+            'bx_if:do_center' => [
+                'condition' => false,
+                'content' => []
+            ]
+        ]);
+    }
+
     function displaySearchBox ($sContent, $sPaginate = '')
     {
 		$sContent = BxDolTemplate::getInstance()->parseHtmlByName('paginate_block.html', array(
@@ -369,6 +383,15 @@ class BxBaseSearchResult extends BxDolSearchResult
         $this->sCenterContentUnitSelector = $s;
     }
 
+    /**
+     * Add ID to search result container 
+     * @param $string HTML ID
+     */
+    function applyContainerId()
+    {
+        return 'bx-search-result-block-' . rand(0, PHP_INT_MAX);
+    }
+
     /**
      * Add class to search result container 
      * @param $mixed CSS class name string or array of classes