<dd>
<label><input type="checkbox" id="visibleEverywhere" name="visibleEverywhere" value="1"{if $visibleEverywhere} checked{/if}> {lang}wcf.acp.box.visibleEverywhere{/lang}</label>
<script data-relocate="true">
- elById('visibleEverywhere').addEventListener('change', function() {
- if (this.checked) {
- elShow(elById('visibilityExceptionHidden'));
- elHide(elById('visibilityExceptionVisible'));
- }
- else {
- elHide(elById('visibilityExceptionHidden'));
- elShow(elById('visibilityExceptionVisible'));
- }
+ require(['Language', 'WoltLab/WCF/Ui/ItemList/Filter'], function(Language, UiItemListFilter) {
+ Language.addObject({
+ 'wcf.global.filter.button.clear': '{lang}wcf.global.filter.button.clear{/lang}',
+ 'wcf.global.filter.error.noMatches': '{lang}wcf.global.filter.error.noMatches{/lang}',
+ 'wcf.global.filter.placeholder': '{lang}wcf.global.filter.placeholder{/lang}'
+ });
+
+ new UiItemListFilter('boxVisibilitySettings');
+
+ // visibility toggle
+ var visibilityExceptionHidden = elById('visibilityExceptionHidden');
+ var visibilityExceptionVisible = elById('visibilityExceptionVisible');
+
+ elById('visibleEverywhere').addEventListener('change', function() {
+ window[this.checked ? 'elShow' : 'elHide'](visibilityExceptionHidden);
+ window[this.checked ? 'elHide' : 'elShow'](visibilityExceptionVisible);
+ });
});
</script>
</dd>
<span id="visibilityExceptionHidden"{if !$visibleEverywhere} style="display: none"{/if}>{lang}wcf.acp.box.visibilityException.hidden{/lang}</span>
</dt>
<dd>
- <ul class="scrollableCheckboxList">
+ <ul class="scrollableCheckboxList" id="boxVisibilitySettings">
{foreach from=$pageNodeList item=pageNode}
<li{if $pageNode->getDepth() > 1} style="padding-left: {$pageNode->getDepth()*20-20}px"{/if}>
<label><input type="checkbox" name="pageIDs[]" value="{@$pageNode->pageID}"{if $pageNode->pageID|in_array:$pageIDs} checked{/if}> {$pageNode->name}</label>
<script data-relocate="true">
$(function() {
- $('#isLandingPage').change(function(event) {
- if ($('#isLandingPage')[0].checked) {
- $('#isDisabled')[0].checked = false;
- $('#isDisabled')[0].disabled = true;
- }
- else {
- $('#isDisabled')[0].disabled = false;
- }
- }).trigger('change');
+ var isDisabled = elById('isDisabled');
+ if (isDisabled !== null) {
+ $('#isLandingPage').change(function() {
+ if ($('#isLandingPage')[0].checked) {
+ isDisabled.checked = false;
+ isDisabled.disabled = true;
+ }
+ else {
+ isDisabled.disabled = false;
+ }
+ }).trigger('change');
+ }
{if $action != 'edit' || !$page->isLandingPage}
$('#isDisabled').change(function(event) {
<dl{if $errorField == 'boxIDs'} class="formError"{/if}>
<dt>{lang}wcf.acp.page.boxes{/lang}</dt>
<dd>
- <ul class="scrollableCheckboxList">
+ <ul class="scrollableCheckboxList" id="boxVisibilitySettings">
{foreach from=$availableBoxes item=availableBox}
<li>
<label><input type="checkbox" name="boxIDs[]" value="{@$availableBox->boxID}"{if $availableBox->boxID|in_array:$boxIDs} checked{/if}{if $availableBox->identifier == 'com.woltlab.wcf.MainMenu'} disabled{/if}> {$availableBox->name}</label>
{/if}
</small>
{/if}
+ <script data-relocate="true">
+ require(['Language', 'WoltLab/WCF/Ui/ItemList/Filter'], function(Language, UiItemListFilter) {
+ Language.addObject({
+ 'wcf.global.filter.button.clear': '{lang}wcf.global.filter.button.clear{/lang}',
+ 'wcf.global.filter.error.noMatches': '{lang}wcf.global.filter.error.noMatches{/lang}',
+ 'wcf.global.filter.placeholder': '{lang}wcf.global.filter.placeholder{/lang}'
+ });
+
+ new UiItemListFilter('boxVisibilitySettings');
+ });
+ </script>
</dd>
</dl>
</div>
--- /dev/null
+/**
+ * Provides a filter input for checkbox lists.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLab/WCF/Permission
+ */
+define(['EventKey', 'Language', 'List', 'StringUtil', 'Dom/Util'], function (EventKey, Language, List, StringUtil, DomUtil) {
+ "use strict";
+
+ /**
+ * Creates a new filter input.
+ *
+ * @param {string} elementId list element id
+ * @constructor
+ */
+ function UiItemListFilter(elementId) { this.init(elementId); }
+ UiItemListFilter.prototype = {
+ /**
+ * Creates a new filter input.
+ *
+ * @param {string} elementId list element id
+ */
+ init: function(elementId) {
+ this._value = '';
+
+ var element = elById(elementId);
+ if (element === null) {
+ throw new Error("Expected a valid element id, '" + elementId + "' does not match anything.");
+ }
+ else if (!element.classList.contains('scrollableCheckboxList')) {
+ throw new Error("Filter only works with elements with the CSS class 'scrollableCheckboxList'.");
+ }
+
+ var container = elCreate('div');
+ container.className = 'itemListFilter';
+
+ element.parentNode.insertBefore(container, element);
+ container.appendChild(element);
+
+ var inputAddon = elCreate('div');
+ inputAddon.className = 'inputAddon';
+
+ var input = elCreate('input');
+ input.className = 'long';
+ input.type = 'text';
+ input.placeholder = Language.get('wcf.global.filter.placeholder');
+ input.addEventListener('keydown', function (event) {
+ if (EventKey.Enter(event)) {
+ event.preventDefault();
+ }
+ });
+ input.addEventListener('keyup', this._keyup.bind(this));
+
+ var clearButton = elCreate('a');
+ clearButton.href = '#';
+ clearButton.className = 'button inputSuffix jsTooltip';
+ clearButton.title = Language.get('wcf.global.filter.button.clear');
+ clearButton.innerHTML = '<span class="icon icon16 fa-times"></span>';
+ clearButton.addEventListener('click', (function(event) {
+ event.preventDefault();
+
+ this._input.value = '';
+ this._keyup();
+ }).bind(this));
+
+ inputAddon.appendChild(input);
+ inputAddon.appendChild(clearButton);
+
+ container.appendChild(inputAddon);
+
+ this._container = container;
+ this._element = element;
+ this._input = input;
+ this._items = null;
+ this._fragment = null;
+ },
+
+ /**
+ * Builds the item list and rebuilds the items' DOM for easier manipulation.
+ *
+ * @protected
+ */
+ _buildItems: function() {
+ this._items = new List();
+
+ var item;
+ for (var i = 0, length = this._element.childElementCount; i < length; i++) {
+ item = this._element.children[i];
+
+ var label = item.children[0];
+ var text = label.textContent.trim();
+
+ var checkbox = label.children[0];
+ while (checkbox.nextSibling) {
+ label.removeChild(checkbox.nextSibling);
+ }
+
+ label.appendChild(document.createTextNode(' '));
+
+ var span = elCreate('span');
+ span.textContent = text;
+ label.appendChild(span);
+
+ this._items.add({
+ item: item,
+ span: span,
+ text: text
+ });
+ }
+ },
+
+ /**
+ * Rebuilds the list on keyup, uses case-insensitive matching.
+ *
+ * @protected
+ */
+ _keyup: function() {
+ var value = this._input.value.trim();
+ if (this._value === value) {
+ return;
+ }
+
+ if (this._fragment === null) {
+ this._fragment = document.createDocumentFragment();
+
+ // set fixed height to avoid layout jumps
+ this._element.style.setProperty('height', this._element.offsetHeight + 'px', '');
+ }
+
+ // move list into fragment before editing items, increases performance
+ // by avoiding the browser to perform repaint/layout over and over again
+ this._fragment.appendChild(this._element);
+
+ if (this._items === null) {
+ this._buildItems();
+ }
+
+ var regexp = new RegExp('(' + StringUtil.escapeRegExp(value) + ')', 'i');
+ var hasVisibleItems = (value === '');
+ this._items.forEach(function (item) {
+ if (value === '') {
+ item.span.textContent = item.text;
+
+ elShow(item.item);
+ }
+ else {
+ if (regexp.test(item.text)) {
+ item.span.innerHTML = item.text.replace(regexp, '<u>$1</u>');
+
+ elShow(item.item);
+ hasVisibleItems = true;
+ }
+ else {
+ elHide(item.item);
+ }
+ }
+ });
+
+ this._container.insertBefore(this._fragment.firstChild, this._container.firstChild);
+ this._value = value;
+
+ var innerError = this._container.nextElementSibling;
+ if (innerError && !innerError.classList.contains('innerError')) innerError = null;
+
+ if (hasVisibleItems) {
+ if (innerError) {
+ elRemove(innerError);
+ }
+ }
+ else {
+ if (!innerError) {
+ innerError = elCreate('small');
+ innerError.className = 'innerError';
+ innerError.textContent = Language.get('wcf.global.filter.error.noMatches');
+ DomUtil.insertAfter(innerError, this._container);
+ }
+ }
+ }
+ };
+
+ return UiItemListFilter;
+});