Revision: 1837
http://mrbs.svn.sourceforge.net/mrbs/?rev=1837&view=rev
Author: cimorrison
Date: 2011-06-21 08:51:00 +0000 (Tue, 21 Jun 2011)
Log Message:
-----------
- On the Report page, converted input fields into auto-complete fields for
custom fields that have select_options defined
- For custom fields allowed $select_options to be an associative array, thus
making it easy to change the displayed value without having to change the
database. (See SF #3315966)
Modified Paths:
--------------
mrbs/trunk/INSTALL
mrbs/trunk/web/Themes/default/header.inc
mrbs/trunk/web/dbsys.inc
mrbs/trunk/web/edit_users.php
mrbs/trunk/web/functions.inc
mrbs/trunk/web/functions_mail.inc
mrbs/trunk/web/functions_view.inc
mrbs/trunk/web/report.php
mrbs/trunk/web/search.php
mrbs/trunk/web/systemdefaults.inc.php
Modified: mrbs/trunk/INSTALL
===================================================================
--- mrbs/trunk/INSTALL 2011-06-08 10:31:11 UTC (rev 1836)
+++ mrbs/trunk/INSTALL 2011-06-21 08:51:00 UTC (rev 1837)
@@ -221,6 +221,20 @@
would define the 'conference_facilities' custom field to have three
possible values.
+For custom fields only (will be extended later) it is also possible to use
+an associative array for $select_options, for example
+
+$select_options['entry.catering'] = array('c' => 'Coffee',
+ 's' => 'Sandwiches',
+ 'h' => 'Hot Lunch');
+
+In this case the key (eg 'c') is stored in the database, but the value
+(eg 'Coffee') is displayed and can be searched for using Search and Report.
+This allows you to alter the displayed values, for example changing 'Coffee'
+to 'Coffee, Tea and Biscuits', without having to alter the database. It can
also
+be useful if the database table is being shared with another application.
+MRBS will auto-detect whether the array is associative.
+
2)
You can specify that a field is mandatory. This will ensure that the
Modified: mrbs/trunk/web/Themes/default/header.inc
===================================================================
--- mrbs/trunk/web/Themes/default/header.inc 2011-06-08 10:31:11 UTC (rev
1836)
+++ mrbs/trunk/web/Themes/default/header.inc 2011-06-21 08:51:00 UTC (rev
1837)
@@ -3,34 +3,28 @@
// $Id$
// Generates the JavaScript code to turn the input with id $id
-// into an autocomplete box. The options will be contained in the
-// first element of each row of the result from the SQL query $sql
-// (eg "SELECT area_name FROM $tbl_area ORDER BY area_name")
-function generate_autocomplete($id, $sql)
+// into an autocomplete box, with options contained in the
+// array $options.
+function generate_autocomplete($id, $options)
{
global $autocomplete_length_breaks;
$js = '';
- $res = sql_query($sql);
- if ($res && (sql_count($res) > 0))
+ $n_options = count($options);
+ if ($n_options > 0)
{
- $names = array();
- for ($i = 0; ($row = sql_row($res, $i)); $i++)
- {
- $names[] = escape_js($row[0]);
- }
// Work out a suitable value for the autocomplete minLength
// option, ie the number of characters that must be typed before
// a list of options appears. We want to avoid presenting a huge
// list of options.
- $n_names = count($names);
+
$min_length = 0;
if (isset($autocomplete_length_breaks) &&
is_array($autocomplete_length_breaks))
{
foreach ($autocomplete_length_breaks as $break)
{
- if ($n_names < $break)
+ if ($n_options < $break)
{
break;
}
@@ -38,7 +32,12 @@
}
}
// Start forming the array literal
- $names_string = "'" . implode("','", $names) . "'";
+ // Escape the options
+ for ($i=0; $i < $n_options; $i++)
+ {
+ $options[$i] = escape_js($options[$i]);
+ }
+ $options_string = "'" . implode("','", $options) . "'";
// Build the JavaScript. We don't support autocomplete in IE6 and below
// because the browser doesn't render the autocomplete box properly - it
// gets hidden behind other elements. Although there are fixes for this,
@@ -46,7 +45,7 @@
$js .= "if ($('#ielte6').length == 0)\n";
$js .= "{\n";
$js .= " $('#$id').autocomplete({\n";
- $js .= " source: [$names_string],\n";
+ $js .= " source: [$options_string],\n";
$js .= " minLength: $min_length\n";
$js .= " })";
// If the minLength is 0, then the autocomplete widget doesn't do
@@ -76,6 +75,7 @@
global $default_language_tokens, $disable_automatic_language_changing,
$override_locale;
global $lang_map_windows, $langs, $server_os;
global $default_duration_all_day;
+ global $select_options;
$page = basename($PHP_SELF, ".php");
$user = getUserName();
@@ -932,14 +932,30 @@
if ($page == 'report')
{
// Make the area match input on the report page into an auto-complete input
- $sql = "SELECT area_name FROM $tbl_area ORDER BY area_name";
- echo generate_autocomplete('areamatch', $sql);
+ $options = sql_query_array("SELECT area_name FROM $tbl_area ORDER BY
area_name");
+ if ($options !== FALSE)
+ {
+ echo generate_autocomplete('areamatch', $options);
+ }
// Make the room match input on the report page into an auto-complete input
// (We need DISTINCT because it's possible to have two rooms of the same
name
// in different areas)
- $sql = "SELECT DISTINCT room_name FROM $tbl_room ORDER BY room_name";
- echo generate_autocomplete('roommatch', $sql);
+ $options = sql_query_array("SELECT DISTINCT room_name FROM $tbl_room ORDER
BY room_name");
+ if ($options !== FALSE)
+ {
+ echo generate_autocomplete('roommatch', $options);
+ }
+
+ // Make any custom fields for the entry table that have an array of options
+ // into auto-complete inputs
+ foreach ($select_options as $field => $options)
+ {
+ if (strpos($field, 'entry.') == 0)
+ {
+ echo generate_autocomplete('match_' . substr($field,
strlen('entry.')), $options);
+ }
+ }
}
// SEARCH.PHP
Modified: mrbs/trunk/web/dbsys.inc
===================================================================
--- mrbs/trunk/web/dbsys.inc 2011-06-08 10:31:11 UTC (rev 1836)
+++ mrbs/trunk/web/dbsys.inc 2011-06-21 08:51:00 UTC (rev 1837)
@@ -99,6 +99,35 @@
}
+// Run an SQL query that returns a simple one dimensional array of results.
+// The SQL query must select only one column. Returns an empty array if
+// no results, or FALSE if there's an error
+function sql_query_array($sql)
+{
+ if (func_num_args() > 1)
+ {
+ $handle = func_get_arg(1);
+ $db_conn = $handle['connection'];
+ }
+
+ $res = ($db_conn) ? sql_query($sql, $db_conn) : sql_query($sql);
+
+ if ($res === FALSE)
+ {
+ return FALSE;
+ }
+ else
+ {
+ $result = array();
+ for ($i = 0; ($row = sql_row($res, $i)); $i++)
+ {
+ $result[] = $row[0];
+ }
+ return $result;
+ }
+}
+
+
// Run a SQL query, returns a result object
function sql_query($sql)
{
@@ -115,7 +144,6 @@
$db_sys = $dbsys;
$db_conn = null;
}
-
$f = "sql_${db_sys}_query";
return $f($sql, $db_conn);
}
Modified: mrbs/trunk/web/edit_users.php
===================================================================
--- mrbs/trunk/web/edit_users.php 2011-06-08 10:31:11 UTC (rev 1836)
+++ mrbs/trunk/web/edit_users.php 2011-06-21 08:51:00 UTC (rev 1837)
@@ -134,6 +134,7 @@
global $tbl_users, $PHP_SELF;
global $user, $level, $min_user_editing_level, $max_content_length;
global $fields, $auth;
+ global $select_options;
$html = '';
$html .= "<div class=\"$class\">\n";
@@ -216,7 +217,14 @@
$html .= "<td><div>" . htmlspecialchars($col_value) .
"</div></td>\n";
break;
default:
- if (($field['nature'] == 'boolean') ||
+ // Where there's an associative array of options, display
+ // the value rather than the key
+ if (is_assoc($select_options["users.$key"]))
+ {
+ $col_value = $select_options["users.$key"][$line[$key]];
+ $html .= "<td><div>" . htmlspecialchars($col_value) .
"</div></td>\n";
+ }
+ elseif (($field['nature'] == 'boolean') ||
(($field['nature'] == 'integer') && isset($field['length']) &&
($field['length'] <= 2)) )
{
// booleans: represent by a checkmark
Modified: mrbs/trunk/web/functions.inc
===================================================================
--- mrbs/trunk/web/functions.inc 2011-06-08 10:31:11 UTC (rev 1836)
+++ mrbs/trunk/web/functions.inc 2011-06-21 08:51:00 UTC (rev 1837)
@@ -359,8 +359,8 @@
// Generates a select box from $options, an array of options
// If $disabled is TRUE, then the select box is disabled and a hidden
-// input is generated to pass through $value
-function generate_select($label_text, $name, $value, $options,
+// input is generated to pass through $current
+function generate_select($label_text, $name, $current, $options,
$mandatory = FALSE, $disabled=FALSE)
{
// generate the HTML
@@ -370,20 +370,33 @@
$html .= ">\n";
if ($mandatory)
{
- $options = array_merge(array(""),$options);
+ $options = array_merge(array('' => ''),$options);
}
- foreach ($options as $option)
+ // We can cope with both associative and ordinary arrays
+ if (is_assoc($options))
{
- $html .= "<option";
- $html .= (isset($value) && ($value == $option)) ? " selected=\"selected\""
: '';
- $html .= ">".htmlspecialchars($option)."</option>\n";
+ foreach ($options as $key => $value)
+ {
+ $html .= "<option value=\"$key\"";
+ $html .= (isset($current) && ($current == $key)) ? "
selected=\"selected\"" : '';
+ $html .= ">".htmlspecialchars($value)."</option>\n";
+ }
}
+ else
+ {
+ foreach ($options as $option)
+ {
+ $html .= "<option";
+ $html .= (isset($current) && ($current == $option)) ? "
selected=\"selected\"" : '';
+ $html .= ">".htmlspecialchars($option)."</option>\n";
+ }
+ }
$html .= "</select>\n";
// and a hidden input if the select box is disabled
if ($disabled)
{
$html .= "<input type=\"hidden\" name=\"$name\" value=\"".
- htmlspecialchars($value)."\">\n";
+ htmlspecialchars($current)."\">\n";
}
echo $html;
@@ -1859,4 +1872,11 @@
return $uid;
}
+// Tests whether an array is associative
+//
+// Thanks to magentix at gmail dot com at
http://php.net/manual/function.is-array.php
+function is_assoc($arr)
+{
+ return (is_array($arr) && count(array_filter(array_keys($arr),'is_string'))
== count($arr));
+}
?>
Modified: mrbs/trunk/web/functions_mail.inc
===================================================================
--- mrbs/trunk/web/functions_mail.inc 2011-06-08 10:31:11 UTC (rev 1836)
+++ mrbs/trunk/web/functions_mail.inc 2011-06-21 08:51:00 UTC (rev 1837)
@@ -388,6 +388,7 @@
global $enable_periods, $approval_enabled, $confirmation_enabled;
global $typel, $mail_settings, $standard_fields, $url_base;
global $tbl_entry;
+ global $select_options;
// set up the body
$body = "";
@@ -595,11 +596,22 @@
(($field['nature'] == 'integer') && isset($field['length']) &&
($field['length'] <= 2)) )
{
$value = ($value) ? get_mail_vocab("yes") : get_mail_vocab("no");
- if (!$compare)
+ if ($compare)
{
$mail_previous[$key] = ($mail_previous[$key]) ?
get_mail_vocab("yes") : get_mail_vocab("no");
}
}
+ // For any associative arrays we want the value rather than the key
+ if (is_assoc($select_options["entry.$key"]) &&
+ array_key_exists($value, $select_options["entry.$key"]))
+ {
+ $value = $select_options["entry.$key"][$value];
+ if ($compare &&
+ array_key_exists($mail_previous[$key],
$select_options["entry.$key"]))
+ {
+ $mail_previous[$key] =
$select_options["entry.$key"][$mail_previous[$key]];
+ }
+ }
$body .= create_body_table_row (get_mail_field_name($tbl_entry, $key),
convertToMailCharset($value),
convertToMailCharset($mail_previous[$key]),
Modified: mrbs/trunk/web/functions_view.inc
===================================================================
--- mrbs/trunk/web/functions_view.inc 2011-06-08 10:31:11 UTC (rev 1836)
+++ mrbs/trunk/web/functions_view.inc 2011-06-21 08:51:00 UTC (rev 1837)
@@ -40,6 +40,7 @@
global $is_private_field, $standard_fields, $typel;
global $strftime_format;
global $tbl_entry;
+ global $select_options;
// Get the duration if we haven't got it already
if (!isset($data['duration']))
@@ -174,7 +175,24 @@
// Otherwise output a string
else
{
- $value = (isset($data[$key])) ? $data[$key] : " ";
+ if (isset($data[$key]))
+ {
+ // If the custom field is an associative array then we want
+ // the value rather than the array key
+ if (is_assoc($select_options["entry.$key"]) &&
+ array_key_exists($data[$key], $select_options["entry.$key"]))
+ {
+ $value = $select_options["entry.$key"][$data[$key]];
+ }
+ else
+ {
+ $value = $data[$key];
+ }
+ }
+ else
+ {
+ $value = " ";
+ }
}
$class = ($keep_private && $is_private_field["entry.$key"]) ? "private"
: "";
$tbody .= create_details_row($label, $value, $as_html, $class);
Modified: mrbs/trunk/web/report.php
===================================================================
--- mrbs/trunk/web/report.php 2011-06-08 10:31:11 UTC (rev 1836)
+++ mrbs/trunk/web/report.php 2011-06-21 08:51:00 UTC (rev 1837)
@@ -196,6 +196,7 @@
global $custom_fields, $field_natures, $field_lengths, $tbl_entry;
global $approval_somewhere, $confirmation_somewhere;
global $strftime_format;
+ global $select_options;
// Initialise the line for CSV reports
$line = "";
@@ -397,9 +398,23 @@
$output = empty($row[$key]) ? get_vocab("no") : get_vocab("yes");
}
// Otherwise output a string
+ elseif (isset($row[$key]))
+ {
+ // If the custom field is an associative array then we want
+ // the value rather than the array key
+ if (is_assoc($select_options["entry.$key"]) &&
+ array_key_exists($row[$key], $select_options["entry.$key"]))
+ {
+ $output = $select_options["entry.$key"][$row[$key]];
+ }
+ else
+ {
+ $output = $row[$key];
+ }
+ }
else
{
- $output = (isset($row[$key])) ? $row[$key] : '';
+ $output = '';
}
if ($output_as_csv)
@@ -978,8 +993,31 @@
foreach ($custom_fields as $key => $value)
{
$var = "match_$key";
+ // Associative arrays
+ if (!empty($var) && is_assoc($select_options["entry.$key"]))
+ {
+ $sql .= " AND ";
+ $or_array = array();
+ foreach($select_options["entry.$key"] as $option_key => $option_value)
+ {
+ // We have to use strpos() rather than stripos() because we cannot
+ // assume PHP5
+ if (strpos(strtolower($option_value), strtolower($$var)) !== FALSE)
+ {
+ $or_array[] = "E.$key='" . addslashes($option_key) . "'";
+ }
+ }
+ if (count($or_array) > 0)
+ {
+ $sql .= "(". implode( " OR ", $or_array ) .")";
+ }
+ else
+ {
+ $sql .= "FALSE";
+ }
+ }
// Booleans (or integers <= 2 bytes which we assume are intended to be
booleans)
- if (($field_natures[$key] == 'boolean') ||
+ elseif (($field_natures[$key] == 'boolean') ||
(($field_natures[$key] == 'integer') && isset($field_lengths[$key]) &&
($field_lengths[$key] <= 2)) )
{
if (!empty($$var))
Modified: mrbs/trunk/web/search.php
===================================================================
--- mrbs/trunk/web/search.php 2011-06-08 10:31:11 UTC (rev 1836)
+++ mrbs/trunk/web/search.php 2011-06-21 08:51:00 UTC (rev 1837)
@@ -81,14 +81,29 @@
. " OR " . sql_syntax_caseless_contains("E.name", $search_str)
. " OR " . sql_syntax_caseless_contains("E.description", $search_str);
-// Also need to search custom fields (but only those with character data)
+// Also need to search custom fields (but only those with character data,
+// which can include fields that have an associative array of options)
$fields = sql_field_info($tbl_entry);
foreach ($fields as $field)
{
if (!in_array($field['name'], $standard_fields['entry']))
{
- if ($field['nature'] == 'character')
+ // If we've got a field that is represented by an associative array of
options
+ // then we have to search for the keys whose values match the search string
+ if (is_assoc($select_options["entry." . $field['name']]))
{
+ foreach($select_options["entry." . $field['name']] as $key => $value)
+ {
+ // We have to use strpos() rather than stripos() because we cannot
+ // assume PHP5
+ if (strpos(strtolower($value), strtolower($search_str)) !== FALSE)
+ {
+ $sql_pred .= " OR E." . $field['name'] . "='" . addslashes($key) .
"'";
+ }
+ }
+ }
+ elseif ($field['nature'] == 'character')
+ {
$sql_pred .= " OR " . sql_syntax_caseless_contains("E." .
$field['name'], $search_str);
}
}
@@ -162,6 +177,7 @@
ORDER BY E.start_time asc "
. sql_syntax_limit($search["count"], $search_pos);
+
// this is a flag to tell us not to display a "Next" link
$result = sql_query($sql);
if (! $result)
Modified: mrbs/trunk/web/systemdefaults.inc.php
===================================================================
--- mrbs/trunk/web/systemdefaults.inc.php 2011-06-08 10:31:11 UTC (rev
1836)
+++ mrbs/trunk/web/systemdefaults.inc.php 2011-06-21 08:51:00 UTC (rev
1837)
@@ -429,10 +429,24 @@
//$select_options['entry.name'] = array('Physics', 'Chemistry', 'Biology');
-// At the moment this feature is only supported as follows:
+// At the moment $select_options is only supported as follows:
// - Entry table: name, description and custom fields
// - Users table: custom fields
+// For custom fields only (will be extended later) it is also possible to use
+// an associative array for $select_options, for example
+
+//$select_options['entry.catering'] = array('c' => 'Coffee',
+// 's' => 'Sandwiches',
+// 'h' => 'Hot Lunch');
+
+// In this case the key (eg 'c') is stored in the database, but the value
+// (eg 'Coffee') is displayed and can be searched for using Search and Report.
+// This allows you to alter the displayed values, for example changing 'Coffee'
+// to 'Coffee, Tea and Biscuits', without having to alter the database. It
can also
+// be useful if the database table is being shared with another application.
+// MRBS will auto-detect whether the array is associative.
+
$is_mandatory_field = array();
// You can define custom entry fields to be mandatory by setting
// items in the array $is_mandatory_field. (Note that making a checkbox
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev
_______________________________________________
Mrbs-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mrbs-commits