I ported textfield autocomplete to versin 6 NEED HELP

sfmerv - December 15, 2008 - 07:05

I ported the textfield autocomplete module to Drupal 6 using deadwood and coder. Coder tells me that everyting is fine but I do not get a text box to appear on the page when I have the auto complete setting selected in cck here is the code for the module

<?php
/**
* @author Ryan Hughes
*/
/**
* @file
* autocomplete text field.
*
*/

// $Id: textfield_autocomplete.module,v 1.1 2007/08/31 16:18:43 linuxbox Exp $

/* TODO db_next_id() is gone, and replaced as db_last_insert_id()
Since db_next_id() introduce some problems, and the use of this function
can be replaced by database level auto increment handling, db_next_id()
is now gone and replaced as db_last_insert_id() with help of serial type
under Schema API (check out http://drupal.org/node/149176 for more details).
Please refer to drupal_write_record() as demonstration. */

/* TODO FormAPI image buttons are now supported.
FormAPI now offers the 'image_button' element type, allowing developers to
use icons or other custom images in place of traditional HTML submit buttons.

$form['my_image_button'] = array(
'#type' => 'image_button',
'#title' => t('My button'),
'#return_value' => 'my_data',
'#src' => 'my/image/path.jpg',
); */

/* TODO Node previews and adding form fields to the node form.
There is a subtle but important difference in the way node previews (and other
such operations) are carried out when adding or editing a node. With the new
Forms API, the node form is handled as a multi-step form. When the node form
is previewed, all the form values are submitted, and the form is rebuilt with
those form values put into $form['#node']. Thus, form elements that are added
to the node form will lose any user input unless they set their '#default_value'
elements using this embedded node object. */

/* TODO New user_mail_tokens() method may be useful.
user.module now provides a user_mail_tokens() function to return an array
of the tokens available for the email notification messages it sends when
accounts are created, activated, blocked, etc. Contributed modules that
wish to make use of the same tokens for their own needs are encouraged
to use this function. */

/* TODO
There is a new hook_watchdog in core. This means that contributed modules
can implement hook_watchdog to log Drupal events to custom destinations.
Two core modules are included, dblog.module (formerly known as watchdog.module),
and syslog.module. Other modules in contrib include an emaillog.module,
included in the logging_alerts module. See syslog or emaillog for an
example on how to implement hook_watchdog.
function example_watchdog($log = array()) {
if ($log['severity'] == WATCHDOG_ALERT) {
mysms_send($log['user']->uid,
$log['type'],
$log['message'],
$log['variables'],
$log['severity'],
$log['referer'],
$log['ip'],
format_date($log['timestamp']));
}
} */

/* TODO Implement the hook_theme registry. Combine all theme registry entries
into one hook_theme function in each corresponding module file.
function textfield_autocomplete_theme() {
return array(
);
}; */

/* TODO
An argument for replacements has been added to format_plural(),
escaping and/or theming the values just as done with t().*/

/**
* Implementation of hook_menu().
*/
function textfield_autocomplete_menu() {
/* TODO
Non menu code that was placed in hook_menu under the '!$may_cache' block
so that it could be run during initialization, should now be moved to hook_init.
Previously we called hook_init twice, once early in the bootstrap process, second
just after the bootstrap has finished. The first instance is now called boot
instead of init.

In Drupal 6, there are now two hooks that can be used by modules to execute code
at the beginning of a page request. hook_boot() replaces hook_boot() in Drupal 5
and runs on each page request, even for cached pages. hook_boot() now only runs
for non-cached pages and thus can be used for code that was previously placed in
hook_menu() with $may_cache = FALSE:

Dynamic menu items under a '!$may_cache' block can often be simplified
to remove references to arg(n) and use of '%' to check
conditions. See http://drupal.org/node/103114.

The title and description arguments should not have strings wrapped in t(),
because translation of these happen in a later stage in the menu system.
*/
if ($may_cache) {
$items['textfield_autocomplete'] = array(
'title' => 'Textfield Autocomplete',
'page callback' => 'textfield_autocomplete',
'type' => MENU_CALLBACK,
'access arguments' => TRUE,
);
} // if may cache

return $items;
} // function nonsense_menu

/**
* Implementation of hook_widget_info().
*/
function textfield_autocomplete_widget_info() {
return array(
'autocomplete' => array(
'label' => 'Text Field With Autocomplete',
'field types' => array('text'),
),
);
}

