aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB
diff options
context:
space:
mode:
authorJoas Schilling <nickvergessen@gmx.de>2014-05-03 16:39:31 +0200
committerJoas Schilling <nickvergessen@gmx.de>2014-05-03 16:39:31 +0200
commitb60108dc78af581fe5327fce4037731555203320 (patch)
treec0e6807e2a3f106e1ecaf5309d94e02e7716d18d /phpBB
parent4e529fda036b5aa3611da30277487907b83b55ac (diff)
parenta62b672530f1134af98f27d5318ceeae38b65f05 (diff)
downloadforums-b60108dc78af581fe5327fce4037731555203320.tar
forums-b60108dc78af581fe5327fce4037731555203320.tar.gz
forums-b60108dc78af581fe5327fce4037731555203320.tar.bz2
forums-b60108dc78af581fe5327fce4037731555203320.tar.xz
forums-b60108dc78af581fe5327fce4037731555203320.zip
Merge pull request #2267 from prototech/ticket/10737
[ticket/10737] Add live member search. * prototech/ticket/10737: [ticket/10737] Remove loading indicator. [ticket/10737] Enforce allow_live_searches setting in memberlist.php. [ticket/10737] Add config setting to disable live searches. [ticket/10737] Add loading indicator and alert box code to simple_footer.html. [ticket/10737] Load core.js and ajax.js in simple_footer.html. [ticket/10737] Set the username as the input value instead of redirecting. [ticket/10737] Drop subsilver2 changes. [ticket/10737] Add a more generic live search implementation. [ticket/10737] Clean up memberlist.php. [ticket/10737] Use dropdown for search results container. [ticket/10737] Adding delayed keyup and removing target_blank. [ticket/10737] Using UTF-8 aware alternatives in PHP code. [ticket/10737] Removing obsolete code. [ticket/10737] Avoid hard-coding table row and use case-insensitive search. [ticket/10737] Removing unnecessary/obsolete code. [ticket/10737] Using JQuery events and JSON response. [ticket/10737] Code fixes in AJAX search feature [ticket/10737] Improvements over last commit [ticket/10737] Adding username suggestions in "Find a member" using AJAX
Diffstat (limited to 'phpBB')
-rw-r--r--phpBB/assets/javascript/core.js348
-rw-r--r--phpBB/includes/acp/acp_board.php1
-rw-r--r--phpBB/install/schemas/schema_data.sql1
-rw-r--r--phpBB/language/en/acp/board.php2
-rw-r--r--phpBB/language/en/common.php1
-rw-r--r--phpBB/memberlist.php39
-rw-r--r--phpBB/phpbb/db/migration/data/v310/live_searches_config.php25
-rw-r--r--phpBB/styles/prosilver/template/ajax.js4
-rw-r--r--phpBB/styles/prosilver/template/memberlist_search.html16
-rw-r--r--phpBB/styles/prosilver/template/simple_footer.html16
-rw-r--r--phpBB/styles/prosilver/theme/common.css4
-rw-r--r--phpBB/styles/prosilver/theme/forms.css2
12 files changed, 438 insertions, 21 deletions
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index a42701877b..f461d5a175 100644
--- a/phpBB/assets/javascript/core.js
+++ b/phpBB/assets/javascript/core.js
@@ -249,7 +249,16 @@ phpbb.ajaxify = function(options) {
callback = options.callback,
overlay = (typeof options.overlay !== 'undefined') ? options.overlay : true,
isForm = elements.is('form'),
- eventName = isForm ? 'submit' : 'click';
+ isText = elements.is('input[type="text"], textarea'),
+ eventName;
+
+ if (isForm) {
+ eventName = 'submit';
+ } else if (isText) {
+ eventName = 'keyup';
+ } else {
+ eventName = 'click';
+ }
elements.bind(eventName, function(event) {
var action, method, data, submit, that = this, $this = $(this);
@@ -349,6 +358,7 @@ phpbb.ajaxify = function(options) {
// If the element is a form, POST must be used and some extra data must
// be taken from the form.
var runFilter = (typeof options.filter === 'function');
+ var data = {};
if (isForm) {
action = $this.attr('action').replace('&amp;', '&');
@@ -362,33 +372,41 @@ phpbb.ajaxify = function(options) {
value: submit.val()
});
}
+ } else if (isText) {
+ var name = ($this.attr('data-name') !== undefined) ? $this.attr('data-name') : this['name'];
+ action = $this.attr('data-url').replace('&amp;', '&');
+ data[name] = this.value;
+ method = 'POST';
} else {
action = this.href;
data = null;
method = 'GET';
}
+ var sendRequest = function() {
+ if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') === 'true')) {
+ phpbb.loadingIndicator();
+ }
+
+ var request = $.ajax({
+ url: action,
+ type: method,
+ data: data,
+ success: returnHandler,
+ error: errorHandler
+ });
+ request.always(function() {
+ loadingIndicator.fadeOut(phpbb.alertTime);
+ });
+ };
+
// If filter function returns false, cancel the AJAX functionality,
// and return true (meaning that the HTTP request will be sent normally).
- if (runFilter && !options.filter.call(this, data)) {
+ if (runFilter && !options.filter.call(this, data, event, sendRequest)) {
return;
}
- if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') === 'true')) {
- phpbb.loadingIndicator();
- }
-
- var request = $.ajax({
- url: action,
- type: method,
- data: data,
- success: returnHandler,
- error: errorHandler
- });
- request.always(function() {
- loadingIndicator.fadeOut(phpbb.alertTime);
- });
-
+ sendRequest();
event.preventDefault();
});
@@ -404,6 +422,278 @@ phpbb.ajaxify = function(options) {
return this;
};
+phpbb.search = {cache: {data: []}, tpl: [], container: []};
+
+/**
+ * Get cached search data.
+ *
+ * @param string id Search ID.
+ * @return bool|object. Cached data object. Returns false if no data exists.
+ */
+phpbb.search.cache.get = function(id) {
+ if (this.data[id]) {
+ return this.data[id];
+ }
+ return false;
+};
+
+/**
+ * Set search cache data value.
+ *
+ * @param string id Search ID.
+ * @param string key Data key.
+ * @param string value Data value.
+ *
+ * @return undefined
+ */
+phpbb.search.cache.set = function(id, key, value) {
+ if (!this.data[id]) {
+ this.data[id] = {results: []};
+ }
+ this.data[id][key] = value;
+};
+
+/**
+ * Cache search result.
+ *
+ * @param string id Search ID.
+ * @param string keyword Keyword.
+ * @param array results Search results.
+ *
+ * @return undefined
+ */
+phpbb.search.cache.setResults = function(id, keyword, value) {
+ this.data[id]['results'][keyword] = value;
+};
+
+/**
+ * Trim spaces from keyword and lower its case.
+ *
+ * @param string keyword Search keyword to clean.
+ * @return string Cleaned string.
+ */
+phpbb.search.cleanKeyword = function(keyword) {
+ return $.trim(keyword).toLowerCase();
+};
+
+/**
+ * Get clean version of search keyword. If textarea supports several keywords
+ * (one per line), it fetches the current keyword based on the caret position.
+ *
+ * @param jQuery el Search input|textarea.
+ * @param string keyword Input|textarea value.
+ * @param bool multiline Whether textarea supports multiple search keywords.
+ *
+ * @return string Clean string.
+ */
+phpbb.search.getKeyword = function(el, keyword, multiline) {
+ if (multiline) {
+ var line = phpbb.search.getKeywordLine(el);
+ keyword = keyword.split("\n").splice(line, 1);
+ }
+ return phpbb.search.cleanKeyword(keyword);
+};
+
+/**
+ * Get the textarea line number on which the keyword resides - for textareas
+ * that support multiple keywords (one per line).
+ *
+ * @param jQuery el Search textarea.
+ * @return int
+ */
+phpbb.search.getKeywordLine = function (el) {
+ return el.val().substr(0, el.get(0).selectionStart).split("\n").length - 1;
+};
+
+/**
+ * Set the value on the input|textarea. If textarea supports multiple
+ * keywords, only the active keyword is replaced.
+ *
+ * @param jQuery el Search input|textarea.
+ * @param string value Value to set.
+ * @param bool multiline Whether textarea supports multiple search keywords.
+ *
+ * @return undefined
+ */
+phpbb.search.setValue = function(el, value, multiline) {
+ if (multiline) {
+ var line = phpbb.search.getKeywordLine(el),
+ lines = el.val().split("\n");
+ lines[line] = value;
+ value = lines.join("\n");
+ }
+ el.val(value);
+};
+
+/**
+ * Sets the onclick event to set the value on the input|textarea to the selected search result.
+ *
+ * @param jQuery el Search input|textarea.
+ * @param object value Result object.
+ * @param object container jQuery object for the search container.
+ *
+ * @return undefined
+ */
+phpbb.search.setValueOnClick = function(el, value, row, container) {
+ row.click(function() {
+ phpbb.search.setValue(el, value.result, el.attr('data-multiline'));
+ container.hide();
+ });
+};
+
+/**
+ * Runs before the AJAX search request is sent and determines whether
+ * there is a need to contact the server. If there are cached results
+ * already, those are displayed instead. Executes the AJAX request function
+ * itself due to the need to use a timeout to limit the number of requests.
+ *
+ * @param array data Data to be sent to the server.
+ * @param object event Onkeyup event object.
+ * @param function sendRequest Function to execute AJAX request.
+ *
+ * @return bool Returns false.
+ */
+phpbb.search.filter = function(data, event, sendRequest) {
+ var el = $(this),
+ dataName = (el.attr('data-name') !== undefined) ? el.attr('data-name') : el.attr('name'),
+ minLength = parseInt(el.attr('data-min-length')),
+ searchID = el.attr('data-results'),
+ keyword = phpbb.search.getKeyword(el, data[dataName], el.attr('data-multiline')),
+ cache = phpbb.search.cache.get(searchID),
+ proceed = true;
+ data[dataName] = keyword;
+
+ if (cache['timeout']) {
+ clearTimeout(cache['timeout']);
+ }
+
+ var timeout = setTimeout(function() {
+ // Check min length and existence of cache.
+ if (minLength > keyword.length) {
+ proceed = false;
+ } else if (cache['last_search']) {
+ // Has the keyword actually changed?
+ if (cache['last_search'] === keyword) {
+ proceed = false;
+ } else {
+ // Do we already have results for this?
+ if (cache['results'][keyword]) {
+ var response = {keyword: keyword, results: cache['results'][keyword]};
+ phpbb.search.handleResponse(response, el, true);
+ proceed = false;
+ }
+
+ // If the previous search didn't yield results and the string only had characters added to it,
+ // then we won't bother sending a request.
+ if (keyword.indexOf(cache['last_search']) === 0 && cache['results'][cache['last_search']].length === 0) {
+ phpbb.search.cache.set(searchID, 'last_search', keyword);
+ phpbb.search.cache.setResults(searchID, keyword, []);
+ proceed = false;
+ }
+ }
+ }
+
+ if (proceed) {
+ sendRequest.call(this);
+ }
+ }, 350);
+ phpbb.search.cache.set(searchID, 'timeout', timeout);
+
+ return false;
+};
+
+/**
+ * Handle search result response.
+ *
+ * @param object res Data received from server.
+ * @param jQuery el Search input|textarea.
+ * @param bool fromCache Whether the results are from the cache.
+ * @param function callback Optional callback to run when assigning each search result.
+ *
+ * @return undefined
+ */
+phpbb.search.handleResponse = function(res, el, fromCache, callback) {
+ if (typeof res !== 'object') {
+ return;
+ }
+
+ var searchID = el.attr('data-results'),
+ container = $(searchID);
+
+ if (this.cache.get(searchID)['callback']) {
+ callback = this.cache.get(searchID)['callback'];
+ } else if (typeof callback === 'function') {
+ this.cache.set(searchID, 'callback', callback);
+ }
+
+ if (!fromCache) {
+ this.cache.setResults(searchID, res.keyword, res.results);
+ }
+
+ this.cache.set(searchID, 'last_search', res.keyword);
+ this.showResults(res.results, el, container, callback);
+};
+
+/**
+ * Show search results.
+ *
+ * @param array results Search results.
+ * @param jQuery el Search input|textarea.
+ * @param jQuery container Search results container element.
+ * @param function callback Optional callback to run when assigning each search result.
+ *
+ * @return undefined
+ */
+phpbb.search.showResults = function(results, el, container, callback) {
+ var resultContainer = $('.search-results', container);
+ this.clearResults(resultContainer);
+
+ if (!results.length) {
+ container.hide();
+ return;
+ }
+
+ var searchID = container.attr('id'),
+ tpl,
+ row;
+
+ if (!this.tpl[searchID]) {
+ tpl = $('.search-result-tpl', container);
+ this.tpl[searchID] = tpl.clone().removeClass('search-result-tpl');
+ tpl.remove();
+ }
+ tpl = this.tpl[searchID];
+
+ $.each(results, function(i, item) {
+ row = tpl.clone();
+ row.find('.search-result').html(item.display);
+
+ if (typeof callback === 'function') {
+ callback.call(this, el, item, row, container);
+ }
+ row.appendTo(resultContainer).show();
+ });
+ container.show();
+};
+
+/**
+ * Clear search results.
+ *
+ * @param jQuery container Search results container.
+ * @return undefined
+ */
+phpbb.search.clearResults = function(container) {
+ container.children(':not(.search-result-tpl)').remove();
+};
+
+$('#phpbb').click(function(e) {
+ var target = $(e.target);
+
+ if (!target.is('.live-search') && !target.parents().is('.live-search')) {
+ $('.live-search').hide();
+ }
+});
+
/**
* Hide the optgroups that are not the selected timezone
*
@@ -543,6 +833,12 @@ phpbb.addAjaxCallback = function(id, callback) {
return this;
};
+/**
+ * This callback handles live member searches.
+ */
+phpbb.addAjaxCallback('member_search', function(res) {
+ phpbb.search.handleResponse(res, $(this), false, phpbb.getFunctionByName('phpbb.search.setValueOnClick'));
+});
/**
* This callback alternates text - it replaces the current text with the text in
@@ -1112,6 +1408,24 @@ phpbb.toggleDisplay = function(id, action, type) {
}
/**
+* Get function from name.
+* Based on http://stackoverflow.com/a/359910
+*
+* @param string functionName Function to get.
+* @return function
+*/
+phpbb.getFunctionByName = function (functionName) {
+ var namespaces = functionName.split('.'),
+ func = namespaces.pop(),
+ context = window;
+
+ for (var i = 0; i < namespaces.length; i++) {
+ context = context[namespaces[i]];
+ }
+ return context[func];
+};
+
+/**
* Apply code editor to all textarea elements with data-bbcode attribute
*/
$(document).ready(function() {
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index 6b52fbbdb2..cf0f23a16e 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -345,6 +345,7 @@ class acp_board
'load_user_activity' => array('lang' => 'LOAD_USER_ACTIVITY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'load_tplcompile' => array('lang' => 'RECOMPILE_STYLES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'allow_cdn' => array('lang' => 'ALLOW_CDN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'allow_live_searches' => array('lang' => 'ALLOW_LIVE_SEARCHES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'legend3' => 'CUSTOM_PROFILE_FIELDS',
'load_cpf_memberlist' => array('lang' => 'LOAD_CPF_MEMBERLIST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index fbf1374346..2ee6b5f806 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -21,6 +21,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_cdn', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_emailreuse', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_password_reset', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_forum_notify', '1');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_live_searches', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_mass_pm', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_name_chars', 'USERNAME_CHARS_ANY');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_namechange', '0');
diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php
index e21d959e40..505709d513 100644
--- a/phpBB/language/en/acp/board.php
+++ b/phpBB/language/en/acp/board.php
@@ -356,6 +356,8 @@ $lang = array_merge($lang, array(
'ALLOW_CDN' => 'Allow usage of third party content delivery networks',
'ALLOW_CDN_EXPLAIN' => 'If this setting is enabled, some files will be served from external third party servers instead of your server. This reduces the network bandwidth required by your server, but may present a privacy issue for some board administrators. In a default phpBB installation, this includes loading “jQuery” and the font “Open Sans” from Google’s content delivery network.',
+ 'ALLOW_LIVE_SEARCHES' => 'Allow live searches',
+ 'ALLOW_LIVE_SEARCHES_EXPLAIN' => 'If this setting is enabled, users are provided with keyword suggestions as they type in certain fields throughout the board.',
'CUSTOM_PROFILE_FIELDS' => 'Custom profile fields',
'LIMIT_LOAD' => 'Limit system load',
'LIMIT_LOAD_EXPLAIN' => 'If the system’s 1-minute load average exceeds this value the board will automatically go offline. A value of 1.0 equals ~100% utilisation of one processor. This only functions on UNIX based servers and where this information is accessible. The value here resets itself to 0 if phpBB was unable to get the load limit.',
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index 4d4a955aa3..e31164dfc8 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -349,6 +349,7 @@ $lang = array_merge($lang, array(
'LDAP_NO_SERVER_CONNECTION' => 'Could not connect to LDAP server.',
'LDAP_SEARCH_FAILED' => 'An error occurred while searching the LDAP directory.',
'LEGEND' => 'Legend',
+ 'LIVE_SEARCHES_NOT_ALLOWED' => 'Live searches are not allowed.',
'LOADING' => 'Loading',
'LOCATION' => 'Location',
'LOCK_POST' => 'Lock post',
diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php
index 82143d44cb..f859960183 100644
--- a/phpBB/memberlist.php
+++ b/phpBB/memberlist.php
@@ -40,7 +40,7 @@ if ($mode == 'leaders')
}
// Check our mode...
-if (!in_array($mode, array('', 'group', 'viewprofile', 'email', 'contact', 'searchuser', 'team')))
+if (!in_array($mode, array('', 'group', 'viewprofile', 'email', 'contact', 'searchuser', 'team', 'livesearch')))
{
trigger_error('NO_MODE');
}
@@ -50,6 +50,13 @@ switch ($mode)
case 'email':
break;
+ case 'livesearch':
+ if (!$config['allow_live_searches'])
+ {
+ trigger_error('LIVE_SEARCHES_NOT_ALLOWED');
+ }
+ // No break
+
default:
// Can this user view profiles/memberlist?
if (!$auth->acl_gets('u_viewprofile', 'a_user', 'a_useradd', 'a_userdel'))
@@ -990,6 +997,35 @@ switch ($mode)
break;
+ case 'livesearch':
+
+ $username_chars = $request->variable('username', '', true);
+
+ $sql = 'SELECT username, user_id, user_colour
+ FROM ' . USERS_TABLE . '
+ WHERE ' . $db->sql_in_set('user_type', array(USER_NORMAL, USER_FOUNDER)) . '
+ AND username_clean ' . $db->sql_like_expression(utf8_clean_string($username_chars) . $db->any_char);
+ $result = $db->sql_query_limit($sql, 10);
+ $user_list = array();
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $user_list[] = array(
+ 'user_id' => (int) $row['user_id'],
+ 'result' => $row['username'],
+ 'username_full' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']),
+ 'display' => get_username_string('no_profile', $row['user_id'], $row['username'], $row['user_colour']),
+ );
+ }
+ $db->sql_freeresult($result);
+ $json_response = new \phpbb\json_response();
+ $json_response->send(array(
+ 'keyword' => $username_chars,
+ 'results' => $user_list,
+ ));
+
+ break;
+
case 'group':
default:
// The basic memberlist
@@ -1627,6 +1663,7 @@ switch ($mode)
'U_FIND_MEMBER' => ($config['load_search'] || $auth->acl_get('a_')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser' . (($start) ? "&amp;start=$start" : '') . (!empty($params) ? '&amp;' . implode('&amp;', $params) : '')) : '',
'U_HIDE_FIND_MEMBER' => ($mode == 'searchuser' || ($mode == '' && $submit)) ? $u_hide_find_member : '',
+ 'U_LIVE_SEARCH' => ($config['allow_live_searches']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=livesearch') : false,
'U_SORT_USERNAME' => $sort_url . '&amp;sk=a&amp;sd=' . (($sort_key == 'a' && $sort_dir == 'a') ? 'd' : 'a'),
'U_SORT_JOINED' => $sort_url . '&amp;sk=c&amp;sd=' . (($sort_key == 'c' && $sort_dir == 'a') ? 'd' : 'a'),
'U_SORT_POSTS' => $sort_url . '&amp;sk=d&amp;sd=' . (($sort_key == 'd' && $sort_dir == 'a') ? 'd' : 'a'),
diff --git a/phpBB/phpbb/db/migration/data/v310/live_searches_config.php b/phpBB/phpbb/db/migration/data/v310/live_searches_config.php
new file mode 100644
index 0000000000..8b147c954c
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/live_searches_config.php
@@ -0,0 +1,25 @@
+<?php
+/**
+*
+* @package migration
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class live_searches_config extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return isset($this->config['allow_live_searches']);
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.add', array('allow_live_searches', '1')),
+ );
+ }
+}
diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js
index bc68e5ae0c..e9f8064b9e 100644
--- a/phpBB/styles/prosilver/template/ajax.js
+++ b/phpBB/styles/prosilver/template/ajax.js
@@ -315,13 +315,17 @@ $('.poll_view_results a').click(function(e) {
$('[data-ajax]').each(function() {
var $this = $(this),
ajax = $this.attr('data-ajax'),
+ filter = $this.attr('data-filter'),
fn;
if (ajax !== 'false') {
fn = (ajax !== 'true') ? ajax : null;
+ filter = (filter !== undefined) ? phpbb.getFunctionByName(filter) : null;
+
phpbb.ajaxify({
selector: this,
refresh: $this.attr('data-refresh') !== undefined,
+ filter: filter,
callback: fn
});
}
diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html
index ee89b103b5..f4439b6934 100644
--- a/phpBB/styles/prosilver/template/memberlist_search.html
+++ b/phpBB/styles/prosilver/template/memberlist_search.html
@@ -7,9 +7,21 @@
<p>{L_FIND_USERNAME_EXPLAIN}</p>
<fieldset class="fields1 column1">
- <dl>
+ <dl style="overflow: visible;">
<dt><label for="username">{L_USERNAME}{L_COLON}</label></dt>
- <dd><input type="text" name="username" id="username" value="{USERNAME}" class="inputbox" /></dd>
+ <dd>
+ <input type="text" name="username" id="username" value="{USERNAME}" class="inputbox"<!-- IF U_LIVE_SEARCH --> autocomplete="off" data-filter="phpbb.search.filter" data-ajax="member_search" data-min-length="3" data-url="{U_LIVE_SEARCH}" data-results="#user-search" data-overlay="false"<!-- ENDIF --> />
+ <!-- IF U_LIVE_SEARCH -->
+ <div class="dropdown-container">
+ <div class="dropdown live-search hidden" id="user-search">
+ <div class="pointer"><div class="pointer-inner"></div></div>
+ <ul class="dropdown-contents search-results">
+ <li class="search-result-tpl"><span class="search-result"></span></li>
+ </ul>
+ </div>
+ </div>
+ <!-- ENDIF -->
+ </dd>
</dl>
<!-- IF S_EMAIL_SEARCH_ALLOWED -->
<dl>
diff --git a/phpBB/styles/prosilver/template/simple_footer.html b/phpBB/styles/prosilver/template/simple_footer.html
index 10edece3cd..02e24ab796 100644
--- a/phpBB/styles/prosilver/template/simple_footer.html
+++ b/phpBB/styles/prosilver/template/simple_footer.html
@@ -4,11 +4,27 @@
<!-- IF TRANSLATION_INFO --><br />{TRANSLATION_INFO}<!-- ENDIF -->
<!-- IF DEBUG_OUTPUT --><br />{DEBUG_OUTPUT}<!-- ENDIF -->
</div>
+
+ <div id="darkenwrapper" data-ajax-error-title="{L_AJAX_ERROR_TITLE}" data-ajax-error-text="{L_AJAX_ERROR_TEXT}" data-ajax-error-text-abort="{L_AJAX_ERROR_TEXT_ABORT}" data-ajax-error-text-timeout="{L_AJAX_ERROR_TEXT_TIMEOUT}" data-ajax-error-text-parsererror="{L_AJAX_ERROR_TEXT_PARSERERROR}">
+ <div id="darken">&nbsp;</div>
+ </div>
+ <div id="loading_indicator"></div>
+
+ <div id="phpbb_alert" class="phpbb_alert" data-l-err="{L_ERROR}" data-l-timeout-processing-req="{L_TIMEOUT_PROCESSING_REQ}">
+ <a href="#" class="alert_close"></a>
+ <h3 class="alert_title"></h3><p class="alert_text"></p>
+ </div>
+ <div id="phpbb_confirm" class="phpbb_alert">
+ <a href="#" class="alert_close"></a>
+ <div class="alert_text"></div>
+ </div>
</div>
<script type="text/javascript" src="{T_JQUERY_LINK}"></script>
<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF -->
+<script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- INCLUDEJS forum_fn.js -->
+<!-- INCLUDEJS ajax.js -->
<!-- EVENT simple_footer_after -->
diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css
index 0e0f847328..a54b84757c 100644
--- a/phpBB/styles/prosilver/theme/common.css
+++ b/phpBB/styles/prosilver/theme/common.css
@@ -473,6 +473,10 @@ ul.linklist.bulletin li.no-bulletin:before {
margin-right: -500px;
}
+.dropdown.live-search {
+ top: auto;
+}
+
.dropdown-container.topic-tools {
float: left;
}
diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css
index 88f2bd65c5..0c0a3e5ca9 100644
--- a/phpBB/styles/prosilver/theme/forms.css
+++ b/phpBB/styles/prosilver/theme/forms.css
@@ -96,7 +96,7 @@ fieldset.fields1 div {
}
/* Set it back to 0px for the reCaptcha divs: PHPBB3-9587 */
-fieldset.fields1 #recaptcha_widget_div div {
+fieldset.fields1 #recaptcha_widget_div div, fieldset.fields1 .live-search div {
margin-bottom: 0;
}