BMLT Root Server
Functions | Variables
server_admin_javascript.js File Reference

Go to the source code of this file.

Functions

function BMLT_Server_Admin ()
 
history_list appendChild (history_item)
 
function BMLT_AjaxRequest_FileUpload (url, callback, file, extra_data)
 A simple, generic AJAX file upload function. * *. More...
 
function BMLT_AjaxRequest (url, callback, method, extra_data)
 A simple, generic AJAX request function. * *. More...
 
function BMLT_Admin_StartFader (in_eid, in_fade_time)
 Starts the message "fader." *

More...
 
function BMLT_Admin_animateFade (lastTick, in_eid)
 Animates the fade. *

More...
 
function BMLT_Admin_getChildElementsByClassName (in_container_element, in_element_type, in_element_className)
 This allows you to get objects within a DOM node hierarchy that have a certain * element name (type, such as 'div' or 'a'), and a className. * This can be used to "drill into" a DOM hierarchy that doesn't have IDs. *. More...
 
function BMLT_Admin_getChildElementById (in_container_element, in_element_id)
 This allows you to search a particular DOM hierarchy for an element with an ID. * This is useful for changing Node IDs in the case of cloneNode(). *. More...
 
function BMLT_Admin_changeTemplateIDToUseThisID (in_container_element, in_element_id)
 This replaces every instance of 'template' in a hierarchy's element ids with the * the given ID. *. More...
 
function BMLT_Admin_setSelectByStringValue (in_select_object, in_value)
 
  More...
 
function BMLT_Admin_setSelectByValue (in_select_object, in_value)
 
function BMLT_Admin_keyDown (event)
 This just traps the enter key for the text entry. *. More...
 
function htmlspecialchars_decode (string, quote_style)
 
function sprintf ()
 
function takeOverConsole ()
 
 if (!g_google_api_key||!g_google_api_key.trim())
 
geocoder geocode ({'address':'27205'}, function(response, status){g_google_api_key_is_good=status=== 'OK';if(!g_google_api_key_is_good){showGoogleApiKeyError(g_maps_api_key_warning);}})
 

Variables

 else
 
this toggleServiceBodyEditor
 Toggles the visibility of the Service body editor section. *. More...
 
this populateServiceBodyEditor
 This sets up the Service Body Editor for the selected Service body. *. More...
 
this makeANewSB
 This simply creates a brand-new, unsullied Service body object. *. More...
 
this setServiceBodyUser
 This handles display of the Service body user. *. More...
 
this setServiceBodyEditorCheckboxes
 This is called when a Service Body Editor checkbox is clicked. *. More...
 
this serviceBodyUserChecboxHandler
 This is called when a Service Body Editor checkbox is clicked. *. More...
 
this validateServiceBodyEditorButtons
 This sets the state of the Service body editor save button. *. More...
 
this isServiceBodyDirty
 See if changes have been made to the Service body. *. More...
 
this recalculateServiceBody
 This goes through the Service body (except the checkboxes) and recalculates * the state of the edited object. *. More...
 
this handleTextInputServiceBodyChange
 
  More...
 
this cancelServiceBodyEdit
 This cancels the Service body editing session. *. More...
 
this saveServiceBody
 This saves the current Service body. *. More...
 
this saveServiceBodyAJAXCallback
 This is the AJAX callback handler for the save operation. *. More...
 
this createServiceBody
 This creates a new Service body. *. More...
 
this createServiceBodyAJAXCallback
 This is the AJAX callback handler for the create operation. *. More...
 
this deleteServiceBody
 This deletes the current Service body. *. More...
 
this deleteServiceBodyAJAXCallback
 This is the AJAX callback handler for the delete operation. *. More...
 
this toggleUserEditor
 Toggles the visibility of the Service body editor section. *. More...
 
this populateUserEditor
 This sets up the Service Body Editor for the selected Service body. *. More...
 
this readUserEditorState
 Reads the current user editor state, and sets the main object accordingly. *. More...
 
this saveUser
 Saves the user state. *. More...
 
this saveUserAJAXCallback
 This is the AJAX callback handler for the save operation. *. More...
 
this createUser
 This creates a new user. *. More...
 
this createUserAJAXCallback
 This is the AJAX callback handler for the create operation. *. More...
 
this deleteUser
 Deletes the user. *. More...
 
this deleteUserAJAXCallback
 This is the AJAX callback handler for the delete operation. *. More...
 
this cancelUserEdit
 Resets the user to the original state. *. More...
 
this isUserDirty
 See if changes have been made to the User. *. More...
 
this makeANewUser
 This simply creates a brand-new, unsullied User object. *. More...
 
this validateUserEditorButtons
 This sets the state of the User editor save button. *. More...
 
this toggleFormatEditor
 Toggles the visibility of the Format editor section. *. More...
 
this getSharedIdForVenueTypeFormat
 methods and variables for venue type format codes * More...
 
this venueTypeSharedIdDict
 
this toggleVenueTypeFormat
 
this checkAllServiceBodies
 
this createFormatRow
 This populates the format display list *. More...
 
this m_server_admin_panel_shown = false
 
this m_account_panel_shown = false
 
this m_search_specifier_shown = true
 
this m_meeting_editor_panel_shown = false
 
this m_warn_user_to_refresh = false
 
this m_success_fade_duration = 10000
 10 seconds for a success fader. More...
 
this m_failure_fade_duration = 10000
 10 seconds for a failure fader. More...
 
this m_format_editor_table_rows = 0
 
var admin_handler_object = new BMLT_Server_Admin
 
var g_google_api_key_is_good = false
 
var showGoogleApiKeyError
 

Function Documentation

option_sheet appendChild ( history_item  )
function BMLT_Admin_animateFade (   lastTick,
  in_eid 
)

Animates the fade. *

Parameters
lastTickThe time of the last tick.
in_eidThe element ID

Definition at line 5710 of file server_admin_javascript.js.

5713  {
5714  var in_element = document.getElementById(in_eid);
5715  if ( in_element ) {
5716  var curTick = new Date().getTime();
5717  var elapsedTicks = curTick - lastTick;
5718 
5719  if ( in_element.FadeTimeLeft <= elapsedTicks ) {
5720  in_element.className = 'bmlt_admin_fader_div item_hidden';
5721  in_element.FadeTimeTotal = null;
5722  in_element.FadeTimeLeft = null;
5723  in_element.FadeState = null;
5724  in_element.style.opacity = null;
5725  in_element.style.filter = null;
5726  return;
5727  };
5728 
5729  in_element.FadeTimeLeft -= elapsedTicks;
5730 
5731  var newOpVal = in_element.FadeTimeLeft/in_element.FadeTimeTotal;
5732 
5733  in_element.style.opacity = newOpVal;
5734  in_element.style.filter = 'alpha(opacity = ' + (newOpVal*100) + ')';
5735 
5736  setTimeout("BMLT_Admin_animateFade(" + curTick + ",'" + in_eid + "')", 33);
5737  };
5738 };
function BMLT_Admin_changeTemplateIDToUseThisID (   in_container_element,
  in_element_id 
)

This replaces every instance of 'template' in a hierarchy's element ids with the * the given ID. *.

Parameters
in_container_elementThe DOM node that contains the hierarchy
in_element_idThe ID you are replacing with.

Definition at line 5801 of file server_admin_javascript.js.

References c, and g.

Referenced by BMLT_Server_Admin().

5804  {
5805  var ret = null;
5806 
5807  if ( in_container_element ) {
5808  if ( in_container_element.attributes && in_container_element.attributes.length ) {
5809  for (var c = 0; c < in_container_element.attributes.length; c++) {
5810  if ( in_container_element.attributes[c].nodeValue ) {
5811  in_container_element.attributes[c].nodeValue = in_container_element.attributes[c].nodeValue.toString().replace(/template/g, in_element_id);
5812  };
5813  };
5814  };
5815 
5816  if ( in_container_element.id ) {
5817  in_container_element.id = in_container_element.id.replace(/template/g, in_element_id);
5818  };
5819  };
5820 
5821  // If we have kids, we check each of them for the ID.
5822  if ( in_container_element && in_container_element.childNodes && in_container_element.childNodes.length ) {
5823  for (var c = 0; c < in_container_element.childNodes.length; c++) {
5824  BMLT_Admin_changeTemplateIDToUseThisID(in_container_element.childNodes[c], in_element_id);
5825  };
5826  };
5827 
5828  return ret;
5829 };
function BMLT_Admin_changeTemplateIDToUseThisID(in_container_element, in_element_id)
This replaces every instance of &#39;template&#39; in a hierarchy&#39;s element ids with the * the given ID...
function g
var c
function BMLT_Admin_getChildElementById (   in_container_element,
  in_element_id 
)

This allows you to search a particular DOM hierarchy for an element with an ID. * This is useful for changing Node IDs in the case of cloneNode(). *.

Returns
a single DOM element, with the given ID. *
Parameters
in_container_elementThe DOM node that contains the hierarchy
in_element_idThe ID you are looking for.

Definition at line 5773 of file server_admin_javascript.js.

References c.

5776  {
5777  var ret = null;
5778 
5779  if ( in_container_element && in_container_element.id == in_element_id ) { // Low-hanging fruit.
5780  ret = in_container_element;
5781  } else {
5782  // If we have kids, we check each of them for the ID.
5783  if ( in_container_element && in_container_element.childNodes && in_container_element.childNodes.length ) {
5784  for (var c = 0; c < in_container_element.childNodes.length; c++) {
5785  ret = BMLT_Admin_getChildElementsById(in_container_element.childNodes[c], in_element_id);
5786 
5787  if ( ret ) {
5788  break;
5789  };
5790  };
5791  };
5792  };
5793 
5794  return ret;
5795 };
var c
function BMLT_Admin_getChildElementsByClassName (   in_container_element,
  in_element_type,
  in_element_className 
)

This allows you to get objects within a DOM node hierarchy that have a certain * element name (type, such as 'div' or 'a'), and a className. * This can be used to "drill into" a DOM hierarchy that doesn't have IDs. *.

Returns
an array of DOM elements that meet the criteria. *
Parameters
in_container_elementThe DOM node that contains the hierarchy
in_element_typeThe type of node that you are seeking.
in_element_classNameThe className for that element.

Definition at line 5746 of file server_admin_javascript.js.

References c.

