Revision: 1938
http://mrbs.svn.sourceforge.net/mrbs/?rev=1938&view=rev
Author: cimorrison
Date: 2011-09-08 18:05:32 +0000 (Thu, 08 Sep 2011)
Log Message:
-----------
Merged in latest changes from trunk
Modified Paths:
--------------
mrbs/branches/datatables/web/Themes/default/header.inc
mrbs/branches/datatables/web/edit_entry.php
mrbs/branches/datatables/web/edit_entry_handler.php
mrbs/branches/datatables/web/lang.en
mrbs/branches/datatables/web/mrbs.css.php
mrbs/branches/datatables/web/mrbs_sql.inc
mrbs/branches/datatables/web/report.php
Property Changed:
----------------
mrbs/branches/datatables/
mrbs/branches/datatables/web/upgrade/5/pgsql.sql
Property changes on: mrbs/branches/datatables
___________________________________________________________________
Modified: svn:mergeinfo
- /mrbs/branches/custom_entry_fields:1374-1396
/mrbs/branches/datepicker:1409-1416
/mrbs/branches/disabled_rooms:1601-1634
/mrbs/branches/from_to_bookings:1491-1587
/mrbs/branches/ics_attachments:1652-1741
/mrbs/branches/improve_css_2008_06:804-872
/mrbs/branches/only_unicode:1747-1749
/mrbs/branches/provisional_bookings:1242-1280
/mrbs/branches/provisional_bookings_new_style:1407-1570
/mrbs/trunk:1863-1933
+ /mrbs/branches/custom_entry_fields:1374-1396
/mrbs/branches/datepicker:1409-1416
/mrbs/branches/disabled_rooms:1601-1634
/mrbs/branches/from_to_bookings:1491-1587
/mrbs/branches/ics_attachments:1652-1741
/mrbs/branches/improve_css_2008_06:804-872
/mrbs/branches/only_unicode:1747-1749
/mrbs/branches/provisional_bookings:1242-1280
/mrbs/branches/provisional_bookings_new_style:1407-1570
/mrbs/trunk:1863-1937
Modified: mrbs/branches/datatables/web/Themes/default/header.inc
===================================================================
--- mrbs/branches/datatables/web/Themes/default/header.inc 2011-09-08
18:00:20 UTC (rev 1937)
+++ mrbs/branches/datatables/web/Themes/default/header.inc 2011-09-08
18:05:32 UTC (rev 1938)
@@ -353,6 +353,14 @@
?>
adjustSlotSelectors(document.getElementById('main'));
<?php
+ if (function_exists('json_encode'))
+ {
+ // If we're doing Ajax checking of the form then we have to validate
+ // the form when the datepicker is closed
+ ?>
+ checkValidBooking();
+ <?php
+ }
}
?>
if (formId)
@@ -422,6 +430,125 @@
if ($page == 'edit_entry')
{
+
+ // Add Ajax capabilities (but only if we can return the result as a JSON
object)
+ if (function_exists('json_encode'))
+ {
+ // Form an array of all the form parameters that could affect whether a
booking can be made, ie
+ // whether it will conflict with another booking or break a policy rule.
(So for example 'name'
+ // and 'description' won't make any difference, but 'type' could be used
in policy checking).
+ $params = array('area', 'rooms[]', 'create_by', 'type', 'all_day', 'id',
'rep_id', 'edit_type',
+ 'start_seconds', 'start_day', 'start_month', 'start_year',
+ 'end_seconds', 'end_day', 'end_month', 'end_year',
+ 'rep_type', 'rep_end_day', 'rep_end_month',
'rep_end_year', 'rep_day[]', 'rep_num_weeks');
+
+ // function to check whether the proposed booking would (a) conflict with
any other bookings
+ // and (b) conforms to the booking policies. Makes an Ajax call to
edit_entry_handler but does
+ // not actually make the booking.
+ ?>
+ function checkValidBooking()
+ {
+ var params = {'ajax': 1}; // This is an Ajax request
+ var form = $('form#main');
+ var formInput;
+ <?php
+
+ foreach ($params as $param)
+ {
+ // Scalar parameters (two types - checkboxes and the rest)
+ if (strpos($param, '[]') === FALSE)
+ {
+ ?>
+ formInput = form.find('[name="<?php echo $param ?>"]');
+ if (formInput.filter(':checkbox').length > 0)
+ {
+ params.<?php echo $param ?> = formInput.is(':checked') ? '1' : '';
+ }
+ else
+ {
+ params.<?php echo $param ?> = formInput.val();
+ }
+ <?php
+ }
+ // Array parameters (two types - checkboxes and the rest)
+ else
+ {
+ ?>
+ formInput = form.find('[name="<?php echo $param ?>"]');
+ params['<?php echo $param ?>'] = [];
+ if (formInput.filter(':checkbox').length > 0)
+ {
+ formInput.each(function(index) {
+ if ($(this).is(':checked'))
+ {
+ params['<?php echo $param ?>'].push($(this).val());
+ }
+ });
+ }
+ else
+ {
+ formInput.each(function(index) {
+ params['<?php echo $param ?>'].push($(this).val());
+ });
+ }
+ <?php
+ // For some reason I don't understand, posting an empty array will
+ // give you a PHP array of ('') at the other end. So to avoid
+ // that problem, delete the property if the array is empty
+ ?>
+ if (params['<?php echo $param ?>'].length == 0)
+ {
+ delete params['<?php echo $param ?>'];
+ }
+ <?php
+ }
+ }
+ ?>
+ $.post('edit_entry_handler.php', params, function(result) {
+ var conflictDiv = $('#conflict_check');
+ var checkMark = "\u2714";
+ var cross = "\u2718";
+ var titleText;
+ var patternSpan = /<span[\s\S]*span>/gi;
+ var patternTags = /<\S[^><]*>/g;
+ if (result.conflicts.length == 0)
+ {
+ conflictDiv.text(checkMark).attr('class', 'good').attr;
+ titleText = '<?php echo get_vocab("no_conflicts") ?>';
+ }
+ else
+ {
+ conflictDiv.text(cross).attr('class', 'bad');
+ titleText = '<?php echo get_vocab("conflict") ?>' + ": \n\n";
+ for (var i=0; i<result.conflicts.length; i++)
+ {
+ titleText += '(' + (i+1).toString() + ') ';
+ <?php // strip out the <span> and its contents and then all
other tags ?>
+ titleText += result.conflicts[i].replace(patternSpan,
'').replace(patternTags, '') + " \n";
+ }
+ }
+ conflictDiv.attr('title', titleText);
+ var policyDiv = $('#policy_check');
+ if (result.rules_broken.length == 0)
+ {
+ policyDiv.text(checkMark).attr('class', 'good');
+ titleText = '<?php echo get_vocab("no_rules_broken") ?>';
+ }
+ else
+ {
+ policyDiv.text(cross).attr('class', 'bad');
+ titleText = '<?php echo get_vocab("rules_broken") ?>' + ": \n\n";
+ for (var i=0; i<result.rules_broken.length; i++)
+ {
+ titleText += '(' + (i+1).toString() + ') ' +
result.rules_broken[i] + " \n";
+ }
+ }
+ policyDiv.attr('title', titleText);
+ }, 'json');
+ }
+ <?php
+ }
+
// Declare some variables to hold details of the slot selectors for each
area.
// We are going to store the contents of the selectors on page load
// (when they will be fully populated with options) so that we can
@@ -961,6 +1088,9 @@
// complete that field, but if it's an existing booking you might
// want to edit any field)
// (2) Adjust the slot selectors
+ // (3) Add some Ajax capabilities to the form (if we can) so that when
+ // a booking parameter is changed MRBS checks to see whether there would
+ // be any conflicts
if ($page == 'edit_entry')
{
?>
@@ -1050,6 +1180,43 @@
OnAllDayClick(true);
<?php
}
+
+ // Add Ajax capabilities (but only if we can return the result as a JSON
object)
+ if (function_exists('json_encode'))
+ {
+ // Add a change event handler to each of the form fields so that when they
change
+ // the validity of the booking is re-checked. Use a click event for
checkboxes
+ // as it seems that in some browsers the event fires before the value is
changed.
+
+ // Note that we also need to add change event handlers to the start and end
+ // datepicker input fields, but we have to that in datepicker_close()
+ ?>
+ var form = $('form#main');
+ var formInput;
+ <?php
+ foreach ($params as $param)
+ {
+ ?>
+ formInput = form.find('[name="<?php echo $param ?>"]');
+ if (formInput.filter(':checkbox').length > 0)
+ {
+ formInput.click(function() {
+ checkValidBooking();
+ });
+ }
+ else
+ {
+ formInput.change(function() {
+ checkValidBooking();
+ });
+ }
+ <?php
+ }
+ ?>
+
+ checkValidBooking();
+ <?php
+ }
?>
<?php
Modified: mrbs/branches/datatables/web/edit_entry.php
===================================================================
--- mrbs/branches/datatables/web/edit_entry.php 2011-09-08 18:00:20 UTC (rev
1937)
+++ mrbs/branches/datatables/web/edit_entry.php 2011-09-08 18:05:32 UTC (rev
1938)
@@ -1258,6 +1258,14 @@
echo "<input class=\"submit\" type=\"submit\" name=\"save_button\"
value=\"" .
get_vocab("save") . "\" onclick=\"return validate('main')\">\n";
echo "</div>\n";
+
+ // divs to hold the results of the Ajax checking of the booking
+ echo "<div id=\"conflict_check\">\n";
+ echo "</div>\n";
+
+ echo "<div id=\"policy_check\">\n";
+ echo "</div>\n";
+
echo "</fieldset>";
?>
</fieldset>
Modified: mrbs/branches/datatables/web/edit_entry_handler.php
===================================================================
--- mrbs/branches/datatables/web/edit_entry_handler.php 2011-09-08 18:00:20 UTC
(rev 1937)
+++ mrbs/branches/datatables/web/edit_entry_handler.php 2011-09-08 18:05:32 UTC
(rev 1938)
@@ -18,6 +18,9 @@
// <input type="checkbox" name="foo[m]" value="1">
+// This page can be called with an Ajax call. In this case it just checks
+// the validity of a proposed booking and does not make the booking.
+
// Get non-standard form variables
$formvars = array('create_by' => 'string',
'name' => 'string',
@@ -51,7 +54,8 @@
'end_day' => 'int',
'end_month' => 'int',
'end_year' => 'int',
- 'back_button' => 'string');
+ 'back_button' => 'string',
+ 'ajax' => 'int');
foreach($formvars as $var => $var_type)
{
@@ -223,7 +227,6 @@
exit;
}
-
// Check that the user has permission to create/edit an entry for this room.
// Get the id of the room that we are creating/editing
if (isset($id))
@@ -258,55 +261,59 @@
exit;
}
-if ($name == '')
+// Form validation checks. Normally checked for client side.
+// Don't bother with them if this is an Ajax request.
+if (!$ajax)
{
- print_header($day, $month, $year, $area, isset($room) ? $room : "");
-?>
- <h1><?php echo get_vocab('invalid_booking'); ?></h1>
- <p>
- <?php echo get_vocab('must_set_description'); ?>
- </p>
-<?php
- // Print footer and exit
- print_footer(TRUE);
-}
+ if ($name == '')
+ {
+ print_header($day, $month, $year, $area, isset($room) ? $room : "");
+ ?>
+ <h1><?php echo get_vocab('invalid_booking'); ?></h1>
+ <p>
+ <?php echo get_vocab('must_set_description'); ?>
+ </p>
+ <?php
+ // Print footer and exit
+ print_footer(TRUE);
+ }
-if (($rep_type == REP_N_WEEKLY) && ($rep_num_weeks < 2))
-{
- print_header($day, $month, $year, $area, isset($room) ? $room : "");
-?>
- <h1><?php echo get_vocab('invalid_booking'); ?></h1>
- <p>
- <?php echo get_vocab('you_have_not_entered')."
".get_vocab("useful_n-weekly_value"); ?>
- </p>
-<?php
- // Print footer and exit
- print_footer(TRUE);
-}
+ if (($rep_type == REP_N_WEEKLY) && ($rep_num_weeks < 2))
+ {
+ print_header($day, $month, $year, $area, isset($room) ? $room : "");
+ ?>
+ <h1><?php echo get_vocab('invalid_booking'); ?></h1>
+ <p>
+ <?php echo get_vocab('you_have_not_entered')."
".get_vocab("useful_n-weekly_value"); ?>
+ </p>
+ <?php
+ // Print footer and exit
+ print_footer(TRUE);
+ }
-if (count($is_mandatory_field))
-{
- foreach ($is_mandatory_field as $field => $value)
+ if (count($is_mandatory_field))
{
- $field = preg_replace('/^entry\./', '', $field);
- if ($value && ($custom_fields[$field] == ''))
+ foreach ($is_mandatory_field as $field => $value)
{
- print_header($day, $month, $year, $area, isset($room) ? $room : "");
-?>
- <h1><?php echo get_vocab('invalid_booking'); ?></h1>
- <p>
- <?php echo get_vocab('missing_mandatory_field')." \"".
- get_loc_field_name($tbl_entry, $field)."\""; ?>
- </p>
-<?php
- // Print footer and exit
- print_footer(TRUE);
+ $field = preg_replace('/^entry\./', '', $field);
+ if ($value && ($custom_fields[$field] == ''))
+ {
+ print_header($day, $month, $year, $area, isset($room) ? $room : "");
+ ?>
+ <h1><?php echo get_vocab('invalid_booking'); ?></h1>
+ <p>
+ <?php echo get_vocab('missing_mandatory_field')." \"".
+ get_loc_field_name($tbl_entry, $field)."\""; ?>
+ </p>
+ <?php
+ // Print footer and exit
+ print_footer(TRUE);
+ }
}
- }
-}
+ }
+}
-
if ($enable_periods)
{
$resolution = 60;
@@ -465,7 +472,7 @@
// Validate the booking for (a) conflicting bookings and (b) conformance to
rules
$valid_booking = TRUE;
-$conflicts = ""; // Holds a list of all the conflicts (ideally this
would be an array)
+$conflicts = array(); // Holds a list of all the conflicts
$rules_broken = array(); // Holds an array of the rules that have been broken
$skip_lists = array(); // Holds a 2D array of bookings to skip past.
Indexed
// by room id and start time
@@ -508,7 +515,7 @@
// In both cases remember the conflict data. (We don't at the
// moment do anything with the data if we're skipping, but we might
// in the future want to display a list of bookings we've skipped
past)
- $conflicts .= $tmp;
+ $conflicts = $conflicts + $tmp; // array union
}
// if we're not an admin for this room, check that the booking
// conforms to the booking policy
@@ -532,10 +539,11 @@
else
{
$tmp = mrbsCheckFree($room_id, $starttime, $endtime-1, $ignore_id, 0);
+
if (!empty($tmp))
{
$valid_booking = FALSE;
- $conflicts .= $tmp;
+ $conflicts = $conflicts + $tmp; // array union
}
// if we're not an admin for this room, check that the booking
// conforms to the booking policy
@@ -552,6 +560,19 @@
} // end foreach rooms
+
+// If this is an Ajax request then we're just trying to find out whether the
booking
+// would succeed if made. We now know that, so output the results and exit.
+if ($ajax && function_exists('json_encode'))
+{
+ $result = array();
+ $result['rules_broken'] = $rules_broken;
+ $result['conflicts'] = $conflicts;
+ echo json_encode($result);
+ exit;
+}
+
+
// If the rooms were free, go ahead an process the bookings
if ($valid_booking)
{
@@ -758,7 +779,12 @@
echo get_vocab("conflict").":\n";
echo "</p>\n";
echo "<ul>\n";
- echo $conflicts;
+ // get rid of duplicate messages
+ $conflicts = array_unique($conflicts);
+ foreach ($conflicts as $conflict)
+ {
+ echo "<li>$conflict</li>\n";
+ }
echo "</ul>\n";
}
}
Modified: mrbs/branches/datatables/web/lang.en
===================================================================
--- mrbs/branches/datatables/web/lang.en 2011-09-08 18:00:20 UTC (rev
1937)
+++ mrbs/branches/datatables/web/lang.en 2011-09-08 18:05:32 UTC (rev
1938)
@@ -146,7 +146,9 @@
$vocab["error"] = "Error";
$vocab["sched_conflict"] = "Scheduling Conflict";
$vocab["conflict"] = "The new booking will conflict with the
following entries";
+$vocab["no_conflicts"] = "No scheduling conflicts";
$vocab["rules_broken"] = "The new booking will conflict with the
following policies";
+$vocab["no_rules_broken"] = "No policy conflicts";
$vocab["too_may_entrys"] = "The selected options will create too many
entries.<br>Please use different options!";
$vocab["returncal"] = "Return to calendar view";
$vocab["failed_to_acquire"] = "Failed to acquire exclusive database access";
Modified: mrbs/branches/datatables/web/mrbs.css.php
===================================================================
--- mrbs/branches/datatables/web/mrbs.css.php 2011-09-08 18:00:20 UTC (rev
1937)
+++ mrbs/branches/datatables/web/mrbs.css.php 2011-09-08 18:05:32 UTC (rev
1938)
@@ -609,7 +609,12 @@
.form_general label.secondary {font-weight: normal; width: auto}
+div#conflict_check, div#policy_check {float: left; clear: none; width: auto;
padding: 1em; cursor: default}
+div#conflict_check {margin-left: 2em}
+div.good {color: green}
+div.bad {color: red}
+
/* ------------ EDIT_ENTRY_HANDLER.PHP ------------------*/
.edit_entry_handler div#submit_buttons {float: left}
.edit_entry_handler #submit_buttons form {float: left; margin: 1em 2em 1em 0}
Modified: mrbs/branches/datatables/web/mrbs_sql.inc
===================================================================
--- mrbs/branches/datatables/web/mrbs_sql.inc 2011-09-08 18:00:20 UTC (rev
1937)
+++ mrbs/branches/datatables/web/mrbs_sql.inc 2011-09-08 18:05:32 UTC (rev
1938)
@@ -13,7 +13,7 @@
*
* Returns:
* nothing - The area is free
- * something - An error occured, the return value is human readable
+ * something - An error occured, the return value is an array of conflicts
*/
function mrbsCheckFree($room_id, $starttime, $endtime, $ignore, $repignore)
{
@@ -54,8 +54,8 @@
// Get the room's area ID for linking to day, week, and month views:
$area = mrbsGetRoomArea($room_id);
- // Build a string listing all the conflicts:
- $err = "";
+ // Build an listing all the conflicts:
+ $err = array();
for ($i = 0; ($row = sql_row_keyed($res, $i)); $i++)
{
$starts = getdate($row['start_time']);
@@ -80,11 +80,12 @@
$row['name'] = get_vocab("private");
}
- $err .= "<li><a
href=\"view_entry.php?id=".$row['id']."\">".$row['name']."</a>"
+ // enclose the viewday etc. links in a span to make it easier for
JavaScript to strip them out
+ $err[] = "<a
href=\"view_entry.php?id=".$row['id']."\">".$row['name']."</a>"
. " ( " . $startstr . ") "
- . "(<a href=\"day.php?$param_ymd\">".get_vocab("viewday")."</a>"
+ . "<span>(<a href=\"day.php?$param_ymd\">".get_vocab("viewday")."</a>"
. " | <a
href=\"week.php?room=$room_id&$param_ymd\">".get_vocab("viewweek")."</a>"
- . " | <a
href=\"month.php?room=$room_id&$param_ym\">".get_vocab("viewmonth")."</a>)</li>\n";
+ . " | <a
href=\"month.php?room=$room_id&$param_ym\">".get_vocab("viewmonth")."</a>)</span>";
}
return $err;
Modified: mrbs/branches/datatables/web/report.php
===================================================================
--- mrbs/branches/datatables/web/report.php 2011-09-08 18:00:20 UTC (rev
1937)
+++ mrbs/branches/datatables/web/report.php 2011-09-08 18:05:32 UTC (rev
1938)
@@ -726,7 +726,8 @@
// Also need to know whether they have admin rights
$user = getUserName();
-$is_admin = (isset($user) && authGetUserLevel($user)>=2) ;
+$user_level = authGetUserLevel($user);
+$is_admin = ($user_level >= 2);
// Set up for Ajax. We need to know whether we're capable of dealing with
Ajax
// requests, which will only be if (a) the browser is using DataTables and (b)
@@ -1155,20 +1156,31 @@
// Only show this part of the form if there are areas that allow
private bookings
if ($private_somewhere)
{
- echo "<div id=\"div_privacystatus\">\n";
- echo "<label>" . get_vocab("privacy_status") . ":</label>\n";
- echo "<div class=\"group\">\n";
- $options = array(PRIVATE_BOTH => 'both', PRIVATE_NO =>
'default_public', PRIVATE_YES => 'default_private');
- foreach ($options as $option => $token)
+ // If they're not logged in then there's no point in showing this
part of the form because
+ // they'll only be able to see public bookings anyway (and we don't
want to alert them to
+ // the existence of porivate bookings)
+ if (empty($user_level))
{
- echo "<label>";
- echo "<input class=\"radio\" type=\"radio\" name=\"match_private\"
value=\"$option\"" .
- (($match_private == $option) ? " checked=\"checked\"" : "") .
- ">" . get_vocab($token);
- echo "</label>\n";
+ echo "<input type=\"hidden\" name=\"match_private\" value=\"" .
PRIVATE_NO . "\">\n";
}
- echo "</div>\n";
- echo "</div>\n";
+ // Otherwise give them the radio buttons
+ else
+ {
+ echo "<div id=\"div_privacystatus\">\n";
+ echo "<label>" . get_vocab("privacy_status") . ":</label>\n";
+ echo "<div class=\"group\">\n";
+ $options = array(PRIVATE_BOTH => 'both', PRIVATE_NO =>
'default_public', PRIVATE_YES => 'default_private');
+ foreach ($options as $option => $token)
+ {
+ echo "<label>";
+ echo "<input class=\"radio\" type=\"radio\"
name=\"match_private\" value=\"$option\"" .
+ (($match_private == $option) ? " checked=\"checked\"" : "")
.
+ ">" . get_vocab($token);
+ echo "</label>\n";
+ }
+ echo "</div>\n";
+ echo "</div>\n";
+ }
}
// Confirmation status
Property changes on: mrbs/branches/datatables/web/upgrade/5/pgsql.sql
___________________________________________________________________
Modified: svn:mergeinfo
- /mrbs/branches/custom_entry_fields/web/upgrade/5/pgsql.sql:1374-1396
/mrbs/branches/datepicker/web/upgrade/5/pgsql.sql:1409-1416
/mrbs/branches/disabled_rooms/web/upgrade/5/pgsql.sql:1601-1634
/mrbs/branches/from_to_bookings/web/upgrade/5/pgsql.sql:1491-1587
/mrbs/branches/ics_attachments/web/upgrade/5/pgsql.sql:1652-1741
/mrbs/branches/only_unicode/web/upgrade/5/pgsql.sql:1747-1749
/mrbs/branches/provisional_bookings/web/upgrade/5/pgsql.sql:1242-1280
/mrbs/branches/provisional_bookings_new_style/web/upgrade/5/pgsql.sql:1407-1570
/mrbs/trunk/web/upgrade/5/pgsql.sql:1863-1933
+ /mrbs/branches/custom_entry_fields/web/upgrade/5/pgsql.sql:1374-1396
/mrbs/branches/datepicker/web/upgrade/5/pgsql.sql:1409-1416
/mrbs/branches/disabled_rooms/web/upgrade/5/pgsql.sql:1601-1634
/mrbs/branches/from_to_bookings/web/upgrade/5/pgsql.sql:1491-1587
/mrbs/branches/ics_attachments/web/upgrade/5/pgsql.sql:1652-1741
/mrbs/branches/only_unicode/web/upgrade/5/pgsql.sql:1747-1749
/mrbs/branches/provisional_bookings/web/upgrade/5/pgsql.sql:1242-1280
/mrbs/branches/provisional_bookings_new_style/web/upgrade/5/pgsql.sql:1407-1570
/mrbs/trunk/web/upgrade/5/pgsql.sql:1863-1937
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Doing More with Less: The Next Generation Virtual Desktop
What are the key obstacles that have prevented many mid-market businesses
from deploying virtual desktops? How do next-generation virtual desktops
provide companies an easier-to-deploy, easier-to-manage and more affordable
virtual desktop model.http://www.accelacomm.com/jaw/sfnl/114/51426474/
_______________________________________________
Mrbs-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mrbs-commits