Changeset f74371 in indico
- Timestamp:
- 11/08/10 15:47:59 (3 years ago)
- Branches:
- master, burotel, hello-world-walkthrough, ipv6, v0.98-series, v0.98.2, v0.98.3, v0.98b1, v0.98b2, v0.99, 051b2622c51afb171a1dedb46a0df4fbb0cbd02e, 4c7d4152dff271ba5df5a8606605969cab454080
- Children:
- 8968bb
- Parents:
- 6b1cbe
- git-author:
- Nikolche Mihajlovski <nmihajlo@…> (08/17/10 19:58:33)
- git-committer:
- Jose Benito <jose.benito.gonzalez@…> (11/08/10 15:47:59)
- Location:
- indico
- Files:
-
- 2 added
- 17 edited
-
MaKaC/fossils/room.py (modified) (2 diffs)
-
MaKaC/plugins/RoomBooking/default/room.py (modified) (1 diff)
-
MaKaC/rb_location.py (modified) (4 diffs)
-
MaKaC/search/cache.py (modified) (2 diffs)
-
MaKaC/services/implementation/roomBooking.py (modified) (1 diff)
-
MaKaC/services/interface/rpc/handlers.py (modified) (1 diff)
-
MaKaC/webinterface/pages/roomBooking.py (modified) (3 diffs)
-
MaKaC/webinterface/rh/roomBooking.py (modified) (3 diffs)
-
MaKaC/webinterface/tpls/RoomBookingAdminLocation.tpl (modified) (2 diffs)
-
MaKaC/webinterface/tpls/RoomBookingMapOfRooms.tpl (modified) (1 diff)
-
MaKaC/webinterface/tpls/RoomBookingMapOfRoomsWidget.tpl (added)
-
MaKaC/webinterface/urlHandlers.py (modified) (1 diff)
-
MaKaC/webinterface/wcomponents.py (modified) (1 diff)
-
htdocs/css/Default.css (modified) (1 diff)
-
htdocs/css/mapofrooms.css (modified) (4 diffs)
-
htdocs/js/indico/Management/Loader.js (modified) (1 diff)
-
htdocs/js/indico/Management/RoomBookingMapOfRooms.js (added)
-
htdocs/js/indico/RoomBooking/MapOfRooms.js (modified) (6 diffs)
-
htdocs/roomBooking.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
indico/MaKaC/fossils/room.py
r975bdf rf74371 47 47 """ ID of the responsible person for the room """ 48 48 49 def getTipPhotoURL(self): 50 """ URL of the tip photo of the room """ 51 49 52 def isActive(self): 50 53 """ Is the room active? """ … … 61 64 def getMarkerDescription(self): 62 65 """ Room description for the map marker """ 66 67 def needsAVCSetup(self): 68 """ Setup for for audio and video conference """ 69 70 def getAvailableVC(self): 71 """ Available equipment for audio and video conference """ -
indico/MaKaC/plugins/RoomBooking/default/room.py
r975bdf rf74371 413 413 """ Room URL """ 414 414 return str(urlHandlers.UHRoomBookingRoomDetails.getURL(target=self)) 415 #return 'http://indico.cern.ch/roomBooking.py/roomDetails?roomLocation=CERN&roomID=3'416 415 417 416 def getMarkerDescription(self): 418 417 """ Room description for the map marker """ 419 return _("Capacity") + ": %s " % self.capacity + _("people") 418 infos = [] 419 if self.capacity: 420 infos.append("%s %s" % (self.capacity , _("people"))) 421 if self.isReservable: 422 infos.append(_("public")) 423 else: 424 infos.append(_("private")) 425 if self.resvsNeedConfirmation: 426 infos.append(_("needs confirmation")) 427 else: 428 infos.append(_("auto-confirmation")) 429 if self.needsAVCSetup: 430 infos.append(_("video conference")) 431 return ", ".join(infos) 432 433 def getTipPhotoURL(self): 434 """ URL of the tip photo of the room """ 435 from MaKaC.webinterface.urlHandlers import UHRoomPhoto 436 return str(UHRoomPhoto.getURL(self._doGetPhotoId(force=True))) 420 437 421 438 def getIsAutoConfirm(self): -
indico/MaKaC/rb_location.py
r56899a rf74371 47 47 root[_ROOM_BOOKING_LOCATION_LIST] = [ ] 48 48 49 def mapper(src, dest, properties): 50 if isinstance(src, dict) and not isinstance(dest, dict): 51 # map from dictionary keys to object attributes 52 for prop in properties: 53 setattr(dest, prop, src.get(prop, None)) 54 elif not isinstance(src, dict) and isinstance(dest, dict): 55 # map from object attributes to dictionary keys 56 for prop in properties: 57 dest[prop] = getattr(src, prop, None) 58 return dest 59 60 class MapAspect(Persistent, object): 61 """ 62 Map aspect is a structure of data related to a view of a Google Map of rooms. 63 The rooms that are specific to a certain location can be viewed from several aspects. 64 A map aspect can be percieved as a combination of map coordinates and zoom level. 65 """ 66 67 def __str__(self): 68 s = _(""" _("Id"): """) + self.id + "\n" 69 s += _(""" _("Name"): """) + self.name + "\n" 70 return s 71 72 def __cmp__(self, second): 73 return cmp(self.id, second.id) 74 75 id = None # str - aspects's ID 76 name = None # str - aspects's name 77 defaultOnStartup = False # bool - is this aspect the default one on start-up 78 centerLatitude = None # str - the latitude of the aspects's perspective center 79 centerLongitude = None # str - the longitude of the aspects's perspective center 80 zoomLevel = None # str - the zoom level of the aspects's perspective 81 topLeftLatitude = None # str - the latitude of the aspects's left corner 82 topLeftLongitude = None # str - the longitude of the aspects's left corner 83 bottomRightLatitude = None # str - the latitude of the aspects's right corner 84 bottomRightLongitude = None # str - the longitude of the aspects's right corner 85 86 __ATTRIBUTES = ['id', 'name', 'defaultOnStartup', 'centerLatitude', 'centerLongitude', 'zoomLevel', 87 'topLeftLatitude', 'topLeftLongitude', 'bottomRightLatitude', 'bottomRightLongitude'] 88 89 def toDictionary(self): 90 return mapper(self, {}, MapAspect.__ATTRIBUTES) 91 92 def updateFromDictionary(self, aspectDict): 93 return mapper(aspectDict, self, MapAspect.__ATTRIBUTES) 49 94 50 95 class Location( Persistent, object ): … … 84 129 self.factory = factory 85 130 self._avcSupportEmails = [] 131 self._aspects = {} 86 132 87 133 def __str__( self ): … … 181 227 return factories 182 228 229 # Aspects management ==================================================== 230 231 def addAspect(self, aspect): 232 self.aspects[aspect.id] = aspect 233 self._p_changed = 1 234 235 def removeAspect(self, aspectId): 236 del self.aspects[aspectId] 237 self._p_changed = 1 238 239 def getAspect(self, aspectId): 240 return self.aspects[aspectId] 241 242 def getAspects(self): 243 return sorted(self.aspects.values()) 244 245 def _getAspects(self): 246 if getattr(self, '_aspects', None) is None: 247 self._aspects = {} 248 return self._aspects 249 250 aspects = property(_getAspects) 251 183 252 # Properties ============================================================ 184 253 … … 214 283 emailList.remove( email ) 215 284 self._avcSupportEmails = emailList 216 217 285 218 286 """ -
indico/MaKaC/search/cache.py
r30b4d4 rf74371 1 import datetime 2 import os 3 import time 4 1 5 from MaKaC.common.cache import MultiLevelCache, MultiLevelCacheEntry 2 6 … … 49 53 return False 50 54 55 56 class MapOfRoomsCacheEntry(MultiLevelCacheEntry): 57 def __init__(self, query): 58 MultiLevelCacheEntry.__init__(self) 59 self._query = query 60 61 def getQuery(self): 62 return self._query 63 64 @classmethod 65 def create(cls, content, query): 66 entry = cls(query) 67 entry.setContent(content) 68 return entry 69 70 class MapOfRoomsCache(MultiLevelCache): 71 """ 72 Cache that stores the appropriate record numbers for a specific search query, 73 in order to allow users to browse map of rooms 74 """ 75 76 _entryFactory = MapOfRoomsCacheEntry 77 78 def __init__(self): 79 super(MapOfRoomsCache, self).__init__('mapOfRooms') 80 self._ttl = 5 81 82 def _generateFileName(self, entry, version): 83 return '%s_%s' % (entry.getQuery(), version) 84 85 def _generatePath(self, entry): 86 return ['maps'] 87 88 def isDirty(self, path, object): 89 creationTime = datetime.datetime(*time.localtime(os.path.getmtime(path))[:6]) 90 return datetime.datetime.now() - creationTime > datetime.timedelta(minutes=self._ttl) -
indico/MaKaC/services/implementation/roomBooking.py
r310d46 rf74371 215 215 216 216 return _( "Warning: holidays chosen" ) 217 218 class RoomBookingMapBase( ServiceBase ): 219 def _param(self, parameterName): 220 try: 221 return self._params[parameterName] 222 except: 223 from MaKaC.services.interface.rpc.common import ServiceError 224 raise ServiceError("ERR-RB0", "Invalid %s." % parameterName) 225 226 class RoomBookingMapCreateAspect(RoomBookingMapBase): 227 228 def _checkParams( self ): 229 self._location = Location.parse(self._param("location")) 230 self._aspect = self._param("aspect") 231 232 def _getAnswer( self ): 233 aspect = MapAspect() 234 aspect.updateFromDictionary(self._aspect) 235 self._location.addAspect(aspect) 236 return {} 237 238 class RoomBookingMapUpdateAspect(RoomBookingMapBase): 239 240 def _checkParams( self ): 241 self._location = Location.parse(self._param("location")) 242 self._aspect = self._param("aspect") 243 244 def _getAnswer( self ): 245 aspect = self._location.getAspect(self._aspect['id']) 246 aspect.updateFromDictionary(self._aspect) 247 return {} 248 249 class RoomBookingMapRemoveAspect(RoomBookingMapBase): 250 251 def _checkParams( self ): 252 self._location = Location.parse(self._param("location")) 253 self._aspectId = self._param("aspectId") 254 255 def _getAnswer( self ): 256 self._location.removeAspect(self._aspectId) 257 return {} 258 259 class RoomBookingMapListAspects(RoomBookingMapBase): 260 261 def _checkParams( self ): 262 self._location = Location.parse(self._param("location")) 263 264 def _getAnswer( self ): 265 return [aspect.toDictionary() for aspect in self._location.getAspects()] 266 -
indico/MaKaC/services/interface/rpc/handlers.py
r064d40 rf74371 21 21 "roomBooking.locationsAndRooms.list" :roomBooking.RoomBookingListLocationsAndRooms, 22 22 "roomBooking.getDateWarning" :roomBooking.GetDateWarning, 23 24 "roomBooking.mapaspects.create": roomBooking.RoomBookingMapCreateAspect, 25 "roomBooking.mapaspects.update": roomBooking.RoomBookingMapUpdateAspect, 26 "roomBooking.mapaspects.remove": roomBooking.RoomBookingMapRemoveAspect, 27 "roomBooking.mapaspects.list": roomBooking.RoomBookingMapListAspects, 23 28 24 29 "resources.timezones.getAll": resources.GetTimezones, -
indico/MaKaC/webinterface/pages/roomBooking.py
r975bdf rf74371 23 23 import MaKaC.webinterface.wcomponents as wcomponents 24 24 from MaKaC.webinterface.pages.main import WPMainBase 25 from MaKaC.webinterface.pages.base import WPNotDecorated 25 26 from MaKaC.rb_location import CrossLocationDB 26 27 import MaKaC.common.info as info … … 223 224 class WPRoomBookingMapOfRooms(WPRoomBookingBase): 224 225 225 def __init__(self, rh):226 WPRoomBookingBase.__init__(self, rh)227 self._rh = rh228 self.addExtraCSSFile('mapofrooms.css')229 230 def getJSFiles(self):231 return WPRoomBookingBase.getJSFiles(self) + \232 self._includeJSPackage('RoomBooking')233 234 226 def _getTitle(self): 235 227 return WPRoomBookingBase._getTitle(self) + " - " + _("Map of rooms") … … 239 231 240 232 def _getBody(self, params): 241 wc = wcomponents.WRoomBookingMapOfRooms(self._rh) 233 wc = wcomponents.WRoomBookingMapOfRooms() 234 return wc.getHTML(params) 235 236 class WPRoomBookingMapOfRoomsWidget(WPNotDecorated): 237 238 def __init__(self, rh, aspects, buildings, defaultLocation, forVideoConference): 239 WPNotDecorated.__init__(self, rh) 240 self._aspects = aspects 241 self._buildings = buildings 242 self._defaultLocation = defaultLocation 243 self._forVideoConference = forVideoConference 244 self.addExtraCSSFile('mapofrooms.css') 245 246 def getJSFiles(self): 247 return WPNotDecorated.getJSFiles(self) + \ 248 self._includeJSPackage('RoomBooking') 249 250 def _getTitle(self): 251 return WPNotDecorated._getTitle(self) + " - " + _("Map of rooms") 252 253 def _setCurrentMenuItem(self): 254 self._roomMapOpt.setActive(True) 255 256 def _getBody(self, params): 257 wc = wcomponents.WRoomBookingMapOfRoomsWidget(self._aspects, self._buildings, self._defaultLocation, self._forVideoConference) 242 258 return wc.getHTML(params) 243 259 -
indico/MaKaC/webinterface/rh/roomBooking.py
r975bdf rf74371 45 45 from MaKaC import plugins 46 46 from MaKaC.plugins.RoomBooking.default.reservation import ResvHistoryEntry 47 from MaKaC.search.cache import MapOfRoomsCache 47 48 48 49 class CandidateDataFrom( object ): … … 669 670 class RHRoomBookingMapOfRooms(RHRoomBookingBase): 670 671 671 def _businessLogic( self ): 672 def _process(self): 673 page = roomBooking_wp.WPRoomBookingMapOfRooms(self) 674 return page.display() 675 676 class RHRoomBookingMapOfRoomsWidget(RHRoomBookingBase): 677 678 def __init__(self, *args, **kwargs): 679 super(RHRoomBookingMapOfRoomsWidget, self).__init__(*args, **kwargs) 680 self._cache = MapOfRoomsCache() 681 682 def _checkParams(self, params): 683 RHRoomBookingBase._checkParams(self, params) 684 685 def _businessLogic(self): 672 686 # get all rooms 673 rooms = RoomBase.getRooms(allFast=True) 687 defaultLocation = Location.getDefaultLocation() 688 rooms = RoomBase.getRooms(location=defaultLocation.friendlyName) 689 aspects = [aspect.toDictionary() for aspect in defaultLocation.getAspects()] 690 691 # specialization for a video conference, CERN-specific 692 possibleEquipment = defaultLocation.factory.getEquipmentManager().getPossibleEquipment() 693 possibleVideoConference = 'Video conference' in possibleEquipment 694 self._forVideoConference = possibleVideoConference and self._getRequestParams().get("avc") == 'y' 674 695 675 696 # break-down the rooms by buildings … … 692 713 693 714 # add the room to its building 694 building['rooms'].append(room.fossilize()) 695 696 # filter the buildings with coordinates and return them 697 buildings_with_coords = [b for b in buildings.values() if b['has_coordinates']] 715 if not self._forVideoConference or room.needsAVCSetup: 716 building['rooms'].append(room.fossilize()) 717 718 # filter the buildings with rooms and coordinates and return them 719 buildings_with_coords = [b for b in buildings.values() if b['rooms'] and b['has_coordinates']] 720 self._defaultLocation = defaultLocation.friendlyName 721 self._aspects = aspects 698 722 self._buildings = buildings_with_coords 699 723 700 724 def _process(self): 701 725 self._businessLogic() 702 p = roomBooking_wp.WPRoomBookingMapOfRooms(self) 703 return p.display() 726 page = roomBooking_wp.WPRoomBookingMapOfRoomsWidget(self, self._aspects, self._buildings, self._defaultLocation, self._forVideoConference) 727 728 params = self._getRequestParams() 729 entry = self._cache.loadObject('', params) 730 if entry: 731 html = entry.getContent() 732 else: 733 html = page.display() 734 self._cache.cacheObject('', html, params) 735 return html 704 736 705 737 # 2. List of ... -
indico/MaKaC/webinterface/tpls/RoomBookingAdminLocation.tpl
r63511f rf74371 139 139 </td> 140 140 </tr> 141 142 <tr><td> </td></tr> 143 <tr> 144 <td class="titleUpCellTD" style="width: 160px;"><span class="titleCellFormat">Room map attributes</span></td> 145 <td bgcolor="white" valign="top" class="blacktext" style="padding-left: 12px;"> 146 <div id="AspectsListHolder"></div> 147 </td> 148 </tr> 149 141 150 </table> 142 151 <br> 143 152 153 <script type="text/javascript"> 154 155 var newAspectsHandler = function(newAspect, setResult) { 156 indicoRequest( 157 'roomBooking.mapaspects.create', 158 { 159 location: '<%=location.friendlyName%>', 160 aspect: newAspect 161 }, 162 function(result,error) { 163 if (!error) { 164 setResult(true); 165 } else { 166 IndicoUtil.errorReport(error); 167 setResult(false); 168 } 169 } 170 ); 171 } 172 173 var editAspectHandler = function(oldAspect, setResult, newAspect) { 174 indicoRequest( 175 'roomBooking.mapaspects.update', 176 { 177 location: '<%=location.friendlyName%>', 178 aspect: newAspect 179 }, 180 function(result,error) { 181 if (!error) { 182 setResult(true); 183 } else { 184 IndicoUtil.errorReport(error); 185 setResult(false); 186 } 187 } 188 ); 189 } 190 191 var removeAspectHandler = function(aspect, setResult) { 192 indicoRequest( 193 'roomBooking.mapaspects.remove', 194 { 195 location: '<%=location.friendlyName%>', 196 aspectId: aspect.get('id') 197 }, 198 function(result,error) { 199 if (!error) { 200 setResult(true); 201 } else { 202 IndicoUtil.errorReport(error); 203 setResult(false); 204 } 205 } 206 ); 207 } 208 indicoRequest( 209 'roomBooking.mapaspects.list', 210 { 211 location: '<%= location.friendlyName %>' 212 }, 213 function(result,error) { 214 if (!error) { 215 var aspectsListField = new MapAspectListField('AspectsListDiv', 'PeopleList', result, 216 newAspectsHandler, editAspectHandler, removeAspectHandler); 217 $E('AspectsListHolder').set(aspectsListField.draw()); 218 } else { 219 IndicoUtil.errorReport(error); 220 } 221 } 222 ); 223 224 </script> 144 225 145 226 <!-- ============== Key Performance Indicators ================= --> … … 238 319 </tr> 239 320 </table> 321 -
indico/MaKaC/webinterface/tpls/RoomBookingMapOfRooms.tpl
r975bdf rf74371 1 <table id="map_table"> 2 <tr> 3 <td id="map_table_left"> 4 <div id="positions_canvas"></div> 5 <div id="map_canvas"></div> 6 </td> 7 <td id="map_table_right"> 8 <div id="filter_canvas"></div> 9 </td> 10 </tr> 11 </table> 12 13 <script type="text/javascript"> 14 15 var positions = [ 16 {'lat':46.23456689405093, 'lon':6.046686172485352, 'zoom':15, 'name':'Meyrin', 'isDefault':true}, 17 {'lat':46.259051447415175, 'lon':6.057773351931246, 'zoom':15, 'name':'PREVESSIN'}, 18 {'lat':46.23573201283012, 'lon':6.054509639707248, 'zoom':17, 'name':'POINT 1'}, 19 {'lat':46.25115822762375, 'lon':6.020456314054172, 'zoom':17, 'name':'POINT 2'}, 20 {'lat':46.30958858268458, 'lon':6.077267646724067, 'zoom':17, 'name':'POINT 5'}, 21 {'lat':46.29345231426436, 'lon':6.1115119456917455, 'zoom':17, 'name':'POINT 6'}, 22 {'lat':46.24158691675184, 'lon':6.097038745847385, 'zoom':17, 'name':'POINT 8'} 23 ]; 24 var buildings = <%= jsonEncode(buildings) %>; 25 26 IndicoUI.executeOnLoad(function(){ 27 var roomMap = new RoomMap($E('map_canvas').dom, $E('positions_canvas').dom, positions, buildings); 28 }); 29 30 </script> 1 <iframe src="<%= mapOfRoomsWidgetURL %>" 2 frameborder="0" 3 width="100%%" 4 height="600px" 5 style="margin-top: -10px;"> 6 </iframe> -
indico/MaKaC/webinterface/urlHandlers.py
r975bdf rf74371 302 302 class UHRoomBookingMapOfRooms( URLHandler ): 303 303 _relativeURL = "roomBooking.py/mapOfRooms" 304 305 class UHRoomBookingMapOfRoomsWidget( URLHandler ): 306 _relativeURL = "roomBooking.py/mapOfRoomsWidget" 304 307 305 308 class UHRoomBookingWelcome( URLHandler ): -
indico/MaKaC/webinterface/wcomponents.py
r975bdf rf74371 6120 6120 class WRoomBookingMapOfRooms(WTemplated): 6121 6121 6122 def __init__(self, rh): 6123 self._rh = rh 6122 def getVars(self): 6123 6124 vars = WTemplated.getVars(self) 6125 vars["mapOfRoomsWidgetURL"] = urlHandlers.UHRoomBookingMapOfRoomsWidget.getURL( None ) 6126 6127 return vars 6128 6129 class WRoomBookingMapOfRoomsWidget(WTemplated): 6130 6131 def __init__(self, aspects, buildings, defaultLocation, forVideoConference): 6132 self._aspects = aspects 6133 self._buildings = buildings 6134 self._defaultLocation = defaultLocation 6135 self._forVideoConference = forVideoConference 6124 6136 6125 6137 def getVars(self): 6126 6138 vars = WTemplated.getVars(self) 6127 6139 6128 vars["buildings"] = self._rh._buildings 6140 vars["aspects"] = self._aspects 6141 vars["buildings"] = self._buildings 6142 vars["defaultLocation"] = self._defaultLocation 6143 vars["forVideoConference"] = self._forVideoConference 6129 6144 6130 6145 return vars -
indico/htdocs/css/Default.css
r8cd77c rf74371 5720 5720 } 5721 5721 5722 div.AspectsListDiv { 5723 margin-bottom: 10px; 5724 height: 100px; 5725 width: 350px; 5726 border: 1px solid #CCCCCC; 5727 overflow: auto; 5728 } 5729 5722 5730 div.PeopleListDiv { 5723 5731 margin-bottom: 10px; -
indico/htdocs/css/mapofrooms.css
r975bdf rf74371 1 .tip p { 2 margin-top: 8px; 3 margin-bottom: 8px; 4 } 5 6 div.caption { 7 padding: 3px; 8 background-color: #F0F0F0 !important; 9 border: 1px solid #888888; 10 border-bottom: none; 11 } 12 1 13 /* Marker info */ 14 15 .mapBuildingInfo { 16 max-height: 300px; 17 overflow-y: auto; 18 } 19 20 .mapRoomInfoLink { 21 border-left: 1px solid #AAAAAA; 22 padding-left: 5px; 23 } 24 25 .mapBookRoomLink { 26 padding-right: 5px; 27 } 2 28 3 29 #filter_canvas { 4 30 width: 200px; 31 padding-left: 10px; 32 } 33 34 .mapFilterTitle { 35 color: #777777; 36 font-size: 15px; 37 margin: 0; 38 padding: 0; 39 font-weight: bold; 40 } 41 42 .mapFilterGroup { 43 padding-left: 20px; 44 } 45 46 .mapFilterTextbox { 47 width: 70px; 48 } 49 50 .mapFilterLabel { 51 color:#444444; 52 font-size:13px; 53 padding-right: 5px; 54 padding-left: 2px; 55 display: inline-block; 56 min-width: 70px; 57 } 58 59 .mapRoomTooltipTitle { 60 font-weight: bold; 61 padding-left: 3px; 62 } 63 64 .mapRoomTooltipImage { 65 padding-left: 8px; 66 padding-right: 8px; 67 } 68 69 .mapRoomTooltipDescription { 70 padding-left: 8px; 71 padding-right: 8px; 72 } 73 74 .mapResultsInfo { 75 font-weight: bold; 76 font-size: 12px; 77 } 78 79 #mapFilterBox { 80 float: none; 81 margin-top: -27px; 82 margin-left: 10px; 83 width: 210px; 84 } 85 86 #mapFilterContentBox { 87 padding-right: 10px; 88 padding-left: 5px; 89 } 90 91 #filter_canvas { 92 margin-top: -3px; 93 } 94 95 #filter_canvas p { 96 margin-top: 10px; 97 margin-bottom: 10px; 98 } 99 .mapBuildingTitle { 100 font-weight: bold; 101 } 102 103 .mapButton { 104 margin-right: 5px; 105 } 106 107 /* Map table */ 108 109 html, body { 110 margin: 0 auto; 111 height: 100%; 112 } 113 114 #map_table { 115 width: 99%; 116 height: 90%; 117 } 118 119 #map_cell { 120 width: 100%; 121 height:100%; 122 } 123 124 #map_canvas { 125 width: 100%; 126 height:100%; 5 127 } 6 128 … … 11 133 #map_table_left { 12 134 width: 100%; 13 }14 15 #map_canvas {16 width: 100%;17 height: 600px;18 }19 20 #map_table {21 width: 100%;22 }23 24 .mapBuildingTitle {25 font-weight: bold;26 135 } 27 136 … … 37 146 38 147 ul.mapAspectsList li { 148 position: relative; 149 padding-right: 5px; 150 padding-left: 5px; 151 border-right: 1px solid #AAAAAA; 152 } 153 154 ul.mapAspectsList li.browserIE7 { 39 155 display: inline; 40 position: relative; 41 padding-right: 15px; 42 padding-left: 15px; 43 border-right: 1px solid #AAAAAA;156 } 157 158 ul.mapAspectsList li.browserDefault { 159 display: inline-table; 44 160 } 45 161 46 162 ul.mapAspectsList a { 47 163 font-family: Verdana; 48 font-size: 1 6px;164 font-size: 13px; 49 165 font-weight: bold; 50 166 cursor: pointer; … … 53 169 ul.mapAspectsList a:hover { 54 170 color: #dbb03a !important; 171 } 172 173 .mapAspectsItem { 174 white-space: nowrap; 55 175 } 56 176 -
indico/htdocs/js/indico/Management/Loader.js
r9033fd rf74371 4 4 include(ScriptRoot + "indico/Management/eventCreation.js"); 5 5 include(ScriptRoot + "indico/Management/Timetable.js"); 6 include(ScriptRoot + "indico/Management/RoomBookingMapOfRooms.js"); -
indico/htdocs/js/indico/RoomBooking/MapOfRooms.js
r975bdf rf74371 1 // include the Google Maps API 2 mapsKey = "ABQIAAAAma3utMfjLLhSmsMwYFxuOxQw5QZGSL2Qh09zAqNyDcYBVXi0OBTBnNqS2Hl5cVWGNuhE9BATvtEqyA"; 3 include("http://maps.google.com/maps?file=api&v=2&key=" + mapsKey); 1 include("http://maps.google.com/maps/api/js?sensor=false"); 4 2 5 3 /** … … 8 6 type ("RoomMap", ["IWidget"], 9 7 { 10 initialize: function(mapCanvas, aspectsCanvas, aspects, buildings) { 11 if (GBrowserIsCompatible()) { 12 this.createMap(mapCanvas); 13 this.createAspectChangeLinks(aspectsCanvas, aspects); 14 this.createMarkers(buildings); 15 } else { 16 this.showNotCompatible(mapCanvas); 8 initialize: function(mapCanvas, aspectsCanvas, filterCanvas, aspects, buildings, filters) { 9 this.initData(aspects, buildings, filters); 10 this.createMap(mapCanvas); 11 this.initializeBounds(); 12 this.createAspectChangeLinks(aspectsCanvas); 13 this.createBuildingMarkers(); 14 this.createFilters(filterCanvas); 15 this.setDefaultFilterValues(); 16 this.updateFiltersState(); 17 this.filterMarkers(); 18 }, 19 20 initData: function(aspects, buildings, filters) { 21 this.aspects = aspects; 22 this.buildings = buildings; 23 this.filters = filters; 24 25 // save a reference to the building number filter 26 for (var i = 0; i < filters.length; i++) { 27 var filter = filters[i]; 28 if (filter.filterType == 'building' && filter.property == 'number') { 29 this.buildingNumberFilter = filter; 30 } 17 31 } 18 32 }, 19 33 20 34 createMap: function(mapCanvas) { 35 this.markers = []; 36 37 // map options 38 var options = { 39 zoom: 17, 40 mapTypeId: google.maps.MapTypeId.HYBRID 41 }; 42 21 43 // Google Maps API setup 22 this.map = new GMap2(mapCanvas); 23 this.map.setMapType(G_HYBRID_MAP); 24 this.map.setUIToDefault(); 25 this.map.enableDoubleClickZoom(); 26 }, 27 28 createInfoMarker: function(point, info) { 29 var marker = new GMarker(point); 30 31 // when the marker is clicked, open the info window 32 GEvent.addListener(marker, "click", function() { 33 marker.openInfoWindowHtml(info); 34 }); 35 36 return marker; 44 this.map = new google.maps.Map(mapCanvas, options); 45 google.maps.event.addListener(this.map, "click", this.createMapClickHandler()); 46 }, 47 48 createMapClickHandler: function() { 49 var self = this; 50 return function() { 51 self.closeTooltips(); 52 self.closeInfoBaloon(); 53 } 54 }, 55 56 createBuildingMarkers: function() { 57 for (var i in this.buildings) { 58 var building = this.buildings[i]; 59 building.point = new google.maps.LatLng(building.latitude, building.longitude); 60 61 // create marker for the building 62 var marker = new google.maps.Marker({ 63 position: building.point, 64 map: this.map, 65 visible: false 66 }); 67 68 // the building and marker reference each-other 69 marker.building = building; 70 building.marker = marker; 71 72 // when the marker is clicked, open the info window 73 marker.onClick = this.createMarkerClickHandler(marker); 74 google.maps.event.addListener(marker, "click", marker.onClick); 75 76 this.markers.push(marker); 77 } 78 }, 79 80 createMarkerClickHandler: function(marker) { 81 var self = this; 82 return function() { 83 // it the info baloon is shown for a first time, create it 84 if (!exists(marker.infoWindow)) { 85 var info = self.createBuildingInfo(marker.building); 86 marker.infoWindow = new google.maps.InfoWindow({content: info}); 87 } 88 89 // closed the tooltips and info baloon 90 self.closeInfoBaloon(); 91 self.closeTooltips(); 92 93 // show the info baloon 94 self.activeInfoWindow = marker.infoWindow; 95 marker.infoWindow.open(self.map, marker); 96 } 97 }, 98 99 closeInfoBaloon: function() { 100 // if a info baloon is shown, close it 101 if (exists(this.activeInfoWindow)) { 102 this.activeInfoWindow.close(); 103 this.activeInfoWindow = null; 104 } 105 }, 106 107 closeTooltips: function() { 108 domTT_closeAll(); 37 109 }, 38 110 … … 40 112 // unselect the previous selected link (if any) 41 113 if (this.selectedLink) { 42 this.selectedLink.dom.className = 'mapAspectUnselected';114 this.selectedLink.dom.className = this.constructAspectCss(false); 43 115 } 44 116 45 117 // select the clicked link 46 118 this.selectedLink = link; 47 link.dom.className = 'mapAspectSelected';119 link.dom.className = this.constructAspectCss(true); 48 120 }, 49 121 50 122 createAspectChangeFunction: function(aspect, link) { 51 setSelectedAspectStyle = this.setSelectedAspectStyle;52 map = this.map;123 var self = this; 124 // execute this every time the user clicks on some aspect and changes the visible map area 53 125 return function() { 54 map.setCenter(new GLatLng(aspect.lat, aspect.lon), aspect.zoom); 55 setSelectedAspectStyle(link); 56 } 57 }, 58 59 createAspectChangeLinks: function(aspectsCanvas, aspects) { 126 self.closeTooltips(); 127 self.map.setCenter(new google.maps.LatLng(aspect.centerLatitude, aspect.centerLongitude)); 128 self.map.setZoom(parseInt(aspect.zoomLevel)); 129 self.setSelectedAspectStyle(link); 130 } 131 }, 132 133 constructBrowserSpecificCss: function() { 134 return this.isBrowserIE7() ? 'browserIE7' : 'browserDefault'; 135 }, 136 137 constructAspectCss: function (selected) { 138 var selectionClass = selected ? 'mapAspectSelected' : 'mapAspectUnselected'; 139 return 'mapAspectsItem ' + selectionClass; 140 }, 141 142 createAspectChangeLinks: function(aspectsCanvas) { 60 143 var links = Html.ul({className:'mapAspectsList'}).dom; 61 for (var i = 0; i < aspects.length; i++) {62 aspect =aspects[i];144 for (var i = 0; i < this.aspects.length; i++) { 145 var aspect = this.aspects[i]; 63 146 64 147 // construct a link that changes the map aspect if clicked 65 var link = Html.a({'href': '#', className:'mapAspectUnselected'}, aspect.name);66 var itemClassName = i == 0 ? 'first ' : i == aspects.length - 1 ? 'last' : '';67 var item = Html.li({className:itemClassName }, link.dom);148 var link = Html.a({'href': '#', className: this.constructAspectCss(false)}, aspect.name); 149 var itemClassName = i == 0 ? 'first ' : i == this.aspects.length - 1 ? 'last ' : ''; 150 var item = Html.li({className:itemClassName + this.constructBrowserSpecificCss()}, link.dom); 68 151 var aspectChangeFunction = this.createAspectChangeFunction(aspect, link); 69 152 153 // store the link for the aspect 154 aspect.link = link; 155 70 156 // if the aspect is a default one, apply it on start 71 if (aspect. isDefault) {157 if (aspect.defaultOnStartup) { 72 158 aspectChangeFunction(); 73 159 } … … 82 168 83 169 createRoomInfo: function(building, room) { 84 // info format: [link with room address] - [description of the room]170 var self = this; 85 171 var address = building.number + '/' + room.floor + '-' + room.roomNr; 86 var link = Html.a({href:room.url, className:'mapRoomLink'}, address).dom; 87 var desc = Html.span({className:'mapRoomDescription'}, room.markerDescription).dom; 88 89 roomInfo = Html.p({className:'mapRoomInfo'}, link, ' - ', desc); 172 var caption = "Room " + address; 173 174 // room address 175 var addr = Html.span({className:'mapRoomAddress'}, address).dom; 176 177 // "Book" link 178 var book = Html.a({href:room.url, className:'mapBookRoomLink'}, "Book"); 179 180 // "More" link - for room details 181 var more = Html.a({href:"#", className:'mapRoomInfoLink'}, "More..."); 182 183 // room details elements 184 var title = Html.div({className: 'mapRoomTooltipTitle'}, caption); 185 var img = Html.img({src: room.tipPhotoURL, width: 212, height: 140, className: 'mapRoomTooltipImage'}); 186 var desc = Html.div({className: 'mapRoomTooltipDescription'}, room.markerDescription); 187 var all = Widget.lines([img, desc]); 188 var help = Html.div({className: 'tip'}, all.dom); 189 190 // when the "More" link is clicked, show a tooltip with room details 191 more.observeClick(function(event) { 192 self.closeTooltips(); 193 domTT_activate(more.dom, event, 'content', help.dom, 'maxWidth', 223, 'type', 'sticky', 'caption', title.dom, 'closeLink', ' x '); 194 }); 195 196 var roomInfo = Html.p({className:'mapRoomInfo'}, addr, ' - ', book.dom, more.dom); 90 197 return roomInfo.dom; 91 198 }, … … 101 208 for (var j = 0; j < building.rooms.length; j++) { 102 209 var room = building.rooms[j]; 103 var roomInfo = this.createRoomInfo(building, room); 104 roomsInfo.appendChild(roomInfo); 105 } 106 210 if (room.showOnMap) { 211 var roomInfo = this.createRoomInfo(building, room); 212 roomsInfo.appendChild(roomInfo); 213 } 214 } 215 216 // building info box 107 217 var buildingInfo = Html.div({className:'mapBuildingInfo'}, title, roomsInfo); 108 218 return buildingInfo.dom; 109 219 }, 110 220 111 createMarkers: function(buildings) { 112 for (var i = 0; i < buildings.length; i++) { 113 var building = buildings[i]; 114 115 // initialize the marker aspect and info 116 var pos = new GLatLng(building.latitude, building.longitude); 117 var info = this.createBuildingInfo(building); 118 119 // construct the marker and add it to the map overlay 120 var marker = this.createInfoMarker(pos, info); 121 this.map.addOverlay(marker); 122 } 123 }, 124 125 showNotCompatible: function(mapCanvas) { 126 var info = Html.div({}, "Your browser is not compatible with Google Maps!").dom; 127 mapCanvas.appendChild(info); 128 }, 221 showMarkers: function() { 222 var bounds = this.map.getBounds(); 223 var inBoundsCount = 0; 224 225 // 'alone' building - a bulding that is displayed alone on the screen 226 var aloneBuilding = null; 227 228 // 'exact' building - a building whose number was entered in the building filter 229 var exactBuilding = null; 230 231 // if a building number filter exists, get its value 232 var exactBuildingNumber = null; 233 if (this.buildingNumberFilter) { 234 exactBuildingNumber = this.getFilterValue(this.buildingNumberFilter); 235 } 236 237 for (var i = 0; i < this.buildings.length; i++) { 238 var building = this.buildings[i]; 239 this.boundCounters[i] = 0; 240 241 // if the building is filtered as visible on map 242 if (building.showOnMap) { 243 // if only 1 building is visible - that's the 'alone' building 244 if (this.visibleBuildingsCount == 1) { 245 aloneBuilding = building; 246 } 247 248 // if the building number is entered in the building filter, that's the 'exact' building 249 if (exactBuildingNumber != null && building.number == exactBuildingNumber) { 250 exactBuilding = building; 251 } 252 253 // initialize the marker aspect and info 254 var pos = new google.maps.LatLng(building.latitude, building.longitude); 255 256 // count the number of rooms in each of the aspect areas 257 for (var j = 0; j < this.bounds.length; j++) { 258 if (this.bounds[j].contains(pos)) { 259 this.boundCounters[j] += building.visibleRoomsSize; 260 } 261 } 262 } 263 264 // show only the filtered buildings 265 building.marker.setVisible(building.showOnMap); 266 } 267 268 // if an 'exact' building if found, show it in the center of the map 269 if (exactBuilding != null) { 270 var center = new google.maps.LatLng(exactBuilding.latitude, exactBuilding.longitude); 271 this.map.setCenter(center); 272 } 273 274 // if an 'alone' building if found, show its info baloon 275 if (aloneBuilding != null) { 276 aloneBuilding.marker.onClick(); 277 } 278 279 }, 280 281 getFilterPropertyOptions: function(filter) { 282 var options = []; 283 function addOption(option) { 284 if (options.indexOf(option) < 0) options.push(option); 285 } 286 287 for (var i = 0; i < this.buildings.length; i++) { 288 var building = this.buildings[i]; 289 if (filter.filterType == 'building') { 290 addOption(building[filter.property]); 291 } else { 292 for (var j = 0; j < building.rooms.length; j++) { 293 var room = building.rooms[j]; 294 addOption(room[filter.property]); 295 } 296 } 297 } 298 299 return options; 300 }, 301 302 updateFiltersState: function() { 303 for (var i = 0; i < this.filters.length; i++) { 304 var filter = this.filters[i]; 305 306 // the corresponding function calculates if the filter input is enabled (default: yes) 307 filter.enabled = !exists(filter.enabledIf) || filter.enabledIf(this); 308 filter.input.dom.disabled = !filter.enabled; 309 310 // the corresponding function calculates if the filter is active (default: yes) 311 filter.active = !exists(filter.activeIf) || filter.activeIf(this); 312 } 313 }, 314 315 createFilterWidget: function(filter) { 316 // value type 317 var input; 318 if (filter.inputType == 'text' || filter.inputType == 'subtext') { 319 // text input for text and sub-text filters 320 input = Html.input('text', {className: 'mapFilterTextbox'}); 321 } else if (filter.inputType == 'boolean') { 322 // checkbox input for boolean filters 323 input = Html.checkbox({className: 'mapFilterCheckbox'}); 324 } else if (filter.inputType == 'list_contains') { 325 // checkbox input for 'list containts' filters 326 input = Html.checkbox({className: 'mapFilterCheckbox'}); 327 } else if (filter.inputType == 'hidden') { 328 // no input for hidden filters 329 input = null; 330 } else if (filter.inputType == 'combo') { 331 // drop-down box input for combo filters 332 var options = []; 333 var optionValues = this.getFilterPropertyOptions(filter); 334 for (var i = 0; i < optionValues.length; i++) { 335 var optionValue = optionValues[i]; 336 var option = Html.option({value: optionValue}, optionValue); 337 options.push(option); 338 } 339 input = Html.select({className: 'mapFilterCombo'}, options); 340 } 341 342 if (input) { 343 filter.input = input; 344 345 // observe change of the filter inputs 346 var self = this; 347 input.observeKeyPress(function(key) { 348 self.onFiltersInputChanged(); 349 }); 350 input.observeChange(function(key) { 351 self.onFiltersInputChanged(); 352 }); 353 354 // title 355 var label = Html.span({className: 'mapFilterLabel'}, filter.label); 356 357 // layout order 358 var order; 359 if (filter.inputType == 'text' || filter.inputType == 'subtext' || filter.inputType == 'combo') { 360 order = [label, input]; 361 } else { 362 order = [input, label]; 363 } 364 return Widget.inline(order); 365 } else { 366 return null; 367 } 368 }, 369 370 onFiltersInputChanged: function() { 371 this.updateFiltersState(); 372 }, 373 374 setDefaultFilterValue: function(filter) { 375 if (filter.group !== undefined) { 376 if (filter.defaultValue !== undefined) { 377 filter.mainCheckbox.dom.checked = filter.defaultValue; 378 filter.mainCheckbox.dispatchEvent("change"); 379 } 380 for (var i = 0; i < filter.group.length; i++) { 381 this.setDefaultFilterValue(filter.group[i]); 382 } 383 } else { 384 if (filter.defaultValue !== undefined && filter.input) { 385 if (filter.inputType == 'boolean' || filter.inputType == 'list_contains') { 386 filter.input.dom.checked = filter.defaultValue; 387 } else { 388 filter.input.dom.value = filter.defaultValue; 389 } 390 filter.input.dispatchEvent("change"); 391 } 392 } 393 }, 394 395 setDefaultFilterValues: function() { 396 for (var i = 0; i < this.filters.length; i++) { 397 this.setDefaultFilterValue(this.filters[i]); 398 } 399 }, 400 401 createGroupWidget: function(filter) { 402 var widgets = Html.div({className: "mapFilterGroup"}, this.createFilterWidgets(filter.group)); 403 404 var mainCheckbox = Html.checkbox({className: 'mapFilterCheckbox'}); 405 406 function onMainCheckboxClick() { 407 if (mainCheckbox.dom.checked) { 408 IndicoUI.Effect.appear(widgets); 409 } else { 410 IndicoUI.Effect.disappear(widgets); 411 } 412 } 413 414 mainCheckbox.observeChange(onMainCheckboxClick); 415 onMainCheckboxClick(); 416 417 var label = Html.span({className: 'mapFilterLabel'}, filter.label); 418 419 var top = Html.div({}, mainCheckbox, label); 420 421 filter.widgets = widgets; 422 filter.mainCheckbox = mainCheckbox 423 return Html.div({}, top, widgets); 424 }, 425 426 createFilterWidgets: function(filters) { 427 var widgets = []; 428 for (var i = 0; i < filters.length; i++) { 429 var filter = filters[i]; 430 var widget; 431 if (exists(filter.group)) { 432 widget = this.createGroupWidget(filter); 433 } else { 434 widget = this.createFilterWidget(filter); 435 } 436 widgets.push(widget); 437 } 438 return Widget.lines(widgets); 439 }, 440 441 createFilters: function(filterCanvas) { 442 var lines = []; 443 444 var title = Html.div({className: 'mapFilterTitle'}, $T("Search criteria")+":"); 445 lines.push(title); 446 447 var widgets = this.createFilterWidgets(this.filters); 448 lines.push(widgets); 449 450 var self = this; 451 452 var filterButton = Html.button('mapButton', $T("Filter")); 453 filterButton.observeClick(function() { 454 self.filterMarkers(); 455 }); 456 457 var resetButton = Html.button('mapButton', $T("Reset")); 458 resetButton.observeClick(function() { 459 self.setDefaultFilterValues(); 460 self.filterMarkers(); 461 }); 462 463 this.buttons = Html.div({}, filterButton, resetButton); 464 lines.push(this.buttons); 465 466 this.progress = Html.span({}, progressIndicator(true, true)).dom; 467 468 this.resultsInfo = Html.span('mapResultsInfo', ""); 469 lines.push(this.resultsInfo); 470 471 filterCanvas.appendChild(Widget.lines(lines).dom); 472 }, 473 474 matchesCriteria: function(x, criteria) { 475 for (var i = 0; i < criteria.length; i++) { 476 var criterium = criteria[i]; 477 if (!criterium(x)) { 478 return false; 479 } 480 } 481 return true; 482 }, 483 484 filterByCriteria: function(items, criteria) { 485 var count = 0; 486 for (var i = 0; i < items.length; i++) { 487 var item = items[i]; 488 item.showOnMap = this.matchesCriteria(item, criteria); 489 if (item.showOnMap) { 490 count++; 491 } 492 } 493 return count; 494 }, 495 496 filterBuildingsByCriteria: function(buildingCriteria, roomCriteria) { 497 this.filterByCriteria(this.buildings, buildingCriteria); 498 for (var i = 0; i < this.buildings.length; i++) { 499 var building = this.buildings[i]; 500 if (building.showOnMap) { 501 building.visibleRoomsSize = this.filterByCriteria(building.rooms, roomCriteria); 502 this.visibleRoomsCount += building.visibleRoomsSize; 503 if (building.visibleRoomsSize > 0) { 504 this.visibleBuildingsCount++; 505 } else { 506 building.showOnMap = false; 507 } 508 } else { 509 building.visibleRoomsSize = 0; 510 } 511 } 512 }, 513 514 building: function(number) { 515 for (var i = 0; i < this.buildings.length; i++) { 516 var building = this.buildings[i]; 517 if (building.number == number) { 518 return building; 519 } 520 } 521 return null; 522 }, 523 524 filterInput: function(index) { 525 return this.getFilterValue(this.filters[index]); 526 }, 527 528 createPropertyFilter: function(inputType, propertyName, expectedValue) { 529 if (inputType == 'list_contains') { 530 return function(obj) { 531 // search for element in the list 532 return obj[propertyName].indexOf(expectedValue) > -1; 533 } 534 } else if (inputType == 'subtext') { 535 return function(obj) { 536 // search for substring in the string 537 return obj[propertyName].indexOf(expectedValue) > -1; 538 } 539 } else { 540 return function(obj) { 541 return obj[propertyName] == expectedValue; 542 } 543 } 544 }, 545 546 getFilterValue: function(filter) { 547 var value; // the filter value 548 if (filter.inputType == 'boolean') { 549 // boolean value that tells if checkbox is checked 550 value = filter.input.dom.checked; 551 if (value && filter.checkedValue !== undefined) { 552 // if the checkbox is checked, the boolean value can be replaced with arbitrary one 553 value = filter.checkedValue; 554 } else if (value && filter.filterFunction !== undefined) { 555 // for more complex filtering logic, a custom filter function can be specified 556 value = filter.filterFunction; 557 } 558 } else if (filter.inputType == 'list_contains') { 559 // if the checkbox is checked, the filter value is the specified one 560 value = filter.input.dom.checked ? filter.value : ''; 561 } else if (filter.inputType == 'hidden') { 562 value = filter.defaultValue; 563 } else { 564 value = filter.input.dom.value; 565 } 566 return value; 567 }, 568 569 addFilterFunctionToCriteria: function(filter, func, buildingCriteria, roomCriteria) { 570 if (filter.filterType == 'building') { 571 buildingCriteria.push(func); 572 } else { 573 roomCriteria.push(func); 574 } 575 }, 576 577 addFiltersToCriteria: function(filters, buildingCriteria, roomCriteria) { 578 for (var i = 0; i < filters.length; i++) { 579 filter = filters[i]; 580 // check if the filter is a group of filters 581 if (filter.group !== undefined) { 582 var value = filter.mainCheckbox.dom.checked; 583 // the group filter shoud be enabled 584 if (!filter.optional || value) { 585 if (filter.property) { 586 // a filter function that checks the specified property for the specified value 587 var func = this.createPropertyFilter('boolean', filter.property, value); 588 this.addFilterFunctionToCriteria(filter, func, buildingCriteria, roomCriteria); 589 } 590 this.addFiltersToCriteria(filter.group, buildingCriteria, roomCriteria); 591 } 592 } else { 593 var value = this.getFilterValue(filter); 594 if ((!filter.optional || value) && filter.active && filter.enabled) { 595 var func; 596 if (filter.filterFunction) { 597 // the first argument of the custom filter function is the calling instance 598 // specify the calling instance (this) and derivate a proper predicate function 599 func = curry(filter.filterFunction, this); 600 } else { 601 // a filter function that checks the specified property for the specified value 602 func = this.createPropertyFilter(filter.inputType, filter.property, value); 603 } 604 this.addFilterFunctionToCriteria(filter, func, buildingCriteria, roomCriteria); 605 } 606 } 607 } 608 }, 609 610 resetFilteringCycle: function() { 611 this.visibleBuildingsCount = 0; 612 this.visibleRoomsCount = 0; 613 614 // the info balloons whould be re-created after each filtering 615 for (var i = 0; i < this.buildings.length; i++) { 616 var building = this.buildings[i]; 617 building.marker.infoWindow = null; 618 } 619 620 // reset the counters for the aspects (areas) 621 for (var i = 0; i < this.boundCounters.length; i++) { 622 this.boundCounters[i] = 0; 623 } 624 }, 625 626 filterMarkers: function() { 627 this.buttons.dom.appendChild(this.progress); 628 var mapView = this; 629 setTimeout(function() { 630 var buildingCriteria = []; 631 var roomCriteria = []; 632 mapView.resetFilteringCycle(); 633 mapView.closeTooltips(); 634 mapView.closeInfoBaloon(); 635 mapView.addFiltersToCriteria(mapView.filters, buildingCriteria, roomCriteria); 636 mapView.filterBuildingsByCriteria(buildingCriteria, roomCriteria); 637 mapView.showMarkers(); 638 mapView.showResultsInfo(); 639 mapView.updateAspectsInfo(); 640 mapView.buttons.dom.removeChild(mapView.progress); 641 }, 0); 642 }, 643 644 showResultsInfo: function() { 645 var info = $T('Total') + ' ' 646 + this.visibleRoomsCount + ' ' + $T('room(s)') 647 + ' / ' + this.visibleBuildingsCount + ' ' + $T('building(s)'); 648 this.resultsInfo.dom.innerHTML = info; 649 }, 650 651 initializeBounds: function() { 652 this.bounds = []; 653 this.boundCounters = []; 654 for (var i = 0; i < this.aspects.length; i++) { 655 var aspect = this.aspects[i]; 656 657 // initialize the bounds of the area descripbed in the aspect 658 var sw = new google.maps.LatLng(aspect.topLeftLatitude, aspect.topLeftLongitude); 659 var ne = new google.maps.LatLng(aspect.bottomRightLatitude, aspect.bottomRightLongitude); 660 this.bounds.push(new google.maps.LatLngBounds(sw, ne)); 661 662 // initialize the array of counters for the aspect areas 663 this.boundCounters.push(0); 664 } 665 }, 666 667 updateAspectsInfo: function() { 668 for (var i = 0; i < this.aspects.length; i++) { 669 var aspect = this.aspects[i]; 670 var counter = this.boundCounters[i]; 671 aspect.link.dom.innerHTML = aspect.name + " (" + counter + ")"; 672 } 673 }, 674 675 isBrowserIE7: function() { 676 var isIE = window.ActiveXObject ? true : false; 677 var agent = navigator.userAgent.toLowerCase(); 678 return isIE && /msie 7/.test(agent); 679 } 129 680 130 681 }, … … 133 684 * Constructor of the RoomMap 134 685 */ 135 function(mapCanvas, aspectsCanvas, aspects, buildings) { 136 this.initialize(mapCanvas, aspectsCanvas, aspects, buildings); 686 687 function(mapCanvas, aspectsCanvas, filterCanvas, aspects, buildings, filters) { 688 this.initialize(mapCanvas, aspectsCanvas, filterCanvas, aspects, buildings, filters); 137 689 this.values = {}; 138 690 this.extraComponents = []; -
indico/htdocs/roomBooking.py
r975bdf rf74371 34 34 def mapOfRooms(req, **params): 35 35 return roomBooking.RHRoomBookingMapOfRooms(req).process(params) 36 def mapOfRoomsWidget(req, **params): 37 return roomBooking.RHRoomBookingMapOfRoomsWidget(req).process(params) 36 38 37 39 # 2. List of...
Note: See TracChangeset
for help on using the changeset viewer.
