<coreobject>
<objectname><![CDATA[wcf\system\poll\PollManager]]></objectname>
</coreobject>
+ <coreobject>
+ <objectname><![CDATA[wcf\system\search\SearchEngine]]></objectname>
+ </coreobject>
</import>
</data>
{capture assign='__searchFormLink'}{link controller='Search'}{/link}{/capture}
-{capture assign='__searchInputPlaceholder'}{lang}wcf.global.search.enterSearchTerm{/lang}{/capture}
-{capture assign='__searchDropdownOptions'}<label><input type="checkbox" name="subjectOnly" value="1" /> {lang}wcf.search.subjectOnly{/lang}</label>{/capture}
-{assign var='__searchHiddenInputFields' value=''}
{event name='settings'}
<div id="pageHeaderSearch" class="pageHeaderSearch">
<form method="post" action="{@$__searchFormLink}">
- <div id="pageHeaderSearchInputContainer" class="pageHeaderSearchInputContainer dropdown" data-disable-auto-focus="true" data-dropdown-prevent-toggle="true">
- <input type="search" name="q" id="pageHeaderSearchInput" class="pageHeaderSearchInput dropdownToggle" placeholder="{@$__searchInputPlaceholder}" autocomplete="off" required="required" value="{if $query|isset}{$query}{/if}" data-toggle="search" />
-
- <ul class="dropdownMenu">
- {hascontent}
- <li class="dropdownText">
+ <div id="pageHeaderSearchInputContainer" class="pageHeaderSearchInputContainer">
+ <div class="pageHeaderSearchType dropdown">
+ <a href="#" class="button dropdownToggle">{lang}wcf.search.type.{if !$searchObjectTypeName|empty}{@$searchObjectTypeName}{else}everywhere{/if}{/lang}</a>
+ <ul class="dropdownMenu">
+ <li><a href="#" data-object-type="">{lang}wcf.search.type.everywhere{/lang}</a></li>
+ <li class="dropdownDivider"></li>
+
+ {hascontent}
{content}
- {@$__searchDropdownOptions}
+ {event name='searchTypesScoped'}
{/content}
- </li>
+
+ <li class="dropdownDivider"></li>
+ {/hascontent}
+
+ {foreach from=$__wcf->getSearchEngine()->getAvailableObjectTypes() key=_searchObjectTypeName item=_searchObjectType}
+ {if $_searchObjectType->isAccessible()}
+ <li><a href="#" data-object-type="{@$_searchObjectTypeName}">{lang}wcf.search.type.{@$_searchObjectTypeName}{/lang}</a></li>
+ {/if}
+ {/foreach}
+
<li class="dropdownDivider"></li>
- {/hascontent}
- <li><a href="{@$__searchFormLink}">{lang}wcf.search.extended{/lang}</a></li>
- </ul>
+ <li><a href="{@$__searchFormLink}">{lang}wcf.search.extended{/lang}</a></li>
+ </ul>
+ </div>
+
+ <input type="search" name="q" id="pageHeaderSearchInput" class="pageHeaderSearchInput" placeholder="{lang}wcf.global.search.enterSearchTerm{/lang}" autocomplete="off" value="{if $query|isset}{$query}{/if}" required>
- <button class="pageHeaderSearchInputButton" type="submit">
- <span class="icon icon16 pointer fa-search" title="{lang}wcf.global.search{/lang}"></span>
+ <button class="pageHeaderSearchInputButton button" type="submit">
+ <span class="icon icon16 fa-search pointer" title="{lang}wcf.global.search{/lang}"></span>
</button>
+
+ {if !$searchObjectTypeName|empty}<input type="hidden" name="types[]" value="{$searchObjectTypeName}">{/if}
+
+ {@SECURITY_TOKEN_INPUT_TAG}
</div>
<label for="pageHeaderSearchInput" class="pageHeaderSearchLabel"></label>
- {@$__searchHiddenInputFields}
+ {if !$searchObjectTypeName|empty}<input type="hidden" name="types[]" value="{$searchObjectTypeName}">{/if}
+
{@SECURITY_TOKEN_INPUT_TAG}
</form>
</div>
{if !OFFLINE || $__wcf->session->getPermission('admin.general.canViewPageDuringOfflineMode')}
<script data-relocate="true">
- $(function() {
- new WCF.Search.Message.SearchArea($('#pageHeaderSearchInputContainer'));
+ require(['WoltLab/WCF/Ui/Search/Page'], function(UiSearchPage) {
+ UiSearchPage.init();
});
</script>
{/if}
\ No newline at end of file
this._itemIndex = -1;
}
});
-
-/**
- * Handles the search area box.
- *
- * @param jQuery searchArea
- */
-WCF.Search.Message.SearchArea = Class.extend({
- /**
- * search area object
- * @var jQuery
- */
- _searchArea: null,
-
- /**
- * Initializes the WCF.Search.Message.SearchArea class.
- *
- * @param jQuery searchArea
- */
- init: function(searchArea) {
- this._searchArea = searchArea;
-
- var $keywordList = new WCF.Search.Message.KeywordList(this._searchArea.find('input[type=search]'), $.proxy(this._callback, this));
- $keywordList.setDelay(500);
-
- // forward clicks on the search icon to input field
- var self = this;
- var $input = this._searchArea.find('input[type=search]');
- this._searchArea.click(function(event) {
- // only forward clicks if the search element itself is the target
- if (event.target == self._searchArea[0]) {
- $input.focus().trigger('click');
- return false;
- }
- });
-
- if (this._searchArea.hasClass('dropdown')) {
- var $containerID = this._searchArea.wcfIdentify();
- var $dropdownMenu = WCF.Dropdown.getDropdownMenu($containerID);
- var $form = this._searchArea.find('form');
- if ($form.length === 0) $form = this._searchArea.parent();
-
- $form.submit(function() {
- // copy checkboxes and hidden fields into form
- $dropdownMenu.find('input[type=hidden]').appendTo($form);
- $dropdownMenu.find('input[type=checkbox]:checked').each(function(index, input) {
- var $input = $(input);
-
- $('<input type="hidden" name="' + $input.attr('name') + '" value="' + $input.attr('value') + '" />').appendTo($form);
- });
- });
-
- var $enableFlexWidth = true;
- require(['Ui/Screen'], function(UiScreen) {
- UiScreen.on('screen-md-down', {
- match: function() { $enableFlexWidth = false; },
- unmatch: function() { $enableFlexWidth = true; },
- setup: function() { $enableFlexWidth = false; }
- })
- });
-
- $dropdownMenu.addClass('pageHeaderSearchDropdown');
- WCF.Dropdown.registerCallback($containerID, (function(containerID, action) {
- if ($enableFlexWidth && action === 'open' && elById('pageHeader').classList.contains('sticky')) {
- var width = elById('pageHeaderSearch').clientWidth + elById('topMenu').clientWidth;
- if (width < 200) width = 200;
-
- this._searchArea.css('width', width + 'px');
- $dropdownMenu.css('width', width + 'px');
- }
- else {
- this._searchArea.css('width', '');
- $dropdownMenu.css('width', '');
- }
- }).bind(this));
-
- $(window).scroll((function () {
- this._searchArea.css('width', '');
- }).bind(this));
- }
- },
-
- /**
- * Callback for WCF.Search.Message.KeywordList.
- *
- * @param object data
- * @return boolean
- */
- _callback: function(data) {
- this._searchArea.find('input[type=search]').val(data.label);
- this._searchArea.find('form').submit();
- return false;
- }
-});
\ No newline at end of file
var _options = {};
var _pageMenuMain = null;
var _pageMenuUser = null;
- var _sidebar = null;
/**
* @exports WoltLab/WCF/Ui/Mobile
_buttonGroupNavigations = elByClass('buttonGroupNavigation');
_main = elById('main');
- _sidebar = elBySel('#main > div > div > .sidebar', _main);
if (Environment.touch()) {
document.documentElement.classList.add('touch');
},
_init: function() {
- //this._initSidebarToggleButtons();
- //this._initSearchBar();
+ this._initSearchBar();
this._initButtonGroupNavigation();
this._initMobileMenu();
DomChangeListener.add('WoltLab/WCF/Ui/Mobile', this._initButtonGroupNavigation.bind(this));
},
- _initSidebarToggleButtons: function() {
- if (_sidebar === null) return;
-
- var sidebarPosition = (_main.classList.contains('sidebarOrientationLeft')) ? 'Left' : '';
- sidebarPosition = (sidebarPosition) ? sidebarPosition : (_main.classList.contains('sidebarOrientationRight') ? 'Right' : '');
-
- if (!sidebarPosition) {
- return;
- }
-
- // use icons if language item is empty/non-existent
- var languageShowSidebar = 'wcf.global.sidebar.show' + sidebarPosition + 'Sidebar';
- if (languageShowSidebar === Language.get(languageShowSidebar) || Language.get(languageShowSidebar) === '') {
- languageShowSidebar = elCreate('span');
- languageShowSidebar.className = 'icon icon16 fa-angle-double-' + sidebarPosition.toLowerCase();
- }
-
- var languageHideSidebar = 'wcf.global.sidebar.hide' + sidebarPosition + 'Sidebar';
- if (languageHideSidebar === Language.get(languageHideSidebar) || Language.get(languageHideSidebar) === '') {
- languageHideSidebar = elCreate('span');
- languageHideSidebar.className = 'icon icon16 fa-angle-double-' + (sidebarPosition === 'Left' ? 'right' : 'left');
- }
-
- // add toggle buttons
- var showSidebar = elCreate('span');
- showSidebar.className = 'button small mobileSidebarToggleButton';
- showSidebar.addEventListener('click', function() { _main.classList.add('mobileShowSidebar'); });
- if (languageShowSidebar instanceof Element) showSidebar.appendChild(languageShowSidebar);
- else showSidebar.textContent = languageShowSidebar;
-
- var hideSidebar = elCreate('span');
- hideSidebar.className = 'button small mobileSidebarToggleButton';
- hideSidebar.addEventListener('click', function() { _main.classList.remove('mobileShowSidebar'); });
- if (languageHideSidebar instanceof Element) hideSidebar.appendChild(languageHideSidebar);
- else hideSidebar.textContent = languageHideSidebar;
-
- elBySel('.content').appendChild(showSidebar);
- _sidebar.appendChild(hideSidebar);
- },
-
_initSearchBar: function() {
var _searchBar = elBySel('.searchBar');
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @module WoltLab/WCF/Ui/Page/Header/Fixed
*/
-define(['Core', 'EventHandler', 'Ui/CloseOverlay', 'Ui/Screen', 'Ui/SimpleDropdown'], function(Core, EventHandler, UiCloseOverlay, UiScreen, UiSimpleDropdown) {
+define(['Core', 'EventHandler', 'Ui/Alignment', 'Ui/CloseOverlay', 'Ui/Screen', 'Ui/SimpleDropdown'], function(Core, EventHandler, UiAlignment, UiCloseOverlay, UiScreen, UiSimpleDropdown) {
"use strict";
- var _pageHeader, _pageHeaderContainer, _triggerHeight, _isFixed = false, _isMobile = false;
+ var _pageHeader, _pageHeaderContainer, _searchInputContainer, _triggerHeight;
+ var _isFixed = false, _isMobile = false;
/**
* @exports WoltLab/WCF/Ui/Page/Header/Fixed
* @protected
*/
_initSearchBar: function() {
+ var searchContainer = elById('pageHeaderSearch');
+ searchContainer.addEventListener(WCF_CLICK_EVENT, function(event) {
+ event.preventDefault();
+ event.stopPropagation();
+ });
+
var searchInput = elById('pageHeaderSearchInput');
- UiSimpleDropdown.registerCallback('pageHeaderSearchInputContainer', function() {
+ var searchLabel = elBySel('.pageHeaderSearchLabel');
+ _searchInputContainer = elById('pageHeaderSearchInputContainer');
+
+ var menu = elById('topMenu');
+ searchLabel.addEventListener(WCF_CLICK_EVENT, function() {
if ((_isFixed || _isMobile) && !_pageHeader.classList.contains('searchBarOpen')) {
+ UiAlignment.set(_searchInputContainer, menu, {
+ horizontal: 'right'
+ });
+
_pageHeader.classList.add('searchBarOpen');
searchInput.focus();
}
* @protected
*/
_scroll: function() {
+ var wasFixed = _isFixed;
+
_isFixed = (window.scrollY > _triggerHeight);
_pageHeader.classList[_isFixed ? 'add' : 'remove']('sticky');
_pageHeaderContainer.classList[_isFixed ? 'add' : 'remove']('stickyPageHeader');
- _pageHeader.classList.remove('searchBarOpen');
+ if (!_isFixed && wasFixed) {
+ _pageHeader.classList.remove('searchBarOpen');
+ ['bottom', 'left', 'right', 'top'].forEach(function(propertyName) {
+ _searchInputContainer.style.removeProperty(propertyName);
+ });
+ }
}
};
});
if (!(this._element instanceof Element)) {
throw new TypeError("Expected a valid DOM element.");
}
- else if (this._element.nodeName !== 'INPUT' || this._element.type !== 'text') {
+ else if (this._element.nodeName !== 'INPUT' || (this._element.type !== 'search' && this._element.type !== 'text')) {
throw new Error('Expected an input[type="text"].');
}
className: '',
interfaceName: 'wcf\\data\\ISearchAction'
},
+ callbackDropdownInit: null,
callbackSelect: null,
delay: 500,
minLength: 3,
this._list.className = 'dropdownMenu';
createdList = true;
+
+ if (typeof this._options.callbackDropdownInit === 'function') {
+ this._options.callbackDropdownInit(this._list);
+ }
}
else {
// reset current list
--- /dev/null
+define(['Dom/Util', './Input'], function(DomUtil, UiSearchInput) {
+ "use strict";
+
+ var _dropdownMenu = null;
+
+ return {
+ init: function () {
+ var searchInput = elById('pageHeaderSearchInput');
+
+ new UiSearchInput(searchInput, {
+ ajax: {
+ className: 'wcf\\data\\search\\keyword\\SearchKeywordAction'
+ },
+ callbackDropdownInit: function(dropdownMenu) {
+ dropdownMenu.classList.add('dropdownMenuPageSearch');
+
+ elData(dropdownMenu, 'dropdown-alignment-horizontal', 'right');
+
+ var minWidth = searchInput.clientWidth;
+ dropdownMenu.style.setProperty('min-width', minWidth + 'px', '');
+
+ // calculate offset to ignore the width caused by the submit button
+ var parent = searchInput.parentNode;
+ var offsetRight = (DomUtil.offset(parent).left + parent.clientWidth) - (DomUtil.offset(searchInput).left + minWidth);
+ var offsetTop = DomUtil.styleAsInt(window.getComputedStyle(parent), 'padding-bottom');
+ dropdownMenu.style.setProperty('transform', 'translateX(-' + Math.ceil(offsetRight) + 'px) translateY(-' + offsetTop + 'px)', '');
+ }
+ });
+ }
+ };
+});
> .inputPrefix,
> .inputSuffix {
+ align-items: center;
+ display: flex;
flex: 0 0 auto;
&.button {
}
.pageHeaderSearchInputContainer .pageHeaderSearchInput {
- padding-bottom: 10px;
- padding-top: 10px;
width: 200px;
}
}
}
.pageHeaderSearchInputContainer {
- display: inline-block;
+ background-color: $wcfHeaderSearchBoxBackground;
+ border-radius: 2px;
+ display: inline-flex;
+ padding: 2px;
position: relative;
- &:hover {
- .pageHeaderSearchInput {
- background-color: $wcfHeaderSearchBoxBackgroundActive;
- color: $wcfHeaderSearchBoxTextActive;
- }
-
- .pageHeaderSearchInputButton > .icon {
- color: $wcfHeaderSearchBoxTextActive;
- }
+ .pageHeaderSearchType > .button {
+ border-radius: 2px 0 0 2px;
+ padding: 4px 7px;
+ }
+
+ .pageHeaderSearchInputButton {
+ border-radius: 0 2px 2px 0;
+ padding: 4px 7px;
}
.pageHeaderSearchInput {
- background-color: $wcfHeaderSearchBoxBackground;
+ background-color: transparent;
border-width: 0;
color: $wcfHeaderSearchBoxText;
- padding: 6px 30px 6px 8px;
- &:focus {
- background-color: $wcfHeaderSearchBoxBackgroundActive;
+ &:focus,
+ &:hover {
+ background-color: transparent;
color: $wcfHeaderSearchBoxTextActive;
- ~ .pageHeaderSearchInputButton > .icon {
- color: $wcfHeaderSearchBoxTextActive;
+ /* set placeholder color */
+ &::-webkit-input-placeholder { /* WebKit browsers */
+ color: $wcfHeaderSearchBoxPlaceholderActive;
+ }
+ &::-moz-placeholder { /* Mozilla Firefox 19+ */
+ color: $wcfHeaderSearchBoxPlaceholderActive;
+ }
+ &:-ms-input-placeholder { /* Internet Explorer 10+ */
+ color: $wcfHeaderSearchBoxPlaceholderActive;
}
}
&:-ms-input-placeholder { /* Internet Explorer 10+ */
color: $wcfHeaderSearchBoxPlaceholder;
}
-
+
/* remove broken cancel-button (webkit) */
&::-webkit-search-cancel-button {
display:none;
}
}
-
- &:hover .pageHeaderSearchInput,
- .pageHeaderSearchInput:focus {
- /* set placeholder color */
- &::-webkit-input-placeholder { /* WebKit browsers */
- color: $wcfHeaderSearchBoxPlaceholderActive;
- }
- &::-moz-placeholder { /* Mozilla Firefox 19+ */
- color: $wcfHeaderSearchBoxPlaceholderActive;
- }
- &:-ms-input-placeholder { /* Internet Explorer 10+ */
- color: $wcfHeaderSearchBoxPlaceholderActive;
- }
- }
-
- .pageHeaderSearchInputButton {
- background: none;
- border: 0 none;
- height: 20px;
- margin: -10px 5px 0 0;
- padding: 0;
- position: absolute;
- right: 0;
- top: 50%;
- width: 20px;
-
- > .icon {
- color: $wcfHeaderSearchBoxText;
- }
- }
}
@include screen-md-down {
}
&:not(.searchBarOpen) {
- .pageHeaderSearchInput,
- .pageHeaderSearchInputButton {
+ .pageHeaderSearchInputContainer {
display: none;
}
}
&.searchBarOpen {
.pageHeaderSearchInputContainer {
- height: 100%;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
position: absolute;
- top: 100%;
- transform: translateX(-50px);
+ top: 50px !important;
z-index: 100;
}
visibility: hidden;
z-index: 450;
+ &.dropdownMenuPageSearch {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+
&.dropdownArrowRight {
&::after {
left: auto;
<item name="wcf.search.subjectOnly"><![CDATA[Nur Betreff durchsuchen]]></item>
<item name="wcf.search.title"><![CDATA[Suche]]></item>
<item name="wcf.search.type"><![CDATA[Suche in]]></item>
+ <item name="wcf.search.type.everywhere"><![CDATA[Alles]]></item>
<item name="wcf.search.error.noMatches"><![CDATA[Es wurde kein{if !$query|empty} mit Ihrer Suchanfrage „{$query}“ übereinstimmender{/if} Eintrag gefunden.]]></item>
<item name="wcf.search.error.user.noMatches"><![CDATA[Es wurde kein Eintrag von diesem Autor gefunden.]]></item>
</category>
<item name="wcf.search.subjectOnly"><![CDATA[Search subject only]]></item>
<item name="wcf.search.title"><![CDATA[Search]]></item>
<item name="wcf.search.type"><![CDATA[Search in]]></item>
+ <item name="wcf.search.type.everywhere"><![CDATA[Everywhere]]></item>
<item name="wcf.search.error.noMatches"><![CDATA[No items matched your search{if !$query|empty} terms: “{$query}”{/if}.]]></item>
<item name="wcf.search.error.user.noMatches"><![CDATA[There were no items matching this author.]]></item>
</category>