5750  {
5751  var starting_pool = in_container_element.getElementsByTagName(in_element_type);
5752  var ret = [];
5753  for (c = 0; c < starting_pool.length; c++) {
5754  if ( starting_pool[c].className == in_element_className ) {
5755  ret.append(starting_pool[c]);
5756  };
5757 
5758  var ret2 = BMLT_Admin_getChildElementsByClassName(starting_pool[c], in_element_type, in_element_className);
5759 
5760  if ( ret2 && ret2.length ) {
5761  ret = ret.concat(ret2);
5762  };
5763  };
5764 
5765  return ret;
5766 };
function BMLT_Admin_getChildElementsByClassName(in_container_element, in_element_type, in_element_className)
This allows you to get objects within a DOM node hierarchy that have a certain * element name (type...
var c
function BMLT_Admin_keyDown (   event)

This just traps the enter key for the text entry. *.

Definition at line 5872 of file server_admin_javascript.js.

5873 {
5874  if ( admin_handler_object.m_search_specifier_shown && (event.keyCode == 13) ) {
5875  admin_handler_object.searchForMeetings();
5876  };
5877 };
var admin_handler_object
function BMLT_Admin_setSelectByStringValue (   in_select_object,
  in_value 
)

 

Definition at line 5834 of file server_admin_javascript.js.

References c.

Referenced by BMLT_Server_Admin().

5837  {
5838  var setIndex = 0;
5839 
5840  for (var c = 0; c < in_select_object.options.length; c ++) {
5841  if (in_select_object.options[c].value == in_value) {
5842  setIndex = c;
5843  break;
5844  }
5845  }
5846 
5847  in_select_object.selectedIndex = setIndex;
5848 }
var c
function BMLT_Admin_setSelectByValue (   in_select_object,
  in_value 
)

Definition at line 5853 of file server_admin_javascript.js.

References c.

Referenced by BMLT_Server_Admin().

5856  {
5857  var setIndex = 0;
5858 
5859  for (var c = 0; c < in_select_object.options.length; c ++) {
5860  if ( parseInt(in_select_object.options[c].value, 10) == parseInt(in_value, 10) ) {
5861  setIndex = c;
5862  break;
5863  };
5864  };
5865 
5866  in_select_object.selectedIndex = setIndex;
5867 };
var c
function BMLT_Admin_StartFader (   in_eid,
  in_fade_time 
)

Starts the message "fader." *

Parameters
in_eidThe element ID to be faded.
in_fade_timeThe number of seconds to fade.

Definition at line 5691 of file server_admin_javascript.js.

Referenced by BMLT_Server_Admin().

5694  {
5695  var in_element = document.getElementById(in_eid);
5696  if ( in_element ) {
5697  in_element.className = 'bmlt_admin_fader_div';
5698  in_element.FadeTimeTotal = in_fade_time;
5699  in_element.FadeTimeLeft = in_element.FadeTimeTotal;
5700  setTimeout("BMLT_Admin_animateFade(" + new Date().getTime() + ",'" + in_eid + "')", 33);
5701  };
5702 };
function BMLT_AjaxRequest (   url,
  callback,
  method,
  extra_data 
)

A simple, generic AJAX request function. * *.

Returns
a new XMLHTTPRequest object. *

Create a generic XMLHTTPObject. *

  • This will account for the various flavors imposed by different browsers. *
  • Returns
    a new XMLHTTPRequest object. *
Parameters
urlThe URI to be called
callbackThe success callback
methodThe method ('get' or 'post')
extra_dataIf supplied, extra data to be delivered to the callback.

Definition at line 5599 of file server_admin_javascript.js.

References e, and i.

Referenced by BMLT_Server_Admin().

5604  {
5605  /************************************************************************************//**
5606  * \brief Create a generic XMLHTTPObject. *
5607  * *
5608  * This will account for the various flavors imposed by different browsers. *
5609  * *
5610  * \returns a new XMLHTTPRequest object. *
5611  ****************************************************************************************/
5612 
5613  function createXMLHTTPObject()
5614  {
5615  var XMLHttpArray = [
5616  function () {
5617  return new XMLHttpRequest()},
5618  function () {
5619  return new ActiveXObject("Msxml2.XMLHTTP")},
5620  function () {
5621  return new ActiveXObject("Msxml2.XMLHTTP")},
5622  function () {
5623  return new ActiveXObject("Microsoft.XMLHTTP")}
5624  ];
5625 
5626  var xmlhttp = false;
5627 
5628  for (var i=0; i < XMLHttpArray.length; i++) {
5629  try {
5630  xmlhttp = XMLHttpArray[i]();
5631  } catch (e) {
5632  continue;
5633  };
5634  break;
5635  };
5636 
5637  return xmlhttp;
5638  };
5639 
5640  var req = createXMLHTTPObject();
5641  req.finalCallback = callback;
5642  var sVars = null;
5643  method = method.toString().toUpperCase();
5644  var drupal_kludge = '';
5645 
5646  // Split the URL up, if this is a POST.
5647  if ( method == "POST" ) {
5648  var rmatch = /^([^\?]*)\?(.*)$/.exec(url);
5649  url = rmatch[1];
5650  sVars = rmatch[2];
5651  // This horrible, horrible kludge, is because Drupal insists on having its q parameter in the GET list only.
5652  var rmatch_kludge = /(q=admin\/settings\/bmlt)&?(.*)/.exec(rmatch[2]);
5653  if ( rmatch_kludge && rmatch_kludge[1] ) {
5654  url += '?'+rmatch_kludge[1];
5655  sVars = rmatch_kludge[2];
5656  };
5657  };
5658  if ( extra_data != null ) {
5659  req.extra_data = extra_data;
5660  };
5661  req.open(method, url, true);
5662  if ( method == "POST" ) {
5663  req.setRequestHeader("Method", "POST "+url+" HTTP/1.1");
5664  req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
5665  };
5666  req.onreadystatechange = function ( ) {
5667  if ( req.readyState != 4 ) {
5668  return;
5669  }
5670  if ( req.status != 200 ) {
5671  return;
5672  }
5673  callback(req, req.extra_data);
5674  req = null;
5675  };
5676  req.send(sVars);
5677 
5678  return req;
5679 };
function e
var i
function BMLT_AjaxRequest_FileUpload (   url,
  callback,
  file,
  extra_data 
)

A simple, generic AJAX file upload function. * *.

Returns
a new XMLHTTPRequest object. *

Create a generic XMLHTTPObject. *

  • This will account for the various flavors imposed by different browsers. *
  • Returns
    a new XMLHTTPRequest object. *
Parameters
urlThe URI to be called
callbackThe success callback
fileThe file object
extra_dataIf supplied, extra data to be delivered to the callback.

Definition at line 5528 of file server_admin_javascript.js.

References e, and i.

5533  {
5534  /************************************************************************************//**
5535  * \brief Create a generic XMLHTTPObject. *
5536  * *
5537  * This will account for the various flavors imposed by different browsers. *
5538  * *
5539  * \returns a new XMLHTTPRequest object. *
5540  ****************************************************************************************/
5541 
5542  function createXMLHTTPObject()
5543  {
5544  var XMLHttpArray = [
5545  function () {
5546  return new XMLHttpRequest()},
5547  function () {
5548  return new ActiveXObject("Msxml2.XMLHTTP")},
5549  function () {
5550  return new ActiveXObject("Msxml2.XMLHTTP")},
5551  function () {
5552  return new ActiveXObject("Microsoft.XMLHTTP")}
5553  ];
5554 
5555  var xmlhttp = false;
5556 
5557  for (var i=0; i < XMLHttpArray.length; i++) {
5558  try {
5559  xmlhttp = XMLHttpArray[i]();
5560  } catch (e) {
5561  continue;
5562  };
5563  break;
5564  };
5565 
5566  return xmlhttp;
5567  };
5568 
5569  var req = createXMLHTTPObject();
5570  req.finalCallback = callback;
5571 
5572  if ( extra_data != null ) {
5573  req.extra_data = extra_data;
5574  }
5575  req.open("POST", url, true);
5576  req.onreadystatechange = function() {
5577  if ( req.readyState != 4 ) {
5578  return;
5579  }
5580  if ( req.status != 200 ) {
5581  return;
5582  }
5583  callback(req, req.extra_data);
5584  req = null;
5585  };
5586 
5587  var formData = new FormData();
5588  formData.append("thefile", file);
5589  req.send(formData);
5590 
5591  return req;
5592 };
function e
var i
function BMLT_Server_Admin ( )

DATA MEMBERS *

< This will be true if the "Server Administration" panel is exposed.

< This will be true if the "My Account" panel is exposed.

< This is true, if the meeting search specifier form is shown.

< This will be true if the "Edit Meetings" panel is exposed.

< This is true, if the Service Body Editor is shown.

< This is any AJAX request currently under way.

< Number of milliseconds for a success fader.

< Number of milliseconds for a failure fader.

< This will contain any meeting search results.

< This will hold any search result display elements (allows easy disposal)

< If there is a meeting editor open, it is recorded here. There can only be one...

< Set to true, if the user editor is open.

< If this is true, then a warning alert will be shown to the user.

< This is used to track the number of rows in the format editor table.

METHODS *

If one of the upper sections has been edited, it can affect the Account, * Meeting or Service Body sections. In this case, the user needs to log out, * then back in again (or refresh the page, but signing out is easier to * explain). This sets an orange fader in each affected section, and also sets * the trigger for an alert that explains it. *

This displays that alert. *

When a text input (either <input> or <textarea> is initialized, we can set * up a default text value that is displayed when the item is empty and not in * focus. If we don't send in a specific value, then the current value of the * text item is considered to be the default. *

This just makes sure that the className is correct. *

< This is the text item to check.

< true, if the item is in focus

When a text item receives focus, we clear any default text. *

When a text item loses focus, we restore any default text, if the item was * left empty. *

This is called when executing a paste. It avoids leaving in the default text.*

When a text item has its text changed, we check to see if it needs to have * its classname changed to the default (usually won't make a difference, as * the text item will be in focus, anyway). *

When a text item has its text changed, we check to see if it needs to have * its classname changed to the default (usually won't make a difference, as * the text item will be in focus, anyway). *

Toggles the selected item of the Server Administration section. *

Toggles the visibility of the Server Administration section. *

Toggles the visibility of the account info section. *

This checks the values of the text items in the My Account section. If any * of them are different from their default, we enable the GO button. *

This is called when the World ID update file input changes *

This is called when the NAWS Import file input changes *

This is called to initiate an AJAX process to update world IDs from file *

This is called to initiate an AJAX process to import meetings from file *

Displays or hides the AJAX Throbber for the Update World IDs button *

Displays or hides the AJAX Throbber for the NAWS Import button *

This is called to initiate an AJAX process to change the account settings. *

This is called to initiate an AJAX process to change the account settings. *

Displays or hides the AJAX Throbber for the My Account button. *

< If true, the throbber is show. If false, it is hidden.

This opens the editor to a particular meeting, as given by an ID. *

< The ID of the meeting to be opened.

Toggles the visibility of the meeting editor section. *

Returns an object with the meeting data for the meeting ID passed in. *

Returns
a meeting object. Null if none found, or invalid ID. *

< The ID of the meeting to fetch

< If true, then the returned meeting object will be a clone (new object).

Selecte the search specifier tab. *

This makes sure that the "All" checkbox syncs with the weekdays. *

< The checkbox that triggered the call.

This handles Service body checkboxes. *

< The checkbox that triggered the call.

This returns the Service body ID of the given Service body ID. *

Returns
an integer that is the ID of the parent Service body. *

Returns an array of Service body objects that are direct descendants of the * given Service body, as specified by ID. *

Returns
an array of Service body objects. *

Returns the name of the given Service body, by ID. *

Returns
a string. *

Displays the Search Results or specifier, dependent upon the switch. *

Reacts to the "Search For Meetings" button being hit. *

Clears any previous search results. *

Definition at line 21 of file server_admin_javascript.js.

References a, admin_handler_object, b, BMLT_Admin_changeTemplateIDToUseThisID(), BMLT_Admin_setSelectByStringValue(), BMLT_Admin_setSelectByValue(), BMLT_Admin_StartFader(), BMLT_AjaxRequest(), c, d(), g, g_google_api_key_is_good, htmlspecialchars_decode(), i, if(), m_account_panel_shown, m_failure_fade_duration, m_format_editor_table_rows, m_meeting_editor_panel_shown, m_search_specifier_shown, m_server_admin_panel_shown, m_success_fade_duration, m_warn_user_to_refresh, n, r, s, services, sprintf(), state, t, v, venueTypeSharedIdDict, and weekdays.

22 {
23  // #mark -
24  // #mark ########## Class Declaration ##########
25  // #mark -
26 
27  /************************************************************************************//**
28  * DATA MEMBERS *
29  ****************************************************************************************/
30  var m_server_admin_panel_shown = null; ///< This will be true if the "Server Administration" panel is exposed.
31  var m_account_panel_shown = null; ///< This will be true if the "My Account" panel is exposed.
32  var m_search_specifier_shown = null; ///< This is true, if the meeting search specifier form is shown.
33  var m_meeting_editor_panel_shown = null; ///< This will be true if the "Edit Meetings" panel is exposed.
34  var m_service_body_editor_panel_shown = null; ///< This is true, if the Service Body Editor is shown.
35  var m_ajax_request_in_progress = null; ///< This is any AJAX request currently under way.
36  var m_success_fade_duration = null; ///< Number of milliseconds for a success fader.
37  var m_failure_fade_duration = null; ///< Number of milliseconds for a failure fader.
38  var m_search_results = null; ///< This will contain any meeting search results.
39  var m_meeting_results_container_div = null; ///< This will hold any search result display elements (allows easy disposal)
40  var m_editing_window_open = null; ///< If there is a meeting editor open, it is recorded here. There can only be one...
41  var m_user_editor_panel_shown = null; ///< Set to true, if the user editor is open.
42  var m_warn_user_to_refresh = null; ///< If this is true, then a warning alert will be shown to the user.
43  var m_format_editor_table_rows = null; ///< This is used to track the number of rows in the format editor table.
44 
45  this.validationMessageTypes = {
46  "ERROR": "error",
47  "WARN": "warn"
48  }
49 
50  /************************************************************************************//**
51  * METHODS *
52  ****************************************************************************************/
53 
54  // #mark -
55  // #mark Affects All Sections
56  // #mark -
57 
58  /************************************************************************************//**
59  * \brief If one of the upper sections has been edited, it can affect the Account, *
60  * Meeting or Service Body sections. In this case, the user needs to log out, *
61  * then back in again (or refresh the page, but signing out is easier to *
62  * explain). This sets an orange fader in each affected section, and also sets *
63  * the trigger for an alert that explains it. *
64  ****************************************************************************************/
65  this.setWarningFaders = function () {
66  if ( document.getElementById('bmlt_admin_fader_service_body_editor_warn_div') ) {
67  document.getElementById('bmlt_admin_fader_service_body_editor_warn_div').className = 'bmlt_admin_fader_div';
68  };
69 
70  if ( document.getElementById('bmlt_admin_fader_meeting_editor_warn_div') ) {
71  document.getElementById('bmlt_admin_fader_meeting_editor_warn_div').className = 'bmlt_admin_fader_div';
72  };
73 
74  if ( document.getElementById('bmlt_admin_fader_account_warn_div') ) {
75  document.getElementById('bmlt_admin_fader_account_warn_div').className = 'bmlt_admin_fader_div';
76  };
77 
78  this.m_warn_user_to_refresh = true;
79  };
80 
81  /************************************************************************************//**
82  * \brief This displays that alert. *
83  ****************************************************************************************/
84  this.showWarningAlert = function () {
85  if ( this.m_warn_user_to_refresh ) { // Only if needed.
86  alert(g_need_refresh_message_alert_text);
87  this.m_warn_user_to_refresh = false;
88  };
89  };
90 
91  // #mark -
92  // #mark Text Item Handlers
93  // #mark -
94 
95  /************************************************************************************//**
96  * \brief When a text input (either <input> or <textarea> is initialized, we can set *
97  * up a default text value that is displayed when the item is empty and not in *
98  * focus. If we don't send in a specific value, then the current value of the *
99  * text item is considered to be the default. *
100  ****************************************************************************************/
101  this.handleTextInputLoad = function (
102  in_text_item,
103  in_default_value,
104  in_small
105  ) {
106  if ( in_text_item ) {
107  in_text_item.original_value = in_text_item.value;
108  if ( !in_text_item.small ) {
109  in_text_item.small = false;
110  };
111 
112  if ( !in_text_item.tiny ) {
113  in_text_item.tiny = false;
114  };
115 
116  in_text_item.small = in_text_item.small || in_small;
117 
118  if ( in_default_value != null ) {
119  in_text_item.defaultValue = in_default_value;
120  } else {
121  in_text_item.defaultValue = in_text_item.value;
122  };
123 
124  in_text_item.value = in_text_item.original_value;
125 
126  if ( !in_text_item.value || (in_text_item.value == in_text_item.defaultValue) ) {
127  in_text_item.value = in_text_item.defaultValue;
128  in_text_item.className = 'bmlt_text_item' + (in_text_item.small ? '_small' : (in_text_item.med ? '_med' : (in_text_item.tiny ? '_tiny' : ''))) + ' bmlt_text_item_dimmed';
129  } else {
130  in_text_item.className = 'bmlt_text_item' + (in_text_item.small ? '_small' : (in_text_item.med ? '_med' : (in_text_item.tiny ? '_tiny' : '')));
131  };
132  };
133  };
134 
135  /************************************************************************************//**
136  * \brief This just makes sure that the className is correct. *
137  ****************************************************************************************/
138  this.setTextItemClass = function (
139  in_text_item, ///< This is the text item to check.
140  is_focused ///< true, if the item is in focus
141  ) {
142  if ( in_text_item ) {
143  if ( !is_focused && ((in_text_item.value == null) || (in_text_item.value == in_text_item.defaultValue)) ) {
144  in_text_item.className = 'bmlt_text_item' + (in_text_item.small ? '_small' : (in_text_item.med ? '_med' : (in_text_item.tiny ? '_tiny' : ''))) + ' bmlt_text_item_dimmed';
145  } else {
146  in_text_item.className = 'bmlt_text_item' + (in_text_item.small ? '_small' : (in_text_item.med ? '_med' : (in_text_item.tiny ? '_tiny' : '')));
147  };
148  };
149  };
150 
151  /************************************************************************************//**
152  * \brief When a text item receives focus, we clear any default text. *
153  ****************************************************************************************/
154  this.handleTextInputFocus = function ( in_text_item
155  ) {
156  if ( in_text_item ) {
157  if ( in_text_item.value == in_text_item.defaultValue ) {
158  in_text_item.value = '';
159  };
160 
161  this.setTextItemClass(in_text_item, true);
162  this.validateAccountGoButton();
163  };
164  };
165 
166  /************************************************************************************//**
167  * \brief When a text item loses focus, we restore any default text, if the item was *
168  * left empty. *
169  ****************************************************************************************/
170  this.handleTextInputBlur = function ( in_text_item
171  ) {
172  if ( in_text_item ) {
173  if ( !in_text_item.value ) {
174  in_text_item.value = in_text_item.defaultValue;
175  };
176 
177  this.setTextItemClass(in_text_item, false);
178  this.validateAccountGoButton();
179  };
180  };
181 
182  /************************************************************************************//**
183  * \brief This is called when executing a paste. It avoids leaving in the default text.*
184  ****************************************************************************************/
185  this.handleTextInputPaste = function ( in_text_item
186  ) {
187  if ( in_text_item ) {
188  this.setTextItemClass(in_text_item, true);
189  this.validateAccountGoButton();
190  };
191  };
192 
193  /************************************************************************************//**
194  * \brief When a text item has its text changed, we check to see if it needs to have *
195  * its classname changed to the default (usually won't make a difference, as *
196  * the text item will be in focus, anyway). *
197  ****************************************************************************************/
198  this.handleTextInputChange = function (
199  in_text_item,
200  in_meeting_id
201  ) {
202  if ( in_text_item ) {
203  this.validateAccountGoButton();
204  this.validateMeetingEditorButton(in_meeting_id);
205  };
206  };
207 
208  /************************************************************************************//**
209  * \brief When a text item has its text changed, we check to see if it needs to have *
210  * its classname changed to the default (usually won't make a difference, as *
211  * the text item will be in focus, anyway). *
212  ****************************************************************************************/
213  this.setItemValue = function (
214  in_item,
215  in_meeting_id,
216  in_value_field
217  ) {
218  var eval_str = '';
219 
220  if ( (null == in_meeting_id) && (null != in_item.meeting_id) ) {
221  in_meeting_id = in_item.meeting_id;
222  };
223 
224  if ( !in_value_field ) {
225  in_value_field = in_item.element;
226  };
227 
228  var editor_object_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id.toString() + '_div';
229  var editor_object = document.getElementById(editor_object_id);
230 
231  if ( (in_item.type == 'text') || (in_item.name == 'textarea') ) {
232  var value = in_item.value.toString();
233 
234  value = value.replace(/'/g, "\\'"); // Make sure to escape apostrophes.
235 
236  if ( value && (value != in_item.defaultValue) ) {
237  eval_str = 'editor_object.meeting_object.' + in_value_field + ' = \'' + value + '\';';
238  } else {
239  if ( 0 == in_meeting_id ) {
240  eval_str = 'delete editor_object.meeting_object.' + in_value_field + ';';
241  } else {
242  eval_str = 'editor_object.meeting_object.' + in_value_field + ' = \'\';';
243  };
244  };
245  };
246 
247  if ( eval_str ) {
248  eval(eval_str);
249  };
250 
251  if ( in_item ) {
252  this.validateAccountGoButton();
253  this.validateMeetingEditorButton(in_meeting_id);
254  this.handleNewAddressInfo(in_meeting_id);
255  };
256  };
257 
258  // #mark -
259  // #mark ########## Account Info Section ##########
260  // #mark -
261 
262  /************************************************************************************//**
263  * \brief Toggles the selected item of the Server Administration section. *
264  ****************************************************************************************/
265  this.toggleServerAdminSelect = function () {
266  var selectedValue = document.getElementById('bmlt_admin_server_admin_select').value;
267  var updateWorldIdsDiv = document.getElementById('bmlt_admin_server_admin_update_world_ids_edit_form_inner_div');
268  var nawsImportDiv = document.getElementById('bmlt_admin_server_admin_naws_import_edit_form_inner_div');
269  if (selectedValue === "naws_import") {
270  updateWorldIdsDiv.className = 'bmlt_admin_server_admin_update_world_ids_edit_form_inner_div item_hidden';
271  nawsImportDiv.className = 'bmlt_admin_server_admin_naws_import_edit_form_inner_div';
272  } else {
273  updateWorldIdsDiv.className = 'bmlt_admin_server_admin_update_world_ids_edit_form_inner_div';
274  nawsImportDiv.className = 'bmlt_admin_server_admin_naws_import_edit_form_inner_div item_hidden';
275  }
276  };
277 
278  /************************************************************************************//**
279  * \brief Toggles the visibility of the Server Administration section. *
280  ****************************************************************************************/
281  this.toggleServerAdmin = function () {
282  this.m_server_admin_panel_shown = !this.m_server_admin_panel_shown;
283 
284  var the_disclosure_div = document.getElementById('bmlt_admin_server_admin_disclosure_div');
285  var the_account_info_div = document.getElementById('bmlt_admin_server_admin_wrapper_div');
286 
287  if ( this.m_server_admin_panel_shown) {
288  the_disclosure_div.className = 'bmlt_admin_server_admin_disclosure_div bmlt_admin_server_admin_disclosure_div_open';
289  the_account_info_div.className = 'bmlt_admin_server_admin_wrapper_div';
290  } else {
291  the_disclosure_div.className = 'bmlt_admin_server_admin_disclosure_div bmlt_admin_server_admin_disclosure_div_closed';
292  the_account_info_div.className = 'bmlt_admin_server_admin_wrapper_div bmlt_admin_server_admin_wrapper_div_hidden';
293  }
294  };
295 
296  /************************************************************************************//**
297  * \brief Toggles the visibility of the account info section. *
298  ****************************************************************************************/
299  this.toggleAccountInfo = function () {
300  this.m_account_panel_shown = !this.m_account_panel_shown;
301 
302  var the_disclosure_div = document.getElementById('bmlt_admin_user_account_disclosure_div');
303  var the_account_info_div = document.getElementById('bmlt_admin_user_account_wrapper_div');
304 
305  if ( this.m_account_panel_shown) {
306  var email_field = document.getElementById('bmlt_admin_user_email_input');
307  var description_field = document.getElementById('bmlt_admin_user_description_textarea');
308  var password_field = document.getElementById('bmlt_admin_user_account_password_input');
309 
310  this.handleTextInputBlur(email_field);
311  this.handleTextInputBlur(description_field);
312  this.handleTextInputBlur(password_field);
313 
314  the_disclosure_div.className = 'bmlt_admin_user_account_disclosure_div bmlt_admin_user_account_disclosure_div_open';
315  the_account_info_div.className = 'bmlt_admin_user_account_wrapper_div';
316  this.showWarningAlert();
317  } else {
318  the_disclosure_div.className = 'bmlt_admin_user_account_disclosure_div bmlt_admin_user_account_disclosure_div_closed';
319  the_account_info_div.className = 'bmlt_admin_user_account_wrapper_div bmlt_admin_user_account_wrapper_div_hidden';
320  };
321  };
322 
323  /************************************************************************************//**
324  * \brief This checks the values of the text items in the My Account section. If any *
325  * of them are different from their default, we enable the GO button. *
326  ****************************************************************************************/
327  this.validateAccountGoButton = function () {
328  var email_field = document.getElementById('bmlt_admin_user_email_input');
329  var password_field = document.getElementById('bmlt_admin_user_account_password_input');
330  var ajax_button = document.getElementById('bmlt_admin_account_change_ajax_button');
331  var description = document.getElementById('bmlt_admin_user_description_textarea');
332  var name_field = document.getElementById('bmlt_admin_user_name_input');
333  var login_field = document.getElementById('bmlt_admin_user_login_input');
334 
335  if ( email_field && password_field && ajax_button && description ) {
336  if ( (email_field.value != email_field.original_value && email_field.value != email_field.defaultValue)
337  || (description.value != description.original_value && description.value != description.defaultValue)
338  || (name_field && (name_field.value != name_field.original_value))
339  || (login_field && (login_field.value != login_field.original_value))
340  || (password_field.value && (password_field.value != password_field.defaultValue)) ) {
341  ajax_button.className = 'bmlt_admin_ajax_button';
342  } else {
343  ajax_button.className = 'bmlt_admin_ajax_button button_disabled';
344  };
345  };
346  };
347 
348  /************************************************************************************//**
349  * \brief This is called when the World ID update file input changes *
350  ****************************************************************************************/
351  this.handleWorldIDFileInputChange = function() {
352  var file_input = document.getElementById('bmlt_admin_naws_spreadsheet_file_input');
353  var save_button = document.getElementById('bmlt_admin_update_world_ids_ajax_button');
354 
355  if (file_input.files && file_input.files.length > 0) {
356  save_button.className = 'bmlt_admin_ajax_button';
357  } else {
358  save_button.className = 'bmlt_admin_ajax_button button_disabled';
359  }
360  };
361 
362  /************************************************************************************//**
363  * \brief This is called when the NAWS Import file input changes *
364  ****************************************************************************************/
365  this.handleNAWSImportFileInputChange = function() {
366  var file_input = document.getElementById('bmlt_admin_naws_import_file_input');
367  var save_button = document.getElementById('bmlt_admin_naws_import_ajax_button');
368 
369  if (file_input.files && file_input.files.length > 0) {
370  save_button.className = 'bmlt_admin_ajax_button';
371  } else {
372  save_button.className = 'bmlt_admin_ajax_button button_disabled';
373  }
374  };
375 
376  /************************************************************************************//**
377  * \brief This is called to initiate an AJAX process to update world IDs from file *
378  ****************************************************************************************/
379  this.handleUpdateWorldIDsFromSpreadsheet = function() {
380  var file_input = document.getElementById('bmlt_admin_naws_spreadsheet_file_input');
381  var save_button = document.getElementById('bmlt_admin_update_world_ids_ajax_button');
382  if (!file_input || !file_input.files || !file_input.files.length) {
383  return;
384  }
385 
386  if ( this.m_ajax_request_in_progress ) {
387  this.m_ajax_request_in_progress.abort();
388  this.m_ajax_request_in_progress = null;
389  }
390 
391  this.m_ajax_request_in_progress = BMLT_AjaxRequest_FileUpload(
392  g_ajax_callback_uri + '&do_update_world_ids=1',
393  function(response) {admin_handler_object.handleUpdateWorldIDsFromSpreadsheetCallback(response);},
394  file_input.files[0]
395  );
396  this.setUpdateWorldIDsThrobber(true);
397  save_button.className = 'bmlt_admin_ajax_button button_disabled';
398  };
399 
400  this.handleUpdateWorldIDsFromSpreadsheetCallback = function(response) {
401  var file_input = document.getElementById('bmlt_admin_naws_spreadsheet_file_input');
402  var save_button = document.getElementById('bmlt_admin_update_world_ids_ajax_button');
403  this.setUpdateWorldIDsThrobber(false);
404  file_input.value = '';
405  save_button.className = 'bmlt_admin_ajax_button button_disabled';
406 
407  if (response && response.responseText) {
408  if (response.responseText === 'NOT AUTHORIZED') {
409  alert(g_AJAX_Auth_Failure);
410  return;
411  }
412 
413  eval('var result = ' + response.responseText + ';');
414  if (!result) {
415  return;
416  }
417 
418  if (result.success) {
419  var report = g_num_meetings_updated_text + result.report.updated.length.toString() + "\n\n";
420  report += g_num_meetings_not_updated_text + result.report.not_updated.length.toString();
421  if (result.report.not_found.length) {
422  report += "\n\n";
423  report += g_warning_text + ": " + result.report.not_found.length.toString() + " " + g_meetings_not_found_text + result.report.not_found.join(", ");
424  }
425  alert(report);
426  } else {
427  alert(g_errors_text + ":\n" + result.errors.join("\n"));
428  }
429  }
430  };
431 
432  /************************************************************************************//**
433  * \brief This is called to initiate an AJAX process to import meetings from file *
434  ****************************************************************************************/
435  this.handleNAWSImport = function() {
436  var file_input = document.getElementById('bmlt_admin_naws_import_file_input');
437  var save_button = document.getElementById('bmlt_admin_naws_import_ajax_button');
438  var publish_button = document.getElementById('bmlt_admin_naws_import_publish_checkbox');
439  if (!file_input || !file_input.files || !file_input.files.length) {
440  return;
441  }
442 
443  if ( this.m_ajax_request_in_progress ) {
444  this.m_ajax_request_in_progress.abort();
445  this.m_ajax_request_in_progress = null;
446  }
447 
448  this.m_ajax_request_in_progress = BMLT_AjaxRequest_FileUpload(
449  g_ajax_callback_uri + '&do_naws_import=1&initialValueForPublished=' + (publish_button.checked ? 'TRUE' : 'FALSE'),
450  function(response) {admin_handler_object.handleNAWSImportCallback(response);},
451  file_input.files[0]
452  );
453  this.setNAWSImportThrobber(true);
454  save_button.className = 'bmlt_admin_ajax_button button_disabled';
455  };
456 
457  this.handleNAWSImportCallback = function(response) {
458  var file_input = document.getElementById('bmlt_admin_naws_import_file_input');
459  var save_button = document.getElementById('bmlt_admin_naws_import_ajax_button');
460  this.setNAWSImportThrobber(false);
461  file_input.value = '';
462  save_button.className = 'bmlt_admin_ajax_button button_disabled';
463 
464  if (response && response.responseText) {
465  if (response.responseText === 'NOT AUTHORIZED') {
466  alert(g_AJAX_Auth_Failure);
467  return;
468  }
469 
470  eval('var result = ' + response.responseText + ';');
471  if (!result) {
472  return;
473  }
474 
475  if (result.success) {
476  var report = g_service_bodies_created_text + result.report.num_service_bodies_created.toString() + "\n\n";
477  report += g_users_created_text + result.report.num_users_created.toString() + "\n\n";
478  report += g_meetings_created_text + result.report.num_meetings_created.toString() + "\n\n";
479  report += g_server_admin_ui_refresh_ui_text;
480  alert(report);
481  } else {
482  alert(g_errors_text + ": " + result.errors);
483  }
484  }
485  };
486 
487  /************************************************************************************//**
488  * \brief Displays or hides the AJAX Throbber for the Update World IDs button *
489  ****************************************************************************************/
490  this.setUpdateWorldIDsThrobber = function(visible) {
491  var button_span = document.getElementById('bmlt_admin_update_world_ids_ajax_button_span');
492  var throbber_span = document.getElementById('bmlt_admin_update_world_ids_ajax_button_throbber_span');
493  throbber_span.className = 'bmlt_admin_value_left' + (visible ? '' : ' item_hidden');
494  button_span.className = 'bmlt_admin_value_left' + (visible ? ' item_hidden' : '');
495  };
496 
497  /************************************************************************************//**
498  * \brief Displays or hides the AJAX Throbber for the NAWS Import button *
499  ****************************************************************************************/
500  this.setNAWSImportThrobber = function(visible) {
501  var button_span = document.getElementById('bmlt_admin_naws_import_ajax_button_span');
502  var throbber_span = document.getElementById('bmlt_admin_naws_import_ajax_button_throbber_span');
503  throbber_span.className = 'bmlt_admin_value_left' + (visible ? '' : ' item_hidden');
504  button_span.className = 'bmlt_admin_value_left' + (visible ? ' item_hidden' : '');
505  };
506 
507 
508  /************************************************************************************//**
509  * \brief This is called to initiate an AJAX process to change the account settings. *
510  ****************************************************************************************/
511  this.handleAccountChange = function () {
512  var email_field = document.getElementById('bmlt_admin_user_email_input');
513  var password_field = document.getElementById('bmlt_admin_user_account_password_input');
514  var description = document.getElementById('bmlt_admin_user_description_textarea');
515  var affected_user_id = document.getElementById('account_affected_user_id');
516  var name_field = document.getElementById('bmlt_admin_user_name_input');
517  var login_field = document.getElementById('bmlt_admin_user_login_input');
518 
519  // We only do something if there is a difference.
520  if ( (affected_user_id.value == g_current_user_id) // Belt and suspenders...
521  && ((email_field.value != email_field.original_value)
522  || (description.value != description.original_value)
523  || (name_field && (name_field.value != name_field.original_value))
524  || (login_field && (login_field.value != login_field.original_value))
525  || (password_field.value && (password_field.value != password_field.defaultValue)))
526  ) {
527  if ( g_min_pw_len && (password_field.value && (password_field.value != password_field.defaultValue)) && (password_field.value.length < g_min_pw_len) ) {
528  alert(sprintf(g_min_password_length_string, g_min_pw_len));
529  } else {
530  this.setMyAccountThrobber(true);
531  var uri = g_ajax_callback_uri + '&target_user=' + encodeURIComponent(g_current_user_id);
532  if ( name_field && (name_field.value != name_field.original_value) ) {
533  uri += '&account_name_value=' + encodeURIComponent(name_field.value);
534  };
535 
536  if ( login_field && (login_field.value != login_field.original_value) ) {
537  uri += '&account_login_value=' + encodeURIComponent(login_field.value);
538  };
539 
540  if ( email_field.value != email_field.original_value ) {
541  uri += '&account_email_value=' + encodeURIComponent(email_field.value);
542  };
543 
544  if ( description.value != description.original_value ) {
545  uri += '&account_description_value=' + encodeURIComponent(description.value);
546  };
547 
548  if ( password_field.value && (password_field.value != password_field.defaultValue) ) {
549  uri += '&account_password_value=' + encodeURIComponent(password_field.value);
550  };
551 
552  if ( this.m_ajax_request_in_progress ) {
553  this.m_ajax_request_in_progress.abort();
554  this.m_ajax_request_in_progress = null;
555  };
556 
557  var salt = new Date();
558  uri += '&salt=' + salt.getTime();
559 
560  this.m_ajax_request_in_progress = BMLT_AjaxRequest(uri, function (in_req) {
561  admin_handler_object.handleAccountChangeAJAXCallback(in_req); }, 'post');
562  };
563  };
564  };
565 
566  /************************************************************************************//**
567  * \brief This is called to initiate an AJAX process to change the account settings. *
568  ****************************************************************************************/
569  this.handleAccountChangeAJAXCallback = function (in_http_request
570  ) {
571  var email_field = document.getElementById('bmlt_admin_user_email_input');
572  var password_field = document.getElementById('bmlt_admin_user_account_password_input');
573  var description = document.getElementById('bmlt_admin_user_description_textarea');
574 
575  this.m_ajax_request_in_progress = null;
576  if ( in_http_request.responseText ) {
577  if ( in_http_request.responseText == 'NOT AUTHORIZED' ) {
578  alert(g_AJAX_Auth_Failure);
579  } else {
580  eval('var json_object = ' + in_http_request.responseText + ';');
581  };
582  };
583 
584  if ( json_object.ACCOUNT_CHANGED ) {
585  var success = true;
586 
587  if ( json_object.ACCOUNT_CHANGED.EMAIL_CHANGED == true ) {
588  email_field.original_value = email_field.value;
589  } else if ( json_object.ACCOUNT_CHANGED.EMAIL_CHANGED == false ) {
590  success = false;
591  };
592 
593  if ( json_object.ACCOUNT_CHANGED.DESCRIPTION_CHANGED == true ) {
594  description.original_value = description.value;
595  } else if ( json_object.ACCOUNT_CHANGED.DESCRIPTION_CHANGED == false ) {
596  success = false;
597  };
598 
599  var reload = false;
600  if ( json_object.ACCOUNT_CHANGED.PASSWORD_CHANGED == true ) {
601  reload = true;
602  } else if ( json_object.ACCOUNT_CHANGED.PASSWORD_CHANGED == false ) {
603  success = false;
604  };
605 
606  if ( json_object.ACCOUNT_CHANGED.PASSWORD_CHANGED == true ) {
607  reload = true;
608  } else if ( json_object.ACCOUNT_CHANGED.PASSWORD_CHANGED == false ) {
609  success = false;
610  };
611 
612  if ( reload ) {
613  window.location.href = g_logout_uri;
614  };
615 
616  password_field.value = '';
617  this.validateAccountGoButton();
618 
619  if ( success ) {
620  BMLT_Admin_StartFader('bmlt_admin_fader_account_success_div', this.m_success_fade_duration);
621  } else {
622  BMLT_Admin_StartFader('bmlt_admin_fader_account_fail_div', this.m_failure_fade_duration);
623  };
624  } else {
625  BMLT_Admin_StartFader('bmlt_admin_fader_account_fail_div', this.m_failure_fade_duration);
626  };
627 
628  this.handleTextInputBlur(email_field);
629  this.handleTextInputBlur(password_field);
630  this.handleTextInputBlur(description);
631 
632  this.setMyAccountThrobber(false);
633  };
634 
635  /************************************************************************************//**
636  * \brief Displays or hides the AJAX Throbber for the My Account button. *
637  ****************************************************************************************/
638  this.setMyAccountThrobber = function ( in_shown ///< If true, the throbber is show. If false, it is hidden.
639  ) {
640  var button_span = document.getElementById('bmlt_admin_account_change_ajax_button_span');
641  var throbber_span = document.getElementById('bmlt_admin_account_change_ajax_button_throbber_span');
642 
643  throbber_span.className = 'bmlt_admin_value_left' + (in_shown ? '' : ' item_hidden');
644  button_span.className = 'bmlt_admin_value_left' + (in_shown ? ' item_hidden' : '');
645  };
646 
647  // #mark -
648  // #mark ########## Meeting Editor Section ##########
649  // #mark -
650 
651  /************************************************************************************//**
652  * \brief This opens the editor to a particular meeting, as given by an ID. *
653  ****************************************************************************************/
654  this.openMeetingForEditing = function ( in_meeting_id ///< The ID of the meeting to be opened.
655  ) {
656  this.m_meeting_editor_panel_shown = false;
657  this.toggleMeetingEditor();
658  var uri = g_ajax_callback_uri + '&do_meeting_search=1&simple_other_fields=1&SearchStringAll=1&SearchString=' + parseInt(in_meeting_id);
659  this.clearSearchResults();
660  this.callRootServerForMeetingSearch(uri);
661  };
662 
663  /************************************************************************************//**
664  * \brief Toggles the visibility of the meeting editor section. *
665  ****************************************************************************************/
666  this.toggleMeetingEditor = function () {
667  this.m_meeting_editor_panel_shown = !this.m_meeting_editor_panel_shown;
668 
669  var the_disclosure_div = document.getElementById('bmlt_admin_meeting_editor_disclosure_div');
670  var the_editor_div = document.getElementById('bmlt_admin_meeting_editor_wrapper_div');
671 
672  if ( this.m_meeting_editor_panel_shown ) {
673  the_disclosure_div.className = 'bmlt_admin_meeting_editor_disclosure_div bmlt_admin_meeting_editor_disclosure_div_open';
674  the_editor_div.className = 'bmlt_admin_meeting_editor_wrapper_div';
675  this.showWarningAlert();
676  } else {
677  the_disclosure_div.className = 'bmlt_admin_meeting_editor_disclosure_div bmlt_admin_meeting_editor_disclosure_div_closed';
678  the_editor_div.className = 'bmlt_admin_meeting_editor_wrapper_div bmlt_admin_meeting_editor_wrapper_div_hidden';
679  };
680  };
681 
682  /************************************************************************************//**
683  * \brief Returns an object with the meeting data for the meeting ID passed in. *
684  * \returns a meeting object. Null if none found, or invalid ID. *
685  ****************************************************************************************/
686  this.getMeetingObjectById = function (
687  in_meeting_id, ///< The ID of the meeting to fetch
688  in_as_a_copy ///< If true, then the returned meeting object will be a clone (new object).
689  ) {
690  var ret = null;
691 
692  if ( in_meeting_id && this.m_search_results && this.m_search_results.length ) {
693  for (var c = 0; c < this.m_search_results.length; c++) {
694  if ( in_meeting_id == this.m_search_results[c].id_bigint ) {
695  var obj = this.m_search_results[c];
696 
697  if ( in_as_a_copy ) {
698  ret = JSON.parse(JSON.stringify(obj));
699  } else {
700  ret = obj;
701  };
702  break;
703  };
704  };
705  };
706 
707  if ( !ret ) { // If we did not find the meeting, we create a placeholder for it.
708  ret = new Object;
709  ret.longitude = g_default_longitude;
710  ret.latitude = g_default_latitude;
711  ret.start_time = g_default_meeting_start_time;
712 
713  var dur = g_default_meeting_duration.split(':');
714  dur[0] = parseInt(dur[0], 10);
715  dur[1] = parseInt(dur[1], 10);
716  ret.duration_time = sprintf('%02d:%02d:00', dur[0], dur[1]);
717 
718  ret.weekday_tinyint = g_default_meeting_weekday.toString();
719  ret.id_bigint = 0; // All new meetings are ID 0.
720  ret.published = g_default_meeting_published;
721  ret.service_body_bigint = g_service_bodies_array[0][0].toString();
722  ret.formats = '';
723  ret.format_shared_id_list = '';
724  };
725 
726  ret.zoom = g_default_zoom;
727 
728  return ret;
729  };
730 
731  // #mark -
732  // #mark Search For Meetings Tab
733  // #mark -
734 
735  /************************************************************************************//**
736  * \brief Selecte the search specifier tab. *
737  ****************************************************************************************/
738  this.selectSearchSpecifierTab = function () {
739  var tab_specifier_element = document.getElementById('bmlt_admin_meeting_editor_tab_specifier_div');
740  var tab_editor_element = document.getElementById('bmlt_admin_meeting_editor_tab_results_div');
741  var tab_specifier_link = document.getElementById('bmlt_admin_meeting_editor_tab_specifier_a');
742  var tab_editor_link = document.getElementById('bmlt_admin_meeting_editor_tab_results_a');
743  var search_specifier_element = document.getElementById('bmlt_admin_meeting_editor_form_specifier_div');
744  var meeting_editor_element = document.getElementById('bmlt_admin_meeting_editor_form_div');
745 
746  tab_specifier_element.className = 'bmlt_admin_tab_div_left bmlt_admin_tab_div_selected';
747  tab_editor_element.className = 'bmlt_admin_tab_div_right bmlt_admin_tab_div_not_selected';
748 
749  tab_editor_link.setAttribute('href', '');
750  tab_editor_link.href = 'javascript:admin_handler_object.selectMeetingEditorTab()';
751  tab_specifier_link.removeAttribute("href");
752 
753  search_specifier_element.className = 'bmlt_admin_meeting_editor_form_specifier_div';
754  meeting_editor_element.className = 'bmlt_admin_meeting_editor_form_div item_hidden';
755  }
756 
757  /************************************************************************************//**
758  * \brief This makes sure that the "All" checkbox syncs with the weekdays. *
759  ****************************************************************************************/
760  this.handleWeekdayCheckBoxChanges = function ( in_checkbox_index ///< The checkbox that triggered the call.
761  ) {
762  var all_checkbox = document.getElementById('bmlt_admin_meeting_search_weekday_checkbox_0');
763  var weekday_checkboxes = new Array(
764  document.getElementById('bmlt_admin_meeting_search_weekday_checkbox_1'),
765  document.getElementById('bmlt_admin_meeting_search_weekday_checkbox_2'),
766  document.getElementById('bmlt_admin_meeting_search_weekday_checkbox_3'),
767  document.getElementById('bmlt_admin_meeting_search_weekday_checkbox_4'),
768  document.getElementById('bmlt_admin_meeting_search_weekday_checkbox_5'),
769  document.getElementById('bmlt_admin_meeting_search_weekday_checkbox_6'),
770  document.getElementById('bmlt_admin_meeting_search_weekday_checkbox_7')
771  );
772 
773  if ( in_checkbox_index ) {
774  var weekday_selected = true;
775  for (var c = 0; c < 7; c++) {
776  if ( !weekday_checkboxes[c].checked ) {
777  weekday_selected = false;
778  };
779  };
780 
781  all_checkbox.checked = weekday_selected;
782  } else {
783  for (var c = 0; c < 7; c++) {
784  weekday_checkboxes[c].checked = all_checkbox.checked;
785  };
786  };
787  };
788 
789  /************************************************************************************//**
790  * \brief This handles Service body checkboxes. *
791  ****************************************************************************************/
792  this.handleServiceCheckBoxChanges = function ( in_service_body_id ///< The checkbox that triggered the call.
793  ) {
794  var the_checkbox = document.getElementById('bmlt_admin_meeting_search_service_body_checkbox_' + in_service_body_id);
795 
796  if ( the_checkbox ) {
797  var my_children = this.getServiceBodyChildren(in_service_body_id);
798  for (var c = 0; my_children && (c < my_children.length); c++) {
799  var child_id = my_children[c][0];
800  var child_checkbox = document.getElementById('bmlt_admin_meeting_search_service_body_checkbox_' + child_id);
801  if ( child_checkbox ) {
802  child_checkbox.checked = the_checkbox.checked;
803  this.handleServiceCheckBoxChanges(child_id);
804  };
805  };
806  };
807  };
808 
809  /************************************************************************************//**
810  * \brief This returns the Service body ID of the given Service body ID. *
811  * \returns an integer that is the ID of the parent Service body. *
812  ****************************************************************************************/
813  this.getServiceBodyParentID = function ( in_service_body_id
814  ) {
815  var the_object = null;
816 
817  for (var c = 0; c < g_service_bodies_array.length; c++) {
818  if ( g_service_bodies_array[c][0] == in_service_body_id ) {
819  the_object = g_service_bodies_array[c];
820  break;
821  };
822  };
823 
824  return the_object[1];
825  };
826 
827  /************************************************************************************//**
828  * \brief Returns an array of Service body objects that are direct descendants of the *
829  * given Service body, as specified by ID. *
830  * \returns an array of Service body objects. *
831  ****************************************************************************************/
832  this.getServiceBodyChildren = function ( in_service_body_id
833  ) {
834  var ret_array = null;
835 
836  for (var c = 0; c < g_service_bodies_array.length; c++) {
837  if ( this.getServiceBodyParentID(g_service_bodies_array[c][0]) == in_service_body_id ) {
838  if ( ! ret_array ) {
839  ret_array = new Array();
840  };
841 
842  ret_array[ret_array.length] = g_service_bodies_array[c];
843  };
844  };
845 
846  return ret_array;
847  };
848 
849  /************************************************************************************//**
850  * \brief Returns the name of the given Service body, by ID. *
851  * \returns a string. *
852  ****************************************************************************************/
853  this.getServiceBodyName = function ( in_service_body_id
854  ) {
855  var the_object = null;
856 
857  for (var c = 0; c < g_service_bodies_array.length; c++) {
858  if ( g_service_bodies_array[c][0] == in_service_body_id ) {
859  the_object = g_service_bodies_array[c];
860  break;
861  };
862  };
863 
864  return the_object[2];
865  };
866 
867  /************************************************************************************//**
868  * \brief Displays the Search Results or specifier, dependent upon the switch. *
869  ****************************************************************************************/
870  this.setSearchResultsVisibility = function () {
871  var search_specifier_div = document.getElementById('bmlt_admin_meeting_editor_form_specifier_div');
872  var search_results_div = document.getElementById('bmlt_admin_meeting_editor_form_results_div');
873 
874  if ( this.m_search_specifier_shown ) {
875  search_specifier_div.className = 'bmlt_admin_meeting_editor_form_specifier_div';
876  search_results_div.className = 'bmlt_admin_meeting_editor_form_results_div item_hidden';
877  } else {
878  search_specifier_div.className = 'bmlt_admin_meeting_editor_form_specifier_div item_hidden';
879  search_results_div.className = 'bmlt_admin_meeting_editor_form_results_div';
880  };
881  };
882 
883  // #mark -
884  // #mark Do A Meeting Search
885  // #mark -
886 
887  /************************************************************************************//**
888  * \brief Reacts to the "Search For Meetings" button being hit. *
889  ****************************************************************************************/
890  this.searchForMeetings = function () {
891  var button_span = document.getElementById('bmlt_admin_meeting_search_ajax_button_span');
892  var throbber_span = document.getElementById('bmlt_admin_meeting_search_ajax_button_throbber_span');
893 
894  var uri = this.createSearchURI();
895 
896  button_span.className = 'bmlt_admin_value_left item_hidden';
897  throbber_span.className = 'bmlt_admin_value_left';
898 
899  this.clearSearchResults();
900  this.callRootServerForMeetingSearch(uri);
901  };
902 
903 
904  /************************************************************************************//**
905  * \brief Clears any previous search results. *
906  ****************************************************************************************/
907  this.clearSearchResults = function () {
908  var the_outer_container = document.getElementById('bmlt_admin_meeting_editor_form_results_inner_div');
909  var the_main_results_display = document.getElementById('bmlt_admin_meeting_editor_form_results_div');
910 
911  if ( this.m_meeting_results_container_div ) { // Make sure we're starting from scratch.
912  this.m_meeting_results_container_div.innerHTML = '';
913  this.m_meeting_results_container_div = null;
914  };
915 
916  the_outer_container.innerHTML = '';
917  the_main_results_display.className = 'bmlt_admin_meeting_editor_form_results_div item_hidden"';
918 
919  this.m_search_results = null;
920  };
921 
922  /************************************************************************************//**
923  * \brief This function constructs a URI to the root server that reflects the search *
924  * parameters, as specified by the search specification section. *
925  * \returns a string, containing the complete URI. *
926  ****************************************************************************************/
927  this.createSearchURI = function () {
928  var uri = g_ajax_callback_uri + '&do_meeting_search=1&sort_key=time&simple_other_fields=1';
929 
930  var search_string = document.getElementById('bmlt_admin_text_specifier_input').value;
931 
932  if ( search_string == document.getElementById('bmlt_admin_text_specifier_input').defaultValue ) {
933  search_string = null;
934  };
935 
936  var is_location = document.getElementById('bmlt_admin_meeting_search_text_is_a_location_checkbox').checked;
937  var weekdays = new Array;
938 
939  if ( !document.getElementById('bmlt_admin_meeting_search_weekday_checkbox_0').checked ) {
940  for (var c = 1; c < 8; c++) {
941  if ( document.getElementById('bmlt_admin_meeting_search_weekday_checkbox_' + c).checked ) {
942  weekdays[weekdays.length] = c;
943  };
944  };
945  };
946 
947  var service_bodies = new Array();
948 
949  if ( g_service_bodies_array.length > 1 ) {
950  for (var c = 0; c < g_service_bodies_array.length; c++) {
951  var service_body_id = g_service_bodies_array[c][0];
952  var sb_checkbox = document.getElementById('bmlt_admin_meeting_search_service_body_checkbox_' + service_body_id);
953  if ( sb_checkbox && sb_checkbox.checked ) {
954  service_bodies[service_bodies.length] = service_body_id;
955  };
956  };
957  } else {
958  service_bodies[0] = g_service_bodies_array[0][0];
959  };
960 
961  var starts_after = new Array();
962  var starts_before = new Array();
963 
964  if ( document.getElementById('bmlt_admin_meeting_search_start_time_morn_checkbox').checked ) {
965  starts_after = new Array(0, 0);
966  starts_before = new Array(12, 0);
967  } else if ( document.getElementById('bmlt_admin_meeting_search_start_time_aft_checkbox').checked ) {
968  starts_after = new Array(11, 59);
969  starts_before = new Array(18, 0);
970  } else if ( document.getElementById('bmlt_admin_meeting_search_start_time_eve_checkbox').checked ) {
971  starts_after = new Array(17, 59);
972  starts_before = new Array(23, 59);
973  };
974 
975  if ( search_string ) {
976  uri += '&SearchStringAll=1&SearchString=' + encodeURIComponent(search_string) + (is_location ? '&StringSearchIsAnAddress=1' : '');
977  };
978 
979  if ( weekdays.length ) {
980  for (var c = 0; c < weekdays.length; c++) {
981  uri += '&weekdays[]=' + parseInt(weekdays[c], 10);
982  };
983  };
984 
985  if ( service_bodies.length ) {
986  for (var c = 0; c < service_bodies.length; c++) {
987  uri += '&services[]=' + parseInt(service_bodies[c], 10);
988  };
989  };
990 
991  if ( starts_after.length ) {
992  uri += '&StartsAfterH=' + starts_after[0];
993  uri += '&StartsAfterM=' + starts_after[1];
994  };
995 
996  if ( starts_before.length ) {
997  uri += '&StartsBeforeH=' + starts_before[0];
998  uri += '&StartsBeforeM=' + starts_before[1];
999  };
1000 
1001  var pub_select = document.getElementById('bmlt_admin_single_meeting_editor_template_meeting_publish_search_select');
1002 
1003  if ( pub_select.value ) {
1004  uri += '&advanced_published=' + pub_select.value;
1005  };
1006 
1007  return uri;
1008  };
1009 
1010  /************************************************************************************//**
1011  * \brief Does an AJAX call for a JSON response, based on the given criteria and *
1012  * callback function. *
1013  * The callback will be a function in the following format: *
1014  * function ajax_callback ( in_json_obj ) *
1015  * where "in_json_obj" is the response, converted to a JSON object. *
1016  * it will be null if the function failed. *
1017  ****************************************************************************************/
1018  this.callRootServerForMeetingSearch = function (in_uri ///< The URI to call (with all the parameters).
1019  ) {
1020  if ( this.m_ajax_request_in_progress ) {
1021  this.m_ajax_request_in_progress.abort();
1022  this.m_ajax_request_in_progress = null;
1023  };
1024 
1025  var salt = new Date();
1026  in_uri += '&salt=' + salt.getTime();
1027 
1028  this.m_ajax_request_in_progress = BMLT_AjaxRequest(in_uri, function (in_req) {
1029  admin_handler_object.meetingSearchResultsCallback(in_req); }, 'post');
1030  };
1031 
1032  /************************************************************************************//**
1033  * \brief This is the meeting search results callback. *
1034  ****************************************************************************************/
1035  this.meetingSearchResultsCallback = function ( in_response_object ///< The HTTPRequest response object.
1036  ) {
1037  var button_span = document.getElementById('bmlt_admin_meeting_search_ajax_button_span');
1038  var throbber_span = document.getElementById('bmlt_admin_meeting_search_ajax_button_throbber_span');
1039  var text_reply = in_response_object.responseText;
1040 
1041  throbber_span.className = 'bmlt_admin_value_left item_hidden';
1042  button_span.className = 'bmlt_admin_value_left';
1043 
1044  if ( text_reply ) {
1045  var json_builder = 'var response_object = ' + text_reply + ';';
1046 
1047  // This is how you create JSON objects.
1048  eval(json_builder);
1049 
1050  if ( response_object.length ) {
1051  this.processSearchResults(response_object);
1052  location.hash = '#bmlt_admin_meeting_editor_form_results_banner_div';
1053  } else {
1054  alert(g_no_search_results_text);
1055  };
1056  } else {
1057  alert(g_no_search_results_text);
1058  };
1059  };
1060 
1061  /************************************************************************************//**
1062  * \brief This creates the meeting search results. *
1063  ****************************************************************************************/
1064  this.processSearchResults = function ( in_search_results_json_object ///< The search results, as a JSON object.
1065  ) {
1066  this.m_search_results = in_search_results_json_object;
1067 
1068  for (var c = 0; c < this.m_search_results.length; c++) {
1069  if ( this.m_search_results[c] ) {
1070  // The reason we do this whacky stuff, is that the formats may not be in the same order from the server as we keep them, so this little dance re-orders them.
1071  var format_array = new Array;
1072  var main_formats = g_format_object_array;
1073  var mtg_formats = this.m_search_results[c].formats.split(',');
1074 
1075  for (var i = 0; i < main_formats.length; i++) {
1076  for (var n = 0; n < mtg_formats.length; n++) {
1077  if ( main_formats[i].key == mtg_formats[n] ) {
1078  format_array[format_array.length] = mtg_formats[n];
1079  };
1080  };
1081  };
1082 
1083  this.m_search_results[c].formats = format_array.join(',');
1084 
1085  var dur = this.m_search_results[c].duration_time.split(':');
1086  dur[0] = parseInt(dur[0], 10);
1087  dur[1] = parseInt(dur[1], 10);
1088  this.m_search_results[c].duration_time = sprintf('%02d:%02d:00', dur[0], dur[1]);
1089  };
1090  };
1091 
1092  this.createMeetingList();
1093 
1094  this.selectMeetingEditorTab();
1095  };
1096 
1097  /************************************************************************************//**
1098  * \brief This creates the DOM tree of the meeting list.
1099  ****************************************************************************************/
1100  this.createMeetingList = function () {
1101  this.m_search_results.sort(admin_handler_object.sortSearchResultsCallback);
1102 
1103  var the_outer_container = document.getElementById('bmlt_admin_meeting_editor_form_results_inner_div');
1104  var the_results_header = document.getElementById('bmlt_admin_meeting_editor_form_results_banner_div');
1105  var the_main_results_display = document.getElementById('bmlt_admin_meeting_editor_form_results_div');
1106 
1107  if ( this.m_meeting_results_container_div ) {
1108  this.m_meeting_results_container_div.innerHTML = '';
1109  this.m_meeting_results_container_div = null;
1110  };
1111 
1112  the_outer_container.innerHTML = '';
1113  the_main_results_display.className = 'bmlt_admin_meeting_editor_form_results_div item_hidden"';
1114  this.m_meeting_results_container_div = document.createElement('div'); // Create the container element.
1115  this.m_meeting_results_container_div.className = 'bmlt_admin_meeting_search_results_container_div';
1116 
1117  for (var c = 0; c < this.m_search_results.length; c++) {
1118  if ( this.m_search_results[c] ) {
1119  var outer_meeting_div = document.createElement('div'); // Create the container element.
1120  outer_meeting_div.meeting_id = this.m_search_results[c].id_bigint;
1121  outer_meeting_div.className = 'bmlt_admin_meeting_search_results_single_meeting_outer_container_' + ((this.m_search_results[c].published != '0') ? 'published' : 'unpublished') + '_div';
1122 
1123  var single_meeting_div = document.createElement('div'); // Create the container element.
1124  single_meeting_div.meeting_id = this.m_search_results[c].id_bigint;
1125  single_meeting_div.className = 'bmlt_admin_meeting_search_results_single_meeting_container_div' + ((c % 2) ? ' meeting_line_odd' : ' meeting_line_even');
1126  single_meeting_div.id = 'bmlt_admin_meeting_search_results_single_meeting_' + single_meeting_div.meeting_id +'_div';
1127 
1128  this.createOneMeetingNode(single_meeting_div, this.m_search_results[c]);
1129 
1130  outer_meeting_div.appendChild(single_meeting_div);
1131 
1132  this.m_meeting_results_container_div.appendChild(outer_meeting_div);
1133  };
1134  };
1135 
1136  var breaker_breaker_rubber_duck = document.createElement('div'); // This is a break element.
1137  breaker_breaker_rubber_duck.className = 'clear_both';
1138  this.m_meeting_results_container_div.appendChild(breaker_breaker_rubber_duck);
1139 
1140  the_outer_container.appendChild(this.m_meeting_results_container_div);
1141  the_main_results_display.className = 'bmlt_admin_meeting_editor_form_results_div"';
1142 
1143  the_results_header.innerHTML = (this.m_search_results.length > 1) ? sprintf(g_meeting_editor_result_count_format, this.m_search_results.length) : '';
1144  };
1145 
1146  /************************************************************************************//**
1147  * \brief Sorts the search results by weekday, then time.
1148  ****************************************************************************************/
1149  this.sortSearchResultsCallback = function (
1150  in_object_a,
1151  in_object_b
1152  ) {
1153  if ( in_object_a && in_object_b ) {
1154  var a_start = in_object_a.start_time.toString().split(':');
1155  var b_start = in_object_b.start_time.toString().split(':');
1156  var a_time = (parseInt(in_object_a.weekday_tinyint, 10) * 100000) + (parseInt(a_start[0], 10) * 100) + parseInt(a_start[1], 10);
1157  var b_time = (parseInt(in_object_b.weekday_tinyint, 10) * 100000) + (parseInt(b_start[0], 10) * 100) + parseInt(b_start[1], 10);
1158 
1159  return (a_time > b_time) ? 1 : ((a_time < b_time) ? -1 : 0);
1160  } else if ( in_object_a && !in_object_b ) {
1161  return -1;
1162  } else if ( in_object_b && !in_object_a ) {
1163  return 1;
1164  };
1165 
1166  return 0;
1167  };
1168 
1169  /************************************************************************************//**
1170  * \brief
1171  ****************************************************************************************/
1172  this.createOneMeetingNode = function (
1173  in_single_meeting_div, ///< The containing div element.
1174  in_meeting_object ///< The meeting object.
1175  ) {
1176  var meeting_editorLink = document.createElement('a');
1177  meeting_editorLink.href = 'javascript:admin_handler_object.toggleMeetingSingleEditor(' + in_meeting_object.id_bigint + ', false)';
1178  meeting_editorLink.className = 'bmlt_admin_meeting_search_results_single_meeting_a';
1179 
1180  var element_span = document.createElement('span'); // Create the container element.
1181  element_span.className = 'bmlt_admin_meeting_search_results_single_meeting_weekday_span';
1182  var text_node = document.createTextNode(g_weekday_name_array[in_meeting_object.weekday_tinyint - 1]);
1183  element_span.appendChild(text_node);
1184  meeting_editorLink.appendChild(element_span);
1185 
1186  element_span = document.createElement('span'); // Create the container element.
1187  element_span.className = 'bmlt_admin_meeting_search_results_single_meeting_start_time_span';
1188  var start_time = in_meeting_object.start_time;
1189  var start_time = in_meeting_object.start_time.toString().split(':');
1190  var hours = 0;
1191  var minutes = 0;
1192  var midnight = false;
1193  var noon = false;
1194  var pm = false;
1195 
1196  if ( start_time && (start_time.length > 1) ) {
1197  var hours = parseInt(start_time[0], 10);
1198  var minutes = parseInt(start_time[1], 10);
1199  var midnight = false;
1200  var noon = false;
1201  var pm = false;
1202 
1203  if ( (hours == 23) && (minutes > 55) ) {
1204  midnight = true;
1205  } else {
1206  if ( (hours == 12) && (minutes == 0) ) {
1207  noon = true;
1208  } else {
1209  if ( hours > 23 ) {
1210  hours = 23;
1211  };
1212 
1213  if ( hours < 0 ) {
1214  hours = 0;
1215  };
1216 
1217  if ( minutes > 59 ) {
1218  minutes = 59;
1219  };
1220 
1221  if ( minutes < 0 ) {
1222  minutes = 0;
1223  };
1224 
1225  if ( minutes % g_default_minute_interval ) {
1226  minutes += g_default_minute_interval;
1227 
1228  if ( minutes >= 60 ) {
1229  hours++;
1230  minutes -= 60;
1231  };
1232  };
1233  };
1234  };
1235 
1236  if ( hours > 12 ) {
1237  hours -= 12;
1238  pm = true;
1239  } else if ( (hours == 12) && (minutes > 0) ) {
1240  pm = true;
1241  };
1242  };
1243 
1244  if ( midnight ) {
1245  start_time = g_time_values[3];
1246  } else if ( noon ) {
1247  start_time = g_time_values[2];
1248  } else {
1249  start_time = sprintf('%d:%02d %s', hours, minutes, (pm ? g_time_values[1] : g_time_values[0]));
1250  };
1251 
1252  text_node = document.createTextNode(start_time);
1253  element_span.appendChild(text_node);
1254  meeting_editorLink.appendChild(element_span);
1255 
1256  element_span = document.createElement('span'); // Create the container element.
1257  element_span.className = 'bmlt_admin_meeting_search_results_single_meeting_meeting_name_span';
1258  text_node = document.createTextNode(in_meeting_object.meeting_name + (in_meeting_object.location_street ? ', ' + in_meeting_object.location_street : '') + (in_meeting_object.location_city_subsection ? ', ' + in_meeting_object.location_city_subsection : '') + (in_meeting_object.location_municipality ? ', ' + in_meeting_object.location_municipality : '') + (in_meeting_object.location_province ? ', ' + in_meeting_object.location_province : '') + (in_meeting_object.location_sub_province ? ', (' + in_meeting_object.location_sub_province + ')' : '') + (in_meeting_object.location_postal_code_1 ? ', ' + in_meeting_object.location_postal_code_1 : ''));
1259  element_span.appendChild(text_node);
1260  meeting_editorLink.appendChild(element_span);
1261 
1262  in_single_meeting_div.appendChild(meeting_editorLink);
1263  var breaker_breaker_rubber_duck = document.createElement('div'); // This is a break element.
1264  breaker_breaker_rubber_duck.className = 'clear_both';
1265  in_single_meeting_div.appendChild(breaker_breaker_rubber_duck);
1266  };
1267 
1268  // #mark -
1269  // #mark Edit Meetings Tab
1270  // #mark -
1271 
1272  /************************************************************************************//**
1273  * \brief Selects the meeting editor tab. *
1274  ****************************************************************************************/
1275  this.selectMeetingEditorTab = function () {
1276  var tab_specifier_element = document.getElementById('bmlt_admin_meeting_editor_tab_specifier_div');
1277  var tab_editor_element = document.getElementById('bmlt_admin_meeting_editor_tab_results_div');
1278  var tab_specifier_link = document.getElementById('bmlt_admin_meeting_editor_tab_specifier_a');
1279  var tab_editor_link = document.getElementById('bmlt_admin_meeting_editor_tab_results_a');
1280  var search_specifier_element = document.getElementById('bmlt_admin_meeting_editor_form_specifier_div');
1281  var meeting_editor_element = document.getElementById('bmlt_admin_meeting_editor_form_div');
1282 
1283  tab_specifier_element.className = 'bmlt_admin_tab_div_left bmlt_admin_tab_div_not_selected';
1284  tab_editor_element.className = 'bmlt_admin_tab_div_right bmlt_admin_tab_div_selected';
1285 
1286  tab_specifier_link.setAttribute('href', '');
1287  tab_specifier_link.href = 'javascript:admin_handler_object.selectSearchSpecifierTab()';
1288  tab_editor_link.removeAttribute("href");
1289 
1290  search_specifier_element.className = 'bmlt_admin_meeting_editor_form_specifier_div item_hidden';
1291  meeting_editor_element.className = 'bmlt_admin_meeting_editor_form_div';
1292  }
1293 
1294  /************************************************************************************//**
1295  * \brief Brings up a new meeting screen. *
1296  ****************************************************************************************/
1297  this.toggleMeetingSingleEditor = function (
1298  in_meeting_id,
1299  in_no_confirm
1300  ) {
1301  var display_parent = document.getElementById('bmlt_admin_meeting_search_results_single_meeting_' + in_meeting_id + '_div');
1302 
1303  if ( display_parent ) {
1304  if ( !display_parent.meeting_editor_object ) {
1305  var proceed = true;
1306  if ( !in_no_confirm && (this.m_editing_window_open != null) && this.isMeetingDirty(this.m_editing_window_open.meeting_id) ) {
1307  proceed = confirm(g_meeting_editor_already_editing_confirm);
1308  };
1309 
1310  if ( proceed ) {
1311  if ( this.m_editing_window_open != null ) {
1312  if ( this.m_editing_window_open.meeting_editor_object && (this.m_editing_window_open.meeting_editor_object.parentNode == this.m_editing_window_open) ) {
1313  this.m_editing_window_open.removeChild(this.m_editing_window_open.meeting_editor_object);
1314  this.m_editing_window_open.meeting_editor_object = null;
1315  } else {
1316  document.getElementById('bmlt_admin_meeting_editor_new_meeting_0_editor_display').className = 'item_hidden';
1317  document.getElementById('bmlt_admin_meeting_editor_form_meeting_0_button').className = 'bmlt_admin_ajax_button button';
1318  };
1319 
1320  this.m_editing_window_open = null;
1321  };
1322 
1323  display_parent.meeting_editor_object = document.createElement('div'); // Create the container element.
1324  display_parent.meeting_editor_object.className = 'bmlt_admin_meeting_search_results_editor_container_div';
1325  display_parent.appendChild(display_parent.meeting_editor_object);
1326  display_parent.meeting_id = in_meeting_id;
1327 
1328  this.m_editing_window_open = display_parent;
1329  this.createNewMeetingEditorScreen(display_parent.meeting_editor_object, in_meeting_id);
1330  location.hash = '#bmlt_admin_meeting_search_results_single_meeting_' + parseInt(in_meeting_id, 10) + '_div';
1331  };
1332  } else {
1333  var proceed = true;
1334  if ( !in_no_confirm && (this.m_editing_window_open != null) && this.isMeetingDirty(this.m_editing_window_open.meeting_id) ) {
1335  proceed = confirm(g_meeting_closure_confirm_text);
1336  };
1337 
1338  if ( proceed ) {
1339  if ( display_parent.meeting_editor_object && (display_parent.meeting_editor_object.parentNode == display_parent) ) {
1340  display_parent.removeChild(display_parent.meeting_editor_object);
1341  };
1342 
1343  this.m_editing_window_open.meeting_id = null;
1344  display_parent.meeting_editor_object = null;
1345  };
1346  };
1347  };
1348  };
1349 
1350  /************************************************************************************//**
1351  * \brief Brings up a new meeting screen. *
1352  ****************************************************************************************/
1353  this.createANewMeetingButtonHit = function ( in_button_object
1354  ) {
1355  var display_parent = document.getElementById('bmlt_admin_meeting_editor_new_meeting_0_editor_display');
1356  var new_meeting_button = document.getElementById('bmlt_admin_meeting_editor_form_meeting_0_button');
1357 
1358  display_parent.innerHTML = '';
1359 
1360  var proceed = true;
1361  if ( (this.m_editing_window_open != null) && this.isMeetingDirty(this.m_editing_window_open.meeting_id) ) {
1362  proceed = confirm(g_meeting_editor_already_editing_confirm);
1363  };
1364 
1365  if ( proceed ) {
1366  if ( this.m_editing_window_open != null ) {
1367  this.cancelMeetingEdit(this.m_editing_window_open.meeting_id, true);
1368  };
1369 
1370  this.createNewMeetingEditorScreen(display_parent, 0);
1371 
1372  new_meeting_button.className = 'bmlt_admin_ajax_button button item_hidden';
1373  display_parent.className = 'bmlt_admin_meeting_editor_meeting_editor_display';
1374  this.changeSaveMeetingButtonToCopy(0);
1375 
1376  this.m_editing_window_open = document.getElementById('bmlt_admin_single_meeting_editor_0_div');
1377  this.m_editing_window_open.meeting_id = 0;
1378  };
1379  };
1380 
1381  /************************************************************************************//**
1382  * \brief
1383  ****************************************************************************************/
1384  this.changeSaveMeetingButtonToCopy = function ( in_meeting_id ///< The BMLT ID of the meeting that is being edited.
1385  ) {
1386  var save_button = document.getElementById('bmlt_admin_meeting_editor_form_meeting_' + in_meeting_id +'_save_button');
1387  save_button.innerHTML = g_Create_new_meeting_button_name;
1388  this.validateMeetingEditorButton(in_meeting_id);
1389  };
1390 
1391  /************************************************************************************//**
1392  * \brief
1393  ****************************************************************************************/
1394  this.changeCopyMeetingButtonToSave = function ( in_meeting_id ///< The BMLT ID of the meeting that is being edited.
1395  ) {
1396  var save_button = document.getElementById('bmlt_admin_meeting_editor_form_meeting_' + in_meeting_id +'_save_button');
1397  save_button.innerHTML = g_Save_meeting_button_name;
1398  this.validateMeetingEditorButton(in_meeting_id);
1399  };
1400 
1401  /************************************************************************************//**
1402  * \brief Validate meeting data before it can be saved.
1403  ****************************************************************************************/
1404  this.checkURL = function(string) {
1405  let url;
1406  try {
1407  url = new URL(string);
1408  } catch (_) {
1409  return false;
1410  }
1411  return ["http:", "https:", "teamspeak:"].includes(url.protocol);
1412  }
1413 
1414  this.validateMeetingDetails = function ( in_meeting_id ) {
1415  var errors = [];
1416  var warnings = [];
1417  var show_warnings = false;
1418  var venue_type = $("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_venue_type").find("input:radio[name=venue_type]:checked").val();
1419  var isInpersonOrHybrid = venue_type === 'inperson' || venue_type === 'hybrid';
1420  var isVirtualOrHybrid = venue_type === 'virtual' || venue_type === 'virtualTC' || venue_type === 'hybrid';
1421  var street = $("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_street_text_input").val().trim();
1422  var city = $("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_city_text_input").val().trim();
1423  // the state might be specified either as a text field, or selected from a list of options
1424  var s = $("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_state_text_input");
1425  if (s.length==0) {
1426  s = $("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_state_select_input");
1427  }
1428  var state = s.val().trim();
1429  var zip = $("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_zip_text_input").val().trim();
1430  var url = $("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_virtual_meeting_link_text_input").val().trim();
1431  var phone = $("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_phone_meeting_number_text_input").val().trim();
1432  var additional = $("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_virtual_meeting_additional_info_text_input").val().trim();
1433 
1434  $(".error_helper_text").remove();
1435  $(".warn_helper_text").remove();
1436  // Error checks as follows:
1437  // - One of the radio buttons for venue_type must be checked
1438  // - Virtual or Hybrid meetings must have at least one of a URL, phone number, or Virtual Meeting Additional Information
1439  // - Virtual Meeting Link must contains a valid URL if it's non-empty
1440  if (venue_type == null) {
1441  errors.push(this.setValidationMessage("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_venue_type",
1442  "meeting_editor_screen_meeting_venue_type_validation",
1443  this.validationMessageTypes.ERROR));
1444  }
1445 
1446  if (isVirtualOrHybrid && url === '' && phone === '' && additional === '') {
1447  // use "_meeting_virtual_meeting_additional_info_text_input" instead of "_meeting_virtual_meta" to position this error under the additional info field
1448  errors.push(this.setValidationMessage("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_virtual_meta",
1449  "meeting_editor_screen_meeting_virtual_info_missing",
1450  this.validationMessageTypes.ERROR,
1451  true));
1452  }
1453 
1454  // require that the virtual meeting link contains a valid URL if it's non-empty
1455  if (url !== '' && !this.checkURL(url)) {
1456  errors.push(this.setValidationMessage("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_virtual_meeting_link_text_input",
1457  "meeting_editor_screen_meeting_url_validation",
1458  this.validationMessageTypes.ERROR));
1459  }
1460 
1461  // Warnings as follows:
1462  // - Every meeting should have some location information (minimally, either city/state or zip). Later this should probably be required.
1463  // - In-person and hybrid meetings should have a street address.
1464  // - Either Virtual Meeting Link or Phone Meeting Dial-in Number field should be filled in for a virtual or hybrid meeting.
1465  // - Virtual Meeting Additional Information should be filled in if there is a Virtual Meeting Link (only checked for virtual meetings).
1466  //
1467  // Notes about warnings:
1468  // - If there is something in Virtual Meeting Additional Information, there should also be something in either Virtual Meeting Link
1469  // or Phone Meeting Dial-in Number ... but we only need to warn about this if the meeting is a virtual or hybrid meeting. So we
1470  // don't actually need a separate check for this.
1471  //
1472 
1473  // check that there is either a city/state or a zip
1474  if ( !(city !== '' && state !== '' || zip !== '') ) {
1475  warnings.push(this.setValidationMessage("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_city_text_input",
1476  "meeting_editor_screen_meeting_location_warning",
1477  this.validationMessageTypes.WARN));
1478  }
1479 
1480  if (isInpersonOrHybrid) {
1481  if (street === '') {
1482  warnings.push(this.setValidationMessage("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_street_text_input",
1483  "meeting_editor_screen_meeting_address_warning",
1484  this.validationMessageTypes.WARN));
1485  }
1486  }
1487 
1488  if (isVirtualOrHybrid) {
1489  if (url === '' && phone === '') {
1490  // use "_meeting_virtual_meeting_additional_info_text_input" instead of "_meeting_virtual_meta" to position this warning under the additional info field
1491  warnings.push(this.setValidationMessage("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_virtual_meta",
1492  "meeting_editor_screen_meeting_url_or_phone_warning",
1493  this.validationMessageTypes.WARN,
1494  true));
1495  }
1496 
1497  if (url !== '' && additional === '') {
1498  warnings.push(this.setValidationMessage("#bmlt_admin_single_meeting_editor_" + in_meeting_id + "_meeting_virtual_meeting_additional_info_text_input",
1499  "meeting_editor_screen_meeting_additional_warning",
1500  this.validationMessageTypes.WARN));
1501  }
1502  }
1503 
1504  if (errors.length == 0 && warnings.length > 0) {
1505  var s = my_localized_strings['comdef_server_admin_strings']['meeting_editor_screen_meeting_validation_warning'];
1506  show_warnings = !confirm(s + "\n----------\n" + warnings.join("\n\n"));
1507  }
1508 
1509  return { "errors": errors, "warnings": warnings, "show_warnings": show_warnings };
1510  }
1511 
1512  // put an error or warning message in the appropriate spot in the DOM, and return the message
1513  this.setValidationMessage = function ( selector, resource, type, use_spacer = false ) {
1514  var r = my_localized_strings['comdef_server_admin_strings'][resource];
1515  var s = "<div class='" + type + "_helper_text'>" + r + "</div>";
1516  var t = (use_spacer ? "<div class='virtual_error_warn_spacer'>" + s + "</div>" : s);
1517  $(selector).parent().append(t);
1518  return r;
1519  }
1520 
1521  // put an error or warning message below the save button in the DOM along with a warning emoji
1522  this.setValidationSaveMessage = function ( selector, resource, type, messages ) {
1523  var r = my_localized_strings['comdef_server_admin_strings'][resource];
1524  var t = "<div class='save_error_spacer'><div class='" + type + "_helper_text'>" + "<table><tr><td class='error_emoji'>\u26A0 </td><td>" + r + messages + "</td></tr></table></div></div>";
1525  $(selector).parent().append(t);
1526  }
1527 
1528  /************************************************************************************//**
1529  * \brief
1530  ****************************************************************************************/
1531  this.saveMeeting = function ( in_meeting_id
1532  ) {
1533  if ( !in_meeting_id ) {
1534  in_meeting_id = 0; // Just to make sure...
1535  };
1536 
1537  var save_button = document.getElementById('bmlt_admin_meeting_editor_form_meeting_' + in_meeting_id + '_save_button');
1538 
1539  if ( save_button.className == 'bmlt_admin_ajax_button button' ) {
1540  var root_element = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
1541  var new_meeting_id = in_meeting_id;
1542  var copy_checkbox = document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_duplicate_checkbox');
1543  var throbber_span = document.getElementById('bmlt_admin_' + in_meeting_id + '_save_ajax_button_throbber_span');
1544  var save_a = document.getElementById('bmlt_admin_meeting_editor_form_meeting_' + in_meeting_id + '_save_button');
1545  var meeting_sent = false;
1546 
1547  var validation = this.validateMeetingDetails(in_meeting_id);
1548  if ( validation.errors.length > 0 || validation.show_warnings ) {
1549  if ( validation.errors.length > 0 ) {
1550  this.setValidationSaveMessage('#bmlt_admin_meeting_editor_form_meeting_' + in_meeting_id + '_save_button',
1551  'meeting_editor_screen_meeting_validation_failed',
1552  this.validationMessageTypes.ERROR,
1553  validation.errors.join(' '));
1554  }
1555  if (validation.warnings.length > 0) {
1556  this.setValidationSaveMessage('#bmlt_admin_meeting_editor_form_meeting_' + in_meeting_id + '_save_button',
1557  'meeting_editor_screen_meeting_validation_warnings',
1558  this.validationMessageTypes.WARN,
1559  validation.warnings.join(' '));
1560  }
1561  return;
1562  }
1563 
1564  if ( !copy_checkbox.checked && new_meeting_id && this.m_search_results && this.m_search_results.length ) {
1565  for (var c = 0; c < this.m_search_results.length; c++) {
1566  if ( new_meeting_id == this.m_search_results[c].id_bigint ) {
1567  save_a.className = 'item_hidden';
1568  throbber_span.className = 'bmlt_admin_ajax_button_throbber_span';
1569  if (g_auto_geocoding_enabled && root_element.original_address_line !== this.getAddressLine(in_meeting_id)) {
1570  var sendMeetingToServer = this.sendMeetingToServer;
1571  this.lookupLocation(in_meeting_id, function () {
1572  sendMeetingToServer(in_meeting_id, false); });
1573  } else {
1574  this.sendMeetingToServer(in_meeting_id, false);
1575  }
1576  meeting_sent = true;
1577  break;
1578  }
1579  }
1580  }
1581 
1582  if ( !meeting_sent ) {
1583  save_a.className = 'item_hidden';
1584  throbber_span.className = 'bmlt_admin_ajax_button_throbber_span';
1585  if (g_auto_geocoding_enabled && root_element.original_address_line !== this.getAddressLine(in_meeting_id)) {
1586  var sendMeetingToServer = this.sendMeetingToServer;
1587  this.lookupLocation(in_meeting_id, function () {
1588  sendMeetingToServer(in_meeting_id, true); });
1589  } else {
1590  this.sendMeetingToServer(in_meeting_id, true);
1591  }
1592  }
1593  }
1594  };
1595 
1596  /************************************************************************************//**
1597  * \brief
1598  ****************************************************************************************/
1599  this.cancelMeetingEdit = function (
1600  in_meeting_id,
1601  in_no_confirm
1602  ) {
1603  if ( !this.isMeetingDirty(in_meeting_id) || (this.isMeetingDirty(in_meeting_id) && (in_no_confirm || confirm(g_meeting_closure_confirm_text))) ) {
1604  var parent_id = 'bmlt_admin_meeting_editor_new_meeting_' + in_meeting_id + '_editor_display';
1605 
1606  var display_parent = document.getElementById(parent_id);
1607 
1608  var editor = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
1609 
1610  if ( editor && editor.main_map ) {
1611  editor.main_map = null;
1612  };
1613 
1614  var map_div = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_map_div');
1615 
1616  if ( map_div ) {
1617  map_div.innerHTML = '';
1618  };
1619 
1620  if ( display_parent ) {
1621  if ( display_parent.m_ajax_request_in_progress ) {
1622  display_parent.m_ajax_request_in_progress.abort();
1623  display_parent.m_ajax_request_in_progress = null;
1624  };
1625 
1626  display_parent.innerHTML = '';
1627  display_parent.className = 'item_hidden';
1628 
1629  if ( in_meeting_id == 0 ) {
1630  var new_meeting_button = document.getElementById('bmlt_admin_meeting_editor_form_meeting_0_button');
1631  new_meeting_button.className = 'bmlt_admin_ajax_button button';
1632  };
1633 
1634  var mtg_window = document.getElementById('bmlt_admin_meeting_search_results_single_meeting_' + in_meeting_id + '_div');
1635 
1636  if ( mtg_window ) {
1637  if ( mtg_window.meeting_editor_object && mtg_window.meeting_editor_object.parentNode && (mtg_window.meeting_editor_object.parentNode == mtg_window) ) {
1638  mtg_window.removeChild(mtg_window.meeting_editor_object);
1639  };
1640 
1641  mtg_window.meeting_editor_object = null;
1642  };
1643 
1644  this.m_editing_window_open = null;
1645  } else {
1646  this.toggleMeetingSingleEditor(in_meeting_id, true);
1647  };
1648  };
1649  };
1650 
1651  /************************************************************************************//**
1652  * \brief
1653  ****************************************************************************************/
1654  this.deleteMeeting = function ( in_meeting_id
1655  ) {
1656  var confirm_str = g_meeting_editor_screen_delete_button_confirm;
1657 
1658  if ( confirm(confirm_str) ) {
1659  var root_element = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
1660 
1661  if ( root_element.m_ajax_request_in_progress ) {
1662  root_element.m_ajax_request_in_progress.abort();
1663  root_element.m_ajax_request_in_progress = null;
1664  };
1665 
1666  var uri = g_ajax_callback_uri + '&delete_meeting=' + in_meeting_id;
1667 
1668  var throbber_span = document.getElementById('bmlt_admin_' + in_meeting_id + '_delete_ajax_button_throbber_span');
1669  var delete_a = document.getElementById('bmlt_admin_meeting_editor_form_meeting_' + in_meeting_id + '_delete_button');
1670  delete_a.className = 'item_hidden';
1671  throbber_span.className = 'bmlt_admin_ajax_button_throbber_span';
1672 
1673  var salt = new Date();
1674  uri += '&salt=' + salt.getTime();
1675 
1676  root_element.m_ajax_request_in_progress = BMLT_AjaxRequest(uri, function (in_req) {
1677  admin_handler_object.handleDeleteMeetingAJAXCallback(in_req); }, 'get');
1678  };
1679  };
1680 
1681  /************************************************************************************//**
1682  * \brief
1683  ****************************************************************************************/
1684  this.handleDeleteMeetingAJAXCallback = function (in_http_request
1685  ) {
1686  if ( in_http_request.responseText ) {
1687  if ( in_http_request.responseText == 'NOT AUTHORIZED' ) {
1688  alert(g_AJAX_Auth_Failure);
1689  } else {
1690  eval('var json_object = ' + in_http_request.responseText + ';');
1691  };
1692  };
1693 
1694  if ( json_object ) {
1695  if ( json_object.success ) {
1696  for (var c = 0; c < this.m_search_results.length; c++) {
1697  if ( this.m_search_results[c].id_bigint == json_object.report ) {
1698  this.m_search_results[c] = null;
1699  this.m_search_results.splice(c, 1);
1700  break;
1701  };
1702  };
1703 
1704  this.cancelMeetingEdit(json_object.report, true);
1705  this.createMeetingList();
1706  BMLT_Admin_StartFader('bmlt_admin_fader_meeting_editor_delete_success_div', this.m_success_fade_duration);
1707  } else {
1708  BMLT_Admin_StartFader('bmlt_admin_fader_meeting_editor_delete_fail_div', this.m_failure_fade_duration);
1709  };
1710  } else {
1711  BMLT_Admin_StartFader('bmlt_admin_fader_meeting_editor_delete_fail_div', this.m_failure_fade_duration);
1712  };
1713  };
1714 
1715  /************************************************************************************//**
1716  * \brief
1717  ****************************************************************************************/
1718  this.isMeetingDirty = function (in_meeting_id ///< The BMLT ID of the meeting that will be dirtified.
1719  ) {
1720  var editor = document.getElementById('bmlt_admin_single_meeting_editor_' + parseInt(in_meeting_id, 10) + '_div');
1721 
1722  if ( editor && editor.meeting_object ) {
1723  var editor_object = JSON.stringify(editor.meeting_object);
1724  var original_object = JSON.stringify(this.getMeetingObjectById(in_meeting_id, false));
1725  return (editor_object != original_object);
1726  };
1727 
1728  return false;
1729  };
1730 
1731  /************************************************************************************//**
1732  * \brief
1733  ****************************************************************************************/
1734  this.validateMeetingEditorButton = function (in_meeting_id
1735  ) {
1736  var save_button = document.getElementById('bmlt_admin_meeting_editor_form_meeting_' + in_meeting_id + '_save_button');
1737  var dup_checkbox = document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_duplicate_checkbox');
1738 
1739  if ( save_button ) {
1740  var enable = this.isMeetingDirty(in_meeting_id) || ((in_meeting_id > 0) && dup_checkbox && dup_checkbox.checked);
1741  if ( enable ) {
1742  save_button.className = 'bmlt_admin_ajax_button button';
1743  } else {
1744  save_button.className = 'bmlt_admin_ajax_button button_disabled';
1745  };
1746  };
1747  };
1748 
1749  /************************************************************************************//**
1750  * \brief This is called to initiate an AJAX process to change the account settings. *
1751  ****************************************************************************************/
1752  this.sendMeetingToServer = function (
1753  in_meeting_id,
1754  is_new_meeting
1755  ) {
1756  var new_editor = document.getElementById('bmlt_admin_single_meeting_editor_' + parseInt(in_meeting_id, 10) + '_div');
1757 
1758  if ( is_new_meeting ) {
1759  new_editor.meeting_object.id_bigint = 0;
1760  };
1761 
1762  var serialized_meeting_object = JSON.stringify(new_editor.meeting_object);
1763 
1764  if ( is_new_meeting ) {
1765  new_editor.meeting_object.id_bigint = in_meeting_id;
1766  };
1767 
1768  var uri = g_ajax_callback_uri + '&set_meeting_change=' + encodeURIComponent(serialized_meeting_object);
1769 
1770  if ( new_editor.m_ajax_request_in_progress ) {
1771  new_editor.m_ajax_request_in_progress.abort();
1772  new_editor.m_ajax_request_in_progress = null;
1773  };
1774 
1775  var salt = new Date();
1776  uri += '&salt=' + salt.getTime();
1777 
1778  new_editor.m_ajax_request_in_progress = BMLT_AjaxRequest(uri, function ( in_req, in_orig_meeting_id ) {
1779  admin_handler_object.handleMeetingChangeAJAXCallback(in_req,in_orig_meeting_id); }, 'post', in_meeting_id);
1780  };
1781 
1782  /************************************************************************************//**
1783  * \brief This is called to initiate an AJAX process to change the account settings. *
1784  ****************************************************************************************/
1785  this.handleMeetingChangeAJAXCallback = function (
1786  in_http_request,
1787  in_orig_meeting_id
1788  ) {
1789  if ( in_http_request.responseText ) {
1790  if ( in_http_request.responseText == 'NOT AUTHORIZED' ) {
1791  alert(g_AJAX_Auth_Failure);
1792  } else {
1793  eval('var json_object = ' + in_http_request.responseText + ';');
1794  };
1795  };
1796 
1797  if ( json_object ) {
1798  var meeting_changed = false;
1799 
1800  if ( json_object.error ) {
1801  alert(json_object.report);
1802  } else {
1803  if ( this.m_search_results ) {
1804  for (var c = 0; c < this.m_search_results.length; c++) {
1805  if ( this.m_search_results[c].id_bigint == json_object[0].id_bigint ) {
1806  this.m_search_results[c] = json_object[0];
1807  single_meeting_div_id = 'bmlt_admin_meeting_search_results_single_meeting_' + json_object[0].id_bigint +'_div';
1808 
1809  var single_meeting_div = document.getElementById(single_meeting_div_id);
1810 
1811  if ( single_meeting_div ) {
1812  single_meeting_div.innerHTML = '';
1813  this.createOneMeetingNode(single_meeting_div, this.m_search_results[c]);
1814  meeting_changed = true;
1815  };
1816 
1817  break;
1818  };
1819  };
1820  };
1821  };
1822 
1823  if ( !meeting_changed ) {
1824  if ( !this.m_search_results ) {
1825  this.m_search_results = new Array;
1826  };
1827 
1828  this.m_search_results[this.m_search_results.length] = json_object[0];
1829  BMLT_Admin_StartFader('bmlt_admin_fader_meeting_editor_add_success_div', this.m_success_fade_duration);
1830  } else {
1831  BMLT_Admin_StartFader('bmlt_admin_fader_meeting_editor_success_div', this.m_success_fade_duration);
1832  };
1833 
1834  this.cancelMeetingEdit(in_orig_meeting_id, true);
1835  this.createMeetingList();
1836  if (json_object && json_object[0] && json_object[0].id_bigint) {
1837  this.toggleMeetingSingleEditor(json_object[0].id_bigint);
1838  }
1839  } else {
1840  if ( in_orig_meeting_id ) {
1841  BMLT_Admin_StartFader('bmlt_admin_fader_meeting_editor_fail_div', this.m_failure_fade_duration);
1842  } else {
1843  BMLT_Admin_StartFader('bmlt_admin_fader_meeting_editor_add_fail_div', this.m_failure_fade_duration);
1844  };
1845  };
1846  };
1847 
1848  // #mark -
1849  // #mark Creating A New Meeting Editor
1850  // #mark -
1851 
1852  /************************************************************************************//**
1853  * \brief This creates a new meeting details editor screen. *
1854  * \returns A new DOM hierarchy with the initialized editor. *
1855  ****************************************************************************************/
1856  this.createNewMeetingEditorScreen = function (
1857  in_parent_element, ///< The parent element of the new instance.
1858  in_meeting_id ///< The BMLT ID of the meeting that will be edited. If null, then it is a new meeting.
1859  ) {
1860  // We first see if one already exists.
1861  var new_editor = document.getElementById('bmlt_admin_single_meeting_editor_' + parseInt(in_meeting_id, 10) + '_div');
1862 
1863  if ( !new_editor ) {
1864  var template_dom_list = document.getElementById('bmlt_admin_single_meeting_editor_template_div');
1865 
1866  var meeting_name_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_name_text_input';
1867  var meeting_cc_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_cc_text_input';
1868  var meeting_contact_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_contact_text_input';
1869 
1870  var meeting_location_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_location_text_input';
1871  var meeting_info_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_info_text_input';
1872  var meeting_street_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_street_text_input';
1873  var meeting_neighborhood_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_neighborhood_text_input';
1874  var meeting_borough_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_borough_text_input';
1875  var meeting_city_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_city_text_input';
1876  var meeting_county_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_county_text_input';
1877  var meeting_state_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_state_text_input';
1878  var meeting_zip_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_zip_text_input';
1879  var meeting_nation_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_nation_text_input';
1880  var meeting_longitude_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_longitude_text_input';
1881  var meeting_latitude_text_item_id = 'bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_latitude_text_input';
1882 
1883  if ( template_dom_list ) { // This makes an exact copy of the template (including IDs, so we'll need to change those).
1884  new_editor = template_dom_list.cloneNode(true);
1885  // This function replaces all of the spots that say "template" with the given ID. That gives us unique IDs.
1886  BMLT_Admin_changeTemplateIDToUseThisID(new_editor, in_meeting_id);
1887  new_editor.meeting_object = this.getMeetingObjectById(in_meeting_id, true);
1888  new_editor.map_disclosed = false;
1889 
1890  new_editor.className = 'bmlt_admin_single_meeting_editor_div';
1891 
1892  in_parent_element.appendChild(new_editor);
1893 
1894  this.handleTextInputLoad(document.getElementById(meeting_name_text_item_id));
1895  this.handleTextInputLoad(document.getElementById(meeting_cc_text_item_id), null, true);
1896  this.handleTextInputLoad(document.getElementById(meeting_contact_text_item_id));
1897  this.handleTextInputLoad(document.getElementById(meeting_location_text_item_id));
1898  this.handleTextInputLoad(document.getElementById(meeting_info_text_item_id));
1899  this.handleTextInputLoad(document.getElementById(meeting_street_text_item_id));
1900  this.handleTextInputLoad(document.getElementById(meeting_neighborhood_text_item_id));
1901  this.handleTextInputLoad(document.getElementById(meeting_borough_text_item_id));
1902  this.handleTextInputLoad(document.getElementById(meeting_city_text_item_id));
1903  this.handleTextInputLoad(document.getElementById(meeting_zip_text_item_id), null, true);
1904  this.handleTextInputLoad(document.getElementById(meeting_nation_text_item_id), null, true);
1905  this.handleTextInputLoad(document.getElementById(meeting_longitude_text_item_id), 0, true);
1906  this.handleTextInputLoad(document.getElementById(meeting_latitude_text_item_id), 0, true);
1907 
1908  var meeting_state_text_input = document.getElementById(meeting_state_text_item_id);
1909  if (meeting_state_text_input !== null) {
1910  this.handleTextInputLoad(meeting_state_text_input, null, g_auto_geocoding_enabled && g_county_auto_geocoding_enabled);
1911  }
1912 
1913  var meeting_county_text_input = document.getElementById(meeting_county_text_item_id);
1914  if (meeting_county_text_input !== null) {
1915  this.handleTextInputLoad(meeting_county_text_input, null, g_auto_geocoding_enabled && g_county_auto_geocoding_enabled);
1916  }
1917 
1918  var map_disclosure_a = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_map_disclosure_a');
1919  map_disclosure_a.href = 'javascript:admin_handler_object.toggleMeetingMapDisclosure(' + in_meeting_id + ')';
1920 
1921  var select_duplicate_checkbox = document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_duplicate_checkbox');
1922  select_duplicate_checkbox.onchange = function () {
1923  var save_button = document.getElementById('bmlt_admin_meeting_editor_form_meeting_' + in_meeting_id + '_save_button');
1924  if ( this.checked ) {
1925  save_button.innerHTML = g_Create_new_meeting_button_name;
1926  } else {
1927  save_button.innerHTML = g_Save_meeting_button_name;
1928  };
1929 
1930  admin_handler_object.validateMeetingEditorButton(in_meeting_id);
1931  };
1932  };
1933  };
1934 
1935  this.populateMeetingEditorForm(new_editor);
1936  new_editor.original_address_line = this.getAddressLine(in_meeting_id);
1937  return new_editor;
1938  };
1939 
1940  /************************************************************************************//**
1941  * \brief
1942  ****************************************************************************************/
1943  this.populateMeetingEditorForm = function ( in_meeting_editor ///< This is the meeting editor object that will be set up for this meeting.
1944  ) {
1945  var meeting_object = in_meeting_editor.meeting_object;
1946  var meeting_id = meeting_object.id_bigint;
1947 
1948  if ( !meeting_id ) { // We add a header for the new meeting form.
1949  var template_header = document.getElementById('bmlt_admin_meeting_editor_' + meeting_id + '_meeting_header');
1950  template_header.innerHTML = g_new_meeting_header_text;
1951  };
1952 
1953  document.getElementById('bmlt_admin_meeting_id_' + meeting_id +'_display').innerHTML = meeting_id;
1954 
1955  var meeting_published_checkbox = document.getElementById('bmlt_admin_meeting_' + meeting_id + '_published_checkbox');
1956 
1957  var meeting_name_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_name_text_input');
1958  var meeting_cc_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_cc_text_input');
1959  var meeting_location_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_location_text_input');
1960  var meeting_info_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_info_text_input');
1961  var meeting_street_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_street_text_input');
1962  var meeting_neighborhood_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_neighborhood_text_input');
1963  var meeting_borough_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_borough_text_input');
1964  var meeting_city_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_city_text_input');
1965  var meeting_county_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_county_text_input');
1966  var meeting_county_select_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_county_select_input');
1967  var meeting_state_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_state_text_input');
1968  var meeting_state_select_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_state_select_input');
1969  var meeting_zip_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_zip_text_input');
1970  var meeting_nation_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_nation_text_input');
1971  var meeting_longitude_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_longitude_text_input');
1972  var meeting_latitude_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_latitude_text_input');
1973  var meeting_contact_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_contact_text_input');
1974 
1975  meeting_name_text_item.value = htmlspecialchars_decode(meeting_object.meeting_name ? meeting_object.meeting_name : meeting_name_text_item.value);
1976  this.setTextItemClass(meeting_name_text_item);
1977  meeting_name_text_item.onkeyup = function () {
1978  admin_handler_object.setItemValue(this, meeting_id, 'meeting_name')};
1979  meeting_name_text_item.onfocus = function () {
1980  admin_handler_object.handleTextInputFocus(this)};
1981  meeting_name_text_item.onblur = function () {
1982  admin_handler_object.handleTextInputBlur(this)};
1983  meeting_name_text_item.onpaste = function () {
1984  var input = this;
1985  setTimeout(function () {
1986  admin_handler_object.setItemValue(input, meeting_id, 'meeting_name'); }, 0);
1987  };
1988  meeting_name_text_item.oncut = function () {
1989  var input = this;
1990  setTimeout(function () {
1991  admin_handler_object.setItemValue(input, meeting_id, 'meeting_name'); }, 0);
1992  };
1993 
1994 
1995  meeting_cc_text_item.value = htmlspecialchars_decode(meeting_object.worldid_mixed ? meeting_object.worldid_mixed : meeting_cc_text_item.value);
1996  this.setTextItemClass(meeting_cc_text_item);
1997  meeting_cc_text_item.onkeyup = function () {
1998  admin_handler_object.setItemValue(this, meeting_id, 'worldid_mixed')};
1999  meeting_cc_text_item.onfocus = function () {
2000  admin_handler_object.handleTextInputFocus(this)};
2001  meeting_cc_text_item.onblur = function () {
2002  admin_handler_object.handleTextInputBlur(this)};
2003  meeting_cc_text_item.onpaste = function () {
2004  var input = this;
2005  setTimeout(function () {
2006  admin_handler_object.setItemValue(input, meeting_id, 'worldid_mixed'); }, 0);
2007  };
2008  meeting_cc_text_item.oncut = function () {
2009  var input = this;
2010  setTimeout(function () {
2011  admin_handler_object.setItemValue(input, meeting_id, 'worldid_mixed'); }, 0);
2012  };
2013 
2014 
2015  meeting_location_text_item.value = htmlspecialchars_decode(meeting_object.location_text ? meeting_object.location_text : meeting_location_text_item.value);
2016  this.setTextItemClass(meeting_location_text_item);
2017  meeting_location_text_item.onkeyup = function () {
2018  admin_handler_object.setItemValue(this, meeting_id, 'location_text')};
2019  meeting_location_text_item.onfocus = function () {
2020  admin_handler_object.handleTextInputFocus(this)};
2021  meeting_location_text_item.onblur = function () {
2022  admin_handler_object.handleTextInputBlur(this)};
2023  meeting_location_text_item.onpaste = function () {
2024  var input = this;
2025  setTimeout(function () {
2026  admin_handler_object.setItemValue(input, meeting_id, 'location_text'); }, 0);
2027  };
2028  meeting_location_text_item.oncut = function () {
2029  var input = this;
2030  setTimeout(function () {
2031  admin_handler_object.setItemValue(input, meeting_id, 'location_text'); }, 0);
2032  };
2033 
2034 
2035  meeting_info_text_item.value = htmlspecialchars_decode(meeting_object.location_info ? meeting_object.location_info : meeting_info_text_item.value);
2036  this.setTextItemClass(meeting_info_text_item);
2037  meeting_info_text_item.onkeyup = function () {
2038  admin_handler_object.setItemValue(this, meeting_id, 'location_info')};
2039  meeting_info_text_item.onfocus = function () {
2040  admin_handler_object.handleTextInputFocus(this)};
2041  meeting_info_text_item.onblur = function () {
2042  admin_handler_object.handleTextInputBlur(this)};
2043  meeting_info_text_item.onpaste = function () {
2044  var input = this;
2045  setTimeout(function () {
2046  admin_handler_object.setItemValue(input, meeting_id, 'location_info'); }, 0);
2047  };
2048  meeting_info_text_item.oncut = function () {
2049  var input = this;
2050  setTimeout(function () {
2051  admin_handler_object.setItemValue(input, meeting_id, 'location_info'); }, 0);
2052  };
2053 
2054  meeting_street_text_item.value = htmlspecialchars_decode(meeting_object.location_street ? meeting_object.location_street : meeting_street_text_item.value);
2055  this.setTextItemClass(meeting_street_text_item);
2056  meeting_street_text_item.onkeyup = function () {
2057  admin_handler_object.setItemValue(this, meeting_id, 'location_street')};
2058  meeting_street_text_item.onfocus = function () {
2059  admin_handler_object.handleTextInputFocus(this)};
2060  meeting_street_text_item.onblur = function () {
2061  admin_handler_object.handleTextInputBlur(this)};
2062  meeting_street_text_item.onpaste = function () {
2063  var input = this;
2064  setTimeout(function () {
2065  admin_handler_object.setItemValue(input, meeting_id, 'location_street'); }, 0);
2066  };
2067  meeting_street_text_item.oncut = function () {
2068  var input = this;
2069  setTimeout(function () {
2070  admin_handler_object.setItemValue(input, meeting_id, 'location_street'); }, 0);
2071  };
2072 
2073 
2074  meeting_neighborhood_text_item.value = htmlspecialchars_decode(meeting_object.location_neighborhood ? meeting_object.location_neighborhood : meeting_neighborhood_text_item.value);
2075  this.setTextItemClass(meeting_neighborhood_text_item);
2076  meeting_neighborhood_text_item.onkeyup = function () {
2077  admin_handler_object.setItemValue(this, meeting_id, 'location_neighborhood')};
2078  meeting_neighborhood_text_item.onfocus = function () {
2079  admin_handler_object.handleTextInputFocus(this)};
2080  meeting_neighborhood_text_item.onblur = function () {
2081  admin_handler_object.handleTextInputBlur(this)};
2082  meeting_neighborhood_text_item.onpaste = function () {
2083  var input = this;
2084  setTimeout(function () {
2085  admin_handler_object.setItemValue(input, meeting_id, 'location_neighborhood'); }, 0);
2086  };
2087  meeting_neighborhood_text_item.oncut = function () {
2088  var input = this;
2089  setTimeout(function () {
2090  admin_handler_object.setItemValue(input, meeting_id, 'location_neighborhood'); }, 0);
2091  };
2092 
2093 
2094  meeting_borough_text_item.value = htmlspecialchars_decode(meeting_object.location_city_subsection ? meeting_object.location_city_subsection : meeting_borough_text_item.value);
2095  this.setTextItemClass(meeting_borough_text_item);
2096  meeting_borough_text_item.onkeyup = function () {
2097  admin_handler_object.setItemValue(this, meeting_id, 'location_city_subsection')};
2098  meeting_borough_text_item.onfocus = function () {
2099  admin_handler_object.handleTextInputFocus(this)};
2100  meeting_borough_text_item.onblur = function () {
2101  admin_handler_object.handleTextInputBlur(this)};
2102  meeting_borough_text_item.onpaste = function () {
2103  var input = this;
2104  setTimeout(function () {
2105  admin_handler_object.setItemValue(input, meeting_id, 'location_city_subsection'); }, 0);
2106  };
2107  meeting_borough_text_item.oncut = function () {
2108  var input = this;
2109  setTimeout(function () {
2110  admin_handler_object.setItemValue(input, meeting_id, 'location_city_subsection'); }, 0);
2111  };
2112 
2113 
2114  meeting_city_text_item.value = htmlspecialchars_decode(meeting_object.location_municipality ? meeting_object.location_municipality : meeting_city_text_item.value);
2115  this.setTextItemClass(meeting_city_text_item);
2116  meeting_city_text_item.onkeyup = function () {
2117  admin_handler_object.setItemValue(this, meeting_id, 'location_municipality')};
2118  meeting_city_text_item.onfocus = function () {
2119  admin_handler_object.handleTextInputFocus(this)};
2120  meeting_city_text_item.onblur = function () {
2121  admin_handler_object.handleTextInputBlur(this)};
2122  meeting_city_text_item.onpaste = function () {
2123  var input = this;
2124  setTimeout(function () {
2125  admin_handler_object.setItemValue(input, meeting_id, 'location_municipality'); }, 0);
2126  };
2127  meeting_city_text_item.oncut = function () {
2128  var input = this;
2129  setTimeout(function () {
2130  admin_handler_object.setItemValue(input, meeting_id, 'location_municipality'); }, 0);
2131  };
2132 
2133 
2134  if (meeting_county_text_item !== null) {
2135  meeting_county_text_item.value = htmlspecialchars_decode(meeting_object.location_sub_province ? meeting_object.location_sub_province : meeting_county_text_item.value);
2136  this.setTextItemClass(meeting_county_text_item);
2137  meeting_county_text_item.onkeyup = function () {
2138  admin_handler_object.setItemValue(this, meeting_id, 'location_sub_province')};
2139  meeting_county_text_item.onfocus = function () {
2140  admin_handler_object.handleTextInputFocus(this)};
2141  meeting_county_text_item.onblur = function () {
2142  admin_handler_object.handleTextInputBlur(this)};
2143  meeting_county_text_item.onpaste = function () {
2144  var input = this;
2145  setTimeout(function () {
2146  admin_handler_object.setItemValue(input, meeting_id, 'location_sub_province');
2147  }, 0);
2148  };
2149  meeting_county_text_item.oncut = function () {
2150  var input = this;
2151  setTimeout(function () {
2152  admin_handler_object.setItemValue(input, meeting_id, 'location_sub_province');
2153  }, 0);
2154  };
2155  } else {
2156  if ( meeting_object.location_sub_province ) {
2157  for (var i = 0; i < meeting_county_select_item.options.length; i++) {
2158  var option = meeting_county_select_item.options[i];
2159  if ( option.value === meeting_object.location_sub_province ) {
2160  meeting_county_select_item.selectedIndex = i;
2161  break;
2162  }
2163  }
2164  }
2165  meeting_county_select_item.onchange = function () {
2166  admin_handler_object.reactToMeetingCountySelect(meeting_id);
2167  }
2168  }
2169 
2170 
2171  if (meeting_state_text_item !== null) {
2172  meeting_state_text_item.value = htmlspecialchars_decode(meeting_object.location_province ? meeting_object.location_province : meeting_state_text_item.value);
2173  this.setTextItemClass(meeting_state_text_item);
2174  meeting_state_text_item.onkeyup = function () {
2175  admin_handler_object.setItemValue(this, meeting_id, 'location_province')};
2176  meeting_state_text_item.onfocus = function () {
2177  admin_handler_object.handleTextInputFocus(this)};
2178  meeting_state_text_item.onblur = function () {
2179  admin_handler_object.handleTextInputBlur(this)};
2180  meeting_state_text_item.onpaste = function () {
2181  var input = this;
2182  setTimeout(function () {
2183  admin_handler_object.setItemValue(input, meeting_id, 'location_province');
2184  }, 0);
2185  };
2186  meeting_state_text_item.oncut = function () {
2187  var input = this;
2188  setTimeout(function () {
2189  admin_handler_object.setItemValue(input, meeting_id, 'location_province');
2190  }, 0);
2191  };
2192  } else {
2193  if ( meeting_object.location_province ) {
2194  for (var i = 0; i < meeting_state_select_item.options.length; i++) {
2195  var option = meeting_state_select_item.options[i];
2196  if ( option.value === meeting_object.location_province ) {
2197  meeting_state_select_item.selectedIndex = i;
2198  break;
2199  }
2200  }
2201  }
2202  meeting_state_select_item.onchange = function () {
2203  admin_handler_object.reactToMeetingStateSelect(meeting_id);}
2204  }
2205 
2206 
2207  meeting_zip_text_item.value = htmlspecialchars_decode(meeting_object.location_postal_code_1 ? meeting_object.location_postal_code_1 : meeting_zip_text_item.value);
2208  this.setTextItemClass(meeting_zip_text_item);
2209  meeting_zip_text_item.onkeyup = function () {
2210  admin_handler_object.setItemValue(this, meeting_id, 'location_postal_code_1')};
2211  meeting_zip_text_item.onfocus = function () {
2212  admin_handler_object.handleTextInputFocus(this)};
2213  meeting_zip_text_item.onblur = function () {
2214  admin_handler_object.handleTextInputBlur(this)};
2215  meeting_zip_text_item.onpaste = function () {
2216  var input = this;
2217  setTimeout(function () {
2218  admin_handler_object.setItemValue(input, meeting_id, 'location_postal_code_1'); }, 0);
2219  };
2220  meeting_zip_text_item.oncut = function () {
2221  var input = this;
2222  setTimeout(function () {
2223  admin_handler_object.setItemValue(input, meeting_id, 'location_postal_code_1'); }, 0);
2224  };
2225 
2226 
2227  meeting_nation_text_item.value = htmlspecialchars_decode(meeting_object.location_nation ? meeting_object.location_nation : meeting_nation_text_item.value);
2228  this.setTextItemClass(meeting_nation_text_item);
2229  meeting_nation_text_item.onkeyup = function () {
2230  admin_handler_object.setItemValue(this, meeting_id, 'location_nation')};
2231  meeting_nation_text_item.onfocus = function () {
2232  admin_handler_object.handleTextInputFocus(this)};
2233  meeting_nation_text_item.onblur = function () {
2234  admin_handler_object.handleTextInputBlur(this)};
2235  meeting_nation_text_item.onpaste = function () {
2236  var input = this;
2237  setTimeout(function () {
2238  admin_handler_object.setItemValue(input, meeting_id, 'location_nation'); }, 0);
2239  };
2240  meeting_nation_text_item.oncut = function () {
2241  var input = this;
2242  setTimeout(function () {
2243  admin_handler_object.setItemValue(input, meeting_id, 'location_nation'); }, 0);
2244  };
2245 
2246 
2247  meeting_longitude_text_item.value = htmlspecialchars_decode(meeting_object.longitude ? meeting_object.longitude : meeting_longitude_text_item.value);
2248  this.setTextItemClass(meeting_longitude_text_item);
2249  meeting_longitude_text_item.onkeyup = function () {
2250  admin_handler_object.setItemValue(this, meeting_id, 'longitude')};
2251  meeting_longitude_text_item.onfocus = function () {
2252  admin_handler_object.handleTextInputFocus(this)};
2253  meeting_longitude_text_item.onblur = function () {
2254  admin_handler_object.handleTextInputBlur(this)};
2255  meeting_longitude_text_item.onpaste = function () {
2256  var input = this;
2257  setTimeout(function () {
2258  admin_handler_object.setItemValue(input, meeting_id, 'longitude'); }, 0);
2259  };
2260  meeting_longitude_text_item.oncut = function () {
2261  var input = this;
2262  setTimeout(function () {
2263  admin_handler_object.setItemValue(input, meeting_id, 'longitude'); }, 0);
2264  };
2265 
2266 
2267  meeting_latitude_text_item.value = htmlspecialchars_decode(meeting_object.latitude ? meeting_object.latitude : meeting_latitude_text_item.value);
2268  this.setTextItemClass(meeting_latitude_text_item);
2269  meeting_latitude_text_item.onkeyup = function () {
2270  admin_handler_object.setItemValue(this, meeting_id, 'latitude')};
2271  meeting_latitude_text_item.onfocus = function () {
2272  admin_handler_object.handleTextInputFocus(this)};
2273  meeting_latitude_text_item.onblur = function () {
2274  admin_handler_object.handleTextInputBlur(this)};
2275  meeting_latitude_text_item.onpaste = function () {
2276  var input = this;
2277  setTimeout(function () {
2278  admin_handler_object.setItemValue(input, meeting_id, 'latitude'); }, 0);
2279  };
2280  meeting_latitude_text_item.oncut = function () {
2281  var input = this;
2282  setTimeout(function () {
2283  admin_handler_object.setItemValue(input, meeting_id, 'latitude'); }, 0);
2284  };
2285 
2286 
2287  meeting_contact_text_item.value = htmlspecialchars_decode(meeting_object.email_contact ? meeting_object.email_contact : meeting_contact_text_item.value);
2288  this.setTextItemClass(meeting_contact_text_item);
2289  meeting_contact_text_item.onkeyup = function () {
2290  admin_handler_object.setItemValue(this, meeting_id, 'email_contact')};
2291  meeting_contact_text_item.onfocus = function () {
2292  admin_handler_object.handleTextInputFocus(this)};
2293  meeting_contact_text_item.onblur = function () {
2294  admin_handler_object.handleTextInputBlur(this)};
2295  meeting_contact_text_item.onpaste = function () {
2296  var input = this;
2297  setTimeout(function () {
2298  admin_handler_object.setItemValue(input, meeting_id, 'email_contact'); }, 0);
2299  };
2300  meeting_contact_text_item.oncut = function () {
2301  var input = this;
2302  setTimeout(function () {
2303  admin_handler_object.setItemValue(input, meeting_id, 'email_contact'); }, 0);
2304  };
2305 
2306 
2307  meeting_published_checkbox.checked = (meeting_object ? true : false);
2308 
2309  this.setFormatCheckboxes(meeting_object);
2310  this.setWeekday(meeting_object);
2311  this.setMeetingStartTime(meeting_object);
2312  this.setMeetingDuration(meeting_object);
2313  if (g_meeting_time_zones_enabled) {
2314  this.setMeetingTimeZone(meeting_object);
2315  }
2316  this.setServiceBody(meeting_object);
2317  this.setUpOtherTab(meeting_object);
2318 
2319  this.setPublished(meeting_object);
2320  this.handleNewAddressInfo(meeting_id);
2321  this.setFormatCheckboxHandlers(meeting_object);
2322  };
2323 
2324  /************************************************************************************//**
2325  * \brief
2326  ****************************************************************************************/
2327  this.setMeetingStartTime = function (in_meeting_object
2328  ) {
2329  var meeting_id = in_meeting_object.id_bigint;
2330 
2331  var time_hour_select = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_start_hour_select');
2332  var time_minute_select = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_start_minute_select');
2333  var time_am_radio = document.getElementById('bmlt_admin_' + meeting_id + '_time_am_radio');
2334  var time_pm_radio = document.getElementById('bmlt_admin_' + meeting_id + '_time_pm_radio');
2335 
2336  var start_time = in_meeting_object.start_time.toString().split(':');
2337 
2338  if ( start_time && (start_time.length > 1) ) {
2339  var hours = parseInt(start_time[0], 10);
2340  var minutes = parseInt(start_time[1], 10);
2341  var midnight = false;
2342  var noon = false;
2343  var pm = false;
2344 
2345  if ( (hours == 23) && (minutes > 55) ) {
2346  midnight = true;
2347  } else {
2348  if ( (hours == 12) && (minutes == 0) ) {
2349  noon = true;
2350  } else {
2351  if ( hours > 23 ) {
2352  hours = 23;
2353  };
2354 
2355  if ( hours < 0 ) {
2356  hours = 0;
2357  };
2358 
2359  if ( minutes > 59 ) {
2360  minutes = 59;
2361  };
2362 
2363  if ( minutes < 0 ) {
2364  minutes = 0;
2365  };
2366 
2367  if ( minutes % g_default_minute_interval ) {
2368  minutes += g_default_minute_interval;
2369 
2370  if ( minutes >= 60 ) {
2371  hours++;
2372  minutes -= 60;
2373  };
2374  };
2375  };
2376  };
2377 
2378  if ( hours > 12 ) {
2379  hours -= 12;
2380  pm = true;
2381  } else if ( (hours == 0) && (minutes > 0) ) {
2382  pm = false;
2383  hours = 12;
2384  } else if ( (hours == 12) && (minutes > 0) ) {
2385  pm = true;
2386  };
2387  };
2388 
2389  if ( midnight ) {
2390  BMLT_Admin_setSelectByValue(time_minute_select, 0);
2391  BMLT_Admin_setSelectByValue(time_hour_select, 0);
2392  } else if ( noon ) {
2393  BMLT_Admin_setSelectByValue(time_hour_select, 13);
2394  BMLT_Admin_setSelectByValue(time_minute_select, 0);
2395  } else {
2396  BMLT_Admin_setSelectByValue(time_hour_select, hours);
2397  BMLT_Admin_setSelectByValue(time_minute_select, minutes);
2398  };
2399 
2400  if ( pm ) {
2401  time_am_radio.checked = false;
2402  time_pm_radio.checked = true;
2403  } else {
2404  time_pm_radio.checked = false;
2405  time_am_radio.checked = true;
2406  };
2407 
2408  this.reactToTimeSelect(meeting_id);
2409 
2410  time_hour_select.onchange = function () {
2411  admin_handler_object.reactToTimeSelect(meeting_id); };
2412  time_minute_select.onchange = function () {
2413  admin_handler_object.reactToTimeSelect(meeting_id); };
2414  time_am_radio.onchange = function () {
2415  admin_handler_object.reactToTimeSelect(meeting_id); };
2416  time_pm_radio.onchange = function () {
2417  admin_handler_object.reactToTimeSelect(meeting_id); };
2418  };
2419 
2420  /************************************************************************************//**
2421  * \brief
2422  ****************************************************************************************/
2423  this.setMeetingDuration = function ( in_meeting_object
2424  ) {
2425  var meeting_id = in_meeting_object.id_bigint;
2426 
2427  var time_hour_select = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_duration_hour_select');
2428  var time_minute_select = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_duration_minute_select');
2429 
2430  var duration_time = in_meeting_object.duration_time.split(':');
2431 
2432  if ( duration_time && (duration_time.length > 1) ) {
2433  var hours = parseInt(duration_time[0], 10);
2434  var minutes = parseInt(duration_time[1], 10);
2435  var oe = false;
2436 
2437  if ( hours == 24 ) {
2438  oe = true;
2439  } else {
2440  if ( minutes % g_default_minute_interval ) {
2441  minutes += g_default_minute_interval;
2442 
2443  if ( minutes >= 60 ) {
2444  hours++;
2445  minutes -= 60;
2446  };
2447  };
2448 
2449  if ( hours > 23 ) {
2450  hours = 23;
2451  };
2452 
2453  if ( hours < 0 ) {
2454  hours = 0;
2455  };
2456  };
2457  };
2458 
2459  if ( oe ) {
2460  BMLT_Admin_setSelectByValue(time_hour_select, 24);
2461  BMLT_Admin_setSelectByValue(time_minute_select, 0);
2462  } else {
2463  BMLT_Admin_setSelectByValue(time_hour_select, hours);
2464  BMLT_Admin_setSelectByValue(time_minute_select, minutes);
2465  };
2466 
2467  this.reactToDurationSelect(meeting_id);
2468 
2469  time_hour_select.onchange = function () {
2470  admin_handler_object.reactToDurationSelect(meeting_id); };
2471  };
2472 
2473  /************************************************************************************//**
2474  * \brief
2475  ****************************************************************************************/
2476  this.setMeetingTimeZone = function (in_meeting_object) {
2477  var meeting_id = in_meeting_object.id_bigint;
2478 
2479  var time_zone_select = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_time_zone_select');
2480 
2481  BMLT_Admin_setSelectByStringValue(time_zone_select, in_meeting_object.time_zone);
2482 
2483  this.reactToTimeZoneSelect(meeting_id);
2484 
2485  time_zone_select.onchange = function () { admin_handler_object.reactToTimeZoneSelect(meeting_id); }
2486  };
2487 
2488  /************************************************************************************//**
2489  * \brief
2490  ****************************************************************************************/
2491  this.setServiceBody = function (in_meeting_object
2492  ) {
2493  var meeting_id = in_meeting_object.id_bigint;
2494 
2495  var service_body_select = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_sb_select');
2496 
2497  if ( service_body_select ) {
2498  BMLT_Admin_setSelectByValue(service_body_select, in_meeting_object.service_body_bigint);
2499 
2500  this.reactToSBSelect(meeting_id);
2501 
2502  service_body_select.onchange = function () {
2503  admin_handler_object.reactToSBSelect(meeting_id); };
2504  };
2505  };
2506 
2507  /************************************************************************************//**
2508  * \brief
2509  ****************************************************************************************/
2510  this.setWeekday = function (in_meeting_object
2511  ) {
2512  var meeting_id = in_meeting_object.id_bigint;
2513 
2514  var weekday_select = document.getElementById('bmlt_admin_single_meeting_editor_' + meeting_id + '_meeting_weekday_select');
2515 
2516  BMLT_Admin_setSelectByValue(weekday_select, in_meeting_object.weekday_tinyint);
2517 
2518  this.reactToWeekdaySelect(meeting_id);
2519 
2520  weekday_select.onchange = function () {
2521  admin_handler_object.reactToWeekdaySelect(meeting_id); };
2522  };
2523 
2524  /************************************************************************************//**
2525  * \brief
2526  ****************************************************************************************/
2527  this.setPublished = function ( in_meeting_object
2528  ) {
2529  var meeting_id = in_meeting_object.id_bigint;
2530 
2531  var published_checkbox = document.getElementById('bmlt_admin_meeting_' + meeting_id + '_published_checkbox');
2532 
2533  published_checkbox.checked = in_meeting_object.published == '1';
2534 
2535  this.reactToPublishedCheck(meeting_id);
2536 
2537  published_checkbox.onchange = function () {
2538  admin_handler_object.reactToPublishedCheck(meeting_id); };
2539  published_checkbox.onclick = function () {
2540  admin_handler_object.reactToPublishedCheck(meeting_id); };
2541  };
2542 
2543  /************************************************************************************//**
2544  * \brief
2545  ****************************************************************************************/
2546  this.setFormatCheckboxHandlers = function ( in_meeting_object
2547  ) {
2548  var meeting_id = in_meeting_object.id_bigint;
2549  var main_formats = g_format_object_array;
2550 
2551  for (var c = 0; c < main_formats.length; c++) {
2552  var format_checkbox = document.getElementById('bmlt_admin_meeting_' + in_meeting_object.id_bigint + '_format_' + main_formats[c].id + '_checkbox');
2553 
2554  if ( format_checkbox ) {
2555  format_checkbox.onchange = function () {
2556  admin_handler_object.reactToFormatCheckbox(format_checkbox, meeting_id); };
2557  format_checkbox.onclick = function () {
2558  admin_handler_object.reactToFormatCheckbox(format_checkbox, meeting_id); };
2559  };
2560  };
2561  };
2562 
2563  // #mark -
2564  // #mark ########## Meeting Editor Internal Tabs ##########
2565  // #mark -
2566 
2567  /************************************************************************************//**
2568  * \brief Selects the meeting editor tab. *
2569  ****************************************************************************************/
2570  this.selectAnEditorTab = function (
2571  in_tab_index,
2572  in_meeting_id
2573  ) {
2574  var tabs = new Array(
2575  document.getElementById('bmlt_admin_meeting_editor_' + in_meeting_id + '_tab_item_basic_a'),
2576  document.getElementById('bmlt_admin_meeting_editor_' + in_meeting_id + '_tab_item_location_a'),
2577  document.getElementById('bmlt_admin_meeting_editor_' + in_meeting_id + '_tab_item_format_a'),
2578  document.getElementById('bmlt_admin_meeting_editor_' + in_meeting_id + '_tab_item_other_a'),
2579  document.getElementById('bmlt_admin_meeting_editor_' + in_meeting_id + '_tab_item_history_a')
2580  );
2581 
2582  var sheets = new Array(
2583  document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_basic_sheet_div'),
2584  document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_location_sheet_div'),
2585  document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_format_sheet_div'),
2586  document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_other_sheet_div'),
2587  document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_history_sheet_div')
2588  );
2589 
2590  for (var c = 0; c < tabs.length; c++) {
2591  var tab_class = '';
2592  var sheet_class = '';
2593 
2594  if ( c == in_tab_index ) {
2595  tab_class = 'bmlt_admin_meeting_editor_tab_item_a_selected';
2596  sheet_class = 'bmlt_admin_meeting_option_sheet_div';
2597  if ( c == 4 ) {
2598  this.openHistoryTab(in_meeting_id);
2599  };
2600  } else {
2601  tab_class = 'bmlt_admin_meeting_editor_tab_item_a_unselected';
2602  if ( c == 4 ) {
2603  tab_class += ' hide_in_new_meeting';
2604  };
2605  sheet_class = 'bmlt_admin_meeting_option_sheet_div item_hidden';
2606  };
2607 
2608  tabs[c].className = tab_class;
2609  sheets[c].className = sheet_class;
2610  };
2611  };
2612 
2613  // #mark -
2614  // #mark Basic Tab
2615  // #mark -
2616 
2617  /************************************************************************************//**
2618  * \brief
2619  ****************************************************************************************/
2620  this.respondToBasicTabSelection = function (in_meeting_id ///< The BMLT ID of the meeting that is being edited.
2621  ) {
2622  this.selectAnEditorTab(0);
2623  };
2624 
2625  /************************************************************************************//**
2626  * \brief
2627  ****************************************************************************************/
2628  this.reactToTimeSelect = function ( in_meeting_id ///< The meeting ID
2629  ) {
2630  var time_hour_select = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_start_hour_select');
2631  var time_items = document.getElementById('bmlt_admin_' + in_meeting_id + '_time_span');
2632  var time_pm_radio = document.getElementById('bmlt_admin_' + in_meeting_id + '_time_pm_radio');
2633  var time_minute_select = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_start_minute_select');
2634 
2635  time_items.className = 'bmlt_admin_time_span' + (( (time_hour_select.options[time_hour_select.selectedIndex].value == 0) || (time_hour_select.options[time_hour_select.selectedIndex].value == 13) ) ? ' item_hidden' : '');
2636 
2637  var editor_object = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
2638  var the_meeting_object = editor_object.meeting_object;
2639 
2640  var timeval = '';
2641 
2642  if ( time_hour_select.options[time_hour_select.selectedIndex].value == 0 ) {
2643  timeval = '23:59:00';
2644  } else if ( time_hour_select.options[time_hour_select.selectedIndex].value == 13 ) {
2645  timeval = '12:00:00';
2646  } else {
2647  var hour = parseInt(time_hour_select.options[time_hour_select.selectedIndex].value, 10);
2648  var minute = parseInt(time_minute_select.options[time_minute_select.selectedIndex].value, 10)
2649 
2650  if ( time_pm_radio.checked && (hour != 12) ) {
2651  hour += 12;
2652  } else if ( !time_pm_radio.checked && (hour == 12) ) {
2653  hour = 0;
2654  }
2655 
2656  timeval = sprintf('%02d:%02d:00', hour, minute);
2657  };
2658 
2659  the_meeting_object.start_time = timeval;
2660  this.validateMeetingEditorButton(in_meeting_id);
2661  };
2662 
2663  /************************************************************************************//**
2664  * \brief
2665  ****************************************************************************************/
2666  this.reactToDurationSelect = function ( in_meeting_id ///< The meeting ID
2667  ) {
2668  var time_hour_select = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_duration_hour_select');
2669  var time_items = document.getElementById('bmlt_admin_' + in_meeting_id + '_duration_span');
2670 
2671  time_items.className = 'bmlt_admin_time_span' + ((time_hour_select.value == 24) ? ' item_hidden' : '');
2672 
2673  var time_minute_select = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_duration_minute_select');
2674  var editor_object = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
2675  var the_meeting_object = editor_object.meeting_object;
2676  var timeval = '';
2677 
2678  if ( time_hour_select.options[time_hour_select.selectedIndex].value == 24 ) {
2679  timeval = '24:00:00';
2680  } else {
2681  timeval = sprintf('%02d:%02d:00', parseInt(time_hour_select.options[time_hour_select.selectedIndex].value, 10), parseInt(time_minute_select.options[time_minute_select.selectedIndex].value, 10));
2682  };
2683 
2684  the_meeting_object.duration_time = timeval;
2685  this.validateMeetingEditorButton(in_meeting_id);
2686  };
2687 
2688  this.reactToMeetingStateSelect = function (in_meeting_id) {
2689  var meeting_state_select_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_state_select_input');
2690  var editor_object = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
2691  var the_meeting_object = editor_object.meeting_object;
2692  the_meeting_object.location_province = meeting_state_select_item.options[meeting_state_select_item.selectedIndex].value;
2693  this.handleNewAddressInfo(in_meeting_id);
2694  this.validateMeetingEditorButton(in_meeting_id);
2695  };
2696 
2697  this.reactToMeetingCountySelect = function (in_meeting_id) {
2698  var meeting_county_select_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_county_select_input');
2699  var editor_object = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
2700  var the_meeting_object = editor_object.meeting_object;
2701  the_meeting_object.location_sub_province = meeting_county_select_item.options[meeting_county_select_item.selectedIndex].value;
2702  this.handleNewAddressInfo(in_meeting_id);
2703  this.validateMeetingEditorButton(in_meeting_id);
2704  };
2705 
2706  /************************************************************************************//**
2707  * \brief
2708  ****************************************************************************************/
2709  this.reactToSBSelect = function (in_meeting_id ///< The meeting ID
2710  ) {
2711  var service_body_select = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_sb_select');
2712 
2713  var editor_object = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
2714  var the_meeting_object = editor_object.meeting_object;
2715 
2716  the_meeting_object.service_body_bigint = service_body_select.value.toString();
2717  this.validateMeetingEditorButton(in_meeting_id);
2718  };
2719 
2720  /************************************************************************************//**
2721  * \brief
2722  ****************************************************************************************/
2723  this.reactToPublishedCheck = function ( in_meeting_id ///< The meeting ID
2724  ) {
2725  var published_checkbox = document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_published_checkbox');
2726 
2727  var editor_object = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
2728  var the_meeting_object = editor_object.meeting_object;
2729  the_meeting_object.published = published_checkbox.checked ? '1' : '0';
2730 
2731  var unpublishedNoteDiv = document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_unpublished_note_div');
2732  if (published_checkbox.checked) {
2733  unpublishedNoteDiv.className += ' item_hidden';
2734  } else {
2735  unpublishedNoteDiv.className = unpublishedNoteDiv.className.replace(" item_hidden", "");
2736  }
2737  this.validateMeetingEditorButton(in_meeting_id);
2738  };
2739 
2740  /************************************************************************************//**
2741  * \brief
2742  ****************************************************************************************/
2743  this.reactToWeekdaySelect = function ( in_meeting_id ///< The meeting ID
2744  ) {
2745  var weekday_select = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_weekday_select');
2746 
2747  var editor_object = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
2748  var the_meeting_object = editor_object.meeting_object;
2749 
2750  the_meeting_object.weekday_tinyint = weekday_select.value.toString();
2751  this.validateMeetingEditorButton(in_meeting_id);
2752  };
2753 
2754  /************************************************************************************//**
2755  * \brief
2756  ****************************************************************************************/
2757  this.reactToTimeZoneSelect = function ( in_meeting_id ///< The meeting ID
2758  ) {
2759  var time_zone_select = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_time_zone_select');
2760 
2761  var editor_object = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
2762  var the_meeting_object = editor_object.meeting_object;
2763 
2764  the_meeting_object.time_zone = time_zone_select.value.toString();
2765  this.validateMeetingEditorButton(in_meeting_id);
2766  };
2767 
2768  // #mark -
2769  // #mark Location Tab
2770  // #mark -
2771 
2772  /************************************************************************************//**
2773  * \brief
2774  ****************************************************************************************/
2775  this.handleNewAddressInfo = function ( in_meeting_id ///< The BMLT ID of the meeting being edited.
2776  ) {
2777  var meeting_street_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_street_text_input');
2778  var meeting_borough_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_borough_text_input');
2779  var meeting_city_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_city_text_input');
2780  var meeting_state_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_state_text_input');
2781  var meeting_state_select_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_state_select_input');
2782  var meeting_zip_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_zip_text_input');
2783  var meeting_nation_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_nation_text_input');
2784 
2785  if ( meeting_street_text_item && meeting_borough_text_item && meeting_city_text_item && ( meeting_state_text_item || meeting_state_select_item ) && meeting_zip_text_item && meeting_nation_text_item ) {
2786  var street_text = meeting_street_text_item.value;
2787  var borough_text = meeting_borough_text_item.value;
2788  var city_text = meeting_city_text_item.value;
2789  var state_text = meeting_state_text_item ? meeting_state_text_item.value : meeting_state_select_item.options[meeting_state_select_item.selectedIndex].value;
2790  var zip_text = meeting_zip_text_item.value;
2791  var nation_text = meeting_nation_text_item.value;
2792  };
2793  };
2794 
2795 
2796  /************************************************************************************//**
2797  * \brief
2798  ****************************************************************************************/
2799  this.getAddressLine = function (in_meeting_id) {
2800  var meeting_street_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_street_text_input');
2801  var meeting_borough_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_borough_text_input');
2802  var meeting_city_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_city_text_input');
2803  var meeting_state_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_state_text_input');
2804  var meeting_state_select_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_state_select_input');
2805  var meeting_zip_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_zip_text_input');
2806  var meeting_nation_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_nation_text_input');
2807 
2808  var street_text = (meeting_street_text_item.value != meeting_street_text_item.defaultValue) ? meeting_street_text_item.value : '';
2809  var borough_text = (meeting_borough_text_item.value != meeting_borough_text_item.defaultValue) ? meeting_borough_text_item.value : '';
2810  var city_text = (meeting_city_text_item.value != meeting_city_text_item.defaultValue) ? meeting_city_text_item.value : '';
2811  var state_text = meeting_state_text_item ? ((meeting_state_text_item.value != meeting_state_text_item.defaultValue) ? meeting_state_text_item.value : '') : meeting_state_select_item.options[meeting_state_select_item.selectedIndex].value;
2812  var zip_text = (meeting_zip_text_item.value != meeting_zip_text_item.defaultValue) ? meeting_zip_text_item.value : '';
2813  var nation_text = (meeting_nation_text_item.value != meeting_nation_text_item.defaultValue) ? meeting_nation_text_item.value : '';
2814 
2815  if ( !nation_text ) {
2816  nation_text = g_region_bias;
2817  };
2818 
2819  // What we do here, is try to create a readable address line to be sent off for geocoding. We just try to clean it up as much as possible.
2820  var address_line = sprintf('%s,%s,%s,%s,%s,%s', street_text, borough_text, city_text, state_text, zip_text, nation_text);
2821 
2822  address_line = address_line.replace(/,+/g, ', ');
2823  address_line = address_line.replace(/^, /g, '');
2824  address_line = address_line.replace(/, $/g, '');
2825  return address_line;
2826  };
2827 
2828  this.lookupLocation = function (in_meeting_id, successCallback) {
2829  if (!g_google_api_key_is_good) {
2830  alert("The meeting couldn't be saved because there is a problem with the Google Maps API Key.");
2831  return;
2832  }
2833 
2834  var address_line = this.getAddressLine(in_meeting_id);
2835  var editor_object = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
2836  var the_meeting_object = editor_object.meeting_object;
2837 
2838  if ( address_line != ', ' ) {
2839  if ( !the_meeting_object.m_geocoder ) {
2840  the_meeting_object.m_geocoder = new google.maps.Geocoder;
2841  }
2842 
2843  the_meeting_object.m_geocoder.geocode(
2844  { 'address' : address_line },
2845  function ( in_geocode_response, status ) {
2846  if (status !== 'OK') {
2847  alert(g_meeting_lookup_failed);
2848  return;
2849  }
2850  admin_handler_object.sGeoCallback(in_geocode_response, in_meeting_id);
2851  if (successCallback) {
2852  successCallback();
2853  }
2854  }
2855  );
2856  } else {
2857  alert(g_meeting_lookup_failed_not_enough_address_info);
2858  }
2859  };
2860  /****************************************************************************************//**
2861  * \brief This catches the AJAX response, and fills in the response form. *
2862  ********************************************************************************************/
2863 
2864  this.sGeoCallback = function (
2865  in_geocode_response, ///< The JSON object.
2866  in_meeting_id ///< The ID of the meeting.
2867  ) {
2868  var meeting_editor = document.getElementById('bmlt_admin_single_meeting_editor_' + parseInt(in_meeting_id, 10) + '_div');
2869 
2870  if ( meeting_editor ) {
2871  var the_meeting_object = meeting_editor.meeting_object;
2872 
2873  if ( in_geocode_response && in_geocode_response.length && (google.maps.OK == in_geocode_response[0].status) ) {
2874  var lng = in_geocode_response[0].geometry.location.lng();
2875  var lat = in_geocode_response[0].geometry.location.lat();
2876 
2877  delete the_meeting_object.m_geocoder;
2878 
2879  var map_center = new google.maps.LatLng(lat, lng);
2880  this.setMeetingLongLat(map_center, in_meeting_id);
2881  if (meeting_editor.main_map) {
2882  meeting_editor.main_map.panTo(map_center);
2883  this.displayMainMarkerInMap(in_meeting_id);
2884  google.maps.event.removeListener(the_meeting_object.m_geocoder);
2885  }
2886 
2887  if (g_auto_geocoding_enabled && g_county_auto_geocoding_enabled) {
2888  var meeting_county_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_county_text_input');
2889  if (meeting_county_text_item) {
2890  for (var i = 0; i < in_geocode_response[0].address_components.length; i++) {
2891  var component = in_geocode_response[0].address_components[i];
2892  if (component.types && component.types[0] === "administrative_area_level_2") {
2893  var county = component.long_name;
2894  if (county.endsWith(" County")) {
2895  county = county.substring(0, county.length - 7);
2896  }
2897  meeting_county_text_item.value = county;
2898  this.setItemValue(meeting_county_text_item, in_meeting_id, 'location_sub_province');
2899  break;
2900  }
2901  }
2902  }
2903  }
2904 
2905  if (g_auto_geocoding_enabled && g_county_auto_geocoding_enabled) {
2906  var meeting_zip_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_zip_text_input');
2907  if (meeting_zip_text_item) {
2908  if (meeting_county_text_item) {
2909  for (var i = 0; i < in_geocode_response[0].address_components.length; i++) {
2910  var component = in_geocode_response[0].address_components[i];
2911  if (component.types && component.types[0] === "postal_code") {
2912  var zipCode = component.long_name;
2913  meeting_zip_text_item.value = zipCode;
2914  this.setItemValue(meeting_zip_text_item, in_meeting_id, 'location_postal_code_1');
2915  break;
2916  }
2917  }
2918  }
2919  }
2920  }
2921 
2922  this.validateMeetingEditorButton(in_meeting_id);
2923  } else {
2924  alert(in_geocode_response[0].status.toString());
2925  };
2926  } else {
2927  alert(g_meeting_lookup_failed);
2928  };
2929  };
2930 
2931  /************************************************************************************//**
2932  * \brief This toggles the map disclosure. *
2933  ****************************************************************************************/
2934  this.toggleMeetingMapDisclosure = function ( in_meeting_id ///< The meeting ID of the editor that gets this map.
2935  ) {
2936  var root_element = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
2937  var map_disclosure_div = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_map_disclosure_div');
2938  var map_div = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_map_div');
2939  var longlat_div = document.getElementById('bmlt_admin_single_location_' + in_meeting_id + '_long_lat_div');
2940 
2941  root_element.map_disclosed = !root_element.map_disclosed;
2942 
2943  map_disclosure_div.className = 'bmlt_admin_single_meeting_disclosure_map_div' + (root_element.map_disclosed ? '_open' : '_closed');
2944  map_div.className = 'bmlt_admin_single_meeting_map_div' + (root_element.map_disclosed ? '' : ' item_hidden');
2945  longlat_div.className = root_element.map_disclosed ? 'bmlt_admin_single_location_long_lat_div item_hidden' : 'bmlt_admin_single_location_long_lat_div';
2946 
2947  if ( root_element.map_disclosed && !root_element.main_map ) {
2948  root_element.main_map = this.createEditorMap(root_element, in_meeting_id);
2949  };
2950  };
2951 
2952  /************************************************************************************//**
2953  * \brief This creates the map for the editor. *
2954  * \returns the map object. *
2955  ****************************************************************************************/
2956  this.createEditorMap = function (
2957  in_editor_parent, ///< The main editor div object.
2958  in_meeting_id ///< The meeting ID of the editor that gets this map.
2959  ) {
2960  var meeting_map_holder = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_inner_map_div');
2961  var map_center = new google.maps.LatLng(in_editor_parent.meeting_object.latitude, in_editor_parent.meeting_object.longitude);
2962 
2963  var myOptions = {
2964  'center': map_center,
2965  'zoom': in_editor_parent.meeting_object.zoom,
2966  'mapTypeId': google.maps.MapTypeId.ROADMAP,
2967  'mapTypeControlOptions': { 'style': google.maps.MapTypeControlStyle.DROPDOWN_MENU },
2968  'zoomControl': true,
2969  'mapTypeControl': true,
2970  'disableDoubleClickZoom' : true,
2971  'draggableCursor': "crosshair",
2972  'scaleControl' : true
2973  };
2974 
2975  myOptions.zoomControlOptions = { 'style': google.maps.ZoomControlStyle.LARGE };
2976 
2977  in_editor_parent.m_main_map = new google.maps.Map(meeting_map_holder, myOptions);
2978 
2979  if ( in_editor_parent.m_main_map ) {
2980  in_editor_parent.m_main_map.setOptions({'scrollwheel': false}); // For some reason, it ignores setting this in the options.
2981  google.maps.event.addListener(in_editor_parent.m_main_map, 'click', function (in_event) {
2982  admin_handler_object.respondToMapClick(in_event, in_meeting_id); });
2983  in_editor_parent.m_main_map.initialcall = google.maps.event.addListener(in_editor_parent.m_main_map, 'tilesloaded', function (in_event) {
2984  admin_handler_object.tilesLoaded(in_meeting_id); });
2985  this.displayMainMarkerInMap(in_meeting_id);
2986  };
2987 
2988  return ( in_editor_parent.m_main_map );
2989  };
2990 
2991  /************************************************************************************//**
2992  * \brief
2993  ****************************************************************************************/
2994  this.tilesLoaded = function (in_meeting_id ///< The meeting this map is associated with.
2995  ) {
2996  var root_element = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
2997 
2998  if ( root_element && root_element.main_map && root_element.m_main_map.initialcall ) {
2999  google.maps.event.removeListener(root_element.m_main_map.initialcall);
3000  root_element.m_main_map.initialcall = null;
3001  };
3002 
3003  this.displayMainMarkerInMap(in_meeting_id);
3004  };
3005 
3006  /************************************************************************************//**
3007  * \brief
3008  ****************************************************************************************/
3009  this.respondToMapClick = function (
3010  in_event, ///< The Google Maps event
3011  in_meeting_id ///< The meeting this map is associated with.
3012  ) {
3013  var root_element = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
3014  var map_center = in_event.latLng;
3015  root_element.main_map.panTo(map_center);
3016  this.setMeetingLongLat(map_center, in_meeting_id);
3017  this.displayMainMarkerInMap(in_meeting_id);
3018  };
3019 
3020  /************************************************************************************//**
3021  * \brief
3022  ****************************************************************************************/
3023  this.respondToMarkerDragEnd = function (
3024  in_event, ///< The Google Maps event
3025  in_meeting_id ///< The meeting this map is associated with.
3026  ) {
3027  var root_element = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
3028  var map_center = in_event.latLng;
3029  root_element.main_map.panTo(map_center);
3030  this.setMeetingLongLat(map_center, in_meeting_id);
3031  };
3032 
3033  /************************************************************************************//**
3034  * \brief This displays the "Your Position" marker in the results map. *
3035  ****************************************************************************************/
3036  this.displayMainMarkerInMap = function ( in_meeting_id ///< The meeting this map is associated with.
3037  ) {
3038  var root_element = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
3039 
3040  if ( root_element && root_element.main_map ) {
3041  if ( root_element.main_map.main_marker ) {
3042  root_element.main_map.main_marker.setMap(null);
3043  root_element.main_map.main_marker = null;
3044  };
3045 
3046  m_icon_image = new google.maps.MarkerImage(g_style_dir + "/images/NACenterMarker.png", new google.maps.Size(21, 36), new google.maps.Point(0,0), new google.maps.Point(11, 36));
3047  m_icon_shadow = new google.maps.MarkerImage(g_style_dir + "/images/NACenterMarkerS.png", new google.maps.Size(43, 36), new google.maps.Point(0,0), new google.maps.Point(11, 36));
3048 
3049  root_element.main_map.main_marker = new google.maps.Marker({
3050  'position': root_element.main_map.getCenter(),
3051  'map': root_element.main_map,
3052  'icon': m_icon_image,
3053  'shadow': m_icon_shadow,
3054  'clickable': false,
3055  'cursor': 'pointer',
3056  'draggable': true
3057  });
3058  google.maps.event.addListener(root_element.main_map.main_marker, 'dragend', function (in_event) {
3059  admin_handler_object.respondToMarkerDragEnd(in_event, in_meeting_id); });
3060  };
3061  };
3062 
3063  /************************************************************************************//**
3064  * \brief
3065  ****************************************************************************************/
3066  this.setMeetingLongLat = function (
3067  in_longLat,
3068  in_meeting_id
3069  ) {
3070  var root_element = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div');
3071  var meeting_object = root_element.meeting_object;
3072  var meeting_longitude_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_longitude_text_input');
3073  var meeting_latitude_text_item = document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_meeting_latitude_text_input');
3074 
3075  var lng = (Math.round(100000000.0 * in_longLat.lng()) / 100000000.0);
3076  var lat = (Math.round(100000000.0 * in_longLat.lat()) / 100000000.0);
3077 
3078  meeting_object.longitude = lng;
3079  meeting_object.latitude = lat;
3080 
3081  meeting_longitude_text_item.value = htmlspecialchars_decode(meeting_object.longitude);
3082  meeting_latitude_text_item.value = htmlspecialchars_decode(meeting_object.latitude);
3083 
3084  this.setItemValue(meeting_longitude_text_item, in_meeting_id, 'longitude');
3085  this.setItemValue(meeting_latitude_text_item, in_meeting_id, 'latitude');
3086 
3087  this.validateMeetingEditorButton(in_meeting_id);
3088  };
3089 
3090  // #mark -
3091  // #mark Format Tab
3092  // #mark -
3093 
3094  /************************************************************************************//**
3095  * \brief
3096  ****************************************************************************************/
3097  this.setFormatCheckboxes = function (in_meeting_object
3098  ) {
3099  var format_keys_string = '';
3100 
3101  if (in_meeting_object) {
3102  if (in_meeting_object.format_shared_id_list) {
3103  format_keys_string = in_meeting_object.format_shared_id_list;
3104  };
3105  };
3106 
3107  var format_keys = new Array();
3108 
3109  // God, this is such an abomination.
3110  // If the format is one integer, or badly formed, then it might not split, in which case, we need to parse it.
3111  if (format_keys_string) {
3112  var splittee = format_keys_string.split(',');
3113  if (splittee && splittee.length) {
3114  format_keys = splittee.map((v) => {return parseInt(v);});
3115  } else {
3116  format_keys[0] = parseInt(format_keys_string);
3117  };
3118  };
3119 
3120  var venue_type_format_selections = { "HY": false, "TC": false, "VM": false };
3121  var main_formats = g_format_object_array;
3122  for (var c = 0; c < main_formats.length; c++) {
3123  var format_checkbox = document.getElementById('bmlt_admin_meeting_' + in_meeting_object.id_bigint + '_format_' + main_formats[c].id + '_checkbox');
3124 
3125  if (this.isVenueTypeFormatBySharedId(main_formats[c].id)) {
3126  $(format_checkbox).closest("div.bmlt_admin_meeting_one_format_div").hide();
3127  }
3128 
3129  if ( format_checkbox ) {
3130  for (var i = 0; i < format_keys.length; i++) {
3131  if ( format_checkbox.value == format_keys[i] ) {
3132 
3133  if (this.venueTypeSharedIdDict['HY'] === main_formats[c].id) {
3134  venue_type_format_selections['HY'] = true;
3135  } else if (this.venueTypeSharedIdDict['TC'] === main_formats[c].id) {
3136  venue_type_format_selections['TC'] = true;
3137  } else if (this.venueTypeSharedIdDict['VM'] === main_formats[c].id) {
3138  venue_type_format_selections['VM'] = true;
3139  }
3140 
3141  format_checkbox.checked = true;
3142  break;
3143  };
3144  };
3145  };
3146  };
3147 
3148  if (!venue_type_format_selections['VM'] && !venue_type_format_selections['TC'] && venue_type_format_selections['HY']) {
3149  document.getElementById("bmlt_admin_single_meeting_editor_" + in_meeting_object.id_bigint + "_meeting_venue_type_hybrid").checked = true;
3150  } else if (venue_type_format_selections['VM'] && venue_type_format_selections['TC'] && !venue_type_format_selections['HY']) {
3151  document.getElementById("bmlt_admin_single_meeting_editor_" + in_meeting_object.id_bigint + "_meeting_venue_type_virtualTC").checked = true;
3152  } else if (venue_type_format_selections['VM'] && !venue_type_format_selections['TC'] && !venue_type_format_selections['HY']) {
3153  document.getElementById("bmlt_admin_single_meeting_editor_" + in_meeting_object.id_bigint + "_meeting_venue_type_virtual").checked = true;
3154  } else if (!venue_type_format_selections['VM'] && !venue_type_format_selections['TC'] && !venue_type_format_selections['HY']) {
3155  document.getElementById("bmlt_admin_single_meeting_editor_" + in_meeting_object.id_bigint + "_meeting_venue_type_inperson").checked = true;
3156  }
3157 
3158  this.reactToFormatCheckbox(null, in_meeting_object.id_bigint);
3159 
3160  // The reason we do this whacky stuff, is that the formats may not be in the same order from the server as we keep them, so this little dance re-orders them.
3161  if ( in_meeting_object.id_bigint && this.m_search_results && this.m_search_results.length ) {
3162  for (var c = 0; c < this.m_search_results.length; c++) {
3163  if ( in_meeting_object.id_bigint == this.m_search_results[c].id_bigint ) {
3164  this.m_search_results[c].formats = in_meeting_object.formats;
3165  break;
3166  };
3167  };
3168  };
3169 
3170  this.validateMeetingEditorButton(in_meeting_object.id_bigint);
3171  };
3172 
3173  /************************************************************************************//**
3174  * \brief
3175  ****************************************************************************************/
3176  this.reactToFormatCheckbox = function (
3177  in_checkbox_object,
3178  in_meeting_id
3179  ) {
3180  var format_array = new Array;
3181  var main_formats = g_format_object_array;
3182 
3183  for (var c = 0; c < main_formats.length; c++) {
3184  var format_checkbox = document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_format_' + main_formats[c].id + '_checkbox');
3185 
3186  if ( format_checkbox && format_checkbox.checked ) {
3187  format_array[format_array.length] = parseInt(format_checkbox.value);
3188  };
3189  };
3190 
3191  format_array.sort(function(a,b) {return a-b;});
3192 
3193  document.getElementById('bmlt_admin_single_meeting_editor_' + in_meeting_id + '_div').meeting_object.format_shared_id_list = format_array.join(',');
3194  this.validateMeetingEditorButton(in_meeting_id);
3195  };
3196 
3197  // #mark -
3198  // #mark Other Tab
3199  // #mark -
3200 
3201  /************************************************************************************//**
3202  * \brief
3203  ****************************************************************************************/
3204  this.setUpOtherTab = function ( in_meeting_object
3205  ) {
3206  for (var c = 0; c < g_other_field_ids.length; c++) {
3207  var element = g_other_field_ids[c];
3208  var val = in_meeting_object[element];
3209  var elementID = 'bmlt_admin_single_meeting_editor_' + in_meeting_object.id_bigint + '_meeting_' + element + '_text_input';
3210  var text_field = document.getElementById(elementID);
3211 
3212  var def_val = text_field.value;
3213 
3214  if ( val ) {
3215  var val_ar = val.toString().split("#@-@#");
3216 
3217  if ( val_ar && (val_ar.length == 2 ) ) {
3218  val = val_ar[1];
3219  } else if ( val_ar && (val_ar.length == 3 ) ) {
3220  val = val_ar[2];
3221  };
3222 
3223  text_field.value = htmlspecialchars_decode(val);
3224  };
3225 
3226  this.setTextItemClass(text_field);
3227  text_field.meeting_id = in_meeting_object.id_bigint;
3228  text_field.element = element.toString();
3229  text_field.onkeyup = function () {
3230  admin_handler_object.setItemValue(this)};
3231  text_field.onfocus = function () {
3232  admin_handler_object.handleTextInputFocus(this)};
3233  text_field.onblur = function () {
3234  admin_handler_object.handleTextInputBlur(this)};
3235  text_field.onpaste = function () {
3236  var input = this;
3237  setTimeout(function () {
3238  admin_handler_object.setItemValue(input); }, 0);
3239  };
3240  text_field.oncut = function () {
3241  var input = this;
3242  setTimeout(function () {
3243  admin_handler_object.setItemValue(input); }, 0);
3244  };
3245 
3246  text_field = null;
3247  };
3248  };
3249 
3250  // #mark -
3251  // #mark History Tab
3252  // #mark -
3253 
3254  /************************************************************************************//**
3255  * \brief
3256  ****************************************************************************************/
3257  this.openHistoryTab = function ( in_meeting_id
3258  ) {
3259  var option_sheet = document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_history_sheet_div');
3260  var history_list = document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_history_list_div');
3261 
3262  if ( !history_list ) {
3263  this.fetchMeetingHistory(in_meeting_id);
3264  };
3265  };
3266 
3267  /************************************************************************************//**
3268  * \brief
3269  ****************************************************************************************/
3270  this.fetchMeetingHistory = function ( in_meeting_id
3271  ) {
3272  var new_editor = document.getElementById('bmlt_admin_single_meeting_editor_' + parseInt(in_meeting_id, 10) + '_div');
3273  var uri = g_ajax_callback_uri + '&get_meeting_history=' + in_meeting_id;
3274 
3275  if ( new_editor.m_ajax_request_in_progress ) {
3276  new_editor.m_ajax_request_in_progress.abort();
3277  new_editor.m_ajax_request_in_progress = null;
3278  };
3279 
3280  var salt = new Date();
3281  uri += '&salt=' + salt.getTime();
3282 
3283  new_editor.m_ajax_request_in_progress = BMLT_AjaxRequest(uri, function (in_req,in_id) {
3284  admin_handler_object.fetchMeetingHistoryAJAXCallback(in_req,in_id); }, 'get', in_meeting_id);
3285  };
3286 
3287  /************************************************************************************//**
3288  * \brief
3289  ****************************************************************************************/
3290  this.fetchMeetingHistoryAJAXCallback = function (
3291  in_http_request,
3292  in_meeting_id
3293  ) {
3294  if ( in_http_request.responseText ) {
3295  if ( in_http_request.responseText == 'NOT AUTHORIZED' ) {
3296  alert(g_AJAX_Auth_Failure);
3297  } else {
3298  eval('var json_object = ' + in_http_request.responseText + ';');
3299  };
3300  };
3301 
3302  if ( json_object ) {
3303  var meeting_changed = false;
3304 
3305  if ( json_object.error ) {
3306  alert(json_object.report);
3307  } else {
3308  document.getElementById('bmlt_admin_history_ajax_button_' + in_meeting_id + '_throbber_div').className = 'bmlt_admin_history_ajax_button_throbber_div item_hidden';
3309  var option_sheet = document.getElementById('bmlt_admin_meeting_' + in_meeting_id + '_history_sheet_div');
3310  var history_list = document.createElement('div');
3311  history_list.id = 'bmlt_admin_meeting_' + in_meeting_id + '_history_list_div';
3312  history_list.className = 'bmlt_admin_meeting_history_list_div';
3313 
3314  if ( json_object.length ) {
3315  for (var c = 0; c < json_object.length; c++) {
3316  var history_item = document.createElement('div');
3317  history_item.id = 'bmlt_admin_meeting_' + in_meeting_id + '_history_' + json_object[c].id + '_list_item_div';
3318  history_item.className = 'bmlt_admin_meeting_history_list_item_div';
3319 
3320  var header_items = sprintf(g_history_header_format.toString().replace(/&gt;/g, '>').replace(/&lt;/g, '<'), json_object[c].date, json_object[c].user);
3321  history_item.innerHTML = header_items;
3322 
3323  if ( json_object[c].description.length ) {
3324  var item = document.createElement('div');
3325  item.className = 'bmlt_admin_meeting_history_list_item_line_div bmlt_admin_meeting_history_list_item_description_div';
3326  for (var i = 0; i < json_object[c].description.length; i++) {
3327  var inner_item = document.createElement('div');
3328  inner_item.className = 'bmlt_admin_meeting_history_list_item_description_line_div';
3329  inner_item.appendChild(document.createTextNode(json_object[c].description[i].toString().replace(/&quot;/g, '"')));
3330  item.appendChild(inner_item);
3331  };
3332 
3333  history_item.appendChild(item);
3334  };
this m_failure_fade_duration
10 seconds for a failure fader.
function BMLT_Admin_changeTemplateIDToUseThisID(in_container_element, in_element_id)
This replaces every instance of &#39;template&#39; in a hierarchy&#39;s element ids with the * the given ID...
BMLTSemanticResult prototype weekdays
The selected weekdays (1-7). This is a CSV string of integer IDs.
this m_warn_user_to_refresh
this m_account_panel_shown
var r
function htmlspecialchars_decode(string, quote_style)
function g
var v
function BMLT_AjaxRequest(url, callback, method, extra_data)
A simple, generic AJAX request function. * *.
this m_search_specifier_shown
this m_meeting_editor_panel_shown
var s
var admin_handler_object
var a
function BMLT_Admin_setSelectByStringValue(in_select_object, in_value)
this m_server_admin_panel_shown
BMLTSemanticResult prototype services
The selected Service bodies. This is a CSV string of integer IDs.
function d(e)
function BMLT_Admin_setSelectByValue(in_select_object, in_value)
this m_success_fade_duration
10 seconds for a success fader.
BMLTSemantic prototype state
if(!g_google_api_key||!g_google_api_key.trim())
var t
var i
var n
this venueTypeSharedIdDict
function sprintf()
var b
var c
function BMLT_Admin_StartFader(in_eid, in_fade_time)
Starts the message "fader." *Simple fader, taken from here: * http://www.switchonthecode.com/tutorials/javascript-tutorial-simple-fade-animation *.
this m_format_editor_table_rows
var g_google_api_key_is_good
geocoder geocode ( {'address':'27205'}  ,
function(response, status){g_google_api_key_is_good=status=== 'OK';if(!g_google_api_key_is_good){showGoogleApiKeyError(g_maps_api_key_warning);}}   
)
function htmlspecialchars_decode (   string,
  quote_style 
)

Definition at line 5882 of file server_admin_javascript.js.

References g, and i.

Referenced by BMLT_Server_Admin(), c_comdef_admin_xml_handler::get_changes_as_csv(), and parse_redirect().

5885  {
5886  // http://kevin.vanzonneveld.net
5887  // + original by: Mirek Slugen
5888  // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
5889  // + bugfixed by: Mateusz "loonquawl" Zalega
5890  // + input by: ReverseSyntax
5891  // + input by: Slawomir Kaniecki
5892  // + input by: Scott Cariss
5893  // + input by: Francois
5894  // + bugfixed by: Onno Marsman
5895  // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
5896  // + bugfixed by: Brett Zamir (http://brett-zamir.me)
5897  // + input by: Ratheous
5898  // + input by: Mailfaker (http://www.weedem.fr/)
5899  // + reimplemented by: Brett Zamir (http://brett-zamir.me)
5900  // + bugfixed by: Brett Zamir (http://brett-zamir.me)
5901  // * example 1: htmlspecialchars_decode("<p>this -&gt; &quot;</p>", 'ENT_NOQUOTES');
5902  // * returns 1: '<p>this -> &quot;</p>'
5903  // * example 2: htmlspecialchars_decode("&amp;quot;");
5904  // * returns 2: '&quot;'
5905  var optTemp = 0,
5906  i = 0,
5907  noquotes = false;
5908 
5909  if (typeof quote_style === 'undefined') {
5910  quote_style = 2;
5911  };
5912 
5913  string = string.toString().replace(/&lt;/g, '<').replace(/&gt;/g, '>');
5914  var OPTS = {
5915  'ENT_NOQUOTES': 0,
5916  'ENT_HTML_QUOTE_SINGLE': 1,
5917  'ENT_HTML_QUOTE_DOUBLE': 2,
5918  'ENT_COMPAT': 2,
5919  'ENT_QUOTES': 3,
5920  'ENT_IGNORE': 4
5921  };
5922 
5923  if (quote_style === 0) {
5924  noquotes = true;
5925  };
5926 
5927  if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags
5928  quote_style = [].concat(quote_style);
5929  for (i = 0; i < quote_style.length; i++) {
5930  // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
5931  if (OPTS[quote_style[i]] === 0) {
5932  noquotes = true;
5933  } else if (OPTS[quote_style[i]]) {
5934  optTemp = optTemp | OPTS[quote_style[i]];
5935  };
5936  };
5937 
5938  quote_style = optTemp;
5939  };
5940 
5941  if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) {
5942  string = string.replace(/&#0*39;/g, "'"); // PHP doesn't currently escape if more than one 0, but it should
5943  // string = string.replace(/&apos;|&#x0*27;/g, "'"); // This would also be useful here, but not a part of PHP
5944  };
5945 
5946  if (!noquotes) {
5947  string = string.replace(/&quot;/g, '"');
5948  };
5949 
5950  // Put this in last place to avoid escape being double-decoded
5951  string = string.replace(/&amp;/g, '&');
5952 
5953  return string;
5954 };
function g
var i
if ( !g_google_api_key||!g_google_api_key.  trim())

Definition at line 6106 of file server_admin_javascript.js.

Referenced by BMLT_Server_Admin().

6106  {
6107  showGoogleApiKeyError(g_maps_api_key_not_set);
6108 } else {
var showGoogleApiKeyError
function sprintf ( )

sprintf() for JavaScript 0.6

Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com> All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of sprintf() for JavaScript nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Changelog: 2007.04.03 - 0.1:

  • initial release 2007.09.11 - 0.2:
  • feature: added argument swapping 2007.09.17 - 0.3:
  • bug fix: no longer throws exception on empty paramenters (Hans Pufal) 2007.10.21 - 0.4:
  • unit test and patch (David Baird) 2010.05.09 - 0.5:
  • bug fix: 0 is now preceeded with a + sign
  • bug fix: the sign was not at the right position on padded results (Kamal Abdali)
  • switched from GPL to BSD license 2010.05.22 - 0.6:
  • reverted to 0.4 and fixed the bug regarding the sign of the number 0 Note: Thanks to Raphael Pigulla <raph (at] n3rd [dot) org> (http://www.n3rd.org/) who warned me about a bug in 0.5, I discovered that the last update was a regress. I appologize for that.

Definition at line 6006 of file server_admin_javascript.js.

References a, b, c, d(), e, f, i, m, o, s, u, and x.

Referenced by BMLT_Server_Admin().

6007 {
6008  function str_repeat(i, m)
6009  {
6010  for (var o = []; m > 0; o[--m] = i) {
6011  }
6012  return o.join('');
6013  };
6014 
6015  var i = 0, a, f = arguments[i++], o = [], m, p, c, x, s = '';
6016 
6017  while (f) {
6018  if (m = /^[^\x25]+/.exec(f)) {
6019  o.push(m[0]);
6020  } else if (m = /^\x25{2}/.exec(f)) {
6021  o.push('%');
6022  } else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) {
6023  if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) {
6024  throw('Too few arguments.');
6025  };
6026 
6027  if (/[^s]/.test(m[7]) && (typeof(a) != 'number')) {
6028  throw('Expecting number but found ' + typeof(a));
6029  };
6030 
6031  switch (m[7]) {
6032  case 'b': a = a.toString(2); break;
6033  case 'c': a = String.fromCharCode(a); break;
6034  case 'd': a = parseInt(a,10); break;
6035  case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break;
6036  case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break;
6037  case 'o': a = a.toString(8); break;
6038  case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break;
6039  case 'u': a = Math.abs(a); break;
6040  case 'x': a = a.toString(16); break;
6041  case 'X': a = a.toString(16).toUpperCase(); break;
6042  };
6043 
6044  a = (/[def]/.test(m[7]) && m[2] && a >= 0 ? '+'+ a : a);
6045  c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' ';
6046  x = m[5] - String(a).length - s.length;
6047  p = m[5] ? str_repeat(c, x) : '';
6048  o.push(s + (m[4] ? a + p : p + a));
6049  } else {
6050  throw('Huh ?!');
6051  };
6052 
6053  f = f.substring(m[0].length);
6054  };
6055 
6056  return o.join('');
6057 };
var f
var x
var s
var a
var u
var o
function d(e)
var m
function e
var i
var b
var c
function takeOverConsole ( )

Definition at line 6072 of file server_admin_javascript.js.

6072  { // taken from http://tobyho.com/2012/07/27/taking-over-console-log/
6073  var console = window.console;
6074  if (!console) {
6075  return;
6076  }
6077 
6078  function intercept(method) {
6079  var original = console[method];
6080  console[method] = function() {
6081  // check message
6082  if (arguments[0].indexOf("Google Maps") !== -1) {
6083  var message = arguments[0];
6084  var idx = message.indexOf("\n");
6085  if (idx !== -1) {
6086  message = message.substring(0, idx);
6087  }
6088  showGoogleApiKeyError(message);
6089  }
6090 
6091  if (original.apply) {
6092  // Do this for normal browsers
6093  original.apply(console, arguments);
6094  } else {
6095  // Do this for IE
6096  original(Array.prototype.slice.apply(arguments).join(' '));
6097  }
6098  }
6099  }
6100  var methods = ['error']; // only interested in the console.error method
6101  for (var i = 0; i < methods.length; i++) {
6102  intercept(methods[i]);
6103  }
6104 }());
var i
var showGoogleApiKeyError

Variable Documentation

var admin_handler_object = new BMLT_Server_Admin
this cancelServiceBodyEdit
Initial value:
= function () {
var main_service_body_editor = document.getElementById('bmlt_admin_single_service_body_editor_div');
main_service_body_editor.service_body_object = null;
}
this populateServiceBodyEditor
This sets up the Service Body Editor for the selected Service body. *.

This cancels the Service body editing session. *.

Definition at line 3781 of file server_admin_javascript.js.

this cancelUserEdit
Initial value:
= function () {
var main_user_editor_div = document.getElementById('bmlt_admin_single_user_editor_div');
main_user_editor_div.current_user_object = null;
}
this populateUserEditor
This sets up the Service Body Editor for the selected Service body. *.

Resets the user to the original state. *.

Definition at line 4471 of file server_admin_javascript.js.

this checkAllServiceBodies
Initial value:
= function(button) {
var desiredState = button.innerText == g_check_all_text;
for (var i = 0; i < g_service_bodies_array.length; i++) {
var serviceBodyId = g_service_bodies_array[i][0];
var checkbox = document.getElementById("bmlt_admin_meeting_search_service_body_checkbox_" + serviceBodyId);
checkbox.checked = desiredState;
}
button.innerText = desiredState ? g_uncheck_all_text : g_check_all_text;
}
var i

Definition at line 4671 of file server_admin_javascript.js.

this createFormatRow

This populates the format display list *.

Definition at line 4684 of file server_admin_javascript.js.

this createServiceBody
Initial value:
= function () {
if ( this.isServiceBodyDirty() != null ) {
var main_service_body_editor = document.getElementById('bmlt_admin_single_service_body_editor_div');
var button_object = document.getElementById('bmlt_admin_service_body_editor_form_service_body_save_button');
var throbber_object = document.getElementById('bmlt_admin_service_body_save_ajax_button_throbber_span');
var serialized_object = JSON.stringify(main_service_body_editor.service_body_object);
var uri = g_ajax_callback_uri + '&create_new_service_body=' + encodeURIComponent(serialized_object);
if ( main_service_body_editor.m_ajax_request_in_progress ) {
main_service_body_editor.m_ajax_request_in_progress.abort();
main_service_body_editor.m_ajax_request_in_progress = null;
};
var salt = new Date();
uri += '&salt=' + salt.getTime();
button_object.className = 'item_hidden';
throbber_object.className = 'bmlt_admin_ajax_button_throbber_span';
main_service_body_editor.m_ajax_request_in_progress = BMLT_AjaxRequest(uri, function (in_req) {
admin_handler_object.createServiceBodyAJAXCallback(in_req); }, 'post');
};
}
this isServiceBodyDirty
See if changes have been made to the Service body. *.
function BMLT_AjaxRequest(url, callback, method, extra_data)
A simple, generic AJAX request function. * *.
var admin_handler_object

This creates a new Service body. *.

Definition at line 3872 of file server_admin_javascript.js.

this createServiceBodyAJAXCallback

This is the AJAX callback handler for the create operation. *.

Definition at line 3901 of file server_admin_javascript.js.

this createUser
Initial value:
= function () {
if ( this.isUserDirty() ) {
var main_user_editor_div = document.getElementById('bmlt_admin_single_user_editor_div');
if ( main_user_editor_div.current_user_object[6] ) {
var button_object = document.getElementById('bmlt_admin_user_editor_form_user_save_button');
var throbber_object = document.getElementById('bmlt_admin_user_save_ajax_button_throbber_span');
var serialized_object = JSON.stringify(main_user_editor_div.current_user_object);
var uri = g_ajax_callback_uri + '&create_new_user=' + encodeURIComponent(serialized_object);
if ( main_user_editor_div.m_ajax_request_in_progress ) {
main_user_editor_div.m_ajax_request_in_progress.abort();
main_user_editor_div.m_ajax_request_in_progress = null;
};
var salt = new Date();
uri += '&salt=' + salt.getTime();
button_object.className = 'item_hidden';
throbber_object.className = 'bmlt_admin_ajax_button_throbber_span';
main_user_editor_div.m_ajax_request_in_progress = BMLT_AjaxRequest(uri, function (in_req) {
admin_handler_object.createUserAJAXCallback(in_req); }, 'post');
} else {
alert(g_user_create_password_alert_text);
};
};
}
function BMLT_AjaxRequest(url, callback, method, extra_data)
A simple, generic AJAX request function. * *.
var admin_handler_object
this isUserDirty
See if changes have been made to the User. *.

This creates a new user. *.

Definition at line 4303 of file server_admin_javascript.js.

this createUserAJAXCallback

This is the AJAX callback handler for the create operation. *.

Definition at line 4337 of file server_admin_javascript.js.

this deleteServiceBody
Initial value:
= function () {
if ( g_service_bodies_array.length > 1 ) {
var perm_check = document.getElementById('bmlt_admin_service_body_delete_perm_checkbox');
var confirm_str = g_service_body_delete_button_confirm + (( perm_check && perm_check.checked ) ? ("\n" + g_service_body_delete_button_confirm_perm) : '');
if ( confirm(confirm_str) ) {
var main_service_body_editor = document.getElementById('bmlt_admin_single_service_body_editor_div');
if ( main_service_body_editor.m_ajax_request_in_progress ) {
main_service_body_editor.m_ajax_request_in_progress.abort();
main_service_body_editor.m_ajax_request_in_progress = null;
};
var id = main_service_body_editor.service_body_object[0];
var uri = g_ajax_callback_uri + '&delete_service_body=' + id + (( perm_check && perm_check.checked ) ? '&permanently=1' : '');
var throbber_span = document.getElementById('bmlt_admin_service_body_delete_ajax_button_throbber_span').className = 'bmlt_admin_ajax_button_throbber_span';
var delete_a = document.getElementById('bmlt_admin_meeting_editor_form_service_body_delete_button').className = 'item_hidden';
var salt = new Date();
uri += '&salt=' + salt.getTime();
main_service_body_editor.m_ajax_request_in_progress = BMLT_AjaxRequest(uri, function (in_req) {
admin_handler_object.deleteServiceBodyAJAXCallback(in_req); }, 'get');
};
};
}
function BMLT_AjaxRequest(url, callback, method, extra_data)
A simple, generic AJAX request function. * *.
var admin_handler_object

This deletes the current Service body. *.

Definition at line 3952 of file server_admin_javascript.js.

this deleteServiceBodyAJAXCallback

This is the AJAX callback handler for the delete operation. *.

Definition at line 3983 of file server_admin_javascript.js.

this deleteUser
Initial value:
= function () {
if ( g_users.length > 1 ) {
var perm_check = document.getElementById('bmlt_admin_user_delete_perm_checkbox');
var confirm_str = g_user_delete_button_confirm + (( perm_check && perm_check.checked ) ? ("\n" + g_user_delete_button_confirm_perm) : '');
if ( confirm(confirm_str) ) {
var main_user_editor_div = document.getElementById('bmlt_admin_single_user_editor_div');
if ( main_user_editor_div.m_ajax_request_in_progress ) {
main_user_editor_div.m_ajax_request_in_progress.abort();
main_user_editor_div.m_ajax_request_in_progress = null;
};
var id = main_user_editor_div.current_user_object[0];
var uri = g_ajax_callback_uri + '&delete_user=' + id + (( perm_check && perm_check.checked ) ? '&permanently=1' : '');
document.getElementById('bmlt_admin_user_delete_ajax_button_throbber_span').className = 'bmlt_admin_ajax_button_throbber_span';
document.getElementById('bmlt_admin_meeting_editor_form_user_delete_button').className = 'item_hidden';
var salt = new Date();
uri += '&salt=' + salt.getTime();
main_user_editor_div.m_ajax_request_in_progress = BMLT_AjaxRequest(uri, function (in_req) {
admin_handler_object.deleteUserAJAXCallback(in_req); }, 'get');
};
};
}
function BMLT_AjaxRequest(url, callback, method, extra_data)
A simple, generic AJAX request function. * *.
var admin_handler_object

Deletes the user. *.

Definition at line 4387 of file server_admin_javascript.js.

this deleteUserAJAXCallback

This is the AJAX callback handler for the delete operation. *.

Definition at line 4418 of file server_admin_javascript.js.

else
Initial value:
{
history_list.innerHTML = g_history_no_history_available_text.toString().replace(/&gt;/g, '>').replace(/&lt;/g, '<')
function g

Definition at line 3338 of file server_admin_javascript.js.

var g_google_api_key_is_good = false

Definition at line 6060 of file server_admin_javascript.js.

Referenced by BMLT_Server_Admin().

this getSharedIdForVenueTypeFormat

methods and variables for venue type format codes *

Definition at line 4571 of file server_admin_javascript.js.

this handleTextInputServiceBodyChange
Initial value:
= function (
in_text_item,
in_value_index
) {
var val = '';
if ( in_text_item ) {
if ( !in_text_item.value || (in_text_item.value == in_text_item.defaultValue) ) {
in_text_item.className = 'bmlt_text_item' + (in_text_item.small ? '_small' : (in_text_item.med ? '_med' : (in_text_item.tiny ? '_tiny' : ''))) + ' bmlt_text_item_dimmed';
} else {
val = in_text_item.value;
in_text_item.className = 'bmlt_text_item' + (in_text_item.small ? '_small' : (in_text_item.med ? '_med' : (in_text_item.tiny ? '_tiny' : '')));
};
};
var main_service_body_editor = document.getElementById('bmlt_admin_single_service_body_editor_div');
main_service_body_editor.service_body_object[in_value_index] = val;
}
this recalculateServiceBody
This goes through the Service body (except the checkboxes) and recalculates * the state of the edited...
this validateServiceBodyEditorButtons
This sets the state of the Service body editor save button. *.

 

Definition at line 3756 of file server_admin_javascript.js.

this isServiceBodyDirty
Initial value:
= function () {
var main_service_body_editor = document.getElementById('bmlt_admin_single_service_body_editor_div');
var edited_service_body_object = main_service_body_editor.service_body_object;
var original_service_body = null;
var index = 0;
if ( edited_service_body_object[0] > 0 ) {
for (; index < g_service_bodies_array.length; index++) {
if ( g_service_bodies_array[index][0] == edited_service_body_object[0] ) {
original_service_body = g_service_bodies_array[index];
break;
};
};
} else {
original_service_body = this.makeANewSB();
};
var current = JSON.stringify(edited_service_body_object);
var orig = JSON.stringify(original_service_body);
var ret = ( (current != orig) ? index : null );
return ret;
}
this makeANewSB
This simply creates a brand-new, unsullied Service body object. *.

See if changes have been made to the Service body. *.

Returns
the service body index (if changed). Null, otherwise (Check for null) *

Definition at line 3653 of file server_admin_javascript.js.

this isUserDirty
Initial value:
= function () {
var edited_user_object = document.getElementById('bmlt_admin_single_user_editor_div').current_user_object;
var original_user_object = null;
var index = 0;
if ( edited_user_object[0] > 0 ) {
for (; index < g_users.length; index++) {
if ( g_users[index][0] == edited_user_object[0] ) {
original_user_object = g_users[index];
break;
};
};
} else {
original_user_object = this.makeANewUser();
};
var current = JSON.stringify(edited_user_object);
var orig = JSON.stringify(original_user_object);
var ret = (current != orig);
return ret;
}
this makeANewUser
This simply creates a brand-new, unsullied User object. *.

See if changes have been made to the User. *.

Returns
true, if the user has been changed. *

Definition at line 4481 of file server_admin_javascript.js.

this m_account_panel_shown = false

Definition at line 5504 of file server_admin_javascript.js.

Referenced by BMLT_Server_Admin().

this m_failure_fade_duration = 10000

10 seconds for a failure fader.

Definition at line 5509 of file server_admin_javascript.js.

Referenced by BMLT_Server_Admin().

this m_format_editor_table_rows = 0

Definition at line 5510 of file server_admin_javascript.js.

Referenced by BMLT_Server_Admin().

this m_meeting_editor_panel_shown = false

Definition at line 5506 of file server_admin_javascript.js.

Referenced by BMLT_Server_Admin().

this m_search_specifier_shown = true

Definition at line 5505 of file server_admin_javascript.js.

Referenced by BMLT_Server_Admin().

this m_server_admin_panel_shown = false

CONSTRUCTOR *

Definition at line 5503 of file server_admin_javascript.js.

Referenced by BMLT_Server_Admin().

this m_success_fade_duration = 10000

10 seconds for a success fader.

Definition at line 5508 of file server_admin_javascript.js.

Referenced by BMLT_Server_Admin().

this m_warn_user_to_refresh = false

Definition at line 5507 of file server_admin_javascript.js.

Referenced by BMLT_Server_Admin().

this makeANewSB
Initial value:
= function () {
var new_service_body_object = new Array;
new_service_body_object[0] = 0;
new_service_body_object[1] = 0;
new_service_body_object[2] = '';
new_service_body_object[3] = '';
new_service_body_object[4] = g_users[1][0];
new_service_body_object[5] = '0';
new_service_body_object[6] = '';
new_service_body_object[7] = '';
new_service_body_object[8] = '';
new_service_body_object[9] = 'AS';
new_service_body_object[10] = true;
new_service_body_object[11] = true;
new_service_body_object[12] = '';
return new_service_body_object;
}

This simply creates a brand-new, unsullied Service body object. *.

Returns
a new Service body object (which is really an array). *

Definition at line 3516 of file server_admin_javascript.js.

this makeANewUser
Initial value:
= function () {
var new_user_object = new Array;
new_user_object[0] = 0;
new_user_object[1] = '';
new_user_object[2] = '';
new_user_object[3] = '';
new_user_object[4] = '';
new_user_object[5] = 4;
new_user_object[6] = '';
new_user_object[7] = -1;
return new_user_object;
}

This simply creates a brand-new, unsullied User object. *.

Returns
a new user object (which is really an array). *

Definition at line 4508 of file server_admin_javascript.js.

this populateServiceBodyEditor

This sets up the Service Body Editor for the selected Service body. *.

Definition at line 3373 of file server_admin_javascript.js.

this populateUserEditor

This sets up the Service Body Editor for the selected Service body. *.

Definition at line 4091 of file server_admin_javascript.js.

this readUserEditorState
Initial value:
= function () {
var main_user_editor_div = document.getElementById('bmlt_admin_single_user_editor_div');
var login_field = document.getElementById('bmlt_admin_user_editor_login_input');
main_user_editor_div.current_user_object[1] = (login_field.value && (login_field.value != login_field.defaultValue)) ? login_field.value : '';
var name_field = document.getElementById('bmlt_admin_user_editor_name_input');
main_user_editor_div.current_user_object[2] = (name_field.value && (name_field.value != name_field.defaultValue)) ? name_field.value : '';
var description_textarea = document.getElementById('bmlt_admin_user_editor_description_textarea');
main_user_editor_div.current_user_object[3] = (description_textarea.value && (description_textarea.value != description_textarea.defaultValue)) ? description_textarea.value : '';
var email_field = document.getElementById('bmlt_admin_user_editor_email_input');
main_user_editor_div.current_user_object[4] = (email_field.value && (email_field.value != email_field.defaultValue)) ? email_field.value : '';
var user_level_select = document.getElementById('bmlt_admin_single_user_editor_level_select');
main_user_editor_div.current_user_object[5] = parseInt(user_level_select.options[user_level_select.selectedIndex].value, 10);
var password_field = document.getElementById('bmlt_admin_user_editor_password_input');
main_user_editor_div.current_user_object[6] = (password_field.value && (password_field.value != password_field.defaultValue)) ? password_field.value : '';
var user_owner_select = document.getElementById('bmlt_admin_single_user_editor_user_owner_select');
main_user_editor_div.current_user_object[7] = parseInt(user_owner_select.options[user_owner_select.selectedIndex].value, 10);
}
this validateUserEditorButtons
This sets the state of the User editor save button. *.

Reads the current user editor state, and sets the main object accordingly. *.

Definition at line 4194 of file server_admin_javascript.js.

this recalculateServiceBody

This goes through the Service body (except the checkboxes) and recalculates * the state of the edited object. *.

Definition at line 3681 of file server_admin_javascript.js.

this saveServiceBody
Initial value:
= function () {
var main_service_body_editor = document.getElementById('bmlt_admin_single_service_body_editor_div');
if ( main_service_body_editor.service_body_object[0] == 0 ) {
} else {
if ( this.isServiceBodyDirty() != null ) {
var button_object = document.getElementById('bmlt_admin_service_body_editor_form_service_body_save_button');
var throbber_object = document.getElementById('bmlt_admin_service_body_save_ajax_button_throbber_span');
var serialized_object = JSON.stringify(main_service_body_editor.service_body_object);
var uri = g_ajax_callback_uri + '&set_service_body_change=' + encodeURIComponent(serialized_object);
if ( main_service_body_editor.m_ajax_request_in_progress ) {
main_service_body_editor.m_ajax_request_in_progress.abort();
main_service_body_editor.m_ajax_request_in_progress = null;
};
var salt = new Date();
uri += '&salt=' + salt.getTime();
button_object.className = 'item_hidden';
throbber_object.className = 'bmlt_admin_ajax_button_throbber_span';
main_service_body_editor.m_ajax_request_in_progress = BMLT_AjaxRequest(uri, function (in_req) {
admin_handler_object.saveServiceBodyAJAXCallback(in_req); }, 'post');
};
};
}
this isServiceBodyDirty
See if changes have been made to the Service body. *.
function BMLT_AjaxRequest(url, callback, method, extra_data)
A simple, generic AJAX request function. * *.
var admin_handler_object
this createServiceBody
This creates a new Service body. *.

This saves the current Service body. *.

Definition at line 3792 of file server_admin_javascript.js.

this saveServiceBodyAJAXCallback

This is the AJAX callback handler for the save operation. *.

Definition at line 3826 of file server_admin_javascript.js.

this saveUser

Saves the user state. *.

Definition at line 4224 of file server_admin_javascript.js.

this saveUserAJAXCallback

This is the AJAX callback handler for the save operation. *.

Definition at line 4264 of file server_admin_javascript.js.

this serviceBodyUserChecboxHandler
Initial value:
= function (
in_user_id,
in_checkbox_object
) {
var main_service_body_editor = document.getElementById('bmlt_admin_single_service_body_editor_div');
var new_users = new Array;
if ( g_users && g_users.length ) {
for (var c = 0; c < g_users.length; c++) {
var checkbox = document.getElementById('service_body_admin_editor_user_' + g_users[c][0] +'_checkbox');
if ( checkbox && checkbox.checked ) {
new_users[new_users.length] = g_users[c][0];
};
};
};
if ( new_users.length ) {
main_service_body_editor.service_body_object[5] = new_users.join(',').toString();
} else {
main_service_body_editor.service_body_object[5] = '0';
};
}
this validateServiceBodyEditorButtons
This sets the state of the Service body editor save button. *.
var c

This is called when a Service Body Editor checkbox is clicked. *.

Definition at line 3596 of file server_admin_javascript.js.

this setServiceBodyEditorCheckboxes
Initial value:
= function () {
var main_service_body_editor = document.getElementById('bmlt_admin_single_service_body_editor_div');
var users = main_service_body_editor.service_body_object[5].toString().split(',');
if ( users && users.length && g_users && g_users.length ) {
for (var c = 0; c < g_users.length; c++) {
var checkbox = document.getElementById('service_body_admin_editor_user_' + g_users[c][0] +'_checkbox');
if ( checkbox ) {
checkbox.checked = false;
for (var i = 0; i < users.length; i++) {
if ( users[i] == g_users[c][0] ) {
checkbox.checked = true;
break;
};
};
};
};
};
}
var i
var c

This is called when a Service Body Editor checkbox is clicked. *.

Definition at line 3571 of file server_admin_javascript.js.

this setServiceBodyUser
Initial value:
= function ( in_selected_service_body
) {
var user_single_display = document.getElementById('single_user_service_body_admin_span');
var user_select_element = document.getElementById('bmlt_admin_single_service_body_editor_principal_user_select');
var sb_primary_user = null;
var user_index = 0;
for (; user_index < g_users.length; user_index++) {
if ( g_users[user_index][0] == in_selected_service_body[4] ) {
sb_primary_user = g_users[user_index];
break;
};
};
if ( sb_primary_user ) {
if ( user_single_display ) {
user_single_display.innerHTML = sb_primary_user[2];
} else if ( user_select_element ) {
for (var c = 0; c < user_select_element.options.length; c++) {
if ( user_select_element.options[c].value == in_selected_service_body[4] ) {
user_select_element.selectedIndex = c;
break;
};
};
};
};
}
var c

This handles display of the Service body user. *.

Definition at line 3538 of file server_admin_javascript.js.

var showGoogleApiKeyError
Initial value:
= function (message) {
var errorElement = document.getElementById('google_maps_api_error_div');
if (errorElement) {
errorElement.className = errorElement.className.replace(/\bitem_hidden\b/g, "");
}
errorElement = document.getElementById('google_maps_api_error_a');
if (errorElement) {
errorElement.innerText = message;
}
}
function g
var b

Definition at line 6061 of file server_admin_javascript.js.

this toggleFormatEditor
Initial value:
= function () {
this.m_user_editor_panel_shown = !this.m_user_editor_panel_shown;
var the_disclosure_div = document.getElementById('bmlt_admin_format_editor_disclosure_div');
var the_editor_div = document.getElementById('bmlt_admin_format_editor_wrapper_div');
if ( this.m_user_editor_panel_shown ) {
the_disclosure_div.className = 'bmlt_admin_format_editor_disclosure_div bmlt_admin_format_editor_disclosure_div_open';
the_editor_div.className = 'bmlt_admin_format_editor_wrapper_div';
} else {
the_disclosure_div.className = 'bmlt_admin_format_editor_disclosure_div bmlt_admin_format_editor_disclosure_div_closed';
the_editor_div.className = 'bmlt_admin_format_editor_wrapper_div bmlt_admin_format_editor_wrapper_div_hidden';
};
}

Toggles the visibility of the Format editor section. *.

Definition at line 4553 of file server_admin_javascript.js.

this toggleServiceBodyEditor
Initial value:
= function () {
this.m_service_body_editor_panel_shown = !this.m_service_body_editor_panel_shown;
var the_disclosure_div = document.getElementById('bmlt_admin_service_body_editor_disclosure_div');
var the_editor_div = document.getElementById('bmlt_admin_service_body_editor_wrapper_div');
if ( this.m_service_body_editor_panel_shown ) {
the_disclosure_div.className = 'bmlt_admin_service_body_editor_disclosure_div bmlt_admin_service_body_editor_disclosure_div_open';
the_editor_div.className = 'bmlt_admin_service_body_editor_wrapper_div';
this.showWarningAlert();
} else {
the_disclosure_div.className = 'bmlt_admin_service_body_editor_disclosure_div bmlt_admin_service_body_editor_disclosure_div_closed';
the_editor_div.className = 'bmlt_admin_service_body_editor_wrapper_div bmlt_admin_service_body_editor_wrapper_div_hidden';
};
}

Toggles the visibility of the Service body editor section. *.

Definition at line 3354 of file server_admin_javascript.js.

this toggleUserEditor
Initial value:
= function () {
this.m_user_editor_panel_shown = !this.m_user_editor_panel_shown;
var the_disclosure_div = document.getElementById('bmlt_admin_user_editor_disclosure_div');
var the_editor_div = document.getElementById('bmlt_admin_user_editor_wrapper_div');
if ( this.m_user_editor_panel_shown ) {
the_disclosure_div.className = 'bmlt_admin_user_editor_disclosure_div bmlt_admin_user_editor_disclosure_div_open';
the_editor_div.className = 'bmlt_admin_user_editor_wrapper_div';
} else {
the_disclosure_div.className = 'bmlt_admin_user_editor_disclosure_div bmlt_admin_user_editor_disclosure_div_closed';
the_editor_div.className = 'bmlt_admin_user_editor_wrapper_div bmlt_admin_user_editor_wrapper_div_hidden';
};
}

Toggles the visibility of the Service body editor section. *.

Definition at line 4073 of file server_admin_javascript.js.

this toggleVenueTypeFormat

Definition at line 4612 of file server_admin_javascript.js.

this validateServiceBodyEditorButtons
Initial value:
= function () {
var save_button = document.getElementById('bmlt_admin_service_body_editor_form_service_body_save_button');
var cancel_button = document.getElementById('bmlt_admin_service_body_editor_form_meeting_template_cancel_button');
if ( this.isServiceBodyDirty() != null ) {
save_button.className = 'bmlt_admin_ajax_button button';
cancel_button.className = 'bmlt_admin_ajax_button button';
} else {
save_button.className = 'bmlt_admin_ajax_button button_disabled';
cancel_button.className = 'bmlt_admin_ajax_button button_disabled';
};
var delete_span = document.getElementById('service_body_editor_delete_span');
if ( delete_span ) {
document.getElementById('bmlt_admin_meeting_editor_form_service_body_delete_button').className = 'bmlt_admin_ajax_button button';
if ( g_service_bodies_array.length > 1 ) {
delete_span.className = 'bmlt_admin_meeting_editor_form_middle_button_single_span bmlt_admin_delete_button_span hide_in_new_service_body_admin';
} else {
delete_span.className = 'item_hidden';
};
};
}
this isServiceBodyDirty
See if changes have been made to the Service body. *.

This sets the state of the Service body editor save button. *.

Definition at line 3625 of file server_admin_javascript.js.

this validateUserEditorButtons
Initial value:
= function () {
var save_button = document.getElementById('bmlt_admin_user_editor_form_user_save_button');
var cancel_button = document.getElementById('bmlt_admin_user_editor_form_user_editor_cancel_button');
var delete_button = document.getElementById('bmlt_admin_meeting_editor_form_user_delete_button');
if ( this.isUserDirty() ) {
save_button.className = 'bmlt_admin_ajax_button button';
cancel_button.className = 'bmlt_admin_ajax_button button';
} else {
save_button.className = 'bmlt_admin_ajax_button button_disabled';
cancel_button.className = 'bmlt_admin_ajax_button button_disabled';
};
if ( g_is_server_admin ) {
delete_button.className = 'bmlt_admin_ajax_button button';
} else {
delete_button.className = 'bmlt_admin_ajax_button button_disabled';
}
}
this isUserDirty
See if changes have been made to the User. *.

This sets the state of the User editor save button. *.

Definition at line 4525 of file server_admin_javascript.js.

this venueTypeSharedIdDict
Initial value:
= {
}
this getSharedIdForVenueTypeFormat
methods and variables for venue type format codes *

Definition at line 4606 of file server_admin_javascript.js.

Referenced by BMLT_Server_Admin().