Changeset 3075

Show
Ignore:
Timestamp:
11/27/10 10:32:44
Author:
johnsa
Message:

personal client: correct scheduling widget to avoid double event binding

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • releases/bedework-3.7/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/javascript/bedeworkScheduling.js

    r3071 r3075  
    891891      $("#" + displayId).html(fbDisplay); 
    892892       
    893        
     893       // now hide the processing message 
     894       $("#bwSchedProcessingMsg").fadeOut(100); 
     895 
    894896      // highlight the time based on the current date/time settings 
    895897      //var curSelectionTime = Number(startSelectionMils); 
     
    897899      //endSelectionMils = Number(curSelectionTime) + Number(durationMils); 
    898900      //bwGrid.highlight(curSelectionTime, endSelectionMils); 
    899        
    900        
    901       // **** ACTIONS **** 
    902       // now add some rollovers and onclick actions  
    903       // to the elements of the freebusy grid 
    904       $("#bwScheduleTable .icon").hover( 
    905         function () { 
    906           $(this).next(".tip").fadeIn(100); 
    907         },  
    908         function () { 
    909           $(this).next(".tip").fadeOut(100); 
    910         } 
    911       );   
    912        
    913       $("#bwScheduleTable .activeCell").hover( 
    914         function () { 
    915           $(this).children(".tip").fadeIn(20); 
    916         },  
    917         function () { 
    918           $(this).children(".tip").fadeOut(20); 
    919         } 
    920       ); 
    921        
    922       $("#bwScheduleTable .fbcell").click ( 
    923         function () { 
    924           // clear all previous highlighting 
    925           $("#bwScheduleTable .highlight").removeClass("highlight"); 
     901    } catch (e) { 
     902      alert(e); 
     903    } 
     904     
     905  }; 
     906     
     907  this.updateBookPath = function(path) { 
     908    $("#bwCardDavBookPath").val(path); 
     909  } 
     910   
     911  this.gotoNextRange = function() { 
     912    $("#bwSchedProcessingMsg").show(); 
     913    bwGrid.startRange.addDays(bwGrid.dayRange); 
     914    bwGrid.endRange.addDays(bwGrid.dayRange); 
     915    if (bwGrid.attendees.length) { 
     916      bwGrid.requestFreeBusy(); 
     917    } else { 
     918      bwGrid.display();  
     919    } 
     920  } 
     921   
     922  this.gotoPreviousRange = function() { 
     923    $("#bwSchedProcessingMsg").show(); 
     924    bwGrid.startRange.subtractDays(bwGrid.dayRange); 
     925    bwGrid.endRange.subtractDays(bwGrid.dayRange); 
     926    if (bwGrid.attendees.length) { 
     927      bwGrid.requestFreeBusy(); 
     928    } else { 
     929      bwGrid.display();  
     930    } 
     931  } 
     932   
     933  this.setDateTimeWidgets = function(startMils) { 
     934    // set the values of the date/time widgets on the main and meeting tabs 
     935    var selectedDate = new Date(Number(startMils)); 
     936    var selectedDateStr = selectedDate.getFullYear() + "-" + selectedDate.getMonthFull() + "-" + selectedDate.getDateFull(); 
     937    $("#bwEventWidgetStartDate").val(selectedDateStr); 
     938    $("#bwEventWidgetStartDateSched").val(selectedDateStr); 
     939    // check for ampm or hour24 
     940    if ($("#eventStartDateSchedAmpm").length) { 
     941      // we are using am/pm 
     942      $("#eventStartDateHour").val(selectedDate.getHours12()); 
     943      $("#eventStartDateMinute").val(selectedDate.getMinutesFull()); 
     944      $("#eventStartDateAmpm").val(selectedDate.getAmpm()); 
     945      $("#eventStartDateSchedHour").val(selectedDate.getHours12()); 
     946      $("#eventStartDateSchedMinute").val(selectedDate.getMinutesFull()); 
     947      $("#eventStartDateSchedAmpm").val(selectedDate.getAmpm()); 
     948    } else { 
     949      // we are using hour24 
     950      $("#eventStartDateHour").val(selectedDate.getHours()); 
     951      $("#eventStartDateMinute").val(selectedDate.getMinutesFull()); 
     952      $("#eventStartDateSchedHour").val(selectedDate.getHours()); 
     953      $("#eventStartDateSchedMinute").val(selectedDate.getMinutesFull()); 
     954    } 
     955  }  
     956}; 
     957 
     958// **** ACTIONS **** 
     959// now add some rollovers and onclick actions  
     960// to the elements of the freebusy grid once the 
     961// document is loaded 
     962$(document).ready(function() { 
     963  $("#bwScheduleTable .icon").hover( 
     964    function () { 
     965      $(this).next(".tip").fadeIn(100); 
     966    },  
     967    function () { 
     968      $(this).next(".tip").fadeOut(100); 
     969    } 
     970  );   
     971   
     972  $("#bwScheduleTable .activeCell").hover( 
     973    function () { 
     974      $(this).children(".tip").fadeIn(20); 
     975    },  
     976    function () { 
     977      $(this).children(".tip").fadeOut(20); 
     978    } 
     979  ); 
     980   
     981  $("#bwScheduleTable .fbcell").click ( 
     982    function () { 
     983      // clear all previous highlighting 
     984      $("#bwScheduleTable .highlight").removeClass("highlight"); 
     985       
     986      // get the id of the current cell - takes the form "1271947500000-attendeestring" 
     987      // we want the first half, which is the same as the time class associated with the column 
     988      var splitId = $(this).attr("id").split("-"); 
     989       
     990      // set the start of the selection range in milliseconds (first half of the ID) 
     991      // we will use this to set the start time and to find cells in the same column 
     992      var startSelectionMils = splitId[0]; 
     993      var endSelectionMils = Number(startSelectionMils) + Number(durationMils); 
     994       
     995      // now do the highlighting 
     996      $("#bwScheduleTable .fbcell").each(function(index) { 
     997        var splId = $(this).attr("id").split("-"); 
     998        if (splId[0] >= startSelectionMils && splId[0] < endSelectionMils) { 
     999          $(this).addClass("highlight"); 
     1000        } 
     1001      }); 
     1002       
     1003      // set the freeTimeIndex to the nearest index for the pickNext/previous buttons 
     1004      for (var i = 0; i < bwGrid.freeTime.length; i++) { 
     1005        if (Number(bwGrid.freeTime[i]) >= Number(startSelectionMils)) { 
     1006          bwGrid.freeTimeIndex = i - 1; // this will make pick previous jump an extra gap after clicking in a busy space, but it makes pick next work correctly in the same circumstance 
     1007          if (bwGrid.freeTimeIndex < 0) { 
     1008            bwGrid.freeTimeIndex = 0; 
     1009          } 
     1010          break; 
     1011        } 
     1012      } 
     1013       
     1014      bwGrid.setDateTimeWidgets(startSelectionMils); 
     1015   
     1016    } 
     1017  ); 
     1018   
     1019  /* 
     1020  $("#bwScheduleTable .fbcell").mousedown ( 
     1021    function () { 
     1022      // clear all previous highlighting 
     1023      $("#bwScheduleTable .highlight").removeClass("highlight"); 
     1024       
     1025      // get the id of the current cell - takes the form "1271947500000-attendeestring" 
     1026      // we want the first half, which is the same as the time class associated with the column 
     1027      var splitId = $(this).attr("id").split("-"); 
     1028       
     1029      // set the start of the selection range in milliseconds (first half of the ID) 
     1030      // we will use this to set the start time and to find cells in the same column 
     1031      startSelectionMils = splitId[0]; 
     1032       
     1033      // find the cells (the column) that share the same class 
     1034      $("#bwScheduleTable ." + startSelectionMils).addClass("highlight"); 
     1035       
     1036      // we are now selecting, so highlight as we go 
     1037      selecting = true;           
     1038    } 
     1039  ); 
     1040   
     1041  $("#bwScheduleTable .fbcell").mouseover ( 
     1042    function () { 
     1043      if (selecting) { 
     1044        // get the id of the current cell - takes the form "1271947500000-attendeestring" 
     1045        // we want the first half, which is the same as the time class associated with the column 
     1046        var splitId = $(this).attr("id").split("-"); 
     1047   
     1048        // find the cells (the column) that contain the first half as a class 
     1049        $("#bwScheduleTable ." + splitId[0]).addClass("highlight"); 
     1050      }           
     1051    } 
     1052  ); 
     1053   
     1054  $("#bwScheduleTable .fbcell").mouseup ( 
     1055    function () { 
     1056      // we are no longer selecting 
     1057      selecting = false; 
     1058       
     1059      // get the id of the current cell - takes the form "1271947500000-attendeestring" 
     1060      // we want the first half, which is the same as the time class associated with the column 
     1061      var splitId = $(this).attr("id").split("-"); 
     1062       
     1063      // set the end of the selection range in milliseconds (first half of the ID) 
     1064      // we will use this to set the end time / duration 
     1065      endSelectionMils = splitId[0]; 
     1066       
     1067    } 
     1068  ); 
     1069  */ 
     1070   
     1071  $("#bwScheduleTable #bwAddAttendee").click ( 
     1072    function () { 
     1073      if (this.value == bwAddAttendeeDisp) { 
     1074        this.value = ""; 
     1075      } 
     1076      $(this).addClass("active"); 
     1077      $(this).removeClass("pending"); 
     1078       
     1079      // hide advanced switch, show add button 
     1080      // $("#bwAddAttendeeAdvanced").hide(); 
     1081      changeClass("bwAddAttendeeAdd","visible"); 
     1082      changeClass("bwAddAttendeeFields", "visible"); 
     1083    } 
     1084  ); 
     1085   
     1086  // add attendee box - use jquery UI autocomplete 
     1087  // carddavUrl supplied in bedework.js 
     1088  // var carddavUrlTemp = "/ucalrsrc/themes/bedeworkTheme/javascript/addrbookUsers.js" 
     1089  // var carddavUrlTemp = "/ucalrsrc/themes/bedeworkTheme/javascript/addrbookLocations.js" 
     1090  $("#bwScheduleTable #bwAddAttendee").autocomplete({ 
     1091    minLength: 1, 
     1092    // set the data source, call it, and format the results: 
     1093    source: function(req, include) { 
     1094      // build the address book url; the path to the address book is determined by the 
     1095      // radio button choices in the "add attendee" widget - these are stored on the fly 
     1096      // in the hidden field with id bwCardDavBookPath 
     1097      addrBookUrl = carddavUrl + "?format=json&addrbook=" + $("#bwCardDavBookPath").val(); 
     1098       
     1099      // call the server and push the results into an array "items" 
     1100      $.getJSON(addrBookUrl, req, function(data) { 
     1101        var acResults = ""; 
     1102        if (data != undefined && data.microformats != undefined && data.microformats.vcard != undefined) { 
     1103          acResults = data.microformats.vcard; 
     1104        } 
     1105        var items = []; 
     1106        $.each(acResults, function(i,entry) { 
    9261107           
    927           // get the id of the current cell - takes the form "1271947500000-attendeestring" 
    928           // we want the first half, which is the same as the time class associated with the column 
    929           var splitId = $(this).attr("id").split("-"); 
     1108          // build the label from the full name and email address 
     1109          var curFn = ""; 
     1110          var curEmail = ""; 
     1111          var curLabel = ""; 
     1112          var curKind = ""; 
    9301113           
    931           // set the start of the selection range in milliseconds (first half of the ID) 
    932           // we will use this to set the start time and to find cells in the same column 
    933           var startSelectionMils = splitId[0]; 
    934           var endSelectionMils = Number(startSelectionMils) + Number(durationMils); 
     1114          if (entry.fn != undefined && entry.fn.value != undefined) { 
     1115            curFn = entry.fn.value; 
     1116          }  
    9351117           
    936           // now do the highlighting 
    937           $("#bwScheduleTable .fbcell").each(function(index) { 
    938             var splId = $(this).attr("id").split("-"); 
    939             if (splId[0] >= startSelectionMils && splId[0] < endSelectionMils) { 
    940               $(this).addClass("highlight"); 
     1118          if (entry.kind != undefined && entry.kind.value != undefined) { 
     1119            curKind = entry.kind.value; 
     1120          } 
     1121           
     1122          if (curKind == "group") { 
     1123            if (entry.member != undefined && entry.member.length > 0) { 
     1124              var members = ""; 
     1125              for (var i = 0; i < entry.member.length; i++ ) { 
     1126                members += entry.member[i].value + ","; 
     1127              } 
     1128              members = members.substring(0,members.length-1); 
     1129              var curItem = {label: curFn, value: members}; 
     1130              items.push(curItem); 
    9411131            } 
    942           }); 
    943            
    944           // set the freeTimeIndex to the nearest index for the pickNext/previous buttons 
    945           for (var i = 0; i < bwGrid.freeTime.length; i++) { 
    946             if (Number(bwGrid.freeTime[i]) >= Number(startSelectionMils)) { 
    947               bwGrid.freeTimeIndex = i - 1; // this will make pick previous jump an extra gap after clicking in a busy space, but it makes pick next work correctly in the same circumstance 
    948               if (bwGrid.freeTimeIndex < 0) { 
    949                 bwGrid.freeTimeIndex = 0; 
     1132          } else { 
     1133            // this is probably not enough: we should account for all email addresses if there is no calendar uri 
     1134            if (entry.email != undefined && entry.email[0] != undefined && entry.email[0].value != undefined) { 
     1135              curEmail = entry.email[0].value; 
     1136            } 
     1137            if (curFn != "") { 
     1138              curLabel = curFn + ", " + curEmail; 
     1139            } else { 
     1140              curLabel = curEmail; 
     1141            } 
     1142             
     1143            // use the calendar address uri if available, otherwise use email 
     1144            var curUri = ""; 
     1145            if (entry.caladruri != undefined && entry.caladruri.value != undefined) { 
     1146              curUri = entry.caladruri.value; 
     1147            } 
     1148            if (curUri == "" && entry.email != undefined && entry.email[0] != undefined && entry.email[0].value != undefined) { 
     1149              var curEmail = entry.email[0].value; 
     1150              if (curEmail != "") { 
     1151                curUri = "mailto:" + curEmail; 
    9501152              } 
    951               break; 
     1153            } 
     1154             
     1155            // only add the entry if there is a uri and a label to use 
     1156            if (curUri != "" && curLabel != "") { 
     1157              var curItem = {label: curLabel, value: curUri}; 
     1158              items.push(curItem); 
    9521159            } 
    9531160          } 
    954            
    955           bwGrid.setDateTimeWidgets(startSelectionMils); 
    956    
    957         } 
    958       ); 
    959        
    960       this.updateBookPath = function(path) { 
    961         $("#bwCardDavBookPath").val(path); 
    962       } 
    963        
    964       this.gotoNextRange = function() { 
    965         $("#bwSchedProcessingMsg").show(); 
    966         bwGrid.startRange.addDays(bwGrid.dayRange); 
    967         bwGrid.endRange.addDays(bwGrid.dayRange); 
    968         if (bwGrid.attendees.length) { 
    969           bwGrid.requestFreeBusy(); 
    970         } else { 
    971           bwGrid.display();  
    972         } 
    973       } 
    974        
    975       this.gotoPreviousRange = function() { 
    976         $("#bwSchedProcessingMsg").show(); 
    977         bwGrid.startRange.subtractDays(bwGrid.dayRange); 
    978         bwGrid.endRange.subtractDays(bwGrid.dayRange); 
    979         if (bwGrid.attendees.length) { 
    980           bwGrid.requestFreeBusy(); 
    981         } else { 
    982           bwGrid.display();  
    983         } 
    984       } 
    985  
    986       this.setDateTimeWidgets = function(startMils) { 
    987         // set the values of the date/time widgets on the main and meeting tabs 
    988         var selectedDate = new Date(Number(startMils)); 
    989         var selectedDateStr = selectedDate.getFullYear() + "-" + selectedDate.getMonthFull() + "-" + selectedDate.getDateFull(); 
    990         $("#bwEventWidgetStartDate").val(selectedDateStr); 
    991         $("#bwEventWidgetStartDateSched").val(selectedDateStr); 
    992         // check for ampm or hour24 
    993         if ($("#eventStartDateSchedAmpm").length) { 
    994           // we are using am/pm 
    995           $("#eventStartDateHour").val(selectedDate.getHours12()); 
    996           $("#eventStartDateMinute").val(selectedDate.getMinutesFull()); 
    997           $("#eventStartDateAmpm").val(selectedDate.getAmpm()); 
    998           $("#eventStartDateSchedHour").val(selectedDate.getHours12()); 
    999           $("#eventStartDateSchedMinute").val(selectedDate.getMinutesFull()); 
    1000           $("#eventStartDateSchedAmpm").val(selectedDate.getAmpm()); 
    1001         } else { 
    1002           // we are using hour24 
    1003           $("#eventStartDateHour").val(selectedDate.getHours()); 
    1004           $("#eventStartDateMinute").val(selectedDate.getMinutesFull()); 
    1005           $("#eventStartDateSchedHour").val(selectedDate.getHours()); 
    1006           $("#eventStartDateSchedMinute").val(selectedDate.getMinutesFull()); 
    1007         } 
    1008       }  
    1009        
    1010       /* 
    1011       $("#bwScheduleTable .fbcell").mousedown ( 
    1012         function () { 
    1013           // clear all previous highlighting 
    1014           $("#bwScheduleTable .highlight").removeClass("highlight"); 
    1015            
    1016           // get the id of the current cell - takes the form "1271947500000-attendeestring" 
    1017           // we want the first half, which is the same as the time class associated with the column 
    1018           var splitId = $(this).attr("id").split("-"); 
    1019            
    1020           // set the start of the selection range in milliseconds (first half of the ID) 
    1021           // we will use this to set the start time and to find cells in the same column 
    1022           startSelectionMils = splitId[0]; 
    1023            
    1024           // find the cells (the column) that share the same class 
    1025           $("#bwScheduleTable ." + startSelectionMils).addClass("highlight"); 
    1026            
    1027           // we are now selecting, so highlight as we go 
    1028           selecting = true;           
    1029         } 
    1030       ); 
    1031  
    1032       $("#bwScheduleTable .fbcell").mouseover ( 
    1033         function () { 
    1034           if (selecting) { 
    1035             // get the id of the current cell - takes the form "1271947500000-attendeestring" 
    1036             // we want the first half, which is the same as the time class associated with the column 
    1037             var splitId = $(this).attr("id").split("-"); 
    1038  
    1039             // find the cells (the column) that contain the first half as a class 
    1040             $("#bwScheduleTable ." + splitId[0]).addClass("highlight"); 
    1041           }           
    1042         } 
    1043       ); 
    1044        
    1045       $("#bwScheduleTable .fbcell").mouseup ( 
    1046         function () { 
    1047           // we are no longer selecting 
    1048           selecting = false; 
    1049            
    1050           // get the id of the current cell - takes the form "1271947500000-attendeestring" 
    1051           // we want the first half, which is the same as the time class associated with the column 
    1052           var splitId = $(this).attr("id").split("-"); 
    1053            
    1054           // set the end of the selection range in milliseconds (first half of the ID) 
    1055           // we will use this to set the end time / duration 
    1056           endSelectionMils = splitId[0]; 
    1057            
    1058         } 
    1059       ); 
    1060       */ 
    1061        
    1062       $("#bwScheduleTable #bwAddAttendee").click ( 
    1063         function () { 
    1064           if (this.value == bwAddAttendeeDisp) { 
    1065             this.value = ""; 
    1066           } 
    1067           $(this).addClass("active"); 
    1068           $(this).removeClass("pending"); 
    1069            
    1070           // hide advanced switch, show add button 
    1071           // $("#bwAddAttendeeAdvanced").hide(); 
    1072           changeClass("bwAddAttendeeAdd","visible"); 
    1073           changeClass("bwAddAttendeeFields", "visible"); 
    1074         } 
    1075       ); 
    1076        
    1077       // add attendee box - use jquery UI autocomplete 
    1078       // carddavUrl supplied in bedework.js 
    1079       // var carddavUrlTemp = "/ucalrsrc/themes/bedeworkTheme/javascript/addrbookUsers.js" 
    1080       // var carddavUrlTemp = "/ucalrsrc/themes/bedeworkTheme/javascript/addrbookLocations.js" 
    1081       $("#bwScheduleTable #bwAddAttendee").autocomplete({ 
    1082         minLength: 1, 
    1083         // set the data source, call it, and format the results: 
    1084         source: function(req, include) { 
    1085           // build the address book url; the path to the address book is determined by the 
    1086           // radio button choices in the "add attendee" widget - these are stored on the fly 
    1087           // in the hidden field with id bwCardDavBookPath 
    1088           addrBookUrl = carddavUrl + "?format=json&addrbook=" + $("#bwCardDavBookPath").val(); 
    1089            
    1090           // call the server and push the results into an array "items" 
    1091           $.getJSON(addrBookUrl, req, function(data) { 
    1092             var acResults = ""; 
    1093             if (data != undefined && data.microformats != undefined && data.microformats.vcard != undefined) { 
    1094               acResults = data.microformats.vcard; 
    1095             } 
    1096             var items = []; 
    1097             $.each(acResults, function(i,entry) { 
    1098                
    1099               // build the label from the full name and email address 
    1100               var curFn = ""; 
    1101               var curEmail = ""; 
    1102               var curLabel = ""; 
    1103               var curKind = ""; 
    1104                
    1105               if (entry.fn != undefined && entry.fn.value != undefined) { 
    1106                 curFn = entry.fn.value; 
    1107               }  
    1108                
    1109               if (entry.kind != undefined && entry.kind.value != undefined) { 
    1110                 curKind = entry.kind.value; 
    1111               } 
    1112                
    1113               if (curKind == "group") { 
    1114                 if (entry.member != undefined && entry.member.length > 0) { 
    1115                   var members = ""; 
    1116                   for (var i = 0; i < entry.member.length; i++ ) { 
    1117                     members += entry.member[i].value + ","; 
    1118                   } 
    1119                   members = members.substring(0,members.length-1); 
    1120                   var curItem = {label: curFn, value: members}; 
    1121                   items.push(curItem); 
    1122                 } 
    1123               } else { 
    1124                 // this is probably not enough: we should account for all email addresses if there is no calendar uri 
    1125                 if (entry.email != undefined && entry.email[0] != undefined && entry.email[0].value != undefined) { 
    1126                   curEmail = entry.email[0].value; 
    1127                 } 
    1128                 if (curFn != "") { 
    1129                   curLabel = curFn + ", " + curEmail; 
    1130                 } else { 
    1131                   curLabel = curEmail; 
    1132                 } 
    1133                  
    1134                 // use the calendar address uri if available, otherwise use email 
    1135                 var curUri = ""; 
    1136                 if (entry.caladruri != undefined && entry.caladruri.value != undefined) { 
    1137                   curUri = entry.caladruri.value; 
    1138                 } 
    1139                 if (curUri == "" && entry.email != undefined && entry.email[0] != undefined && entry.email[0].value != undefined) { 
    1140                   var curEmail = entry.email[0].value; 
    1141                   if (curEmail != "") { 
    1142                     curUri = "mailto:" + curEmail; 
    1143                   } 
    1144                 } 
    1145                  
    1146                 // only add the entry if there is a uri and a label to use 
    1147                 if (curUri != "" && curLabel != "") { 
    1148                   var curItem = {label: curLabel, value: curUri}; 
    1149                   items.push(curItem); 
    1150                 } 
    1151               } 
    1152             }); 
    1153              
    1154             // pass items to the callback function for display in the autocomplete pulldown 
    1155             include(items); 
    1156           }); 
    1157         } 
     1161        }); 
     1162         
     1163        // pass items to the callback function for display in the autocomplete pulldown 
     1164        include(items); 
    11581165      }); 
    1159        
    1160       // capture the enter key when entering an attendee; 
    1161       // do not submit the form; add the attendee. 
    1162       $("#bwScheduleTable #bwAddAttendee").keypress ( 
    1163           function (e) { 
    1164             if(e.keyCode == 13) { // enter 
    1165               e.preventDefault(); 
    1166               bwGrid.addAttendeeFromGrid(); 
    1167             } 
    1168           } 
    1169         ); 
    1170        
    1171       $("#bwScheduleTable #bwAddAttendeeAdd").click ( 
    1172         function () { 
     1166    } 
     1167  }); 
     1168   
     1169  // capture the enter key when entering an attendee; 
     1170  // do not submit the form; add the attendee. 
     1171  $("#bwScheduleTable #bwAddAttendee").keypress ( 
     1172      function (e) { 
     1173        if(e.keyCode == 13) { // enter 
     1174          e.preventDefault(); 
    11731175          bwGrid.addAttendeeFromGrid(); 
    11741176        } 
    1175       ); 
    1176        
    1177        
    1178       $("#bwScheduleTable .removeAttendee").click ( 
    1179         function () { 
    1180           var i = $("#bwScheduleTable .removeAttendee").index(this); 
    1181           bwGrid.removeAttendee(i); 
    1182         } 
    1183       ); 
    1184        
    1185       // enable or disable an attendee 
    1186       $("#bwScheduleTable input.selectedToggle").click ( 
    1187         function () { 
    1188           var i = $("#bwScheduleTable input.selectedToggle").index(this); 
    1189           if (this.checked) { 
    1190              bwGrid.attendees[i].selected = true; 
    1191           } else { 
    1192              bwGrid.attendees[i].selected = false; 
    1193           } 
    1194            
    1195           bwGrid.display(); 
    1196         } 
    1197       ); 
    1198        
    1199       // now add some interactions between the freebusy control buttons, 
    1200       // the scheduling widget, and the rest of the form. 
    1201        
    1202       // toggle 24 hour mode - can be done with text or with checkbox 
    1203       // checkbox handler: 
    1204       function switchSched24() { 
    1205         if($("#bwSched24HoursCb").is(":checked")) { 
    1206           bwGrid.workday = false; 
    1207         } else { 
    1208           bwGrid.workday = true; 
    1209         } 
    1210         // must unbind the click event from the checkbox or we'll stack up events 
    1211         $("#bwSched24HoursCb").unbind("click", switchSched24); 
    1212         bwGrid.display();  
    1213       } 
    1214       // text handler: checks or unchecks the box 
    1215       function switchSched24Text() { 
    1216         if($("#bwSched24HoursCb").is(":checked")) { 
    1217           $("#bwSched24HoursCb").removeAttr('checked'); 
    1218         } else { 
    1219           $("#bwSched24HoursCb").attr('checked','checked'); 
    1220         } 
    1221         // must unbind the click event from the checkbox or we'll stack up events 
    1222         $("#bwSched24HoursText").unbind("click", switchSched24Text); 
    1223         switchSched24(); 
    1224       } 
    1225       // bind the text and the checkbox to the handlers 
    1226       $("#bwSched24HoursCb").click(switchSched24); 
    1227       $("#bwSched24HoursText").click(switchSched24Text); 
    1228        
    1229       // if we change the main tab's start date, time, or duration, update the meeting tab 
    1230       // and reset the range of the scheduling grid 
    1231       $("#bwEventWidgetStartDate").change(function() { 
    1232         $("#bwEventWidgetStartDateSched").val($("#bwEventWidgetStartDate").val()); 
    1233         bwGrid.startRange = $("#bwEventWidgetStartDate").datepicker("getDate"); 
    1234         bwGrid.endRange = $("#bwEventWidgetStartDate").datepicker("getDate"); 
    1235         bwGrid.endRange.addDays(bwGrid.dayRange); 
    1236         if (bwGrid.attendees.length) { 
    1237           bwGrid.requestFreeBusy(); 
    1238         } else { 
    1239           bwGrid.display();  
    1240         } 
    1241       }); 
    1242        
    1243       $("#eventStartDateHour").change(function() {  
    1244         bwGrid.bwSchedChangeTime("#eventStartDateHour"); 
    1245       }); 
    1246        
    1247       $("#eventStartDateMinute").change(function() {  
    1248         bwGrid.bwSchedChangeTime("#eventStartDateMinute"); 
    1249       }); 
    1250  
    1251       $("#durationDays").change(function() { 
    1252         bwGrid.bwSchedChangeDuration("#durationDays"); 
    1253       }); 
    1254        
    1255       $("#durationHours").change(function() { 
    1256         bwGrid.bwSchedChangeDuration("#durationHours"); 
    1257       }); 
    1258        
    1259       $("#durationMinutes").change(function() { 
    1260         bwGrid.bwSchedChangeDuration("#durationMinutes"); 
    1261       }); 
    1262  
    1263       // if we change the meeting tab's date, time, or duration, update the main tab 
    1264       // and reset the range of the scheduling grid 
    1265       $("#bwEventWidgetStartDateSched").change(function() { 
    1266         $("#bwEventWidgetStartDate").val($("#bwEventWidgetStartDateSched").val()); 
    1267         bwGrid.startRange = $("#bwEventWidgetStartDateSched").datepicker("getDate"); 
    1268         bwGrid.endRange = $("#bwEventWidgetStartDateSched").datepicker("getDate"); 
    1269         bwGrid.endRange.addDays(bwGrid.dayRange); 
    1270         if (bwGrid.attendees.length) { 
    1271           bwGrid.requestFreeBusy(); 
    1272         } else { 
    1273           bwGrid.display();  
    1274         } 
    1275       }); 
    1276        
    1277       $("#eventStartDateSchedHour").change(function() {  
    1278         alert($("#eventStartDateSchedHour").val()); 
    1279         bwGrid.bwSchedChangeTime("#eventStartDateSchedHour"); 
    1280       }); 
    1281        
    1282       $("#eventStartDateSchedMinute").change(function() {  
    1283         bwGrid.bwSchedChangeTime("#eventStartDateSchedMinute"); 
    1284       }); 
    1285        
    1286       $("#durationDaysSched").change(function() { 
    1287         bwGrid.bwSchedChangeDuration("#durationDaysSched"); 
    1288       }); 
    1289        
    1290       $("#durationHoursSched").change(function() { 
    1291         bwGrid.bwSchedChangeDuration("#durationHoursSched"); 
    1292       }); 
    1293        
    1294       $("#durationMinutesSched").change(function() { 
    1295         bwGrid.bwSchedChangeDuration("#durationMinutesSched"); 
    1296       }); 
    1297        
    1298       // after all else, hide the processing message 
    1299       $("#bwSchedProcessingMsg").fadeOut(100); 
    1300  
    1301     } catch (e) { 
    1302       alert(e); 
    1303     } 
    1304      
    1305   }; 
    1306 }; 
     1177      } 
     1178    ); 
     1179   
     1180  $("#bwScheduleTable #bwAddAttendeeAdd").click ( 
     1181    function () { 
     1182      bwGrid.addAttendeeFromGrid(); 
     1183    } 
     1184  ); 
     1185   
     1186   
     1187  $("#bwScheduleTable .removeAttendee").click ( 
     1188    function () { 
     1189      var i = $("#bwScheduleTable .removeAttendee").index(this); 
     1190      bwGrid.removeAttendee(i); 
     1191    } 
     1192  ); 
     1193   
     1194  // enable or disable an attendee 
     1195  $("#bwScheduleTable input.selectedToggle").click ( 
     1196    function () { 
     1197      var i = $("#bwScheduleTable input.selectedToggle").index(this); 
     1198      if (this.checked) { 
     1199         bwGrid.attendees[i].selected = true; 
     1200      } else { 
     1201         bwGrid.attendees[i].selected = false; 
     1202      } 
     1203       
     1204      bwGrid.display(); 
     1205    } 
     1206  ); 
     1207   
     1208  // now add some interactions between the freebusy control buttons, 
     1209  // the scheduling widget, and the rest of the form. 
     1210   
     1211  // toggle 24 hour mode - can be done with text or with checkbox 
     1212  // checkbox handler: 
     1213  function switchSched24() { 
     1214    if($("#bwSched24HoursCb").is(":checked")) { 
     1215      bwGrid.workday = false; 
     1216    } else { 
     1217      bwGrid.workday = true; 
     1218    } 
     1219    bwGrid.display();  
     1220  } 
     1221  // text handler: checks or unchecks the box 
     1222  function switchSched24Text() { 
     1223    if($("#bwSched24HoursCb").is(":checked")) { 
     1224      $("#bwSched24HoursCb").removeAttr('checked'); 
     1225    } else { 
     1226      $("#bwSched24HoursCb").attr('checked','checked'); 
     1227    } 
     1228    switchSched24(); 
     1229  } 
     1230  // bind the text and the checkbox to the handlers 
     1231  $("#bwSched24HoursCb").click(switchSched24); 
     1232  $("#bwSched24HoursText").click(switchSched24Text); 
     1233   
     1234  // if we change the main tab's start date, time, or duration, update the meeting tab 
     1235  // and reset the range of the scheduling grid 
     1236  $("#bwEventWidgetStartDate").change(function(event) { 
     1237    $("#bwEventWidgetStartDateSched").val($("#bwEventWidgetStartDate").val()); 
     1238    bwGrid.startRange = $("#bwEventWidgetStartDate").datepicker("getDate"); 
     1239    bwGrid.endRange = $("#bwEventWidgetStartDate").datepicker("getDate"); 
     1240    bwGrid.endRange.addDays(bwGrid.dayRange); 
     1241    if (bwGrid.attendees.length) { 
     1242      bwGrid.requestFreeBusy(); 
     1243    } else { 
     1244      bwGrid.display(); 
     1245    } 
     1246  }); 
     1247   
     1248  $("#eventStartDateHour").change(function() {  
     1249    bwGrid.bwSchedChangeTime("#eventStartDateHour"); 
     1250  }); 
     1251   
     1252  $("#eventStartDateMinute").change(function() {  
     1253    bwGrid.bwSchedChangeTime("#eventStartDateMinute"); 
     1254  }); 
     1255   
     1256  $("#durationDays").change(function() { 
     1257    bwGrid.bwSchedChangeDuration("#durationDays"); 
     1258  }); 
     1259   
     1260  $("#durationHours").change(function() { 
     1261    bwGrid.bwSchedChangeDuration("#durationHours"); 
     1262  }); 
     1263   
     1264  $("#durationMinutes").change(function() { 
     1265    bwGrid.bwSchedChangeDuration("#durationMinutes"); 
     1266  }); 
     1267   
     1268  // if we change the meeting tab's date, time, or duration, update the main tab 
     1269  // and reset the range of the scheduling grid 
     1270  $("#bwEventWidgetStartDateSched").change(function(event) { 
     1271    $("#bwEventWidgetStartDate").val($("#bwEventWidgetStartDateSched").val()); 
     1272    bwGrid.startRange = $("#bwEventWidgetStartDateSched").datepicker("getDate"); 
     1273    bwGrid.endRange = $("#bwEventWidgetStartDateSched").datepicker("getDate"); 
     1274    bwGrid.endRange.addDays(bwGrid.dayRange); 
     1275    if (bwGrid.attendees.length) { 
     1276      bwGrid.requestFreeBusy(); 
     1277    } else { 
     1278      bwGrid.display();  
     1279    } 
     1280  }); 
     1281   
     1282  $("#eventStartDateSchedHour").change(function() {  
     1283    bwGrid.bwSchedChangeTime("#eventStartDateSchedHour"); 
     1284  }); 
     1285   
     1286  $("#eventStartDateSchedMinute").change(function() {  
     1287    bwGrid.bwSchedChangeTime("#eventStartDateSchedMinute"); 
     1288  }); 
     1289   
     1290  $("#durationDaysSched").change(function() { 
     1291    bwGrid.bwSchedChangeDuration("#durationDaysSched"); 
     1292  }); 
     1293   
     1294  $("#durationHoursSched").change(function() { 
     1295    bwGrid.bwSchedChangeDuration("#durationHoursSched"); 
     1296  }); 
     1297   
     1298  $("#durationMinutesSched").change(function() { 
     1299    bwGrid.bwSchedChangeDuration("#durationMinutesSched"); 
     1300  }); 
     1301}); 
    13071302 
    13081303// Utilities