1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-06-26 03:30:48 +03:00

Доработка компонентов

This commit is contained in:
Denis Shakhov 2014-10-09 23:17:36 +07:00
parent 6948e79d2d
commit 75f8bac631
23 changed files with 481 additions and 127 deletions

View file

@ -535,6 +535,7 @@ $config['head']['default']['js'] = array(
"___path.framework.frontend.web___/js/ui/alert.js",
"___path.framework.frontend.web___/js/ui/captcha.js",
/* LiveStreet */
"___path.skin.web___/components/dropdown/js/dropdown.js",
"___path.application.web___/frontend/common/js/favourite.js",
"___path.application.web___/frontend/common/js/favourite_topic.js",
"___path.application.web___/frontend/common/js/blocks.js",
@ -579,6 +580,7 @@ $config['head']['default']['js'] = array(
"___path.application.web___/frontend/common/js/search.js",
"___path.application.web___/frontend/common/js/more.js",
"___path.application.web___/frontend/common/js/init.js",
"___path.skin.web___/components/actionbar/js/actionbar-item-select.js",
"//yandex.st/share/share.js" => array('merge' => false),
);
@ -587,7 +589,7 @@ $config['head']['default']['css'] = array(
"___path.framework.frontend.web___/css/reset.css",
"___path.framework.frontend.web___/css/helpers.css",
"___path.framework.frontend.web___/css/text.css",
"___path.framework.frontend.web___/css/dropdowns.css",
"___path.skin.web___/components/dropdown/css/dropdown.css",
"___path.framework.frontend.web___/css/buttons.css",
"___path.framework.frontend.web___/css/forms.css",
"___path.framework.frontend.web___/css/navs.css",

View file

@ -1757,6 +1757,19 @@ return array(
'alphanumeric' => array(
'all' => 'Все'
),
/**
* Экшнбар
*/
'actionbar' => array(
'select' => array(
'title' => 'Выбрать',
'menu' => array(
'all' => 'Все',
'deselect' => 'Убрать выделение',
'invert' => 'Инвертировать',
),
),
),
/**
* Управление правами (RBAC)
*/

View file

@ -20,6 +20,24 @@ jQuery(document).ready(function($){
ls.dev.init();
/**
* Actionbar
*/
$('.js-talk-actionbar-select').lsActionbarItemSelect({
selectors: {
target_item: '.js-message-list-item'
}
});
$('.js-user-list-modal-actionbar').livequery(function () {
$( this ).lsActionbarItemSelect({
selectors: {
target_item: '.js-user-list-select .js-user-list-small-item'
}
});
});
/**
* Modals
*/
@ -36,7 +54,7 @@ jQuery(document).ready(function($){
* Dropdowns
*/
$('.js-dropdown-default').livequery(function () {
$(this).dropdown();
$(this).lsDropdown();
});
@ -399,30 +417,6 @@ jQuery(document).ready(function($){
$( $(this).data('button-submit-form') ).submit();
});
// Временный код экшнбара (кнопка выделения объектов)
// TODO: Перенести в виджет
$(document).on('click', 'li[data-select-item]', function (e) {
var oElement = $(this),
sItemSelector = $(this).data('select-item'),
sItemFilter = $(this).data('select-filter') || '*',
aItems = $( sItemSelector ),
aItemsFiltered = aItems.filter( sItemFilter ),
aCheckboxes = aItems.find('input[type=checkbox]');
aItems.removeClass('selected');
aCheckboxes.prop('checked', false);
aItemsFiltered.addClass('selected').find('input[type=checkbox]').prop('checked', true);
e.preventDefault();
});
$(document).on('click', '.js-message-list-item input[type=checkbox]', function (e) {
$(this).closest('.js-message-list-item').toggleClass('selected');
});
$(document).on('click', '.js-user-list-small-item input[type=checkbox]', function (e) {
$(this).closest('.js-user-list-small-item').toggleClass('selected');
});
// Хук конца инициализации javascript-составляющих шаблона
ls.hook.run('ls_template_init_end',[],window);
});

View file

@ -0,0 +1,35 @@
{**
* Экшнбар / Контрол выбора объектов
*
* @param string $target
*
* @extends {actionbar}/actionbar-item.tpl
*}
{extends './actionbar-item.tpl'}
{block 'actionbar_item'}
{$target = $smarty.local.target}
{* Дефолтные пункты меню *}
{$menu = [
[ 'name' => 'all', 'text' => {lang 'actionbar.select.menu.all'}, 'data' => [ 'select-item' => $target ] ],
[ 'name' => 'deselect', 'text' => {lang 'actionbar.select.menu.deselect'}, 'data' => [ 'select-item' => $target, 'select-filter' => ':not(*)' ] ],
[ 'name' => 'invert', 'text' => {lang 'actionbar.select.menu.invert'}, 'data' => [ 'select-item' => $target, 'select-filter' => ':not(.selected)' ] ],
[ 'name' => '-', 'is_enabled' => !! $smarty.local.items ]
]}
{* Добавляем кастомные пункты меню *}
{foreach $smarty.local.items as $item}
{$menu[] = [
'text' => $item['text'],
'data' => [ 'select-item' => $target, 'select-filter' => $item['filter'] ]
]}
{/foreach}
{* Выпадающее меню *}
{include 'components/dropdown/dropdown.tpl'
classes = "actionbar-item-link {$smarty.local.classes}"
text = {lang 'actionbar.select.title'}
menu = $menu}
{/block}

View file

@ -0,0 +1,18 @@
{**
* Кнопка экшнбара
*
* @param array $item Массив с опциями кнопки
*}
{$item = $smarty.local.item}
<li class="actionbar-item">
{block 'actionbar_item'}
{include 'components/button/button.tpl'
sUrl = $item['url']
sClasses = "actionbar-item-link {$item['classes']}"
sText = $item['text']
sIcon = $item['icon']
sAttributes = $item['attributes']}
{/block}
</li>

View file

@ -1,26 +0,0 @@
{**
* Экшнбар / Контрол выбора объектов
*}
{extends './actionbar.item.tpl'}
{block 'actionbar_item'}
{* Дефолтные пункты *}
{$_aItems = [
[ 'name' => 'all', 'text' => 'Все', 'attributes' => "data-select-item=\"{$sItemSelector}\"" ],
[ 'name' => 'deselect', 'text' => 'Убрать выделение', 'attributes' => "data-select-item=\"{$sItemSelector}\" data-select-filter=\":not(*)\"" ],
[ 'name' => 'invert', 'text' => 'Инвертировать', 'attributes' => "data-select-item=\"{$sItemSelector}\" data-select-filter=\":not(.selected)\"" ],
[ 'name' => '-', 'is_enabled' => !! $smarty.local.aItems ]
]}
{* Кастомные пункты *}
{foreach $smarty.local.aItems as $aItem}
{$_aItems[] = [ 'text'=> $aItem['text'], 'attributes' => "data-select-item=\"{$sItemSelector}\" data-select-filter=\"{$aItem['filter']}\"" ]}
{/foreach}
{include 'components/dropdown/dropdown.tpl'
sName = 'actionbar_item_select'
sClasses = 'actionbar-item-link'
sText = 'Выбрать'
aMenu = $_aItems}
{/block}

View file

@ -1,10 +0,0 @@
<li class="actionbar-item">
{block 'actionbar_item'}
{include 'components/button/button.tpl'
sUrl = $aItem['url']
sClasses = "actionbar-item-link {$aItem['classes']}"
sText = $aItem['text']
sIcon = $aItem['icon']
sAttributes = $aItem['attributes']}
{/block}
</li>

View file

@ -1,24 +1,22 @@
{**
* Экшнбар
*
* @param array $aItems Массив с кнопками
*
* @styles css/common.css
* @param array $items Массив с кнопками
*}
{* Название компонента *}
{$_sComponentName = 'actionbar'}
{$component = 'actionbar'}
{if $smarty.local.aItems}
<ul class="{$_sComponentName} clearfix {mod name=$_sComponentName mods=$smarty.local.sMods} {$smarty.local.sClasses}" {$smarty.local.sAttributes}>
{foreach $smarty.local.aItems as $aItem}
{if $aItem['html']}
{$aItem['html']}
{else}
{if $aItem['show']|default:true}
{include './actionbar.item.tpl'}
{/if}
{/if}
{/foreach}
</ul>
{if $smarty.local.items}
<ul class="{$component} clearfix {mod name=$component mods=$smarty.local.mods} {$smarty.local.classes}" {$smarty.local.attributes}>
{foreach $smarty.local.items as $item}
{if $item['html']}
{$item['html']}
{else}
{if $item['show']|default:true}
{include './actionbar-item.tpl' item=$item}
{/if}
{/if}
{/foreach}
</ul>
{/if}

View file

@ -9,6 +9,16 @@
* @author Denis Shakhov <denis.shakhov@gmail.com>
*/
.actionbar { background: #fafafa; padding: 10px 10px 0; margin-bottom: 10px; }
.actionbar-item { float: left; white-space: nowrap; margin-right: 10px; }
.actionbar-item-link { margin-bottom: 10px; }
.actionbar {
background: #fafafa;
padding: 10px 10px 0;
margin-bottom: 10px;
}
.actionbar-item {
float: left;
white-space: nowrap;
margin-right: 10px;
}
.actionbar-item-link {
margin-bottom: 10px;
}

View file

@ -0,0 +1,66 @@
/**
* Actionbar Select button
*
* @module ls/actionbar-item-select
*
* @license GNU General Public License, version 2
* @copyright 2013 OOO "ЛС-СОФТ" {@link http://livestreetcms.com}
* @author Denis Shakhov <denis.shakhov@gmail.com>
*/
(function($) {
"use strict";
$.widget( "livestreet.lsActionbarItemSelect", {
/**
* Дефолтные опции
*/
options: {
// Селекторы
selectors: {
target_item: '.js-actionbar-select-target-item'
},
// Классы
classes : {
target_selected: 'selected'
}
},
/**
* Конструктор
*
* @constructor
* @private
*/
_create: function () {
var _this = this;
this.element.lsDropdown();
this.elements = {
target_items: $( this.option( 'selectors.target_item') ),
select_menu_items: this.element.lsDropdown( 'getMenu' ).find( 'li[data-select-item]' )
};
this.elements.select_menu_items.on( 'click' + this.eventNamespace, function ( event ) {
var items = _this.elements.target_items.filter( $( this ).data( 'select-filter' ) || '*' );
_this.elements.target_items
.removeClass( _this.option( 'classes.target_selected' ) )
.find( 'input[type=checkbox]' )
.prop( 'checked', false );
items
.addClass( _this.option( 'classes.target_selected' ) )
.find( 'input[type=checkbox]' )
.prop( 'checked', true );
event.preventDefault();
});
this.document.on( 'click' + this.eventNamespace, this.option( 'selectors.target_item' ) + ' input[type=checkbox]', function () {
$( this ).closest( _this.option( 'selectors.target_item' ) ).toggleClass( _this.option( 'classes.target_selected' ) );
});
},
});
})(jQuery);

View file

@ -59,7 +59,7 @@
]}
{/block}
{include 'components/actionbar/actionbar.tpl' aItems=$items}
{include 'components/actionbar/actionbar.tpl' items=$items}
{/if}
</header>
{/block}

View file

@ -83,6 +83,6 @@
]}
{/if}
{include 'components/actionbar/actionbar.tpl' aItems=$aActionbarItems}
{include 'components/actionbar/actionbar.tpl' items=$aActionbarItems}
{/if}
</div>

View file

@ -63,7 +63,7 @@
{* TODO: Добавить хук *}
{include 'components/actionbar/actionbar.tpl' aItems=$aItems sClasses='comments-actions'}
{include 'components/actionbar/actionbar.tpl' items=$aItems classes='comments-actions'}
{**

View file

@ -0,0 +1,3 @@
# Компонент dropdown
Выпадающее меню

View file

@ -0,0 +1,68 @@
/**
* Dropdowns
*
* @module ls/dropdown
*
* @license GNU General Public License, version 2
* @copyright 2013 OOO "ЛС-СОФТ" {@link http://livestreetcms.com}
* @author Denis Shakhov <denis.shakhov@gmail.com>
*/
.dropdown {
display: inline-block;
background: #2891d3;
color: #fff;
padding: 7px 35px 7px 13px;
margin-bottom: 10px;
min-height: 18px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
text-decoration: none;
position: relative;
}
/* Dropdown toggle */
.dropdown-toggle {
position: relative;
cursor: pointer;
padding-right: 25px;
}
.dropdown-toggle:after {
content: "";
position: absolute;
top: 50%;
right: 9px;
height: 0;
width: 0;
margin-top: -1px;
border: 4px solid transparent;
border-top-color: #333;
}
.dropdown-toggle.open:after { border-top-color: #fff; }
.dropdown-toggle.open { background: #08c; color: #fff; }
.dropdown .dropdown-toggle {
border-left: 1px solid #40BAF7;
position: absolute;
top: 0;
bottom: 0;
right: 0;
width: 25px;
}
.dropdown .dropdown-toggle.open { border-color: transparent; }
.dropdown .dropdown-toggle:hover { background: #08c; }
/**
* Выпадающее меню
*/
.dropdown-menu {
display: none;
position: absolute;
z-index: 900;
}

View file

@ -1,18 +1,18 @@
{**
* Выпадающее меню
*
* @param string sName
* @param string sText
* @param string sClasses
* @param string sAttributes
* @param string sActiveItem
* @param array aItems
* @param string name
* @param string text
* @param string classes
* @param string attributes
* @param string activeItem
* @param array items
*}
{include 'components/nav/nav.tpl'
sName = "{$smarty.local.sName}_menu"
sActiveItem = $smarty.local.sActiveItem
sMods = 'stacked dropdown'
sClasses = "dropdown-menu {$smarty.local.sClasses}"
sAttributes = $smarty.local.sAttributes
aItems = $smarty.local.aItems}
sName = "{$smarty.local.name}_menu"
sActiveItem = $smarty.local.activeItem
sMods = 'stacked dropdown'
sClasses = "dropdown-menu {$smarty.local.classes}"
sAttributes = "{$smarty.local.attributes} id=\"{$smarty.local.id}\""
aItems = $smarty.local.items}

View file

@ -1,28 +1,26 @@
{**
* Выпадающее меню
*
* @param string sName
* @param string sText
* @param string sActiveItem
* @param array aMenu
* @param string text
* @param string activeItem
* @param array menu
*}
{* Название компонента *}
{$_sComponentName = 'dropdown'}
{* Дефолтные значения *}
{$_sName = ($smarty.local.sName) ? $smarty.local.sName : rand(0, 9999999)}
{$component = 'dropdown'}
{* Уникальный ID для привязки кнопки к меню *}
{$uid = "dropdown{rand( 0, 10e10 )}"}
{* Кнопка *}
{include 'components/button/button.tpl'
sClasses = "{$_sComponentName}-toggle js-dropdown-default {$smarty.local.sClasses}"
sAttributes = "data-{$_sComponentName}-target=\"js-{$_sComponentName}-{$_sName}-menu\" {$smarty.local.sAttributes}"
sText = $smarty.local.sText}
sType = 'button'
sClasses = "{$component}-toggle {$smarty.local.classes}"
sAttributes = "data-{$component}-target=\"{$uid}\" {$smarty.local.attributes}"
sText = $smarty.local.text}
{* Выпадающее меню *}
{* Меню *}
{include './dropdown.menu.tpl'
sName = "{$_sName}_menu"
sActiveItem = $smarty.local.sActiveItem
sAttributes = "id=\"js-{$_sComponentName}-{$_sName}-menu\""
aItems = $smarty.local.aMenu}
id = $uid
activeItem = $smarty.local.activeItem
items = $smarty.local.menu}

View file

@ -0,0 +1,173 @@
/**
* Выпадающее меню
*
* @module dropdown
*
* @license GNU General Public License, version 2
* @copyright 2013 OOO "ЛС-СОФТ" {@link http://livestreetcms.com}
* @author Denis Shakhov <denis.shakhov@gmail.com>
*/
$.widget( "livestreet.lsDropdown", {
/**
* Дефолтные опции
*/
options: {
// Позиционирование
// Для позиционирования используется модуль position библиотеки jQuery UI
position: {
my: "left top+5",
at: "left bottom",
collision: "flipfit flip"
},
// Анимация при показе
show: {
effect: 'slideDown',
duration: 200
},
// Анимация при скрытии
hide: {
effect: 'slideUp',
duration: 200
},
// Поведение как у select'а
selectable: false,
// Выносить меню в тег body или нет
body: false,
// Коллбэки
reposition: null,
aftershow: null,
afterhide: null,
beforeshow: null,
beforehide: null
},
/**
* Конструктор
*
* @constructor
* @private
*/
_create: function() {
this.options = $.extend({}, this.options, ls.utils.getDataOptions(this.element, 'dropdown'));
this._menu = $( '#' + this.element.data('dropdown-target') );
// Вынос меню в тег body
if ( this.options.body ) this._menu.appendTo('body');
// Пункты меню
var items = this._menu.find('li:not(.dropdown-separator)');
// Присваиваем текст активного пункта меню переключателю
if ( this.options.selectable ) {
var text = items.filter('.active').eq(0).find('a').text();
if ( text ) this.element.text( text );
}
// Объект относительно которого позиционируется меню
this.options.position.of = this.options.position.of || this.element;
this.options.position.using = this.options.position.using || function ( position, feedback ) {
ls.utils.removeClassByPrefix( this._menu, 'position-' );
this._menu
.addClass( 'position-y-' + feedback.vertical + ' ' + 'position-x-' + feedback.horizontal )
.css( position );
}.bind(this);
// События
// ----------
// Клик по переключателю
this._on({
click : function (event) {
this.toggle();
event.preventDefault();
}
});
// Обработка кликов по пунктам меню
this._on( items.find('a'), {
click: function (event) {
if ( this.options.selectable ) {
var itemLink = $(event.currentTarget);
items.removeClass('active');
itemLink.closest('li').addClass('active');
this.element.text( itemLink.text() );
}
this.hide();
}
});
// Reposition menu on window scroll or resize
this.window.on('resize' + this.eventNamespace + 'scroll' + this.eventNamespace, this._reposition.bind(this));
// Hide when click anywhere but menu or toggle
this.document.on('click' + this.eventNamespace, function (event) {
if ( ! this._menu.is(event.target) && this._menu.has(event.target).length === 0 && ! this.element.is(event.target) && this.element.has(event.target).length === 0 ) this.hide();
}.bind(this));
},
/**
* Показавает/скрывает меню
*/
toggle: function () {
if ( this._menu.is(':visible') ) {
this.hide();
} else {
this.show();
}
},
/**
* Показывает меню
*/
show: function () {
this._trigger("beforeshow", null, this);
this._show(this._menu, this.options.show, function () {
this._trigger("aftershow", null, this);
}.bind(this));
this._reposition();
this.element.addClass('open');
},
/**
* Скрывает меню
*/
hide: function () {
if ( ! this._menu.is(':visible') || this.element.data('dropdown-state-hide') === true ) return false;
this._trigger("beforehide", null, this);
this.element.data('dropdown-state-hide', true);
this._hide(this._menu, this.options.hide, function () {
this.element.removeClass('open').removeData('dropdown-state-hide');
this._trigger("afterhide", null, this);
}.bind(this));
},
/**
*
*/
getMenu: function () {
return this._menu;
},
/**
* Изменение положения меню
*/
_reposition: function () {
if ( ! this._menu.is(':visible') ) return false;
this._menu.position(this.options.position);
this._trigger("reposition", null, this);
}
});

View file

@ -36,7 +36,10 @@
{if $_bIsDropdown}{$_sComponentName}-item--has-children{/if}
{$aItem['classes']}"
{if isset($aItem['title'])}title="{$aItem['title']}"{/if}
{$aItem['attributes']}>
{$aItem['attributes']}
{foreach $aItem['data'] as $data}
data-{$data@key}={$data@value}
{/foreach}>
{* Ссылка *}
<a href="{if $aItem['url']}{$aItem['url']}{else}#{/if}">

View file

@ -4,11 +4,12 @@
{if $sPeriodSelectCurrent}
{include 'components/dropdown/dropdown.tpl'
sName = 'sort_by_date'
sText = 'Loading...'
sAttributes = "data-dropdown-selectable=\"true\""
sActiveItem = $sPeriodSelectCurrent
aMenu = [
classes = 'js-dropdown-default'
name = 'sort_by_date'
text = 'Loading...'
attributes = "data-dropdown-selectable=\"true\""
activeItem = $sPeriodSelectCurrent
menu = [
[ 'name' => '1', 'url' => "{$sPeriodSelectRoot}?period=1", 'text' => {lang name='blog.menu.top_period_1'} ],
[ 'name' => '7', 'url' => "{$sPeriodSelectRoot}?period=7", 'text' => {lang name='blog.menu.top_period_7'} ],
[ 'name' => '30', 'url' => "{$sPeriodSelectRoot}?period=30", 'text' => {lang name='blog.menu.top_period_30'} ],

View file

@ -13,12 +13,16 @@
{* Экшнбар *}
{if $smarty.local.selectable}
{include 'components/actionbar/actionbar.item.select.tpl' sItemSelector='.js-message-list-item' assign=select aItems=[
[ 'text' => $aLang.talk.actionbar.read, 'filter' => ":not('.message-unread')" ],
[ 'text' => $aLang.talk.actionbar.unread, 'filter' => ".message-unread" ]
]}
{include 'components/actionbar/actionbar-item.select.tpl'
classes = 'js-talk-actionbar-select'
target = '.js-message-list-item'
assign = select
items = [
[ 'text' => $aLang.talk.actionbar.read, 'filter' => ":not('.message-unread')" ],
[ 'text' => $aLang.talk.actionbar.unread, 'filter' => ".message-unread" ]
]}
{include 'components/actionbar/actionbar.tpl' aItems=[
{include 'components/actionbar/actionbar.tpl' items=[
[ 'html' => $select ],
[ 'icon' => 'icon-ok', 'classes' => 'js-talk-form-action', 'attributes' => 'data-action="mark_as_read"', 'text' => $aLang.talk.actionbar.mark_as_read ],
[ 'icon' => 'icon-remove', 'classes' => 'js-talk-form-action', 'attributes' => 'data-action="remove"', 'text' => $aLang.common.remove ]

View file

@ -11,9 +11,13 @@
{block 'modal_content'}
{* Экшнбар *}
{if $aUserList && $bSelectable}
{include 'components/actionbar/actionbar.item.select.tpl' sItemSelector='.js-user-list-select .js-user-list-small-item' assign=sUsersSelect}
{include 'components/actionbar/actionbar.tpl' aItems=[
[ 'html' => $sUsersSelect ]
{include 'components/actionbar/actionbar-item.select.tpl'
classes = 'js-user-list-modal-actionbar'
target = '.js-user-list-select .js-user-list-small-item'
assign = users}
{include 'components/actionbar/actionbar.tpl' items=[
[ 'html' => $users ]
]}
{/if}

View file

@ -37,7 +37,7 @@ $aCss = array(
// Components
"___path.skin.assets.web___/css/components/vote.css",
"___path.skin.assets.web___/css/components/actionbar.css",
"___path.skin.web___/components/actionbar/css/actionbar.css",
"___path.skin.assets.web___/css/components/more.css",
"___path.skin.assets.web___/css/components/favourite.css",
"___path.skin.assets.web___/css/components/user_note.css",