Dashboard sipadu mbip
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

aui-scheduler-view-debug.js 72KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801
  1. AUI.add('aui-scheduler-view', function(A) {
  2. var Lang = A.Lang,
  3. isBoolean = Lang.isBoolean,
  4. isFunction = Lang.isFunction,
  5. isNumber = Lang.isNumber,
  6. isObject = Lang.isObject,
  7. isString = Lang.isString,
  8. toNumber = function(v) {
  9. return parseFloat(v) || 0;
  10. },
  11. roundToNearestMultiple = function(n, multiple) {
  12. return Math.round(n/multiple)*multiple;
  13. },
  14. DateMath = A.DataType.DateMath,
  15. WidgetStdMod = A.WidgetStdMod,
  16. WEEK_LENGTH = DateMath.WEEK_LENGTH,
  17. SCHEDULER_VIEW = 'scheduler-view',
  18. SCHEDULER_VIEW_DAY = 'scheduler-view-day',
  19. SCHEDULER_VIEW_MONTH = 'scheduler-view-month',
  20. SCHEDULER_VIEW_TABLE = 'scheduler-view-table',
  21. SCHEDULER_VIEW_WEEK = 'scheduler-view-week',
  22. ACTIVE_COLUMN = 'activeColumn',
  23. ACTIVE_VIEW = 'activeView',
  24. ALL_DAY = 'allDay',
  25. BODY = 'body',
  26. BOUNDING_BOX = 'boundingBox',
  27. CANCEL = 'cancel',
  28. CLOSE = 'close',
  29. COL = 'col',
  30. COL_DAYS_NODE = 'colDaysNode',
  31. COL_HEADER_DAYS_NODE = 'colHeaderDaysNode',
  32. COLBLANK = 'colblank',
  33. COLDATA = 'coldata',
  34. COLDAY = 'colday',
  35. COLGRID = 'colgrid',
  36. COLSPAN = 'colspan',
  37. COLTIME = 'coltime',
  38. COLUMN_DATA = 'columnData',
  39. COLUMN_DAY_HEADER = 'columnDayHeader',
  40. COLUMN_SHIMS = 'columnShims',
  41. COLUMN_TABLE_GRID = 'columnTableGrid',
  42. COLUMN_TIME = 'columnTime',
  43. CONTAINER = 'container',
  44. CONTENT = 'content',
  45. CREATION_END_DATE = 'creationEndDate',
  46. CREATION_START_DATE = 'creationStartDate',
  47. CURRENT_DATE = 'currentDate',
  48. DATA = 'data',
  49. DAY = 'day',
  50. DAYS = 'days',
  51. DD = 'dd',
  52. DELEGATE = 'delegate',
  53. DELEGATE_CONFIG = 'delegateConfig',
  54. DISABLED = 'disabled',
  55. DISPLAY_DAYS_INTERVAL = 'displayDaysInterval',
  56. DISPLAY_ROWS = 'displayRows',
  57. DIV = 'div',
  58. DIVISION = 'division',
  59. DOTTED = 'dotted',
  60. DOWN = 'down',
  61. DRAG_NODE = 'dragNode',
  62. DRAGGING = 'dragging',
  63. DRAGGING_EVENT = 'draggingEvent',
  64. DURATION = 'duration',
  65. END_DATE = 'endDate',
  66. EVENT = 'event',
  67. EVENT_CLASS = 'eventClass',
  68. EVENT_PLACEHOLDER = 'eventPlaceholder',
  69. EVENT_RECORDER = 'eventRecorder',
  70. EVENT_WIDTH = 'eventWidth',
  71. EVENTS = 'events',
  72. EVENTS_OVERLAY = 'eventsOverlay',
  73. EVENTS_OVERLAY_NODE = 'eventsOverlayNode',
  74. FILTER_FN = 'filterFn',
  75. FIRST = 'first',
  76. FIRST_DAY_OF_WEEK = 'firstDayOfWeek',
  77. FIXED_HEIGHT = 'fixedHeight',
  78. GRID = 'grid',
  79. GRID_CONTAINER = 'gridContainer',
  80. GRIP = 'grip',
  81. HD = 'hd',
  82. HEADER = 'header',
  83. HEADER_DATE_FORMATTER = 'headerDateFormatter',
  84. HEADER_TABLE_NODE = 'headerTableNode',
  85. HEADER_VIEW = 'headerView',
  86. HEADER_VIEW_CONFIG = 'headerViewConfig',
  87. HEADER_VIEW_LABEL_NODE = 'headerViewLabelNode',
  88. HEIGHT = 'height',
  89. HORIZONTAL = 'horizontal',
  90. HOST = 'host',
  91. HOUR_HEIGHT = 'hourHeight',
  92. ICON = 'icon',
  93. ICON = 'icon',
  94. ISO_TIME = 'isoTime',
  95. LABEL = 'label',
  96. LASSO = 'lasso',
  97. LEFT = 'left',
  98. LOCALE = 'locale',
  99. MARGIN_RIGHT = 'marginRight',
  100. MARKER = 'marker',
  101. MARKERCELL = 'markercell',
  102. MARKERCELLS_NODE = 'markercellsNode',
  103. MARKERS = 'markers',
  104. MARKERS_NODE = 'markersNode',
  105. MONTH = 'month',
  106. MONTH_CONTAINER_NODE = 'monthContainerNode',
  107. MONTH_ROW_CONTAINER = 'monthRowContainer',
  108. MONTH_ROWS = 'monthRows',
  109. MORE = 'more',
  110. MOUSEDOWN = 'mousedown',
  111. MOUSEMOVE = 'mousemove',
  112. MOUSEUP = 'mouseup',
  113. NEXT = 'next',
  114. NODE = 'node',
  115. NOMONTH = 'nomonth',
  116. NOSCROLL = 'noscroll',
  117. OFFSET_HEIGHT = 'offsetHeight',
  118. OFFSET_WIDTH = 'offsetWidth',
  119. OVERLAY = 'overlay',
  120. PAD = 'pad',
  121. PADDING_NODE = 'paddingNode',
  122. PARENT_EVENT = 'parentEvent',
  123. PARENT_NODE = 'parentNode',
  124. PROXY = 'proxy',
  125. PROXY_NODE = 'proxyNode',
  126. PX = 'px',
  127. REGION = 'region',
  128. RENDERED = 'rendered',
  129. REPEATED = 'repeated',
  130. RESIZER = 'resizer',
  131. RESIZER_NODE = 'resizerNode',
  132. RESIZING = 'resizing',
  133. RIGHT = 'right',
  134. ROW = 'row',
  135. ROWS_CONTAINER_NODE = 'rowsContainerNode',
  136. SAVE = 'save',
  137. SCHEDULER = 'scheduler',
  138. SCHEDULER_EVENT = 'scheduler-event',
  139. SCROLLABLE = 'scrollable',
  140. SHIM = 'shim',
  141. SHOW_MORE = 'showMore',
  142. START_DATE = 'startDate',
  143. START_XY = 'startXY',
  144. STRINGS = 'strings',
  145. TABLE = 'table',
  146. TABLE_GRID_NODE = 'tableGridNode',
  147. TABLE_NODE = 'tableNode',
  148. TABLE_ROW_CONTAINER = 'tableRowContainer',
  149. TABLE_ROWS = 'tableRows',
  150. TBODY = 'tbody',
  151. TD = 'td',
  152. TIME = 'time',
  153. TIMES_NODE = 'timesNode',
  154. TITLE = 'title',
  155. TL = 'tl',
  156. TODAY = 'today',
  157. TOP = 'top',
  158. TR = 'tr',
  159. VIEW = 'view',
  160. VISIBLE = 'visible',
  161. WEEK = 'week',
  162. WIDTH = 'width',
  163. DATA_COLNUMBER = 'data-colnumber',
  164. ANCHOR = 'a',
  165. COMMA = ',',
  166. DASH = '-',
  167. DOT = '.',
  168. EMPTY_STR = '',
  169. MDASH = '—',
  170. PERCENT = '%',
  171. SPACE = ' ',
  172. getCN = A.getClassName,
  173. CSS_SCHEDULER_VIEW_NOSCROLL = getCN(SCHEDULER_VIEW, NOSCROLL),
  174. CSS_SCHEDULER_VIEW_SCROLLABLE = getCN(SCHEDULER_VIEW, SCROLLABLE);
  175. var SchedulerView = A.Component.create({
  176. NAME: SCHEDULER_VIEW,
  177. AUGMENTS: [A.WidgetStdMod],
  178. ATTRS: {
  179. bodyContent: {
  180. value: EMPTY_STR
  181. },
  182. eventClass: {
  183. valueFn: function() {
  184. return A.SchedulerEvent;
  185. }
  186. },
  187. filterFn: {
  188. validator: isFunction,
  189. value: function(evt) { return true; }
  190. },
  191. height: {
  192. value: 600
  193. },
  194. isoTime: {
  195. value: false,
  196. validator: isBoolean
  197. },
  198. name: {
  199. value: EMPTY_STR,
  200. validator: isString
  201. },
  202. /**
  203. * The function to format the navigation header date.
  204. *
  205. * @attribute navigationDateFormatter
  206. * @default %A - %d %b %Y
  207. * @type Function
  208. */
  209. navigationDateFormatter: {
  210. value: function(date) {
  211. var instance = this;
  212. var scheduler = instance.get(SCHEDULER);
  213. return A.DataType.Date.format(date, {
  214. format: '%A, %d %B, %Y',
  215. locale: scheduler.get(LOCALE)
  216. });
  217. },
  218. validator: isFunction
  219. },
  220. nextDate: {
  221. getter: 'getNextDate',
  222. readOnly: true
  223. },
  224. prevDate: {
  225. getter: 'getPrevDate',
  226. readOnly: true
  227. },
  228. scheduler: {
  229. lazyAdd: false,
  230. setter: '_setScheduler'
  231. },
  232. scrollable: {
  233. value: true,
  234. validator: isBoolean
  235. },
  236. triggerNode: {
  237. setter: A.one
  238. },
  239. visible: {
  240. value: false
  241. }
  242. },
  243. BIND_UI_ATTRS: [SCROLLABLE],
  244. prototype: {
  245. initializer: function() {
  246. var instance = this;
  247. instance.after('render', instance._afterRender);
  248. },
  249. syncUI: function() {
  250. var instance = this;
  251. instance.syncStdContent();
  252. },
  253. adjustCurrentDate: function() {
  254. var instance = this;
  255. var scheduler = instance.get(SCHEDULER);
  256. var currentDate = scheduler.get(CURRENT_DATE);
  257. scheduler.set(CURRENT_DATE, currentDate);
  258. },
  259. flushViewCache: function() {
  260. },
  261. getNextDate: function() {
  262. },
  263. getPrevDate: function() {
  264. },
  265. getToday: function() {
  266. return DateMath.clearTime(new Date());
  267. },
  268. limitDate: function(date, maxDate) {
  269. var instance = this;
  270. if (DateMath.after(date, maxDate)) {
  271. date = DateMath.clone(maxDate);
  272. }
  273. return date;
  274. },
  275. plotEvents: function() {
  276. },
  277. syncStdContent: function() {
  278. },
  279. syncEventUI: function(evt) {
  280. },
  281. _uiSetCurrentDate: function(val) {
  282. },
  283. _afterRender: function(event) {
  284. var instance = this;
  285. instance.adjustCurrentDate();
  286. instance._uiSetScrollable(
  287. instance.get(SCROLLABLE)
  288. );
  289. },
  290. _setScheduler: function(val) {
  291. var instance = this;
  292. var scheduler = instance.get(SCHEDULER);
  293. if (scheduler) {
  294. instance.removeTarget(scheduler);
  295. }
  296. if (val) {
  297. instance.addTarget(val);
  298. val.after('eventsChange', A.bind(instance.flushViewCache, instance));
  299. }
  300. return val;
  301. },
  302. _uiSetScrollable: function(val) {
  303. var instance = this;
  304. var bodyNode = instance.bodyNode;
  305. if (bodyNode) {
  306. bodyNode.toggleClass(CSS_SCHEDULER_VIEW_SCROLLABLE, val);
  307. bodyNode.toggleClass(CSS_SCHEDULER_VIEW_NOSCROLL, !val);
  308. }
  309. },
  310. _uiSetVisible: function(val) {
  311. var instance = this;
  312. SchedulerView.superclass._uiSetVisible.apply(this, arguments);
  313. if (val && instance.get(RENDERED)) {
  314. instance.adjustCurrentDate();
  315. }
  316. }
  317. }
  318. });
  319. A.SchedulerView = SchedulerView;
  320. var sub = Lang.sub;
  321. var getScrollbarWidth = A.cached(function () {
  322. var doc = A.config.doc,
  323. testNode = doc.createElement('div'),
  324. body = doc.getElementsByTagName('body')[0],
  325. // 0.1 because cached doesn't support falsy refetch values
  326. width = 0.1;
  327. if (body) {
  328. testNode.style.cssText = "position:absolute;visibility:hidden;overflow:scroll;width:20px;";
  329. testNode.appendChild(doc.createElement('p')).style.height = '1px';
  330. body.insertBefore(testNode, body.firstChild);
  331. width = testNode.offsetWidth - testNode.clientWidth;
  332. body.removeChild(testNode);
  333. }
  334. return width;
  335. }, null, 0.1);
  336. var getNodeListHTMLParser = function(selector, sizeCondition) {
  337. return function(srcNode) {
  338. var nodes = srcNode.all(selector);
  339. return (nodes.size() >= sizeCondition) ? nodes : null;
  340. };
  341. },
  342. CSS_ICON = getCN(ICON),
  343. CSS_ICON_GRIP_DOTTED_HORIZONTAL = getCN(ICON, GRIP, DOTTED, HORIZONTAL),
  344. CSS_SCHEDULER_EVENT = getCN(SCHEDULER_EVENT),
  345. CSS_SCHEDULER_EVENT_DISABLED = getCN(SCHEDULER_EVENT, DISABLED),
  346. CSS_SCHEDULER_EVENT_PROXY = getCN(SCHEDULER_EVENT, PROXY),
  347. CSS_SCHEDULER_TODAY = getCN(SCHEDULER, TODAY),
  348. CSS_SCHEDULER_TODAY_HD = getCN(SCHEDULER, TODAY, HD),
  349. CSS_SCHEDULER_VIEW_DAY_COLDATA = getCN(SCHEDULER_VIEW, COLDATA),
  350. CSS_SCHEDULER_VIEW_DAY_COLGRID = getCN(SCHEDULER_VIEW, COLGRID),
  351. CSS_SCHEDULER_VIEW_DAY_GRID = getCN(SCHEDULER_VIEW, GRID),
  352. CSS_SCHEDULER_VIEW_DAY_GRID_CONTAINER = getCN(SCHEDULER_VIEW, GRID, CONTAINER),
  353. CSS_SCHEDULER_VIEW_DAY_RESIZER_ICON = getCN(SCHEDULER_VIEW, DAY, RESIZER, ICON),
  354. CSS_SCHEDULER_VIEW_DAY_RESIZER = getCN(SCHEDULER_VIEW, DAY, RESIZER),
  355. CSS_SCHEDULER_VIEW_DAY_MARKER_DIVISION = getCN(SCHEDULER_VIEW, MARKER, DIVISION),
  356. CSS_SCHEDULER_VIEW_DAY_MARKERCELL = getCN(SCHEDULER_VIEW, MARKERCELL),
  357. CSS_SCHEDULER_VIEW_DAY_MARKERS = getCN(SCHEDULER_VIEW, MARKERS),
  358. CSS_SCHEDULER_VIEW_DAY_TABLE = getCN(SCHEDULER_VIEW, DAY, TABLE),
  359. CSS_SCHEDULER_VIEW_DAY_HEADER_TABLE = getCN(SCHEDULER_VIEW, DAY, HEADER, TABLE),
  360. CSS_SCHEDULER_VIEW_DAY_HEADER_DAY = getCN(SCHEDULER_VIEW, DAY, HEADER, DAY),
  361. CSS_SCHEDULER_VIEW_DAY_HEADER_DAY_PAD_RIGHT = getCN(SCHEDULER_VIEW, DAY, HEADER, DAY, PAD, RIGHT),
  362. CSS_SCHEDULER_VIEW_DAY_HEADER_DAY_FIRST = getCN(SCHEDULER_VIEW, DAY, HEADER, DAY, FIRST),
  363. CSS_SCHEDULER_VIEW_DAY_HEADER_COL = getCN(SCHEDULER_VIEW, DAY, HEADER, COL),
  364. CSS_SCHEDULER_VIEW_DAY_HEADER_VIEW_LABEL = getCN(SCHEDULER_VIEW, DAY, HEADER, VIEW, LABEL),
  365. CSS_SCHEDULER_VIEW_DAY_TABLE_COL = getCN(SCHEDULER_VIEW, DAY, TABLE, COL),
  366. CSS_SCHEDULER_VIEW_DAY_TABLE_COL_SHIM = getCN(SCHEDULER_VIEW, DAY, TABLE, COL, SHIM),
  367. CSS_SCHEDULER_VIEW_DAY_TABLE_COLBLANK = getCN(SCHEDULER_VIEW, DAY, TABLE, COLBLANK),
  368. CSS_SCHEDULER_VIEW_DAY_TABLE_COLDAY = getCN(SCHEDULER_VIEW, DAY, TABLE, COLDAY),
  369. CSS_SCHEDULER_VIEW_DAY_TABLE_COLTIME = getCN(SCHEDULER_VIEW, DAY, TABLE, COLTIME),
  370. CSS_SCHEDULER_VIEW_DAY_TABLE_TIME = getCN(SCHEDULER_VIEW, DAY, TABLE, TIME),
  371. TPL_SCHEDULER_VIEW_DAY_RESIZER = '<div class="' + CSS_SCHEDULER_VIEW_DAY_RESIZER + '">' +
  372. '<div class="' + [CSS_ICON, CSS_ICON_GRIP_DOTTED_HORIZONTAL, CSS_SCHEDULER_VIEW_DAY_RESIZER_ICON].join(SPACE) + '"></div>' +
  373. '</div>',
  374. TPL_SCHEDULER_VIEW_DAY_MARKERCELL = '<div class="' + CSS_SCHEDULER_VIEW_DAY_MARKERCELL + '">' +
  375. '<div class="' + CSS_SCHEDULER_VIEW_DAY_MARKER_DIVISION + '"></div>' +
  376. '</div>',
  377. TPL_SCHEDULER_VIEW_DAY_HEADER_VIEW_LABEL = '<span class="' + CSS_SCHEDULER_VIEW_DAY_HEADER_VIEW_LABEL + '">{label}</span>',
  378. TPL_SCHEDULER_VIEW_DAY_TABLE = '<table cellspacing="0" cellpadding="0" class="' + CSS_SCHEDULER_VIEW_DAY_TABLE + '">' +
  379. '<tbody>' +
  380. '<tr class="' + CSS_SCHEDULER_VIEW_DAY_COLGRID + '" height="1">' +
  381. '<td height="0" class="' + [ CSS_SCHEDULER_VIEW_DAY_TABLE_COL, CSS_SCHEDULER_VIEW_DAY_TABLE_COLBLANK ].join(SPACE) + '"></td>' +
  382. '<td class="' + CSS_SCHEDULER_VIEW_DAY_GRID_CONTAINER + '" colspan="1">' +
  383. '<div class="' + CSS_SCHEDULER_VIEW_DAY_GRID + '">' +
  384. '<div class="' + CSS_SCHEDULER_VIEW_DAY_MARKERS + '"></div>' +
  385. '</div>' +
  386. '</td>' +
  387. '</tr>' +
  388. '<tr class="' + CSS_SCHEDULER_VIEW_DAY_COLDATA + '">' +
  389. '<td class="' + [ CSS_SCHEDULER_VIEW_DAY_TABLE_COL, CSS_SCHEDULER_VIEW_DAY_TABLE_COLTIME ].join(SPACE) + '"></td>' +
  390. '</tr>' +
  391. '</tbody>' +
  392. '</table>',
  393. TPL_SCHEDULER_VIEW_DAY_TABLE_COLDAY = '<td class="' + [ CSS_SCHEDULER_VIEW_DAY_TABLE_COL, CSS_SCHEDULER_VIEW_DAY_TABLE_COLDAY ].join(SPACE) + '" data-colnumber="{colNumber}">' +
  394. '<div class="' + CSS_SCHEDULER_VIEW_DAY_TABLE_COL_SHIM + '"></div>' +
  395. '</td>',
  396. TPL_SCHEDULER_VIEW_DAY_TABLE_TIME = '<div class="' + CSS_SCHEDULER_VIEW_DAY_TABLE_TIME + '">{hour}</div>',
  397. TPL_SCHEDULER_VIEW_DAY_HEADER_TABLE = '<table cellspacing="0" cellpadding="0" class="' + CSS_SCHEDULER_VIEW_DAY_HEADER_TABLE + '">' +
  398. '<tbody>' +
  399. '<tr class="' + CSS_SCHEDULER_VIEW_DAY_HEADER_COL + '"></tr>' +
  400. '</tbody>' +
  401. '</table>',
  402. TPL_SCHEDULER_VIEW_DAY_HEADER_DAY = '<th class="' + CSS_SCHEDULER_VIEW_DAY_HEADER_DAY + '" data-colnumber="{colNumber}"><a href="#">&nbsp;</a></th>',
  403. TPL_SCHEDULER_VIEW_DAY_HEADER_DAY_FIRST = '<td class="' + [ CSS_SCHEDULER_VIEW_DAY_HEADER_DAY, CSS_SCHEDULER_VIEW_DAY_HEADER_DAY_FIRST ].join(SPACE) + '"></td>',
  404. TPL_SCHEDULER_VIEW_DAY_HEADER_DAY_PAD_RIGHT = '<th class="' + [ CSS_SCHEDULER_VIEW_DAY_HEADER_DAY, CSS_SCHEDULER_VIEW_DAY_HEADER_DAY_PAD_RIGHT ].join(SPACE) + '">&nbsp;</th>';
  405. var SchedulerDayView = A.Component.create({
  406. NAME: SCHEDULER_VIEW_DAY,
  407. ATTRS: {
  408. bodyContent: {
  409. value: EMPTY_STR
  410. },
  411. days: {
  412. value: 1,
  413. validator: isNumber
  414. },
  415. delegateConfig: {
  416. value: {},
  417. setter: function(val) {
  418. var instance = this;
  419. return A.merge(
  420. {
  421. dragConfig: {
  422. useShim: false
  423. },
  424. bubbleTargets: instance,
  425. container: instance.get(BOUNDING_BOX),
  426. nodes: DOT+CSS_SCHEDULER_EVENT,
  427. invalid: 'input, select, button, a, textarea, ' + DOT+CSS_SCHEDULER_EVENT_DISABLED
  428. },
  429. val || {}
  430. );
  431. },
  432. validator: isObject
  433. },
  434. eventWidth: {
  435. value: 95,
  436. validator: isNumber
  437. },
  438. filterFn: {
  439. value: function(evt) {
  440. return (evt.getHoursDuration() <= 24 && !evt.get(ALL_DAY));
  441. }
  442. },
  443. headerDateFormatter: {
  444. value: function(date) {
  445. var instance = this;
  446. var scheduler = instance.get(SCHEDULER);
  447. return A.DataType.Date.format(
  448. date,
  449. {
  450. format: '%a %m/%d',
  451. locale: scheduler.get(LOCALE)
  452. }
  453. );
  454. },
  455. validator: isString
  456. },
  457. headerView: {
  458. value: true,
  459. validator: isBoolean
  460. },
  461. headerViewConfig: {
  462. setter: function(val) {
  463. var instance = this;
  464. return A.merge(
  465. {
  466. displayDaysInterval: 1,
  467. displayRows: 6,
  468. filterFn: function(evt) {
  469. return ((evt.getHoursDuration() > 24) || evt.get(ALL_DAY));
  470. },
  471. height: 'auto',
  472. visible: true
  473. },
  474. val || {}
  475. );
  476. },
  477. value: {}
  478. },
  479. hourHeight: {
  480. value: 52,
  481. validator: isNumber
  482. },
  483. name: {
  484. value: DAY
  485. },
  486. navigationDateFormatter: {
  487. value: function(date) {
  488. var instance = this;
  489. var scheduler = instance.get(SCHEDULER);
  490. return A.DataType.Date.format(
  491. date,
  492. {
  493. format: '%A, %b %d, %Y',
  494. locale: scheduler.get(LOCALE)
  495. }
  496. );
  497. },
  498. validator: isFunction
  499. },
  500. strings: {
  501. value: {
  502. allDay: 'All day'
  503. }
  504. },
  505. /*
  506. * HTML_PARSER attributes
  507. */
  508. headerTableNode: {
  509. valueFn: function() {
  510. return A.Node.create(TPL_SCHEDULER_VIEW_DAY_HEADER_TABLE);
  511. }
  512. },
  513. headerViewLabelNode: {
  514. valueFn: function() {
  515. var instance = this;
  516. var strings = instance.get(STRINGS);
  517. return A.Node.create(
  518. sub(TPL_SCHEDULER_VIEW_DAY_HEADER_VIEW_LABEL, {
  519. label: strings[ALL_DAY]
  520. })
  521. );
  522. }
  523. },
  524. resizerNode: {
  525. valueFn: function() {
  526. return A.Node.create(TPL_SCHEDULER_VIEW_DAY_RESIZER);
  527. }
  528. },
  529. tableNode: {
  530. valueFn: function() {
  531. return A.Node.create(TPL_SCHEDULER_VIEW_DAY_TABLE);
  532. }
  533. },
  534. colDaysNode: {
  535. valueFn: '_valueColDaysNode'
  536. },
  537. colHeaderDaysNode: {
  538. valueFn: '_valueColHeaderDaysNode'
  539. },
  540. markercellsNode: {
  541. valueFn: '_valueMarkercellsNode'
  542. },
  543. timesNode: {
  544. valueFn: '_valueTimesNode'
  545. }
  546. },
  547. HTML_PARSER: {
  548. colDaysNode: getNodeListHTMLParser(DOT+CSS_SCHEDULER_VIEW_DAY_TABLE_COLDAY, 1),
  549. colHeaderDaysNode: getNodeListHTMLParser(DOT+CSS_SCHEDULER_VIEW_DAY_HEADER_DAY, 2),
  550. headerTableNode: DOT+CSS_SCHEDULER_VIEW_DAY_HEADER_TABLE,
  551. headerViewLabelNode: DOT+CSS_SCHEDULER_VIEW_DAY_HEADER_VIEW_LABEL,
  552. markercellsNode: getNodeListHTMLParser(DOT+CSS_SCHEDULER_VIEW_DAY_MARKERCELL, 24),
  553. resizerNode: DOT+CSS_SCHEDULER_VIEW_DAY_RESIZER,
  554. tableNode: DOT+CSS_SCHEDULER_VIEW_DAY_TABLE,
  555. timesNode: getNodeListHTMLParser(DOT+CSS_SCHEDULER_VIEW_DAY_TABLE_TIME, 24)
  556. },
  557. EXTENDS: A.SchedulerView,
  558. prototype: {
  559. initializer: function() {
  560. var instance = this;
  561. instance[COL_DAYS_NODE] = instance.get(COL_DAYS_NODE);
  562. instance[COL_HEADER_DAYS_NODE] = instance.get(COL_HEADER_DAYS_NODE);
  563. instance[HEADER_TABLE_NODE] = instance.get(HEADER_TABLE_NODE);
  564. instance[MARKERCELLS_NODE] = instance.get(MARKERCELLS_NODE);
  565. instance[RESIZER_NODE] = instance.get(RESIZER_NODE);
  566. instance[TABLE_NODE] = instance.get(TABLE_NODE);
  567. instance[TIMES_NODE] = instance.get(TIMES_NODE);
  568. instance[ACTIVE_COLUMN] = null;
  569. instance[COLUMN_DATA] = instance[TABLE_NODE].one(DOT+CSS_SCHEDULER_VIEW_DAY_COLDATA);
  570. instance[COLUMN_DAY_HEADER] = instance.headerTableNode.one(DOT+CSS_SCHEDULER_VIEW_DAY_HEADER_COL);
  571. instance[COLUMN_SHIMS] = instance[COL_DAYS_NODE].all(DOT+CSS_SCHEDULER_VIEW_DAY_TABLE_COL_SHIM);
  572. instance[COLUMN_TIME] = instance[TABLE_NODE].one(DOT+CSS_SCHEDULER_VIEW_DAY_TABLE_COLTIME);
  573. instance[GRID_CONTAINER] = instance[TABLE_NODE].one(DOT+CSS_SCHEDULER_VIEW_DAY_GRID_CONTAINER);
  574. instance[MARKERS_NODE] = instance[TABLE_NODE].one(DOT+CSS_SCHEDULER_VIEW_DAY_MARKERS);
  575. if (instance.get(HEADER_VIEW)) {
  576. instance[HEADER_VIEW] = new A.SchedulerTableView(
  577. instance.get(HEADER_VIEW_CONFIG)
  578. );
  579. }
  580. },
  581. renderUI: function() {
  582. var instance = this;
  583. instance[COLUMN_TIME].setContent(instance[TIMES_NODE]);
  584. instance[MARKERS_NODE].setContent(instance[MARKERCELLS_NODE]);
  585. instance[COL_DAYS_NODE].appendTo(instance[COLUMN_DATA]);
  586. instance[COL_HEADER_DAYS_NODE].appendTo(instance[COLUMN_DAY_HEADER]);
  587. if (instance[HEADER_VIEW]) {
  588. instance[HEADER_VIEW].set(SCHEDULER, instance.get(SCHEDULER));
  589. instance[HEADER_VIEW].render();
  590. }
  591. },
  592. bindUI: function() {
  593. var instance = this;
  594. instance[HEADER_TABLE_NODE].delegate('click', A.bind(instance._onClickDaysHeader, instance), DOT+CSS_SCHEDULER_VIEW_DAY_HEADER_DAY);
  595. instance[COLUMN_DATA].delegate('mousedown', A.bind(instance._onMouseDownTableCol, instance), DOT+CSS_SCHEDULER_VIEW_DAY_TABLE_COL);
  596. instance[COLUMN_DATA].delegate('mouseenter', A.bind(instance._onMouseEnterEvent, instance), DOT+CSS_SCHEDULER_EVENT);
  597. instance[COLUMN_DATA].delegate('mouseleave', A.bind(instance._onMouseLeaveEvent, instance), DOT+CSS_SCHEDULER_EVENT);
  598. instance[COLUMN_DATA].delegate('mousemove', A.bind(instance._onMouseMoveTableCol, instance), DOT+CSS_SCHEDULER_VIEW_DAY_TABLE_COLDAY);
  599. instance[COLUMN_DATA].delegate('mouseup', A.bind(instance._onMouseUpTableCol, instance), DOT+CSS_SCHEDULER_VIEW_DAY_TABLE_COL);
  600. instance.on('drag:end', instance._onEventDragEnd);
  601. instance.on('drag:start', instance._onEventDragStart);
  602. instance.on('drag:tickAlignY', instance._dragTickAlignY);
  603. instance.on('schedulerChange', instance._onSchedulerChange);
  604. instance.after('drag:align', instance._afterDragAlign);
  605. },
  606. syncUI: function() {
  607. var instance = this;
  608. SchedulerDayView.superclass.syncUI.apply(this, arguments);
  609. instance[GRID_CONTAINER].attr(COLSPAN, instance.get(DAYS));
  610. instance._setupDragDrop();
  611. },
  612. syncStdContent: function() {
  613. var instance = this;
  614. instance.setStdModContent(
  615. WidgetStdMod.BODY, instance[TABLE_NODE].getDOM());
  616. var headerNodes = A.NodeList.create(instance[HEADER_TABLE_NODE]);
  617. if (instance[HEADER_VIEW]) {
  618. headerNodes.push(instance[HEADER_VIEW].get(BOUNDING_BOX));
  619. headerNodes.push(instance.get(HEADER_VIEW_LABEL_NODE));
  620. }
  621. instance.setStdModContent(WidgetStdMod.HEADER, headerNodes);
  622. },
  623. calculateEventHeight: function(duration) {
  624. var instance = this;
  625. var hourHeight = instance.get(HOUR_HEIGHT);
  626. return Math.max(duration*(hourHeight/60), hourHeight/2);
  627. },
  628. calculateTop: function(date) {
  629. var instance = this;
  630. return ((date.getHours()*60) + date.getMinutes() +
  631. (date.getSeconds()/60)) * (instance.get(HOUR_HEIGHT)/60);
  632. },
  633. getNextDate: function() {
  634. var instance = this;
  635. var currentDate = instance.get(SCHEDULER).get(CURRENT_DATE);
  636. return DateMath.add(currentDate, DateMath.DAY, 1);
  637. },
  638. getPrevDate: function() {
  639. var instance = this;
  640. var currentDate = instance.get(SCHEDULER).get(CURRENT_DATE);
  641. return DateMath.subtract(currentDate, DateMath.DAY, 1);
  642. },
  643. getColumnByDate: function(date) {
  644. var instance = this;
  645. return instance[COL_DAYS_NODE].item(instance.getDateDaysOffset(date));
  646. },
  647. getColumnShimByDate: function(date) {
  648. var instance = this;
  649. return instance[COLUMN_SHIMS].item(instance.getDateDaysOffset(date));
  650. },
  651. getDateByColumn: function(colNumber) {
  652. var instance = this;
  653. var currentDate = DateMath.safeClearTime(
  654. instance.get(SCHEDULER).get(CURRENT_DATE));
  655. return DateMath.add(currentDate, DateMath.DAY, colNumber);
  656. },
  657. getDateDaysOffset: function(date) {
  658. var instance = this;
  659. var currentDate = DateMath.safeClearTime(
  660. instance.get(SCHEDULER).get(CURRENT_DATE));
  661. return DateMath.getDayOffset(
  662. DateMath.safeClearTime(date), currentDate);
  663. },
  664. getYCoordTime: function(top) {
  665. var instance = this;
  666. var hourHeight = instance.get(HOUR_HEIGHT);
  667. var prop = toNumber((top/hourHeight).toFixed(2));
  668. // Isolate the decimals and convert to minutes: (prop*100)%100*0.6.
  669. var minutes = Math.floor((prop*100)%100*0.6);
  670. var hours = Math.floor(prop);
  671. return [ hours, minutes, 0 ];
  672. },
  673. plotEvent: function(evt) {
  674. var instance = this;
  675. var nodeList = evt.get(NODE);
  676. if (nodeList.size() < 2) {
  677. evt.addPaddingNode();
  678. }
  679. var node = evt.get(NODE).item(0);
  680. var paddingNode = evt.get(NODE).item(1);
  681. var endShim = instance.getColumnShimByDate(evt.get(END_DATE));
  682. var startShim = instance.getColumnShimByDate(evt.get(START_DATE));
  683. if (startShim) {
  684. startShim.append(node);
  685. if (evt.get(VISIBLE)) {
  686. node.show();
  687. }
  688. }
  689. else {
  690. node.hide();
  691. }
  692. if (endShim) {
  693. if (endShim.compareTo(startShim) || evt.isDayBoundaryEvent()) {
  694. paddingNode.hide();
  695. }
  696. else {
  697. endShim.append(paddingNode);
  698. if (evt.get(VISIBLE)) {
  699. paddingNode.show();
  700. }
  701. }
  702. }
  703. else {
  704. paddingNode.hide();
  705. }
  706. evt.syncNodeUI();
  707. instance.syncEventTopUI(evt);
  708. instance.syncEventHeightUI(evt);
  709. },
  710. plotEvents: function() {
  711. var instance = this;
  712. var scheduler = instance.get(SCHEDULER);
  713. var filterFn = instance.get(FILTER_FN);
  714. instance[COLUMN_SHIMS].each(function(colShimNode, i) {
  715. var columnEvents = scheduler.getEventsByDay(instance.getDateByColumn(i), true);
  716. var plottedEvents = [];
  717. colShimNode.empty();
  718. A.Array.each(columnEvents, function(evt) {
  719. if (filterFn.apply(instance, [evt])) {
  720. instance.plotEvent(evt);
  721. plottedEvents.push(evt);
  722. }
  723. });
  724. instance.syncEventsIntersectionUI(plottedEvents);
  725. });
  726. if (instance.get(HEADER_VIEW)) {
  727. instance.syncHeaderViewUI();
  728. }
  729. },
  730. syncColumnsUI: function() {
  731. var instance = this;
  732. instance[COL_DAYS_NODE].each(function(columnNode, i) {
  733. var columnDate = instance.getDateByColumn(i);
  734. columnNode.toggleClass(
  735. CSS_SCHEDULER_TODAY, DateMath.isToday(columnDate));
  736. });
  737. },
  738. syncDaysHeaderUI: function() {
  739. var instance = this;
  740. var currentDate = instance.get(SCHEDULER).get(CURRENT_DATE);
  741. var formatter = instance.get(HEADER_DATE_FORMATTER);
  742. var locale = instance.get(LOCALE);
  743. instance[COL_HEADER_DAYS_NODE].all(ANCHOR).each(
  744. function(columnNode, i) {
  745. var columnDate = DateMath.add(currentDate, DateMath.DAY, i);
  746. columnNode.toggleClass(
  747. CSS_SCHEDULER_TODAY_HD, DateMath.isToday(columnDate));
  748. columnNode.html(formatter.call(instance, columnDate));
  749. }
  750. );
  751. },
  752. // TODO
  753. syncEventsIntersectionUI: function(columnEvents) {
  754. var instance = this;
  755. var eventWidth = instance.get(EVENT_WIDTH);
  756. instance.get(SCHEDULER).flushEvents();
  757. A.Array.each(columnEvents, function(colEvt) {
  758. var intercessors = instance.findEventIntersections(
  759. colEvt, columnEvents);
  760. var total = intercessors.length;
  761. var distributionRate = (eventWidth/total);
  762. A.Array.each(intercessors, function(evt, j) {
  763. var evtNode = evt.get(NODE).item(0);
  764. var left = distributionRate*j;
  765. var width = distributionRate*1.7;
  766. if (j === (total - 1)) {
  767. width = eventWidth - left;
  768. }
  769. evtNode.setStyle(WIDTH, width+PERCENT);
  770. evtNode.setStyle(LEFT, left+PERCENT);
  771. var evtParentNode = evtNode.get(PARENT_NODE);
  772. if (evtParentNode) {
  773. evtParentNode.insert(evtNode, j);
  774. }
  775. evt._filtered = true;
  776. });
  777. });
  778. },
  779. syncEventHeightUI: function(evt) {
  780. var instance = this;
  781. var endDate = evt.get(END_DATE);
  782. var startDate = evt.get(START_DATE);
  783. var maxVisibleDate = DateMath.clone(startDate);
  784. maxVisibleDate.setHours(24, 0, 0);
  785. var minutesOffset = DateMath.getMinutesOffset(
  786. instance.limitDate(endDate, maxVisibleDate), startDate);
  787. evt.get(NODE).item(0).set(OFFSET_HEIGHT, instance.calculateEventHeight(minutesOffset));
  788. var paddingNode = evt.get(NODE).item(1);
  789. if (paddingNode.inDoc()) {
  790. var paddingMinutesOffset = DateMath.getMinutesOffset(
  791. endDate, DateMath.toMidnight(evt.getClearEndDate()));
  792. paddingNode.set(OFFSET_HEIGHT, instance.calculateEventHeight(paddingMinutesOffset));
  793. }
  794. },
  795. syncEventTopUI: function(evt) {
  796. var instance = this;
  797. evt.get(NODE).item(0).setStyle(TOP,
  798. instance.calculateTop(evt.get(START_DATE)) + PX);
  799. evt.get(NODE).item(1).setStyle(TOP, 0);
  800. },
  801. syncHeaderViewUI: function() {
  802. var instance = this;
  803. if (instance.get(HEADER_VIEW)) {
  804. var headerView = instance[HEADER_VIEW];
  805. headerView.plotEvents();
  806. var headerViewBB = headerView.get(BOUNDING_BOX);
  807. headerViewBB.setStyle(MARGIN_RIGHT, getScrollbarWidth());
  808. var headerViewData = headerViewBB.one(DOT+CSS_SVT_TABLE_DATA);
  809. var height = Math.max(headerViewData.get(OFFSET_HEIGHT), 40);
  810. headerView.set(HEIGHT, height);
  811. instance._fillHeight();
  812. }
  813. },
  814. calculateYDelta: function(startXY, xy) {
  815. var instance = this;
  816. return (xy[1] - startXY[1])/(instance.get(HOUR_HEIGHT)/2)*30;
  817. },
  818. findEventIntersections: function(evt, events) {
  819. var instance = this;
  820. var group = [];
  821. A.Array.each(events, function(evtCmp) {
  822. if (!evt._filtered && evt.intersectHours(evtCmp)) {
  823. group.push(evtCmp);
  824. }
  825. });
  826. return group;
  827. },
  828. getXYDelta: function(event) {
  829. var instance = this;
  830. var xy = event.currentTarget.getXY(),
  831. pageXY = [event.pageX, event.pageY];
  832. return A.Array.map(xy, function(val, i) {
  833. return (pageXY[i] - val);
  834. });
  835. },
  836. getTickY: function() {
  837. var instance = this;
  838. return roundToNearestMultiple(
  839. Math.ceil(instance.get(HOUR_HEIGHT) / 2), 10);
  840. },
  841. roundToNearestHour: function(date, time) {
  842. var instance = this;
  843. date.setHours(
  844. time[0],
  845. roundToNearestMultiple(time[1], instance.getTickY()),
  846. time[2]);
  847. },
  848. _afterDragAlign: function(event) {
  849. var instance = this;
  850. var dd = event.target;
  851. if (!instance[START_XY]) {
  852. instance[START_XY] = dd.actXY;
  853. }
  854. dd.actXY[0] = null;
  855. },
  856. _dragTickAlignX: function(activeColumn) {
  857. var instance = this;
  858. var draggingEvent = instance[DRAGGING_EVENT];
  859. if (draggingEvent && !instance[RESIZING]) {
  860. var placeholder = instance[EVENT_PLACEHOLDER];
  861. var delta = toNumber(activeColumn.attr(DATA_COLNUMBER)) - instance.startColNumber;
  862. instance.draggingEventStartDate = DateMath.add(draggingEvent.get(START_DATE), DateMath.DAY, delta);
  863. var startDate = DateMath.clone(instance.draggingEventStartDate);
  864. DateMath.copyHours(startDate, placeholder.get(START_DATE));
  865. placeholder.move(startDate);
  866. instance.plotEvent(placeholder);
  867. }
  868. },
  869. _dragTickAlignY: function(event) {
  870. var instance = this;
  871. var scheduler = instance.get(SCHEDULER);
  872. var recorder = scheduler.get(EVENT_RECORDER);
  873. var draggingEvent = instance[DRAGGING_EVENT];
  874. if (draggingEvent) {
  875. var dd = event.target.get(HOST);
  876. var placeholder = instance[EVENT_PLACEHOLDER];
  877. var delta = instance.calculateYDelta(instance[START_XY], dd.actXY);
  878. if (instance[RESIZING]) {
  879. var endDate = DateMath.add(instance.draggingEventEndDate, DateMath.MINUTES, delta);
  880. if (DateMath.getMinutesOffset(endDate, instance.draggingEventStartDate) <= recorder.get(DURATION)) {
  881. return;
  882. }
  883. placeholder.set(END_DATE, endDate);
  884. }
  885. else {
  886. placeholder.move(DateMath.add(instance.draggingEventStartDate, DateMath.MINUTES, delta));
  887. }
  888. instance.plotEvent(placeholder);
  889. }
  890. },
  891. _setupDragDrop: function() {
  892. var instance = this;
  893. if (!instance[EVENT_PLACEHOLDER]) {
  894. var scheduler = instance.get(SCHEDULER);
  895. instance[EVENT_PLACEHOLDER] = new (instance.get(EVENT_CLASS))({
  896. scheduler: scheduler
  897. });
  898. instance[EVENT_PLACEHOLDER].removeTarget(scheduler);
  899. instance[EVENT_PLACEHOLDER].get(NODE).addClass(
  900. CSS_SCHEDULER_EVENT_PROXY).hide();
  901. }
  902. if (!instance.delegate) {
  903. instance.delegate = new A.DD.Delegate(
  904. instance.get(DELEGATE_CONFIG));
  905. }
  906. var dd = instance.delegate.dd;
  907. dd.unplug(A.Plugin.DDConstrained);
  908. dd.unplug(A.Plugin.DDNodeScroll);
  909. var region = instance.bodyNode.get(REGION);
  910. region.bottom = Infinity;
  911. region.top = -Infinity;
  912. dd.plug(A.Plugin.DDConstrained, {
  913. bubbleTargets: instance,
  914. constrain: region,
  915. stickY: true,
  916. tickY: instance.get(HOUR_HEIGHT) / 2
  917. });
  918. dd.plug(A.Plugin.DDNodeScroll, {
  919. node: instance.bodyNode,
  920. scrollDelay: 150
  921. });
  922. },
  923. _uiSetCurrentDate: function(val) {
  924. var instance = this;
  925. instance.syncColumnsUI();
  926. instance.syncDaysHeaderUI();
  927. },
  928. _onClickDaysHeader: function(event) {
  929. var instance = this;
  930. var scheduler = instance.get(SCHEDULER);
  931. if (event.target.test(ANCHOR)) {
  932. var dayView = scheduler.getViewByName(DAY);
  933. if (dayView) {
  934. var colNumber = toNumber(event.currentTarget.attr(DATA_COLNUMBER));
  935. scheduler.set(
  936. CURRENT_DATE, instance.getDateByColumn(colNumber));
  937. scheduler.set(ACTIVE_VIEW, dayView);
  938. }
  939. }
  940. event.preventDefault();
  941. },
  942. _onEventDragEnd: function(event) {
  943. var instance = this;
  944. var draggingEvent = instance[DRAGGING_EVENT];
  945. if (draggingEvent) {
  946. var placeholder = instance[EVENT_PLACEHOLDER];
  947. placeholder.set(VISIBLE, false);
  948. draggingEvent.set(VISIBLE, true);
  949. draggingEvent.copyDates(placeholder);
  950. instance.get(SCHEDULER).syncEventsUI();
  951. }
  952. instance[START_XY] = null;
  953. instance[DRAGGING_EVENT] = null;
  954. },
  955. _onEventDragStart: function(event) {
  956. var instance = this;
  957. var draggingEvent = instance[DRAGGING_EVENT] = instance.delegate.dd.get(NODE).getData(SCHEDULER_EVENT);
  958. if (draggingEvent) {
  959. var placeholder = instance[EVENT_PLACEHOLDER];
  960. placeholder.copyPropagateAttrValues(draggingEvent);
  961. instance.plotEvent(placeholder);
  962. draggingEvent.set(VISIBLE, false);
  963. instance.draggingEventStartDate = DateMath.clone(draggingEvent.get(START_DATE));
  964. instance.draggingEventEndDate = DateMath.clone(draggingEvent.get(END_DATE));
  965. var startColumn = instance.getColumnByDate(draggingEvent.get(START_DATE));
  966. instance.startColNumber = startColumn ? toNumber(startColumn.attr(DATA_COLNUMBER)) : 0;
  967. }
  968. },
  969. _onMouseDownTableCol: function(event) {
  970. var instance = this;
  971. var target = event.target;
  972. var scheduler = instance.get(SCHEDULER);
  973. var recorder = scheduler.get(EVENT_RECORDER);
  974. if (recorder && !scheduler.get(DISABLED)) {
  975. recorder.hideOverlay();
  976. if (target.test(DOT+CSS_SCHEDULER_VIEW_DAY_TABLE_COL_SHIM)) {
  977. instance[START_XY] = [ event.pageX, event.pageY ];
  978. var colNumber = toNumber(event.currentTarget.attr(DATA_COLNUMBER));
  979. var startDate = instance.getDateByColumn(colNumber);
  980. var clickLeftTop = instance.getXYDelta(event);
  981. instance.roundToNearestHour(
  982. startDate, instance.getYCoordTime(clickLeftTop[1]));
  983. var endDate = DateMath.add(startDate, DateMath.MINUTES, recorder.get(DURATION));
  984. recorder.move(startDate);
  985. recorder.set(ALL_DAY, false);
  986. recorder.set(END_DATE, endDate);
  987. instance[CREATION_START_DATE] = startDate;
  988. instance[CREATION_END_DATE] = endDate;
  989. event.halt();
  990. }
  991. else if (target.test(
  992. [ DOT+CSS_SCHEDULER_VIEW_DAY_RESIZER,
  993. DOT+CSS_SCHEDULER_VIEW_DAY_RESIZER_ICON ].join(COMMA))) {
  994. instance[RESIZING] = true;
  995. }
  996. }
  997. instance.get(BOUNDING_BOX).unselectable();
  998. },
  999. _onMouseEnterEvent: function(event) {
  1000. var instance = this;
  1001. var target = event.currentTarget;
  1002. var evt = target.getData(SCHEDULER_EVENT);
  1003. if (evt && !evt.get(DISABLED)) {
  1004. instance[RESIZER_NODE].appendTo(target);
  1005. }
  1006. },
  1007. _onMouseLeaveEvent: function(event) {
  1008. var instance = this;
  1009. if (!instance[RESIZING]) {
  1010. instance._removeResizer();
  1011. }
  1012. },
  1013. _onMouseMoveTableCol: function(event) {
  1014. var instance = this;
  1015. var activeColumn = event.currentTarget;
  1016. var recorder = instance.get(SCHEDULER).get(EVENT_RECORDER);
  1017. if (instance[ACTIVE_COLUMN] !== activeColumn) {
  1018. instance[ACTIVE_COLUMN] = activeColumn;
  1019. instance._dragTickAlignX(instance[ACTIVE_COLUMN]);
  1020. }
  1021. var creationEndDate = instance[CREATION_END_DATE];
  1022. var creationStartDate = instance[CREATION_START_DATE];
  1023. if (creationStartDate) {
  1024. var delta = roundToNearestMultiple(
  1025. instance.calculateYDelta(instance[START_XY], [ event.pageX, event.pageY ]),
  1026. instance.getTickY()
  1027. );
  1028. if (instance._delta !== delta) {
  1029. if (delta > 0) {
  1030. recorder.set(END_DATE, DateMath.add(creationEndDate, DateMath.MINUTES, delta));
  1031. }
  1032. else {
  1033. recorder.set(START_DATE, DateMath.add(creationStartDate, DateMath.MINUTES, delta));
  1034. }
  1035. instance.plotEvent(recorder);
  1036. instance._delta = delta;
  1037. }
  1038. }
  1039. },
  1040. _onMouseUpTableCol: function(event) {
  1041. var instance = this;
  1042. var scheduler = instance.get(SCHEDULER);
  1043. var recorder = scheduler.get(EVENT_RECORDER);
  1044. if (recorder && !scheduler.get(DISABLED)) {
  1045. if (instance[CREATION_START_DATE]) {
  1046. instance.plotEvent(recorder);
  1047. recorder.showOverlay([ event.pageX, event.pageY ]);
  1048. }
  1049. }
  1050. instance[CREATION_START_DATE] = null;
  1051. instance[CREATION_END_DATE] = null;
  1052. instance[RESIZING] = false;
  1053. instance[START_XY] = null;
  1054. instance._removeResizer();
  1055. instance.get(BOUNDING_BOX).selectable();
  1056. },
  1057. _onSchedulerChange: function(event) {
  1058. var instance = this;
  1059. if (instance[HEADER_VIEW]) {
  1060. instance[HEADER_VIEW].set(SCHEDULER, event.newVal);
  1061. }
  1062. },
  1063. _removeResizer: function() {
  1064. var instance = this;
  1065. instance[RESIZER_NODE].remove();
  1066. },
  1067. _valueColDaysNode: function() {
  1068. var instance = this;
  1069. var days = instance.get(DAYS);
  1070. var buffer = [], colNumber = 0;
  1071. while (days--) {
  1072. buffer.push(
  1073. A.Lang.sub(TPL_SCHEDULER_VIEW_DAY_TABLE_COLDAY, {
  1074. colNumber: colNumber++
  1075. })
  1076. );
  1077. }
  1078. return A.NodeList.create(buffer.join(EMPTY_STR));
  1079. },
  1080. _valueColHeaderDaysNode: function() {
  1081. var instance = this;
  1082. var days = instance.get(DAYS);
  1083. var buffer = [], colNumber = 0;
  1084. buffer.push(TPL_SCHEDULER_VIEW_DAY_HEADER_DAY_FIRST);
  1085. while (days--) {
  1086. buffer.push(
  1087. A.Lang.sub(TPL_SCHEDULER_VIEW_DAY_HEADER_DAY, {
  1088. colNumber: colNumber++
  1089. })
  1090. );
  1091. }
  1092. buffer.push(TPL_SCHEDULER_VIEW_DAY_HEADER_DAY_PAD_RIGHT);
  1093. return A.NodeList.create(buffer.join(EMPTY_STR));
  1094. },
  1095. _valueMarkercellsNode: function() {
  1096. var instance = this;
  1097. var buffer = [], i;
  1098. for (i = 0; i <= 23; i++) {
  1099. buffer.push(TPL_SCHEDULER_VIEW_DAY_MARKERCELL);
  1100. }
  1101. return A.NodeList.create(buffer.join(EMPTY_STR));
  1102. },
  1103. _valueTimesNode: function() {
  1104. var instance = this;
  1105. var isoTime = instance.get(ISO_TIME);
  1106. var buffer = [], hour;
  1107. for (hour = 0; hour <= 23; hour++) {
  1108. buffer.push(
  1109. sub(
  1110. TPL_SCHEDULER_VIEW_DAY_TABLE_TIME,
  1111. {
  1112. hour: isoTime ? DateMath.toIsoTimeString(hour) : DateMath.toUsTimeString(hour, false, true)
  1113. }
  1114. )
  1115. );
  1116. }
  1117. return A.NodeList.create(buffer.join(EMPTY_STR));
  1118. }
  1119. }
  1120. });
  1121. A.SchedulerDayView = SchedulerDayView;
  1122. var SchedulerWeekView = A.Component.create({
  1123. NAME: SCHEDULER_VIEW_WEEK,
  1124. ATTRS: {
  1125. bodyContent: {
  1126. value: EMPTY_STR
  1127. },
  1128. days: {
  1129. value: 7
  1130. },
  1131. headerViewConfig: {
  1132. value: {
  1133. displayDaysInterval: WEEK_LENGTH
  1134. }
  1135. },
  1136. name: {
  1137. value: WEEK
  1138. },
  1139. navigationDateFormatter: {
  1140. valueFn: function() {
  1141. return this._valueNavigationDateFormatter;
  1142. },
  1143. validator: isFunction
  1144. }
  1145. },
  1146. EXTENDS: A.SchedulerDayView,
  1147. prototype: {
  1148. adjustCurrentDate: function() {
  1149. var instance = this;
  1150. var scheduler = instance.get(SCHEDULER);
  1151. var currentDate = scheduler.get(CURRENT_DATE);
  1152. var firstDayOfWeek = scheduler.get(FIRST_DAY_OF_WEEK);
  1153. scheduler.set(
  1154. CURRENT_DATE,
  1155. DateMath.getFirstDayOfWeek(currentDate, firstDayOfWeek)
  1156. );
  1157. },
  1158. getNextDate: function() {
  1159. var instance = this;
  1160. var scheduler = instance.get(SCHEDULER);
  1161. var currentDate = scheduler.get(CURRENT_DATE);
  1162. var firstDayOfWeekDate = instance._firstDayOfWeek(currentDate);
  1163. return DateMath.add(firstDayOfWeekDate, DateMath.WEEK, 1);
  1164. },
  1165. getPrevDate: function() {
  1166. var instance = this;
  1167. var scheduler = instance.get(SCHEDULER);
  1168. var currentDate = scheduler.get(CURRENT_DATE);
  1169. var firstDayOfWeekDate = instance._firstDayOfWeek(currentDate);
  1170. return DateMath.subtract(firstDayOfWeekDate, DateMath.WEEK, 1);
  1171. },
  1172. getToday: function() {
  1173. var instance = this;
  1174. var todayDate = SchedulerWeekView.superclass.getToday.apply(this, arguments);
  1175. return instance._firstDayOfWeek(todayDate);
  1176. },
  1177. _firstDayOfWeek: function(date) {
  1178. var instance = this;
  1179. var scheduler = instance.get(SCHEDULER);
  1180. var firstDayOfWeek = scheduler.get(FIRST_DAY_OF_WEEK);
  1181. return DateMath.getFirstDayOfWeek(date, firstDayOfWeek);
  1182. },
  1183. _valueNavigationDateFormatter: function(date) {
  1184. var instance = this;
  1185. var scheduler = instance.get(SCHEDULER);
  1186. var locale = scheduler.get(LOCALE);
  1187. var startDate = instance._firstDayOfWeek(date);
  1188. var startDateLabel = A.DataType.Date.format(
  1189. startDate,
  1190. {
  1191. format: '%b %d',
  1192. locale: locale
  1193. }
  1194. );
  1195. var endDate = DateMath.add(startDate, DateMath.DAY, instance.get(DAYS) - 1);
  1196. var endDateLabel = A.DataType.Date.format(
  1197. endDate,
  1198. {
  1199. format: (DateMath.isMonthOverlapWeek(date) ? '%b %d' : '%d') + ', %Y',
  1200. locale: locale
  1201. }
  1202. );
  1203. return [startDateLabel, MDASH, endDateLabel].join(SPACE);
  1204. }
  1205. }
  1206. });
  1207. A.SchedulerWeekView = SchedulerWeekView;
  1208. var CSS_ICON = getCN(ICON),
  1209. CSS_ICON_ARROWSTOP_LEFT = getCN(ICON, 'arrowstop-1-l'),
  1210. CSS_ICON_ARROWSTOP_RIGHT = getCN(ICON, 'arrowstop-1-r'),
  1211. CSS_SVT_COLGRID = getCN(SCHEDULER_VIEW, TABLE, COLGRID),
  1212. CSS_SVT_COLGRID_FIRST = getCN(SCHEDULER_VIEW, TABLE, COLGRID, FIRST),
  1213. CSS_SVT_COLGRID_TODAY = getCN(SCHEDULER_VIEW, TABLE, COLGRID, TODAY),
  1214. CSS_SVT_CONTAINER = getCN(SCHEDULER_VIEW, TABLE, CONTAINER),
  1215. CSS_SVT_EVENTS_OVERLAY_NODE = getCN(SCHEDULER_VIEW, TABLE, EVENTS, OVERLAY, NODE),
  1216. CSS_SVT_EVENTS_OVERLAY_NODE_BODY = getCN(SCHEDULER_VIEW, TABLE, EVENTS, OVERLAY, NODE, BODY),
  1217. CSS_SVT_EVENTS_OVERLAY_NODE_CLOSE = getCN(SCHEDULER_VIEW, TABLE, EVENTS, OVERLAY, NODE, CLOSE),
  1218. CSS_SVT_HEADER_COL = getCN(SCHEDULER_VIEW, TABLE, HEADER, COL),
  1219. CSS_SVT_HEADER_DAY = getCN(SCHEDULER_VIEW, TABLE, HEADER, DAY),
  1220. CSS_SVT_HEADER_TABLE = getCN(SCHEDULER_VIEW, TABLE, HEADER, TABLE),
  1221. CSS_SVT_MORE = getCN(SCHEDULER_VIEW, TABLE, MORE),
  1222. CSS_SVT_ROW = getCN(SCHEDULER_VIEW, TABLE, ROW),
  1223. CSS_SVT_ROW_CONTAINER = getCN(SCHEDULER_VIEW, TABLE, ROW, CONTAINER),
  1224. CSS_SVT_TABLE_DATA = getCN(SCHEDULER_VIEW, TABLE, DATA),
  1225. CSS_SVT_TABLE_DATA_COL = getCN(SCHEDULER_VIEW, TABLE, DATA, COL),
  1226. CSS_SVT_TABLE_DATA_COL_TITLE = getCN(SCHEDULER_VIEW, TABLE, DATA, COL, TITLE),
  1227. CSS_SVT_TABLE_DATA_COL_TITLE_DOWN = getCN(SCHEDULER_VIEW, TABLE, DATA, COL, TITLE, DOWN),
  1228. CSS_SVT_TABLE_DATA_COL_TITLE_FIRST = getCN(SCHEDULER_VIEW, TABLE, DATA, COL, TITLE, FIRST),
  1229. CSS_SVT_TABLE_DATA_COL_TITLE_NEXT = getCN(SCHEDULER_VIEW, TABLE, DATA, COL, TITLE, NEXT),
  1230. CSS_SVT_TABLE_DATA_COL_TITLE_TODAY = getCN(SCHEDULER_VIEW, TABLE, DATA, COL, TITLE, TODAY),
  1231. CSS_SVT_TABLE_DATA_EVENT = getCN(SCHEDULER_VIEW, TABLE, DATA, EVENT),
  1232. CSS_SVT_TABLE_DATA_EVENT_LEFT = getCN(SCHEDULER_VIEW, TABLE, DATA, EVENT, LEFT),
  1233. CSS_SVT_TABLE_DATA_EVENT_REPEATED = getCN(SCHEDULER_VIEW, TABLE, DATA, EVENT, REPEATED),
  1234. CSS_SVT_TABLE_DATA_EVENT_RIGHT = getCN(SCHEDULER_VIEW, TABLE, DATA, EVENT, RIGHT),
  1235. CSS_SVT_TABLE_DATA_FIRST = getCN(SCHEDULER_VIEW, TABLE, DATA, FIRST),
  1236. CSS_SVT_TABLE_GRID = getCN(SCHEDULER_VIEW, TABLE, GRID),
  1237. CSS_SVT_TABLE_GRID_FIRST = getCN(SCHEDULER_VIEW, TABLE, GRID, FIRST),
  1238. TPL_SVT_CONTAINER = '<div class="' + CSS_SVT_CONTAINER + '">' +
  1239. '<div class="' + CSS_SVT_ROW_CONTAINER + '"></div>' +
  1240. '</div>',
  1241. TPL_SVT_EVENTS_OVERLAY_NODE = '<div class="' + CSS_SVT_EVENTS_OVERLAY_NODE + '">' +
  1242. '<div class="' + CSS_SVT_EVENTS_OVERLAY_NODE_BODY + '"></div>' +
  1243. '<a href="javascript:;" class="' + CSS_SVT_EVENTS_OVERLAY_NODE_CLOSE + '">{label}</a>' +
  1244. '</div>',
  1245. TPL_SVT_GRID_COLUMN = '<td class="' + CSS_SVT_COLGRID + '">&nbsp;</td>',
  1246. TPL_SVT_HEADER_DAY = '<th class="' + CSS_SVT_HEADER_DAY + '"><div>&nbsp;</div></th>',
  1247. TPL_SVT_HEADER_TABLE = '<table cellspacing="0" cellpadding="0" class="' + CSS_SVT_HEADER_TABLE + '">' +
  1248. '<tbody>' +
  1249. '<tr class="' + CSS_SVT_HEADER_COL + '"></tr>' +
  1250. '</tbody>' +
  1251. '</table>',
  1252. TPL_SVT_MORE = '<a href="javascript:;" class="' + CSS_SVT_MORE + '">{label} {count}</a>',
  1253. TPL_SVT_ROW = '<div class="' + CSS_SVT_ROW + '" style="top: {top}%; height: {height}%;"></div>',
  1254. TPL_SVT_TABLE_DATA = '<table cellspacing="0" cellpadding="0" class="' + CSS_SVT_TABLE_DATA + '">' +
  1255. '<tbody></tbody>' +
  1256. '</table>',
  1257. TPL_SVT_TABLE_GRID = '<table cellspacing="0" cellpadding="0" class="' + CSS_SVT_TABLE_GRID + '">' +
  1258. '<tbody>' +
  1259. '<tr></tr>' +
  1260. '</tbody>' +
  1261. '</table>',
  1262. TPL_SVT_EV_ICON_LEFT = '<span class="' + [ CSS_ICON, CSS_ICON_ARROWSTOP_LEFT ].join(SPACE) + '"></span>',
  1263. TPL_SVT_EV_ICON_RIGHT = '<span class="' + [ CSS_ICON, CSS_ICON_ARROWSTOP_RIGHT ].join(SPACE) + '"></span>',
  1264. TPL_SVT_TABLE_DATA_COL = '<td class="' + CSS_SVT_TABLE_DATA_COL + '"><div></div></td>',
  1265. TPL_SVT_TABLE_DATA_ROW = '<tr></tr>';
  1266. var SchedulerTableView = A.Component.create({
  1267. NAME: SCHEDULER_VIEW_TABLE,
  1268. ATTRS: {
  1269. bodyContent: {
  1270. value: EMPTY_STR
  1271. },
  1272. displayDaysInterval: {
  1273. value: 42
  1274. },
  1275. displayRows: {
  1276. value: 4
  1277. },
  1278. fixedHeight: {
  1279. value: true
  1280. },
  1281. name: {
  1282. value: TABLE
  1283. },
  1284. headerDateFormatter: {
  1285. value: function(date) {
  1286. var instance = this;
  1287. var scheduler = instance.get(SCHEDULER);
  1288. return A.DataType.Date.format(
  1289. date,
  1290. {
  1291. format: '%a',
  1292. locale: scheduler.get(LOCALE)
  1293. }
  1294. );
  1295. },
  1296. validator: isString
  1297. },
  1298. navigationDateFormatter: {
  1299. value: function(date) {
  1300. var instance = this;
  1301. var scheduler = instance.get(SCHEDULER);
  1302. return A.DataType.Date.format(
  1303. date,
  1304. {
  1305. format: '%b %Y',
  1306. locale: scheduler.get(LOCALE)
  1307. }
  1308. );
  1309. },
  1310. validator: isFunction
  1311. },
  1312. scrollable: {
  1313. value: false
  1314. },
  1315. strings: {
  1316. value: {
  1317. close: 'Close',
  1318. showMore: 'Show more'
  1319. }
  1320. },
  1321. /*
  1322. * HTML_PARSER attributes
  1323. */
  1324. headerTableNode: {
  1325. valueFn: function() {
  1326. return A.Node.create(TPL_SVT_HEADER_TABLE);
  1327. }
  1328. },
  1329. colHeaderDaysNode: {
  1330. valueFn: '_valueColHeaderDaysNode'
  1331. },
  1332. rowsContainerNode: {
  1333. valueFn: function() {
  1334. return A.Node.create(TPL_SVT_CONTAINER);
  1335. }
  1336. },
  1337. tableGridNode: {
  1338. valueFn: '_valueTableGridNode'
  1339. }
  1340. },
  1341. HTML_PARSER: {
  1342. colHeaderDaysNode: getNodeListHTMLParser(DOT+CSS_SVT_HEADER_DAY, 7),
  1343. headerTableNode: DOT+CSS_SVT_HEADER_TABLE,
  1344. rowsContainerNode: DOT+CSS_SVT_CONTAINER,
  1345. tableGridNode: getNodeListHTMLParser(DOT+CSS_SVT_TABLE_GRID, 7)
  1346. },
  1347. EXTENDS: A.SchedulerView,
  1348. prototype: {
  1349. evtDateStack: null,
  1350. evtRenderedStack: null,
  1351. rowDataTableStack: null,
  1352. initializer: function() {
  1353. var instance = this;
  1354. instance.evtDateStack = {};
  1355. instance.evtRenderedStack = {};
  1356. instance.rowDataTableStack = {};
  1357. instance[COL_HEADER_DAYS_NODE] = instance.get(COL_HEADER_DAYS_NODE);
  1358. instance[HEADER_TABLE_NODE] = instance.get(HEADER_TABLE_NODE);
  1359. instance[ROWS_CONTAINER_NODE] = instance.get(ROWS_CONTAINER_NODE);
  1360. instance[TABLE_GRID_NODE] = instance.get(TABLE_GRID_NODE);
  1361. instance[COLUMN_DAY_HEADER] = instance.headerTableNode.one(DOT+CSS_SVT_HEADER_COL);
  1362. instance[COLUMN_TABLE_GRID] = A.NodeList.create();
  1363. instance[TABLE_ROW_CONTAINER] = instance[ROWS_CONTAINER_NODE].one(DOT+CSS_SVT_ROW_CONTAINER);
  1364. instance[TABLE_ROWS] = A.NodeList.create();
  1365. },
  1366. bindUI: function() {
  1367. var instance = this;
  1368. instance[ROWS_CONTAINER_NODE].delegate('click', A.bind(instance._onClickMore, instance), DOT+CSS_SVT_MORE);
  1369. },
  1370. renderUI: function() {
  1371. var instance = this;
  1372. var displayRowsCount = instance._getDisplayRowsCount();
  1373. for (var rowIndex = 0; rowIndex < displayRowsCount; rowIndex++) {
  1374. instance[TABLE_ROWS].push(
  1375. instance.buildGridRowNode(rowIndex)
  1376. );
  1377. }
  1378. instance._renderEventsOverlay();
  1379. instance[COL_HEADER_DAYS_NODE].appendTo(instance[COLUMN_DAY_HEADER]);
  1380. instance[TABLE_ROWS].appendTo(instance[TABLE_ROW_CONTAINER]);
  1381. },
  1382. buildEventsRow: function(rowStartDate, rowEndDate, rowDisplayIndex) {
  1383. var instance = this;
  1384. var displayRows = instance.get(DISPLAY_ROWS);
  1385. var displayRowDaysCount = instance._getDisplayRowDaysCount();
  1386. var rowRenderedColumns = 0;
  1387. var rowNode = A.Node.create(TPL_SVT_TABLE_DATA_ROW);
  1388. instance.loopDates(rowStartDate, rowEndDate, function(celDate, index) {
  1389. if (rowRenderedColumns > index) {
  1390. return;
  1391. }
  1392. var events = instance.getIntersectEvents(celDate);
  1393. var evt = instance._getRenderableEvent(events, rowStartDate, rowEndDate, celDate);
  1394. var evtColNode = A.Node.create(TPL_SVT_TABLE_DATA_COL);
  1395. var evtNodeContainer = evtColNode.one(DIV);
  1396. if ((displayRows < events.length) && (rowDisplayIndex === (displayRows - 1))) {
  1397. var strings = instance.get(STRINGS);
  1398. var showMoreEventsLink = A.Node.create(
  1399. Lang.sub(
  1400. TPL_SVT_MORE,
  1401. {
  1402. count: (events.length - (displayRows - 1)),
  1403. label: strings[SHOW_MORE]
  1404. }
  1405. )
  1406. );
  1407. showMoreEventsLink.setData(EVENTS, events);
  1408. evtNodeContainer.append(showMoreEventsLink);
  1409. }
  1410. else if (evt) {
  1411. var evtSplitInfo = instance._getEvtSplitInfo(evt, celDate, rowStartDate, rowEndDate);
  1412. evtColNode.attr(COLSPAN, evtSplitInfo.colspan);
  1413. rowRenderedColumns += (evtSplitInfo.colspan - 1);
  1414. instance._syncEventNodeContainerUI(evt, evtNodeContainer, evtSplitInfo);
  1415. instance._syncEventNodeUI(evt, evtNodeContainer, celDate);
  1416. var key = String(celDate.getTime());
  1417. instance.evtRenderedStack[key].push(evt);
  1418. }
  1419. rowRenderedColumns++;
  1420. rowNode.append(evtColNode);
  1421. });
  1422. return rowNode;
  1423. },
  1424. buildEventsTable: function(rowStartDate, rowEndDate) {
  1425. var instance = this;
  1426. var displayRows = instance.get(DISPLAY_ROWS);
  1427. var intervalStartDate = DateMath.clearTime(instance._findCurrentIntervalStart());
  1428. var cacheKey = String(intervalStartDate.getTime())
  1429. .concat(rowStartDate.getTime())
  1430. .concat(rowEndDate.getTime());
  1431. var rowDataTableNode = instance.rowDataTableStack[cacheKey];
  1432. if (!rowDataTableNode) {
  1433. rowDataTableNode = A.Node.create(TPL_SVT_TABLE_DATA);
  1434. var tableBody = rowDataTableNode.one(TBODY);
  1435. var titleRowNode = instance.buildEventsTitleRow(rowDataTableNode, rowStartDate, rowEndDate);
  1436. tableBody.append(titleRowNode);
  1437. for (var rowDisplayIndex = 0; rowDisplayIndex < displayRows; rowDisplayIndex++) {
  1438. var rowNode = instance.buildEventsRow(rowStartDate, rowEndDate, rowDisplayIndex);
  1439. tableBody.append(rowNode);
  1440. }
  1441. instance.rowDataTableStack[cacheKey] = rowDataTableNode;
  1442. }
  1443. return rowDataTableNode;
  1444. },
  1445. buildEventsTitleRow: function(tableNode, rowStartDate, rowEndDate) {
  1446. var instance = this;
  1447. var titleRowNode = A.Node.create(TPL_SVT_TABLE_DATA_ROW);
  1448. instance.loopDates(rowStartDate, rowEndDate, function(celDate, index) {
  1449. var colTitleNode = A.Node.create(TPL_SVT_TABLE_DATA_COL);
  1450. colTitleNode
  1451. .addClass(CSS_SVT_TABLE_DATA_COL_TITLE)
  1452. .toggleClass(
  1453. CSS_SVT_TABLE_DATA_COL_TITLE_FIRST,
  1454. (index === 0)
  1455. )
  1456. .toggleClass(
  1457. CSS_SVT_TABLE_DATA_COL_TITLE_TODAY,
  1458. DateMath.isToday(celDate)
  1459. )
  1460. .toggleClass(
  1461. CSS_SVT_TABLE_DATA_COL_TITLE_NEXT,
  1462. DateMath.isToday(DateMath.subtract(celDate, DateMath.DAY, 1))
  1463. )
  1464. .toggleClass(
  1465. CSS_SVT_TABLE_DATA_COL_TITLE_DOWN,
  1466. DateMath.isToday(DateMath.subtract(celDate, DateMath.WEEK, 1))
  1467. );
  1468. titleRowNode.append(
  1469. colTitleNode.setContent(celDate.getDate())
  1470. );
  1471. });
  1472. return titleRowNode;
  1473. },
  1474. buildGridRowNode: function(rowIndex) {
  1475. var instance = this;
  1476. var displayRowsCount = instance._getDisplayRowsCount();
  1477. var rowRelativeHeight = 100 / displayRowsCount;
  1478. var tableGridNode = instance._getTableGridNode(rowIndex);
  1479. var rowNode = A.Node.create(
  1480. Lang.sub(
  1481. TPL_SVT_ROW,
  1482. {
  1483. height: rowRelativeHeight,
  1484. top: rowRelativeHeight * rowIndex
  1485. }
  1486. )
  1487. );
  1488. rowNode.append(
  1489. tableGridNode.toggleClass(CSS_SVT_TABLE_GRID_FIRST, (rowIndex === 0))
  1490. );
  1491. return rowNode;
  1492. },
  1493. flushViewCache: function() {
  1494. var instance = this;
  1495. instance.evtDateStack = {};
  1496. instance.evtRenderedStack = {};
  1497. instance.rowDataTableStack = {};
  1498. },
  1499. getIntersectEvents: function(date) {
  1500. var instance = this;
  1501. var scheduler = instance.get(SCHEDULER);
  1502. var key = String(date.getTime());
  1503. if (!instance.evtDateStack[key]) {
  1504. var events = scheduler.getIntersectEvents(date);
  1505. instance.evtDateStack[key] = events.filter(
  1506. instance.get(FILTER_FN)
  1507. );
  1508. }
  1509. return instance.evtDateStack[key];
  1510. },
  1511. getNextDate: function() {
  1512. var instance = this;
  1513. var scheduler = instance.get(SCHEDULER);
  1514. var currentDate = scheduler.get(CURRENT_DATE);
  1515. var displayDaysInterval = instance.get(DISPLAY_DAYS_INTERVAL);
  1516. return DateMath.add(currentDate, DateMath.DAY, displayDaysInterval);
  1517. },
  1518. getPrevDate: function() {
  1519. var instance = this;
  1520. var scheduler = instance.get(SCHEDULER);
  1521. var currentDate = scheduler.get(CURRENT_DATE);
  1522. var displayDaysInterval = instance.get(DISPLAY_DAYS_INTERVAL);
  1523. return DateMath.subtract(currentDate, DateMath.DAY, displayDaysInterval);
  1524. },
  1525. hideEventsOverlay: function() {
  1526. var instance = this;
  1527. instance[EVENTS_OVERLAY].set(VISIBLE, false);
  1528. },
  1529. loopDates: function(startDate, endDate, fn, incrementBy, factor) {
  1530. var instance = this;
  1531. var curDate = DateMath.clone(startDate);
  1532. var endDateMs = endDate.getTime();
  1533. var index;
  1534. for (index = 0; curDate.getTime() <= endDateMs; index++) {
  1535. fn.apply(instance, [curDate, index]);
  1536. curDate = DateMath.add(curDate, (incrementBy || DateMath.DAY), (factor || 1));
  1537. }
  1538. },
  1539. plotEvents: function() {
  1540. var instance = this;
  1541. var intervalStartDate = instance._findCurrentIntervalStart();
  1542. var startDateRef = DateMath.safeClearTime(intervalStartDate);
  1543. instance.flushViewCache();
  1544. instance.hideEventsOverlay();
  1545. instance.bodyNode.all(DOT+CSS_SVT_TABLE_DATA).remove();
  1546. var displayDaysInterval = instance.get(DISPLAY_DAYS_INTERVAL);
  1547. var weekDaysCount = Math.min(displayDaysInterval, WEEK_LENGTH);
  1548. instance[TABLE_ROWS].each(function(rowNode, index) {
  1549. var rowStartDate = DateMath.add(startDateRef, DateMath.DAY, weekDaysCount * index);
  1550. var rowEndDate = DateMath.add(rowStartDate, DateMath.DAY, weekDaysCount - 1);
  1551. var tableNode = instance.buildEventsTable(rowStartDate, rowEndDate);
  1552. if (index === 0) {
  1553. tableNode.addClass(CSS_SVT_TABLE_DATA_FIRST);
  1554. }
  1555. rowNode.append(tableNode);
  1556. });
  1557. },
  1558. syncDaysHeaderUI: function() {
  1559. var instance = this;
  1560. var scheduler = instance.get(SCHEDULER);
  1561. var currentDate = scheduler.get(CURRENT_DATE);
  1562. var formatter = instance.get(HEADER_DATE_FORMATTER);
  1563. var locale = instance.get(LOCALE);
  1564. var firstDayOfWeekDt = instance._findFirstDayOfWeek(currentDate);
  1565. instance.colHeaderDaysNode.all(DIV).each(
  1566. function(columnNode, i) {
  1567. var columnDate = DateMath.add(firstDayOfWeekDt, DateMath.DAY, i);
  1568. columnNode.html(formatter.call(instance, columnDate));
  1569. }
  1570. );
  1571. },
  1572. syncGridUI: function() {
  1573. var instance = this;
  1574. var today = instance.getToday();
  1575. var scheduler = instance.get(SCHEDULER);
  1576. instance[COLUMN_TABLE_GRID].removeClass(CSS_SVT_COLGRID_TODAY);
  1577. var intervalStartDate = instance._findCurrentIntervalStart();
  1578. var intervalEndDate = instance._findCurrentIntervalEnd();
  1579. if (DateMath.between(today, intervalStartDate, intervalEndDate)) {
  1580. var firstDayOfWeek = scheduler.get(FIRST_DAY_OF_WEEK);
  1581. var firstWeekDay = instance._findFirstDayOfWeek(today);
  1582. var rowIndex = DateMath.getWeekNumber(today, firstDayOfWeek) - DateMath.getWeekNumber(intervalStartDate, firstDayOfWeek);
  1583. var colIndex = (today.getDate() - firstWeekDay.getDate());
  1584. var celIndex = instance._getCellIndex([colIndex, rowIndex]);
  1585. var todayCel = instance[COLUMN_TABLE_GRID].item(celIndex);
  1586. if (todayCel) {
  1587. todayCel.addClass(CSS_SVT_COLGRID_TODAY);
  1588. }
  1589. }
  1590. },
  1591. syncStdContent: function() {
  1592. var instance = this;
  1593. instance.setStdModContent(
  1594. WidgetStdMod.BODY, instance[ROWS_CONTAINER_NODE].getDOM());
  1595. instance.setStdModContent(
  1596. WidgetStdMod.HEADER, instance[HEADER_TABLE_NODE].getDOM());
  1597. },
  1598. _findCurrentIntervalEnd: function() {
  1599. var instance = this;
  1600. var scheduler = instance.get(SCHEDULER);
  1601. var currentDate = scheduler.get(CURRENT_DATE);
  1602. var displayDaysInterval = instance.get(DISPLAY_DAYS_INTERVAL);
  1603. return DateMath.add(currentDate, DateMath.DAY, displayDaysInterval);
  1604. },
  1605. _findCurrentIntervalStart: function() {
  1606. var instance = this;
  1607. var scheduler = instance.get(SCHEDULER);
  1608. return scheduler.get(CURRENT_DATE);
  1609. },
  1610. _findFirstDayOfWeek: function(date) {
  1611. var instance = this;
  1612. var scheduler = instance.get(SCHEDULER);
  1613. var firstDayOfWeek = scheduler.get(FIRST_DAY_OF_WEEK);
  1614. return DateMath.getFirstDayOfWeek(date, firstDayOfWeek);
  1615. },
  1616. _getDisplayRowsCount: function() {
  1617. var instance = this;
  1618. var displayDaysInterval = instance.get(DISPLAY_DAYS_INTERVAL);
  1619. return Math.ceil(displayDaysInterval / WEEK_LENGTH);
  1620. },
  1621. _getDisplayRowDaysCount: function() {
  1622. var instance = this;
  1623. var displayDaysInterval = instance.get(DISPLAY_DAYS_INTERVAL);
  1624. return Math.min(displayDaysInterval, WEEK_LENGTH);
  1625. },
  1626. _getEvtLabel: function(evt) {
  1627. var instance = this;
  1628. var endDate = evt.get(END_DATE);
  1629. var startDate = evt.get(START_DATE);
  1630. return [ startDate.getHours(), DASH, endDate.getHours(), SPACE, evt.get(CONTENT) ].join(EMPTY_STR);
  1631. },
  1632. _getEvtSplitInfo: function(evt, celDate, rowStartDate, rowEndDate) {
  1633. var instance = this;
  1634. var startDate = evt.getClearStartDate();
  1635. var endDate = evt.getClearEndDate();
  1636. var maxColspan = DateMath.getDayOffset(rowEndDate, celDate);
  1637. var info = {
  1638. colspan: Math.min(DateMath.getDayOffset(endDate, celDate), maxColspan) + 1,
  1639. left: DateMath.before(startDate, rowStartDate),
  1640. right: DateMath.after(endDate, rowEndDate)
  1641. };
  1642. return info;
  1643. },
  1644. _getRenderableEvent: function(events, rowStartDate, rowEndDate, celDate) {
  1645. var instance = this;
  1646. var key = String(celDate.getTime());
  1647. if (!instance.evtRenderedStack[key]) {
  1648. instance.evtRenderedStack[key] = [];
  1649. }
  1650. for (var i = 0; i < events.length; i++) {
  1651. var evt = events[i];
  1652. var startDate = evt.get(START_DATE);
  1653. var isEventDateContinuation = DateMath.after(celDate, startDate) && !DateMath.isDayOverlap(celDate, rowStartDate);
  1654. var isEventStartDateDay = !DateMath.isDayOverlap(startDate, celDate);
  1655. var isRendered = A.Array.indexOf(instance.evtRenderedStack[key], evt) > -1;
  1656. if (!isRendered && (isEventStartDateDay || isEventDateContinuation)) {
  1657. return evt;
  1658. }
  1659. }
  1660. return null;
  1661. },
  1662. _getTableGridNode: function(rowIndex) {
  1663. var instance = this;
  1664. var displayDaysInterval = instance.get(DISPLAY_DAYS_INTERVAL);
  1665. var tableGridNode = instance[TABLE_GRID_NODE].item(rowIndex);
  1666. var firstRowNode = tableGridNode.one(TR);
  1667. for (var i = 0; i < Math.min(displayDaysInterval, WEEK_LENGTH); i++) {
  1668. var columnNode = A.Node.create(TPL_SVT_GRID_COLUMN);
  1669. firstRowNode.append(columnNode);
  1670. instance[COLUMN_TABLE_GRID].push(columnNode);
  1671. }
  1672. return tableGridNode;
  1673. },
  1674. _onClickMore: function(event) {
  1675. var instance = this;
  1676. var target = event.target;
  1677. var events = target.getData(EVENTS);
  1678. var eventsNodeList = A.NodeList.create();
  1679. A.Array.each(events, function(evt) {
  1680. var evtNode = evt.get(NODE).item(0).clone();
  1681. evtNode.setData(SCHEDULER_EVENT, evt);
  1682. evtNode.setStyles({
  1683. height: 'auto',
  1684. left: 0,
  1685. position: 'relative',
  1686. top: 0,
  1687. width: 'auto'
  1688. });
  1689. eventsNodeList.push(evtNode);
  1690. });
  1691. instance[EVENTS_OVERLAY].bodyNode.one(DOT+CSS_SVT_EVENTS_OVERLAY_NODE_BODY).setContent(eventsNodeList);
  1692. instance[EVENTS_OVERLAY].setAttrs({
  1693. visible: true,
  1694. xy: target.getXY()
  1695. });
  1696. },
  1697. _renderEventsOverlay: function() {
  1698. var instance = this;
  1699. var strings = instance.get(STRINGS);
  1700. instance[EVENTS_OVERLAY] = new A.Overlay({
  1701. align: {
  1702. points: [ TL, TL ]
  1703. },
  1704. bodyContent: Lang.sub(
  1705. TPL_SVT_EVENTS_OVERLAY_NODE,
  1706. {
  1707. label: strings[CLOSE]
  1708. }
  1709. ),
  1710. render: instance[ROWS_CONTAINER_NODE],
  1711. visible: false,
  1712. width: 250,
  1713. zIndex: 450
  1714. });
  1715. instance[EVENTS_OVERLAY].bodyNode.delegate('click', A.bind(instance.hideEventsOverlay, instance), DOT+CSS_SVT_EVENTS_OVERLAY_NODE_CLOSE);
  1716. },
  1717. _syncEventNodeContainerUI: function(evt, node, evtSplitInfo) {
  1718. var instance = this;
  1719. node.addClass(CSS_SVT_TABLE_DATA_EVENT);
  1720. if (evtSplitInfo.left) {
  1721. node.addClass(CSS_SVT_TABLE_DATA_EVENT_LEFT).prepend(TPL_SVT_EV_ICON_LEFT);
  1722. }
  1723. if (evtSplitInfo.right) {
  1724. node.addClass(CSS_SVT_TABLE_DATA_EVENT_RIGHT).append(TPL_SVT_EV_ICON_RIGHT);
  1725. }
  1726. if (evt.get(PARENT_EVENT)) {
  1727. node.addClass(CSS_SVT_TABLE_DATA_EVENT_REPEATED);
  1728. }
  1729. },
  1730. _syncEventNodeUI: function(evt, container, celDate) {
  1731. var instance = this;
  1732. var scheduler = instance.get(SCHEDULER);
  1733. var firstDayOfWeek = scheduler.get(FIRST_DAY_OF_WEEK);
  1734. var evtNodeList = evt.get(NODE);
  1735. var startDate = evt.get(START_DATE);
  1736. var intervalStartDate = DateMath.clearTime(instance._findCurrentIntervalStart());
  1737. var startDateFirstDayOfWeek = DateMath.getFirstDayOfWeek(new Date(Math.max(startDate, intervalStartDate)), firstDayOfWeek);
  1738. var paddingNodeIndex = Math.floor(DateMath.getDayOffset(celDate, startDateFirstDayOfWeek) / WEEK_LENGTH);
  1739. if (evtNodeList.size() <= paddingNodeIndex) {
  1740. evt.addPaddingNode();
  1741. }
  1742. var evtNode = evtNodeList.item(paddingNodeIndex);
  1743. evtNode.setStyles({
  1744. height: 'auto',
  1745. left: 0,
  1746. top: 0,
  1747. width: 'auto'
  1748. });
  1749. evtNode.appendTo(container);
  1750. evt.syncNodeUI();
  1751. },
  1752. _uiSetCurrentDate: function(val) {
  1753. var instance = this;
  1754. instance.syncDaysHeaderUI();
  1755. instance.syncGridUI();
  1756. },
  1757. _valueColHeaderDaysNode: function() {
  1758. var instance = this;
  1759. var displayDaysInterval = instance.get(DISPLAY_DAYS_INTERVAL);
  1760. var weekDaysCount = Math.min(displayDaysInterval, WEEK_LENGTH);
  1761. return instance._valueNodeList(weekDaysCount, TPL_SVT_HEADER_DAY);
  1762. },
  1763. _valueTableGridNode: function() {
  1764. var instance = this;
  1765. var displayDaysInterval = instance.get(DISPLAY_DAYS_INTERVAL);
  1766. var weekDaysCount = Math.min(displayDaysInterval, WEEK_LENGTH);
  1767. return instance._valueNodeList(weekDaysCount, TPL_SVT_TABLE_GRID);
  1768. },
  1769. _valueNodeList: function(size, tpl) {
  1770. var instance = this;
  1771. var buffer = [];
  1772. while (size--) {
  1773. buffer.push(tpl);
  1774. }
  1775. return A.NodeList.create(buffer.join(EMPTY_STR));
  1776. }
  1777. }
  1778. });
  1779. A.SchedulerTableView = SchedulerTableView;
  1780. var CSS_SVM_TABLE_DATA_COL_NOMONTH = getCN(SCHEDULER_VIEW_MONTH, TABLE, DATA, COL, NOMONTH);
  1781. var SchedulerMonthView = A.Component.create({
  1782. NAME: SCHEDULER_VIEW_MONTH,
  1783. ATTRS: {
  1784. displayDaysInterval: {
  1785. readOnly: true,
  1786. value: 42
  1787. },
  1788. name: {
  1789. value: MONTH
  1790. },
  1791. navigationDateFormatter: {
  1792. value: function(date) {
  1793. var instance = this;
  1794. var scheduler = instance.get(SCHEDULER);
  1795. return A.DataType.Date.format(
  1796. date,
  1797. {
  1798. format: '%B %Y',
  1799. locale: scheduler.get(LOCALE)
  1800. }
  1801. );
  1802. },
  1803. validator: isFunction
  1804. }
  1805. },
  1806. EXTENDS: A.SchedulerTableView,
  1807. prototype: {
  1808. getNextDate: function() {
  1809. var instance = this;
  1810. var scheduler = instance.get(SCHEDULER);
  1811. var currentDate = scheduler.get(CURRENT_DATE);
  1812. return DateMath.add(currentDate, DateMath.MONTH, 1);
  1813. },
  1814. getPrevDate: function() {
  1815. var instance = this;
  1816. var scheduler = instance.get(SCHEDULER);
  1817. var currentDate = scheduler.get(CURRENT_DATE);
  1818. return DateMath.subtract(currentDate, DateMath.MONTH, 1);
  1819. },
  1820. plotEvents: function() {
  1821. var instance = this;
  1822. A.SchedulerMonthView.superclass.plotEvents.apply(instance, arguments);
  1823. var scheduler = instance.get(SCHEDULER);
  1824. var currentDate = scheduler.get(CURRENT_DATE);
  1825. var monthEnd = DateMath.findMonthEnd(currentDate);
  1826. var monthStart = DateMath.findMonthStart(currentDate);
  1827. var currentIntervalStart = instance._findCurrentIntervalStart();
  1828. var colTitleNodes = instance[TABLE_ROW_CONTAINER].all(DOT+CSS_SVT_TABLE_DATA_COL_TITLE);
  1829. colTitleNodes.each(function(colTitleNode, index) {
  1830. var celDate = DateMath.add(currentIntervalStart, DateMath.DAY, index);
  1831. if (DateMath.before(celDate, monthStart) || DateMath.after(celDate, monthEnd)) {
  1832. colTitleNode.addClass(CSS_SVM_TABLE_DATA_COL_NOMONTH);
  1833. }
  1834. });
  1835. },
  1836. _findCurrentIntervalStart: function() {
  1837. var instance = this;
  1838. var scheduler = instance.get(SCHEDULER);
  1839. var currentDate = scheduler.get(CURRENT_DATE);
  1840. var monthStartDate = DateMath.findMonthStart(currentDate);
  1841. return instance._findFirstDayOfWeek(monthStartDate);
  1842. },
  1843. _findFirstDayOfWeek: function(date) {
  1844. var instance = this;
  1845. var scheduler = instance.get(SCHEDULER);
  1846. var firstDayOfWeek = scheduler.get(FIRST_DAY_OF_WEEK);
  1847. return DateMath.getFirstDayOfWeek(date, firstDayOfWeek);
  1848. }
  1849. }
  1850. });
  1851. A.SchedulerMonthView = SchedulerMonthView;
  1852. var CSS_SVT_DRAGGING = getCN(SCHEDULER_VIEW, TABLE, DRAGGING),
  1853. CSS_SVT_LASSO = getCN(SCHEDULER_VIEW, TABLE, LASSO),
  1854. CSS_SVT_PROXY_NODE = getCN(SCHEDULER_VIEW, TABLE, PROXY, NODE),
  1855. TPL_SVT_LASSO = '<div class="' + CSS_SVT_LASSO + '"></div>',
  1856. TPL_SVT_PROXY_NODE = '<div class="' + CSS_SVT_PROXY_NODE + '"></div>';
  1857. A.SchedulerTableViewDD = function() {};
  1858. A.SchedulerTableViewDD.ATTRS = {
  1859. delegateConfig: {
  1860. value: {},
  1861. setter: function(val) {
  1862. var instance = this;
  1863. return A.merge(
  1864. {
  1865. dragConfig: {
  1866. offsetNode: false,
  1867. useShim: false
  1868. },
  1869. bubbleTargets: instance,
  1870. container: instance.get(BOUNDING_BOX),
  1871. nodes: DOT+CSS_SCHEDULER_EVENT,
  1872. invalid: 'input, select, button, a, textarea, ' + DOT+CSS_SCHEDULER_EVENT_DISABLED
  1873. },
  1874. val || {}
  1875. );
  1876. },
  1877. validator: isObject
  1878. }
  1879. };
  1880. A.mix(A.SchedulerTableViewDD.prototype, {
  1881. initializer: function() {
  1882. var instance = this;
  1883. instance[PROXY_NODE] = A.Node.create(TPL_SVT_PROXY_NODE);
  1884. instance.after(instance.viewDDBindUI, instance, 'bindUI');
  1885. instance.after(instance.viewDDRenderUI, instance, 'renderUI');
  1886. instance.after(instance.viewDDSyncUI, instance, 'syncUI');
  1887. },
  1888. viewDDBindUI: function() {
  1889. var instance = this;
  1890. var recorder = instance.get(SCHEDULER).get(EVENT_RECORDER);
  1891. if (recorder) {
  1892. recorder.on({
  1893. cancel: A.bind(instance.removeLasso, instance),
  1894. save: A.bind(instance.removeLasso, instance)
  1895. });
  1896. }
  1897. instance[ROWS_CONTAINER_NODE].on({
  1898. mousedown: A.bind(instance._onMouseDownGrid, instance),
  1899. mousemove: A.bind(instance._onMouseMoveGrid, instance),
  1900. mouseup: A.bind(instance._onMouseUpGrid, instance)
  1901. });
  1902. instance.after('drag:align', instance._afterDragAlign);
  1903. instance.on('drag:end', instance._onEventDragEnd);
  1904. instance.on('drag:start', instance._onEventDragStart);
  1905. },
  1906. viewDDRenderUI: function() {
  1907. var instance = this;
  1908. },
  1909. viewDDSyncUI: function() {
  1910. var instance = this;
  1911. instance._setupDragDrop();
  1912. },
  1913. removeLasso: function() {
  1914. var instance = this;
  1915. if (instance[LASSO]) {
  1916. instance[LASSO].remove();
  1917. }
  1918. },
  1919. removeProxy: function() {
  1920. var instance = this;
  1921. if (instance[PROXY_NODE]) {
  1922. instance[PROXY_NODE].remove();
  1923. }
  1924. },
  1925. renderLasso: function(startPos, endPos) {
  1926. var instance = this;
  1927. var minPos = startPos;
  1928. var maxPos = endPos;
  1929. if (startPos[1] > endPos[1]) {
  1930. minPos = endPos;
  1931. maxPos = startPos;
  1932. }
  1933. var imin = minPos[0], jmin = minPos[1],
  1934. imax = maxPos[0], jmax = maxPos[1];
  1935. instance.removeLasso();
  1936. instance.lasso = A.NodeList.create();
  1937. for (var j = jmin; j <= jmax; j++) {
  1938. var h = instance.gridCellHeight,
  1939. w = instance.gridCellWidth,
  1940. x = 0,
  1941. y = (h * j);
  1942. if (j === jmin) {
  1943. if (jmin === jmax) {
  1944. x += Math.min(imin, imax) * w;
  1945. w *= Math.abs(imax - imin) + 1;
  1946. }
  1947. else {
  1948. x += imin * w;
  1949. w *= WEEK_LENGTH - imin;
  1950. }
  1951. }
  1952. else if (j === jmax) {
  1953. w *= imax + 1;
  1954. }
  1955. else {
  1956. w *= WEEK_LENGTH;
  1957. }
  1958. var lassoNode = A.Node.create(TPL_SVT_LASSO);
  1959. instance.lasso.push(lassoNode);
  1960. instance[ROWS_CONTAINER_NODE].append(lassoNode);
  1961. lassoNode.sizeTo(w, h);
  1962. lassoNode.setXY(instance._offsetXY([x, y], 1));
  1963. }
  1964. },
  1965. _afterDragAlign: function(event) {
  1966. var instance = this;
  1967. var dd = event.target;
  1968. var bodyRegion = instance.bodyNode.get(REGION);
  1969. var mouseRegion = {
  1970. bottom: event.pageY,
  1971. left: event.pageX,
  1972. right: event.pageX,
  1973. top: event.pageY
  1974. };
  1975. if (!A.DOM.inRegion(null, bodyRegion, true, mouseRegion)) {
  1976. return;
  1977. }
  1978. var draggingEvent = instance[DRAGGING_EVENT];
  1979. var eventXY = [event.pageX, event.pageY];
  1980. var position = instance._findPosition(instance._offsetXY(eventXY, -1));
  1981. if (draggingEvent && instance._hasLassoChanged(position)) {
  1982. instance.lassoLastPosition = position;
  1983. var endPositionDate = DateMath.add(
  1984. instance._getPositionDate(position),
  1985. DateMath.MINUTES,
  1986. draggingEvent.getMinutesDuration()
  1987. );
  1988. instance.renderLasso(position, instance._getDatePosition(endPositionDate));
  1989. }
  1990. },
  1991. _findPosition: function(xy) {
  1992. var instance = this;
  1993. var i = Math.floor(xy[0] / instance.gridCellWidth);
  1994. var j = Math.floor(xy[1] / instance.gridCellHeight);
  1995. return [i, j];
  1996. },
  1997. _getCellIndex: function(position) {
  1998. var instance = this;
  1999. return position[1] * WEEK_LENGTH + position[0];
  2000. },
  2001. _getDatePosition: function(date) {
  2002. var instance = this;
  2003. var intervalStartDate = instance._findCurrentIntervalStart();
  2004. var offset = DateMath.getDayOffset(date, intervalStartDate);
  2005. var position = [];
  2006. position[1] = Math.floor(offset / WEEK_LENGTH);
  2007. position[0] = offset % WEEK_LENGTH;
  2008. return position;
  2009. },
  2010. _getPositionDate: function(position) {
  2011. var instance = this;
  2012. var intervalStartDate = instance._findCurrentIntervalStart();
  2013. var startDateRef = DateMath.safeClearTime(instance._findFirstDayOfWeek(intervalStartDate));
  2014. var date = DateMath.add(startDateRef, DateMath.DAY, instance._getCellIndex(position));
  2015. date.setHours(0, 0, 0, 0);
  2016. return date;
  2017. },
  2018. _hasLassoChanged: function(position) {
  2019. var instance = this;
  2020. var lassoLastPosition = instance.lassoLastPosition || instance.lassoStartPosition;
  2021. return lassoLastPosition && ((position[0] !== lassoLastPosition[0]) || (position[1] !== lassoLastPosition[1]));
  2022. },
  2023. _offsetXY: function(xy, sign) {
  2024. var instance = this;
  2025. var offsetXY = instance[ROWS_CONTAINER_NODE].getXY();
  2026. return [ xy[0] + offsetXY[0]*sign, xy[1] + offsetXY[1]*sign ];
  2027. },
  2028. _onEventDragEnd: function(event) {
  2029. var instance = this;
  2030. var draggingEvent = instance[DRAGGING_EVENT];
  2031. if (draggingEvent) {
  2032. draggingEvent.move(instance._getPositionDate(instance.lassoLastPosition));
  2033. draggingEvent.set(VISIBLE, true);
  2034. instance[ROWS_CONTAINER_NODE].removeClass(CSS_SVT_DRAGGING).unselectable();
  2035. event.target.set(DRAG_NODE, instance.originalDragNode);
  2036. instance.removeLasso();
  2037. instance.removeProxy();
  2038. instance.get(SCHEDULER).syncEventsUI();
  2039. }
  2040. instance[DRAGGING_EVENT] = null;
  2041. },
  2042. _onEventDragStart: function(event) {
  2043. var instance = this;
  2044. var draggingEvent = instance[DRAGGING_EVENT] = instance[DELEGATE][DD].get(NODE).getData(SCHEDULER_EVENT);
  2045. if (draggingEvent) {
  2046. instance._syncCellDimensions();
  2047. var eventXY = [event.pageX, event.pageY];
  2048. var startPosition = instance._findPosition(instance._offsetXY(eventXY, -1));
  2049. var endPositionDate = DateMath.add(
  2050. instance._getPositionDate(startPosition),
  2051. DateMath.MINUTES,
  2052. draggingEvent.getMinutesDuration()
  2053. );
  2054. instance.renderLasso(startPosition, instance._getDatePosition(endPositionDate));
  2055. draggingEvent.set(VISIBLE, false);
  2056. instance._syncProxyNodeUI(draggingEvent);
  2057. instance.lassoStartPosition = instance.lassoLastPosition = startPosition;
  2058. instance[ROWS_CONTAINER_NODE].addClass(CSS_SVT_DRAGGING).unselectable();
  2059. instance.originalDragNode = event.target.get(DRAG_NODE);
  2060. event.target.set(DRAG_NODE, instance[PROXY_NODE]);
  2061. }
  2062. },
  2063. _onMouseDownGrid: function(event) {
  2064. var instance = this;
  2065. var scheduler = instance.get(SCHEDULER);
  2066. var recorder = scheduler.get(EVENT_RECORDER);
  2067. var target = event.target;
  2068. if (recorder && target.test([DOT+CSS_SVT_COLGRID, DOT+CSS_SVT_TABLE_DATA_COL].join(COMMA))) {
  2069. instance._recording = true;
  2070. instance._syncCellDimensions();
  2071. var eventXY = instance._offsetXY([event.pageX, event.pageY], -1);
  2072. instance.lassoStartPosition = instance.lassoLastPosition = instance._findPosition(eventXY);
  2073. instance.renderLasso(instance.lassoStartPosition, instance.lassoLastPosition);
  2074. instance[ROWS_CONTAINER_NODE].unselectable();
  2075. }
  2076. },
  2077. _onMouseMoveGrid: function(event) {
  2078. var instance = this;
  2079. var target = event.currentTarget;
  2080. var eventXY = [event.pageX, event.pageY];
  2081. var position = instance._findPosition(instance._offsetXY(eventXY, -1));
  2082. if (instance._recording && instance._hasLassoChanged(position)) {
  2083. instance.lassoLastPosition = position;
  2084. instance.renderLasso(instance.lassoStartPosition, position);
  2085. }
  2086. },
  2087. _onMouseUpGrid: function(event) {
  2088. var instance = this;
  2089. var scheduler = instance.get(SCHEDULER);
  2090. var recorder = scheduler.get(EVENT_RECORDER);
  2091. if (recorder && instance._recording && !scheduler.get(DISABLED)) {
  2092. var startPositionDate = instance._getPositionDate(instance.lassoStartPosition);
  2093. var endPositionDate = instance._getPositionDate(instance.lassoLastPosition);
  2094. var startDate = new Date(Math.min(startPositionDate, endPositionDate));
  2095. startDate.setHours(0, 0, 0);
  2096. var endDate = new Date(Math.max(startPositionDate, endPositionDate));
  2097. endDate.setHours(23, 59, 59);
  2098. recorder.set(ALL_DAY, true);
  2099. recorder.set(END_DATE, endDate);
  2100. recorder.set(START_DATE, startDate);
  2101. recorder.showOverlay([event.pageX, event.pageY]);
  2102. instance._recording = false;
  2103. }
  2104. },
  2105. _setupDragDrop: function() {
  2106. var instance = this;
  2107. if (!instance[DELEGATE]) {
  2108. instance[DELEGATE] = new A.DD.Delegate(
  2109. instance.get(DELEGATE_CONFIG));
  2110. }
  2111. var dd = instance[DELEGATE][DD];
  2112. dd.unplug(A.Plugin.DDConstrained);
  2113. dd.unplug(A.Plugin.DDNodeScroll);
  2114. dd.unplug(A.Plugin.DDProxy);
  2115. dd.plug(A.Plugin.DDConstrained, {
  2116. bubbleTargets: instance,
  2117. constrain: instance.bodyNode
  2118. });
  2119. dd.plug(A.Plugin.DDNodeScroll, {
  2120. node: instance.bodyNode,
  2121. scrollDelay: 150
  2122. });
  2123. dd.plug(A.Plugin.DDProxy, {
  2124. moveOnEnd: false,
  2125. positionProxy: false
  2126. });
  2127. },
  2128. _syncCellDimensions: function() {
  2129. var instance = this;
  2130. var displayDaysInterval = instance.get(DISPLAY_DAYS_INTERVAL);
  2131. var displayRowsCount = Math.ceil(displayDaysInterval / WEEK_LENGTH);
  2132. var weekDaysCount = Math.min(displayDaysInterval, WEEK_LENGTH);
  2133. instance.gridCellHeight = instance[ROWS_CONTAINER_NODE].get(OFFSET_HEIGHT) / displayRowsCount;
  2134. instance.gridCellWidth = instance[ROWS_CONTAINER_NODE].get(OFFSET_WIDTH) / weekDaysCount;
  2135. },
  2136. _syncProxyNodeUI: function(evt) {
  2137. var instance = this;
  2138. var eventNode = evt.get(NODE).item(0);
  2139. instance[PROXY_NODE].setStyles({
  2140. backgroundColor: eventNode.getStyle('backgroundColor'),
  2141. display: 'block',
  2142. width: '200px'
  2143. });
  2144. instance[PROXY_NODE].appendTo(instance[ROWS_CONTAINER_NODE]);
  2145. instance[PROXY_NODE].setContent(evt.get(CONTENT));
  2146. }
  2147. });
  2148. A.Base.mix(A.SchedulerTableView, [ A.SchedulerTableViewDD ]);
  2149. }, '@VERSION@' ,{skinnable:true, requires:['aui-scheduler-event','aui-calendar','aui-button-item','dd-drag','dd-delegate','dd-drop','dd-constrain']});