| 22 | | Ext.each(['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], function(day) { |
| | 60 | // create state brushes |
| | 61 | // tack a random number to the end to avoid clashes |
| | 62 | this.stateBrushName = 'schedule-state-brush-' + Math.round(Math.random() * 10000); |
| | 63 | |
| | 64 | var el1 = createEl(dom, 'div'); |
| | 65 | |
| | 66 | var el2 = createEl(el1, 'div'); |
| | 67 | this.stateBrush = el2; |
| | 68 | el2.id = this.stateBrushName; |
| | 69 | |
| | 70 | // for webkit |
| | 71 | var floatAttr = 'float'; |
| | 72 | if (el2.style.float == undefined) { |
| | 73 | // for firefox |
| | 74 | if (el2.style.cssFloat != undefined) floatAttr = 'cssFloat'; |
| | 75 | // for IE |
| | 76 | if (el2.style.styleFloat != undefined) floatAttr = 'styleFloat'; |
| | 77 | } |
| | 78 | el2.style[floatAttr] = 'right'; |
| | 79 | |
| | 80 | for (var i=0; i < this.states.length; i++) { |
| | 81 | var el3 = createEl(el2, 'input'); |
| | 82 | el3.type = 'radio'; |
| | 83 | el3.value = this.states[i].value; |
| | 84 | el3.name = this.stateBrushName; |
| | 85 | el3.id = this.stateBrushName + '-' + this.states[i].name; |
| | 86 | |
| | 87 | // isn't the first one |
| | 88 | if (i > 0) el3.style.marginLeft = '7px'; |
| | 89 | |
| | 90 | // assume the first is the default state, so make the 2nd one the default brush |
| | 91 | if (i == 1) el3.checked = true; |
| | 92 | |
| | 93 | var el4 = createEl(el2, 'label'); |
| | 94 | el4.appendChild(document.createTextNode(this.states[i].name)); |
| | 95 | el4.htmlFor = el3.id; |
| | 96 | el4.style.backgroundColor = this.states[i].backgroundColor; |
| | 97 | el4.style.borderBottom = '2px solid ' + this.states[i].borderColor; |
| | 98 | el4.style.padding = '2px 3px'; |
| | 99 | el4.style.marginLeft = '3px'; |
| | 100 | } |
| | 101 | |
| | 102 | el1.appendChild(document.createTextNode('Select a state brush:')); |
| | 103 | |
| | 104 | el1.style.marginBottom = '10px'; |
| | 105 | |
| | 106 | // keep the radio buttons separate from the time bars |
| | 107 | createEl(dom, 'div').style.clear = 'both'; |
| | 108 | |
| | 109 | var table = createEl(dom, 'table'); |
| | 110 | table.cellSpacing = 0; |
| | 111 | |
| | 112 | // cache access to cells for easier access later |
| | 113 | this.scheduleCells = { }; |
| | 114 | |
| | 115 | Ext.each(this.daysOfWeek, function(day) { |
| | 116 | var cells = [ ]; |
| | 178 | |
| | 179 | return v; |
| | 180 | }, |
| | 181 | |
| | 182 | onCellClick: function(event, cell) { |
| | 183 | cell.oldValue = cell.currentValue; |
| | 184 | |
| | 185 | this.dragAnchor = null; |
| | 186 | }, |
| | 187 | |
| | 188 | onCellMouseDown: function(event, cell) { |
| | 189 | this.dragAnchor = cell; |
| | 190 | }, |
| | 191 | |
| | 192 | onCellMouseUp: function(event, cell) { |
| | 193 | // if we're dragging... |
| | 194 | if (this.dragAnchor) { |
| | 195 | // set all those between here and the anchor to the new values |
| | 196 | if (cell.hour > this.dragAnchor.hour) |
| | 197 | this.confirmCells(cell.day, this.dragAnchor.hour, cell.hour); |
| | 198 | else if (cell.hour < this.dragAnchor.hour) |
| | 199 | this.confirmCells(cell.day, cell.hour, this.dragAnchor.hour); |
| | 200 | else |
| | 201 | this.confirmCells(cell.day, cell.hour, cell.hour); |
| | 202 | |
| | 203 | this.hideCellLeftTooltip(); |
| | 204 | this.hideCellRightTooltip(); |
| | 205 | this.dragAnchor = null; |
| | 206 | } |
| | 207 | }, |
| | 208 | |
| | 209 | onCellMouseOver: function(event, cell) { |
| | 210 | // LEFT TOOL TIP |
| | 211 | // if it isn't showing and we're dragging, show it. |
| | 212 | // otherwise if dragging, leave it alone unless we're dragging to the left. |
| | 213 | // if we're not dragging, show it. |
| | 214 | var leftTooltipCell = null; |
| | 215 | if (!this.dragAnchor) |
| | 216 | leftTooltipCell = cell; |
| | 217 | else if ((this.dragAnchor && this.isCellLeftTooltipHidden()) || |
| | 218 | (this.dragAnchor && this.dragAnchor.hour > cell.hour)) |
| | 219 | leftTooltipCell = this.dragAnchor; |
| | 220 | |
| | 221 | if (leftTooltipCell) { |
| | 222 | var hour = leftTooltipCell.hour; |
| | 223 | var pm = false; |
| | 224 | |
| | 225 | // convert to 12-hour time |
| | 226 | if (hour >= 12) { |
| | 227 | pm = true; |
| | 228 | if (hour > 12) hour -= 12; |
| | 229 | } |
| | 230 | // change 0 hour to 12am |
| | 231 | else if (hour == 0) { |
| | 232 | hour = 12; |
| | 233 | } |
| | 234 | this.showCellLeftTooltip(hour + ' ' + (pm ? 'pm' : 'am'), leftTooltipCell); |
| | 235 | } |
| | 236 | |
| | 237 | // RIGHT TOOL TIP |
| | 238 | var rightTooltipCell = null; |
| | 239 | if (this.dragAnchor) { |
| | 240 | if (this.dragAnchor.hour == cell.hour) |
| | 241 | this.hideCellRightTooltip(); |
| | 242 | else if (this.dragAnchor.hour > cell.hour && this.isCellRightTooltipHidden()) |
| | 243 | rightTooltipCell = this.dragAnchor; |
| | 244 | else // cell.hour > this.dragAnchor.hour |
| | 245 | rightTooltipCell = cell; |
| | 246 | } |
| | 247 | |
| | 248 | if (rightTooltipCell) { |
| | 249 | var hour = rightTooltipCell.hour; |
| | 250 | var pm = false; |
| | 251 | |
| | 252 | // convert to 12-hour time |
| | 253 | if (hour >= 12) { |
| | 254 | pm = true; |
| | 255 | if (hour > 12) hour -= 12; |
| | 256 | } |
| | 257 | // change 0 hour to 12am |
| | 258 | else if (hour == 0) { |
| | 259 | hour = 12; |
| | 260 | } |
| | 261 | this.showCellRightTooltip(hour + ' ' + (pm ? 'pm' : 'am'), rightTooltipCell); |
| | 262 | } |
| | 263 | |
| | 264 | // preview colour change and |
| | 265 | // revert state for all those on the outer side of the drag if dragging |
| | 266 | if (this.dragAnchor) { |
| | 267 | if (cell.day != this.dragAnchor.day) { |
| | 268 | // dragged into another day. Abort! Abort! |
| | 269 | Ext.each(this.daysOfWeek, function(day) { |
| | 270 | this.revertCells(day, 0, 23); |
| | 271 | }, this); |
| | 272 | this.dragAnchor = null; |
| | 273 | this.hideCellLeftTooltip(); |
| | 274 | this.hideCellRightTooltip(); |
| | 275 | } |
| | 276 | else if (cell.hour > this.dragAnchor.hour) { |
| | 277 | // dragging right |
| | 278 | this.revertCells(cell.day, cell.hour+1, 23); |
| | 279 | this.previewCells(cell.day, this.dragAnchor.hour, cell.hour); |
| | 280 | } |
| | 281 | else if (cell.hour < this.dragAnchor.hour) { |
| | 282 | // dragging left |
| | 283 | this.revertCells(cell.day, 0, cell.hour-1); |
| | 284 | this.previewCells(cell.day, cell.hour, this.dragAnchor.hour); |
| | 285 | } |
| | 286 | else { |
| | 287 | // back to anchor cell |
| | 288 | // don't know if it is from right or left, so revert all except this |
| | 289 | this.revertCells(cell.day, cell.hour+1, 23); |
| | 290 | this.revertCells(cell.day, 0, cell.hour-1); |
| | 291 | } |
| | 292 | } |
| | 293 | else { |
| | 294 | // not dragging, just preview this cell |
| | 295 | this.previewCells(cell.day, cell.hour, cell.hour); |
| | 296 | } |
| | 297 | }, |
| | 298 | |
| | 299 | onCellMouseOut: function(event, cell) { |
| | 300 | if (!this.dragAnchor) |
| | 301 | this.hideCellLeftTooltip(); |
| | 302 | |
| | 303 | // revert state. If new state has been set, old and new will be equal. |
| | 304 | // if dragging, this will be handled by the next mouse over |
| | 305 | if (this.dragAnchor == null && cell.oldValue != cell.currentValue) { |
| | 306 | this.revertCells(cell.day, cell.hour, cell.hour); |
| | 307 | } |
| | 308 | }, |
| | 309 | |
| | 310 | previewCells: function(day, fromHour, toHour) { |
| | 311 | var cells = this.scheduleCells[day]; |
| | 312 | var curBrushValue = this.getCurrentBrushValue(); |
| | 313 | |
| | 314 | if (toHour > cells.length) toHour = cells.length; |
| | 315 | |
| | 316 | for (var i=fromHour; i <= toHour; i++) { |
| | 317 | if (cells[i].currentValue != curBrushValue) { |
| | 318 | cells[i].oldValue = cells[i].currentValue; |
| | 319 | cells[i].currentValue = curBrushValue; |
| | 320 | this.updateCell(cells[i]); |
| | 321 | } |
| | 322 | } |
| | 323 | }, |
| | 324 | |
| | 325 | revertCells: function(day, fromHour, toHour) { |
| | 326 | var cells = this.scheduleCells[day]; |
| | 327 | |
| | 328 | if (toHour > cells.length) toHour = cells.length; |
| | 329 | |
| | 330 | for (var i=fromHour; i <= toHour; i++) { |
| | 331 | cells[i].currentValue = cells[i].oldValue; |
| | 332 | this.updateCell(cells[i]); |
| | 333 | } |
| | 334 | }, |
| | 335 | |
| | 336 | confirmCells: function(day, fromHour, toHour) { |
| | 337 | var cells = this.scheduleCells[day]; |
| | 338 | |
| | 339 | if (toHour > cells.length) toHour = cells.length; |
| | 340 | |
| | 341 | for (var i=fromHour; i <= toHour; i++) { |
| | 342 | if (cells[i].currentValue != cells[i].oldValue) { |
| | 343 | cells[i].oldValue = cells[i].currentValue; |
| | 344 | } |
| | 345 | } |
| | 346 | }, |
| | 347 | |
| | 348 | showCellLeftTooltip: function(text, cell) { |
| | 349 | var tooltip = this.cellLeftTooltip; |
| | 350 | |
| | 351 | if (!tooltip) { |
| | 352 | // no cached left tooltip exists, create one |
| | 353 | tooltip = document.createElement('div'); |
| | 354 | this.cellLeftTooltip = tooltip; |
| | 355 | this.body.dom.appendChild(tooltip); |
| | 356 | tooltip.style.position = 'absolute'; |
| | 357 | tooltip.style.backgroundColor = '#F2F2F2'; |
| | 358 | tooltip.style.border = '1px solid #333333'; |
| | 359 | tooltip.style.padding = '1px 3px'; |
| | 360 | tooltip.style.opacity = 0.8; |
| | 361 | } |
| | 362 | |
| | 363 | // remove all existing children |
| | 364 | while (tooltip.childNodes.length > 0) { |
| | 365 | tooltip.removeChild(tooltip.firstChild); |
| | 366 | } |
| | 367 | // add the requested text |
| | 368 | tooltip.appendChild(document.createTextNode(text)); |
| | 369 | |
| | 370 | // place the tooltip |
| | 371 | Ext.get(tooltip).alignTo(cell, 'br-tr'); |
| | 372 | |
| | 373 | // make it visible |
| | 374 | tooltip.style.visibility = 'visible'; |
| | 375 | }, |
| | 376 | |
| | 377 | hideCellLeftTooltip: function() { |
| | 378 | if (this.cellLeftTooltip) { |
| | 379 | this.cellLeftTooltip.style.visibility = 'hidden'; |
| | 380 | } |
| | 381 | }, |
| | 382 | |
| | 383 | isCellLeftTooltipHidden: function() { |
| | 384 | if (this.cellLeftTooltip) |
| | 385 | return this.cellLeftTooltip.style.visibility == 'hidden'; |
| | 386 | else |
| | 387 | return true; |
| | 388 | }, |
| | 389 | |
| | 390 | showCellRightTooltip: function(text, cell) { |
| | 391 | var tooltip = this.cellRightTooltip; |
| | 392 | |
| | 393 | if (!tooltip) { |
| | 394 | // no cached left tooltip exists, create one |
| | 395 | tooltip = document.createElement('div'); |
| | 396 | this.cellRightTooltip = tooltip; |
| | 397 | this.body.dom.appendChild(tooltip); |
| | 398 | tooltip.style.position = 'absolute'; |
| | 399 | tooltip.style.backgroundColor = '#F2F2F2'; |
| | 400 | tooltip.style.border = '1px solid #333333'; |
| | 401 | tooltip.style.padding = '1px 3px'; |
| | 402 | tooltip.style.opacity = 0.8; |
| | 403 | } |
| | 404 | |
| | 405 | // remove all existing children |
| | 406 | while (tooltip.childNodes.length > 0) { |
| | 407 | tooltip.removeChild(tooltip.firstChild); |
| | 408 | } |
| | 409 | // add the requested text |
| | 410 | tooltip.appendChild(document.createTextNode(text)); |
| | 411 | |
| | 412 | // place the tooltip |
| | 413 | Ext.get(tooltip).alignTo(cell, 'bl-tl'); |
| | 414 | |
| | 415 | // make it visible |
| | 416 | tooltip.style.visibility = 'visible'; |
| | 417 | }, |
| | 418 | |
| | 419 | hideCellRightTooltip: function() { |
| | 420 | if (this.cellRightTooltip) { |
| | 421 | this.cellRightTooltip.style.visibility = 'hidden'; |
| | 422 | } |
| | 423 | }, |
| | 424 | |
| | 425 | isCellRightTooltipHidden: function() { |
| | 426 | if (this.cellRightTooltip) |
| | 427 | return this.cellRightTooltip.style.visibility == 'hidden'; |
| | 428 | else |
| | 429 | return true; |
| | 430 | }, |
| | 431 | |
| | 432 | getConfig: function() { |
| | 433 | var config = [ ]; |
| | 434 | |
| | 435 | for (var i=0; i < 24; i++) { |
| | 436 | var hourConfig = [ 0, 0, 0, 0, 0, 0, 0 ]; |
| | 437 | |
| | 438 | for (var j=0; j < this.daysOfWeek.length; j++) { |
| | 439 | hourConfig[j] = parseInt(this.scheduleCells[this.daysOfWeek[j]][i].currentValue); |
| | 440 | } |
| | 441 | |
| | 442 | config.push(hourConfig); |
| | 443 | } |
| | 444 | |
| | 445 | return config; |
| | 446 | }, |
| | 447 | |
| | 448 | setConfig: function(config) { |
| | 449 | for (var i=0; i < 24; i++) { |
| | 450 | var hourConfig = config[i]; |
| | 451 | |
| | 452 | for (var j=0; j < this.daysOfWeek.length; j++) { |
| | 453 | var cell = this.scheduleCells[this.daysOfWeek[j]][i]; |
| | 454 | cell.currentValue = cell.oldValue = hourConfig[j]; |
| | 455 | this.updateCell(cell); |
| | 456 | } |
| | 457 | } |