/**
* Implementation of hook_widget().
*/
function textfield_autocomplete_widget($op, &$node, $field, &$items) {
switch ($op) {
case 'form':
$form = array();

$form[$field['field_name']] = array('#tree' => TRUE);

if ($field['multiple']) {
$form[$field['field_name']]['#type'] = 'fieldset';
$form[$field['field_name']]['#description'] = t($field['widget']['description']);
$delta = 0;
foreach ($items as $data) {
if ($data['value']) {
$form[$field['field_name']][$delta]['value'] = array(
'#type' => 'textfield',
'#title' => ($delta == 0) ? t($field['widget']['label']) : '',
'#default_value' => $data['value'],
'#required' => ($delta == 0) ? $field['required'] : FALSE,
'#maxlength' => $field['max_length'] ? $field['max_length'] : NULL,
'#weight' => $field['widget']['weight'],
'#autocomplete_path' => 'textfield_autocomplete/'. $field['field_name'],
);
if ($field['text_processing']) {
$form[$field['field_name']][$delta]['format'] = filter_form($data['format'], $form[$field['field_name']][$delta]['value']['#weight'] + 1, array($field['field_name'], $delta, 'format'));
}
$delta++;
} // if this is an item with a value
} // foreach item
foreach (range($delta, $delta + 2) as $delta) {
$form[$field['field_name']][$delta]['value'] = array(
'#type' => 'textfield',
'#title' => ($delta == 0) ? t($field['widget']['label']) : '',
'#default_value' => '',
'#required' => ($delta == 0) ? $field['required'] : FALSE,
'#maxlength' => $field['max_length'] ? $field['max_length'] : NULL,
'#weight' => $field['widget']['weight'],
'#autocomplete_path' => 'textfield_autocomplete/'. $field['field_name'],
);
if ($field['text_processing']) {
$form[$field['field_name']][$delta]['format'] = filter_form($items[$delta]['format'], $form[$field['field_name']][$delta]['value']['#weight'] + 1, array($field['field_name'], $delta, 'format'));
}
} // foreach item in the range of (end - end+2)
} // if it's multiple
else {
$form[$field['field_name']][0]['value'] = array(
'#type' => 'textfield',
'#title' => t($field['widget']['label']),
'#default_value' => isset($items[0]['value']) ? $items[0]['value'] : '',
'#required' => $field['required'],
'#description' => t($field['widget']['description']),
'#maxlength' => $field['max_length'] ? $field['max_length'] : NULL,
'#weight' => $field['widget']['weight'],
'#autocomplete_path' => 'textfield_autocomplete/'. $field['field_name'],
);
if ($field['text_processing']) {
$form[$field['field_name']][0]['format'] = filter_form($items[0]['format'], $form[$field['field_name']][0]['value']['#weight'] + 1, array($field['field_name'], 0, 'format'));
}
} // else it's not multiple
return $form;

case 'process form values':
// Don't save empty fields except the first value
foreach ($items as $delta => $item) {
if ($item['value'] == '' && $delta > 0) {
unset($items[$delta]);
}
}
break;
} // switch op
} // function textfield_autocomplete_widget

/**
* Callback to return the values for autocomplete.
*/
function textfield_autocomplete($fieldname, $startswith) {
/*
$items = func_get_args();
$items = array_combine($items, $items);
echo drupal_to_js($items);
die();
*/

$field = content_fields($fieldname);
$db_info = content_database_info($field);
$getdatafrom[$db_info['table']][$db_info['columns']['value']['column']] = TRUE;

$items = array();
foreach ($getdatafrom as $table => $columns) {
$cols = array_keys($columns);

// I do this self-join business because I want the latest version ID.
// So I join with itself, saying I want all the pairs of
// (a row, a row with a greater version id).
// Then I cut it down, saying I only want ones where the one with the
// greater version id is null.
// Taken together, it's like saying "Give me all the ones such that there
// is no row with a greater version id."
// Doing it this way means that I don't have to do a subselect, which can
// be slow.
$likes = array();
$likes_vals = array();
foreach ($cols as $col) {
$likes[] = "A.". $col ." LIKE '%s%%'";
$likes_vals[] = $startswith;
} // foreach likes

$query = "SELECT DISTINCT A.". implode(', A.', $cols) ."
FROM {". $table ."} A
LEFT JOIN {". $table ."} B ON (A.nid=B.nid AND B.vid > A.vid)
WHERE B.vid IS NULL
AND ". implode(" AND ", $likes);
$result = db_query($query, $likes_vals);

while ($row = db_fetch_array($result)) {
foreach ($row as $colname => $colval) {
$items[] = $colval;
} // foreach col value
} // while there's rows
} // foreach table

if ($items) {
$items = array_combine($items, $items);
}
echo drupal_to_js($items);
die();
} // function nonsense_autocomplete

 
 

Drupal is a registered trademark of Dries Buytaert.