summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorSteven Wittens <steven@10.no-reply.drupal.org>2005-05-24 06:00:22 +0000
committerSteven Wittens <steven@10.no-reply.drupal.org>2005-05-24 06:00:22 +0000
commit58bddf8abc2cb4c51b49a1ad1dc6c7eca411eb22 (patch)
tree21911a0ec62eca709567daf3ddaf9f467409ddf7 /modules
parent0de88f50baa5eed0eb90448d7964aa04c4fbc1de (diff)
downloadbrdo-58bddf8abc2cb4c51b49a1ad1dc6c7eca411eb22.tar.gz
brdo-58bddf8abc2cb4c51b49a1ad1dc6c7eca411eb22.tar.bz2
* cue Star Wars theme tune *
Return of the JavaScript! - #22519: form_autocomplete(): Ajax based autocompletion. Currently used for user names and folksonomy tags.
Diffstat (limited to 'modules')
-rw-r--r--modules/node.module2
-rw-r--r--modules/node/node.module2
-rw-r--r--modules/taxonomy.module39
-rw-r--r--modules/taxonomy/taxonomy.module39
-rw-r--r--modules/user.module16
-rw-r--r--modules/user/user.module16
6 files changed, 110 insertions, 4 deletions
diff --git a/modules/node.module b/modules/node.module
index 7e5ad8a7c..5b01a2159 100644
--- a/modules/node.module
+++ b/modules/node.module
@@ -1317,7 +1317,7 @@ function node_form($edit) {
if (user_access('administer nodes')) {
$output .= '<div class="admin">';
- $author = form_textfield(t('Authored by'), 'name', $edit->name, 20, 60);
+ $author = form_autocomplete(t('Authored by'), 'name', $edit->name, 20, 60, 'user/autocomplete');
$author .= form_textfield(t('Authored on'), 'date', $edit->date, 20, 25, NULL, NULL, TRUE);
$output .= '<div class="authored">';
diff --git a/modules/node/node.module b/modules/node/node.module
index 7e5ad8a7c..5b01a2159 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -1317,7 +1317,7 @@ function node_form($edit) {
if (user_access('administer nodes')) {
$output .= '<div class="admin">';
- $author = form_textfield(t('Authored by'), 'name', $edit->name, 20, 60);
+ $author = form_autocomplete(t('Authored by'), 'name', $edit->name, 20, 60, 'user/autocomplete');
$author .= form_textfield(t('Authored on'), 'date', $edit->date, 20, 25, NULL, NULL, TRUE);
$output .= '<div class="authored">';
diff --git a/modules/taxonomy.module b/modules/taxonomy.module
index 44586cf6b..81b3f7ae9 100644
--- a/modules/taxonomy.module
+++ b/modules/taxonomy.module
@@ -82,6 +82,11 @@ function taxonomy_menu($may_cache) {
'callback' => 'taxonomy_term_page',
'access' => user_access('access content'),
'type' => MENU_CALLBACK);
+
+ $items[] = array('path' => 'taxonomy/autocomplete', 'title' => t('autocomplete taxonomy'),
+ 'callback' => 'taxonomy_autocomplete',
+ 'access' => user_access('access content'),
+ 'type' => MENU_CALLBACK);
}
else {
if (is_numeric(arg(2))) {
@@ -519,7 +524,7 @@ function taxonomy_node_form($type, $node = '', $help = NULL, $name = 'taxonomy')
}
}
$typed_string = implode(', ', $typed_terms) . (array_key_exists('tags', $terms) ? $terms['tags'][$vocabulary->vid] : NULL);
- $result[] = form_textfield($vocabulary->name, "$name][tags][". $vocabulary->vid, $typed_string, 50, 100, t('A comma-separated list of terms describing this content (Example: funny, bungie jumping, "Company, Inc.").'), NULL, ($vocabulary->required ? TRUE : FALSE));
+ $result[] = form_autocomplete($vocabulary->name, "$name][tags][". $vocabulary->vid, $typed_string, 50, 100, 'taxonomy/autocomplete/'. $vocabulary->vid, t('A comma-separated list of terms describing this content (Example: funny, bungie jumping, "Company, Inc.").'), NULL, ($vocabulary->required ? TRUE : FALSE));
}
else {
$ntterms = array_key_exists('taxonomy', $node) ? $terms : array_keys($terms);
@@ -1259,4 +1264,36 @@ function _taxonomy_get_tid_from_term($term) {
return $term->tid;
}
+/**
+ * Helper function for autocompletion
+ */
+function taxonomy_autocomplete($vid, $string = '') {
+ // The user enters a comma-separated list of tags. We only autocomplete the last tag.
+ // This regexp allows the following types of user input:
+ // this, "somecmpany, llc", "and ""this"" w,o.rks", foo bar
+ $regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x';
+ preg_match_all($regexp, $string, $matches);
+ $array = $matches[1];
+
+ // Fetch last tag
+ $last_string = trim(array_pop($array));
+ if ($last_string != '') {
+ $result = db_query_range("SELECT name FROM {term_data} WHERE vid = %d AND LOWER(name) LIKE LOWER('%%%s%%')", $vid, $last_string, 0, 10);
+
+ $prefix = count($array) ? implode(', ', $array) .', ' : '';
+
+ $matches = array();
+ while ($tag = db_fetch_object($result)) {
+ $n = $tag->name;
+ // Commas and quotes in terms are special cases, so encode 'em.
+ if (preg_match('/,/', $tag->name) || preg_match('/"/', $tag->name)) {
+ $n = '"'. preg_replace('/"/', '""', $tag->name) .'"';
+ }
+ $matches[$prefix . $n] = check_plain($tag->name);
+ }
+ print drupal_implode_autocomplete($matches);
+ exit();
+ }
+}
+
?>
diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module
index 44586cf6b..81b3f7ae9 100644
--- a/modules/taxonomy/taxonomy.module
+++ b/modules/taxonomy/taxonomy.module
@@ -82,6 +82,11 @@ function taxonomy_menu($may_cache) {
'callback' => 'taxonomy_term_page',
'access' => user_access('access content'),
'type' => MENU_CALLBACK);
+
+ $items[] = array('path' => 'taxonomy/autocomplete', 'title' => t('autocomplete taxonomy'),
+ 'callback' => 'taxonomy_autocomplete',
+ 'access' => user_access('access content'),
+ 'type' => MENU_CALLBACK);
}
else {
if (is_numeric(arg(2))) {
@@ -519,7 +524,7 @@ function taxonomy_node_form($type, $node = '', $help = NULL, $name = 'taxonomy')
}
}
$typed_string = implode(', ', $typed_terms) . (array_key_exists('tags', $terms) ? $terms['tags'][$vocabulary->vid] : NULL);
- $result[] = form_textfield($vocabulary->name, "$name][tags][". $vocabulary->vid, $typed_string, 50, 100, t('A comma-separated list of terms describing this content (Example: funny, bungie jumping, "Company, Inc.").'), NULL, ($vocabulary->required ? TRUE : FALSE));
+ $result[] = form_autocomplete($vocabulary->name, "$name][tags][". $vocabulary->vid, $typed_string, 50, 100, 'taxonomy/autocomplete/'. $vocabulary->vid, t('A comma-separated list of terms describing this content (Example: funny, bungie jumping, "Company, Inc.").'), NULL, ($vocabulary->required ? TRUE : FALSE));
}
else {
$ntterms = array_key_exists('taxonomy', $node) ? $terms : array_keys($terms);
@@ -1259,4 +1264,36 @@ function _taxonomy_get_tid_from_term($term) {
return $term->tid;
}
+/**
+ * Helper function for autocompletion
+ */
+function taxonomy_autocomplete($vid, $string = '') {
+ // The user enters a comma-separated list of tags. We only autocomplete the last tag.
+ // This regexp allows the following types of user input:
+ // this, "somecmpany, llc", "and ""this"" w,o.rks", foo bar
+ $regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x';
+ preg_match_all($regexp, $string, $matches);
+ $array = $matches[1];
+
+ // Fetch last tag
+ $last_string = trim(array_pop($array));
+ if ($last_string != '') {
+ $result = db_query_range("SELECT name FROM {term_data} WHERE vid = %d AND LOWER(name) LIKE LOWER('%%%s%%')", $vid, $last_string, 0, 10);
+
+ $prefix = count($array) ? implode(', ', $array) .', ' : '';
+
+ $matches = array();
+ while ($tag = db_fetch_object($result)) {
+ $n = $tag->name;
+ // Commas and quotes in terms are special cases, so encode 'em.
+ if (preg_match('/,/', $tag->name) || preg_match('/"/', $tag->name)) {
+ $n = '"'. preg_replace('/"/', '""', $tag->name) .'"';
+ }
+ $matches[$prefix . $n] = check_plain($tag->name);
+ }
+ print drupal_implode_autocomplete($matches);
+ exit();
+ }
+}
+
?>
diff --git a/modules/user.module b/modules/user.module
index 9e148d3bc..6bf23f3d6 100644
--- a/modules/user.module
+++ b/modules/user.module
@@ -641,6 +641,9 @@ function user_menu($may_cache) {
$items[] = array('path' => 'user', 'title' => t('user account'),
'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
+ $items[] = array('path' => 'user/autocomplete', 'title' => t('user autocomplete'),
+ 'callback' => 'user_autocomplete', 'access' => $admin_access, 'type' => MENU_CALLBACK);
+
//registration and login pages.
$items[] = array('path' => 'user/login', 'title' => t('log in'),
'type' => MENU_DEFAULT_LOCAL_TASK);
@@ -1854,4 +1857,17 @@ function _user_forms(&$edit, $account, $category, $hook = 'form') {
return $output;
}
+/**
+ * Retrieve a pipe delimited string of autocomplete suggestions for existing users
+ */
+function user_autocomplete($string) {
+ $matches = array();
+ $result = db_query_range('SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER("%%%s%%")', $string, 0, 10);
+ while ($user = db_fetch_object($result)) {
+ $matches[$user->name] = check_plain($user->name);
+ }
+ print drupal_implode_autocomplete($matches);
+ exit();
+}
+
?>
diff --git a/modules/user/user.module b/modules/user/user.module
index 9e148d3bc..6bf23f3d6 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -641,6 +641,9 @@ function user_menu($may_cache) {
$items[] = array('path' => 'user', 'title' => t('user account'),
'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
+ $items[] = array('path' => 'user/autocomplete', 'title' => t('user autocomplete'),
+ 'callback' => 'user_autocomplete', 'access' => $admin_access, 'type' => MENU_CALLBACK);
+
//registration and login pages.
$items[] = array('path' => 'user/login', 'title' => t('log in'),
'type' => MENU_DEFAULT_LOCAL_TASK);
@@ -1854,4 +1857,17 @@ function _user_forms(&$edit, $account, $category, $hook = 'form') {
return $output;
}
+/**
+ * Retrieve a pipe delimited string of autocomplete suggestions for existing users
+ */
+function user_autocomplete($string) {
+ $matches = array();
+ $result = db_query_range('SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER("%%%s%%")', $string, 0, 10);
+ while ($user = db_fetch_object($result)) {
+ $matches[$user->name] = check_plain($user->name);
+ }
+ print drupal_implode_autocomplete($matches);
+ exit();
+}
+
?>