暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

jquery.fabric.js 100KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367
  1. //Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  2. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  3. /**
  4. * Breadcrumb component
  5. *
  6. * Shows the user's current location in a hierarchy and provides a means of navigating upward.
  7. *
  8. */
  9. /**
  10. * @namespace fabric
  11. */
  12. var fabric = fabric || {};
  13. /**
  14. *
  15. * @param {HTMLElement} container - the target container for an instance of Breadcrumb
  16. * @constructor
  17. *
  18. * If dynamically populating a list run the constructor after the list has been populated
  19. * in the DOM.
  20. */
  21. fabric.Breadcrumb = function(container) {
  22. this.container = container;
  23. this.init();
  24. };
  25. fabric.Breadcrumb.prototype = (function() {
  26. //medium breakpoint
  27. var MEDIUM = 639;
  28. //cached DOM elements
  29. var _breadcrumb;
  30. var _listItems;
  31. var _contextMenu;
  32. var _overflowButton;
  33. var _overflowMenu;
  34. var _breadcrumbList;
  35. var _currentMaxItems = 0;
  36. var _itemCollection = [];
  37. /**
  38. * create internal model of list items from DOM
  39. */
  40. var _createItemCollection = function() {
  41. var length = _listItems.length;
  42. var i = 0;
  43. var item;
  44. var text;
  45. var link;
  46. var tabIndex;
  47. for(i; i < length; i++) {
  48. item = _listItems[i].querySelector('.ms-Breadcrumb-itemLink');
  49. text = item.textContent;
  50. link = item.getAttribute('href');
  51. tabIndex = parseInt(item.getAttribute('tabindex'), 10);
  52. _itemCollection.push({text: text, link: link, tabIndex: tabIndex});
  53. }
  54. };
  55. /**
  56. * Re-render lists on resize
  57. *
  58. */
  59. var _onResize = function() {
  60. _closeOverflow(null);
  61. _renderList();
  62. };
  63. /**
  64. * render breadcrumbs and overflow menus
  65. */
  66. var _renderList = function() {
  67. var maxItems = window.innerWidth > MEDIUM ? 4 : 2;
  68. if(maxItems !== _currentMaxItems) {
  69. if(_itemCollection.length > maxItems) {
  70. _breadcrumb.className += ' is-overflow';
  71. } else {
  72. _removeClass(_breadcrumb, ' is-overflow');
  73. }
  74. _addBreadcrumbItems(maxItems);
  75. _addItemsToOverflow(maxItems);
  76. }
  77. _currentMaxItems = maxItems;
  78. };
  79. /**
  80. * creates the overflow menu
  81. */
  82. var _addItemsToOverflow = function(maxItems) {
  83. _resetList(_contextMenu);
  84. var end = _itemCollection.length - maxItems;
  85. var overflowItems = _itemCollection.slice(0, end);
  86. overflowItems.forEach(function(item) {
  87. var li = document.createElement('li');
  88. li.className = 'ms-ContextualMenu-item';
  89. if(!isNaN(item.tabIndex)) {
  90. li.setAttribute('tabindex', item.tabIndex);
  91. }
  92. var a = document.createElement('a');
  93. a.className = 'ms-ContextualMenu-link';
  94. a.setAttribute('href', item.link);
  95. a.textContent = item.text;
  96. li.appendChild(a);
  97. _contextMenu.appendChild(li);
  98. });
  99. };
  100. /**
  101. * creates the breadcrumbs
  102. */
  103. var _addBreadcrumbItems = function(maxItems) {
  104. _resetList(_breadcrumbList);
  105. var i = _itemCollection.length - maxItems;
  106. if(i >= 0) {
  107. for(i; i < _itemCollection.length; i++) {
  108. var listItem = document.createElement('li');
  109. var item = _itemCollection[i];
  110. var a = document.createElement('a');
  111. var chevron = document.createElement('i');
  112. listItem.className = 'ms-Breadcrumb-listItem';
  113. a.className = 'ms-Breadcrumb-itemLink';
  114. a.setAttribute('href', item.link);
  115. if(!isNaN(item.tabIndex)) {
  116. a.setAttribute('tabindex', item.tabIndex);
  117. }
  118. a.textContent = item.text;
  119. chevron.className = 'ms-Breadcrumb-chevron ms-Icon ms-Icon--chevronRight';
  120. listItem.appendChild(a);
  121. listItem.appendChild(chevron);
  122. _breadcrumbList.appendChild(listItem);
  123. }
  124. }
  125. };
  126. /**
  127. * resets a list by removing its children
  128. */
  129. var _resetList = function(list) {
  130. while (list.firstChild) {
  131. list.removeChild(list.firstChild);
  132. }
  133. };
  134. /**
  135. * opens the overflow menu
  136. */
  137. var _openOverflow = function(event) {
  138. if(_overflowMenu.className.indexOf(' is-open') === -1) {
  139. _overflowMenu.className += ' is-open';
  140. removeOutlinesOnClick(event);
  141. // force focus rect onto overflow button
  142. _overflowButton.focus();
  143. }
  144. };
  145. var _overflowKeyPress = function(event) {
  146. if(event.keyCode === 13) {
  147. _openOverflow(event);
  148. }
  149. };
  150. /**
  151. * closes the overflow menu
  152. */
  153. var _closeOverflow = function(event) {
  154. if(!event || event.target !== _overflowButton) {
  155. _removeClass(_overflowMenu, ' is-open');
  156. }
  157. };
  158. /**
  159. * utility that removes a class from an element
  160. */
  161. var _removeClass = function (element, value) {
  162. var index = element.className.indexOf(value);
  163. if(index > -1) {
  164. element.className = element.className.substring(0, index);
  165. }
  166. };
  167. /**
  168. * caches elements and values of the component
  169. */
  170. var _cacheDOM = function(context) {
  171. _breadcrumb = context.container;
  172. _breadcrumbList = _breadcrumb.querySelector('.ms-Breadcrumb-list');
  173. _listItems = _breadcrumb.querySelectorAll('.ms-Breadcrumb-listItem');
  174. _contextMenu = _breadcrumb.querySelector('.ms-ContextualMenu');
  175. _overflowButton = _breadcrumb.querySelector('.ms-Breadcrumb-overflowButton');
  176. _overflowMenu = _breadcrumb.querySelector('.ms-Breadcrumb-overflowMenu');
  177. };
  178. /**
  179. * sets handlers for resize and button click events
  180. */
  181. var _setListeners = function() {
  182. window.addEventListener('resize', _onResize);
  183. _overflowButton.addEventListener('click', _openOverflow, false);
  184. _overflowButton.addEventListener('keypress', _overflowKeyPress, false);
  185. document.addEventListener('click', _closeOverflow, false);
  186. _breadcrumbList.addEventListener('click', removeOutlinesOnClick, false);
  187. };
  188. /**
  189. * removes focus outlines so they don't linger after click
  190. */
  191. var removeOutlinesOnClick = function(event) {
  192. event.target.blur();
  193. };
  194. /**
  195. * initializes component
  196. */
  197. var init = function() {
  198. _cacheDOM(this);
  199. _setListeners();
  200. _createItemCollection();
  201. _onResize(null);
  202. };
  203. return {
  204. init: init
  205. };
  206. }());
  207. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  208. /**
  209. * Command Bar Plugin
  210. */
  211. (function ($) {
  212. $.fn.CommandBar = function () {
  213. var createMenuItem = function(text) {
  214. var item = '<li class="ms-ContextualMenu-item"><a class="ms-ContextualMenu-link"" href="#">';
  215. item += text;
  216. item += '</a></li>';
  217. return item;
  218. };
  219. var saveCommands = function($commands, $commandWidth, $commandarea) {
  220. var commands = [];
  221. $commands.each(function() {
  222. var $Item = $(this);
  223. var $rightOffset = ($Item.position().left + $Item.outerWidth() + $commandWidth + 10) - $commandarea.position().left; // Added padding of 10
  224. commands.push({ jquery: $Item, rightOffset: $rightOffset});
  225. });
  226. return commands;
  227. };
  228. var processCommands = function(commands, width, overflowwidth) {
  229. var overFlowCommands = [];
  230. for(var i=0; i < commands.length; i++) {
  231. var $Item = commands[i].jquery;
  232. var rightOffset = commands[i].rightOffset;
  233. // If the command is outside the right boundaries add to overflow items
  234. if(!$Item.hasClass('ms-CommandBarItem-overflow')) {
  235. if((rightOffset + overflowwidth) > width) {
  236. overFlowCommands.push($Item);
  237. } else {
  238. // Make sure item is displayed
  239. $Item.removeClass('is-hidden');
  240. }
  241. }
  242. }
  243. return overFlowCommands;
  244. };
  245. var processOverflow = function(overFlowCommands, $oCommand, $menu) {
  246. var overflowStrings = '';
  247. if(overFlowCommands.length > 0) {
  248. $oCommand.addClass("is-visible");
  249. // Empty menu
  250. $menu.html('');
  251. // Add overflowed commands to ContextualMenu
  252. for(var i = 0; i < overFlowCommands.length; i++) {
  253. var $Item = $(overFlowCommands[i]);
  254. // Hide Element in CommandBar
  255. $Item.addClass('is-hidden');
  256. var commandBarItemText = $Item.find('.ms-CommandBarItem-commandText').text();
  257. overflowStrings += createMenuItem(commandBarItemText);
  258. }
  259. $menu.html(overflowStrings);
  260. } else {
  261. $oCommand.removeClass("is-visible");
  262. }
  263. };
  264. /** Go through each CommandBar we've been given. */
  265. return this.each(function () {
  266. var $CommandBar = $(this);
  267. var $CommandMainArea = $CommandBar.find('.ms-CommandBar-mainArea');
  268. var $CommandBarItems = $CommandMainArea.find('.ms-CommandBarItem').not('.ms-CommandBarItem-overflow');
  269. var $OverflowCommand = $CommandBar.find('.ms-CommandBarItem-overflow');
  270. var $OverflowCommandWidth = $CommandBar.find('.ms-CommandBarItem-overflow').outerWidth();
  271. var $OverflowMenu = $CommandBar.find('.ms-CommandBar-overflowMenu');
  272. var $SearchBox = $CommandBar.find('.ms-CommandBarSearch');
  273. var mobileSwitch = false;
  274. var overFlowCommands;
  275. var allCommands;
  276. // Go through process and save commands
  277. allCommands = saveCommands($CommandBarItems, $OverflowCommandWidth, $CommandMainArea);
  278. // Initiate process commands and add commands to overflow on load
  279. overFlowCommands = processCommands(allCommands, $CommandMainArea.innerWidth(), $OverflowCommandWidth);
  280. processOverflow(overFlowCommands, $OverflowCommand, $OverflowMenu);
  281. // Set Search Behavior
  282. if($(window).width() < 640) {
  283. $('.ms-CommandBarSearch-iconSearchWrapper').click(function() {
  284. $(this).closest('.ms-CommandBarSearch').addClass('is-active');
  285. });
  286. }
  287. // Add resize event handler on commandBar
  288. $(window).resize(function() {
  289. var overFlowCommands;
  290. if($(window).width() < 640 && mobileSwitch === false) {
  291. // Go through process and save commands
  292. allCommands = saveCommands($CommandBarItems, $OverflowCommandWidth, $CommandMainArea);
  293. mobileSwitch = true;
  294. // Search Behavior
  295. $('.ms-CommandBarSearch-iconSearchWrapper').unbind();
  296. $('.ms-CommandBarSearch-iconSearchWrapper').click(function() {
  297. $(this).closest('.ms-CommandBarSearch').addClass('is-active');
  298. });
  299. } else if($(window).width() > 639 && mobileSwitch === true) {
  300. // Go through process and save commands
  301. allCommands = saveCommands($CommandBarItems, $OverflowCommandWidth, $CommandMainArea);
  302. mobileSwitch = false;
  303. $('.ms-CommandBarSearch').unbind();
  304. }
  305. // Initiate process commands and add commands to overflow on load
  306. overFlowCommands = processCommands(allCommands, $CommandMainArea.innerWidth(), $OverflowCommandWidth);
  307. processOverflow(overFlowCommands, $OverflowCommand, $OverflowMenu);
  308. });
  309. // Hook up contextual menu
  310. $OverflowCommand.click(function() {
  311. $OverflowMenu.toggleClass('is-open');
  312. });
  313. $OverflowCommand.focusout(function() {
  314. $OverflowMenu.removeClass('is-open');
  315. });
  316. $SearchBox.find('.ms-CommandBarSearch-input').click(function() {
  317. $(this).closest('.ms-CommandBarSearch').addClass('is-active');
  318. });
  319. $SearchBox.find('.ms-CommandBarSearch-input').on('focus', function() {
  320. $(this).closest('.ms-CommandBarSearch').addClass('is-active');
  321. });
  322. // When clicking the x clear the SearchBox and put state back to normal
  323. $SearchBox.find('.ms-CommandBarSearch-iconClearWrapper').click(function() {
  324. var $input = $(this).parent().find('.ms-CommandBarSearch-input');
  325. $input.val('');
  326. $input.parent().removeClass('is-active');
  327. });
  328. $SearchBox.parent().find('.ms-CommandBarSearch-input').blur(function() {
  329. var $input = $(this);
  330. $input.val('');
  331. $input.parent().removeClass('is-active');
  332. });
  333. });
  334. };
  335. })(jQuery);
  336. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  337. /**
  338. * Contextual Menu Plugin
  339. */
  340. (function ($) {
  341. $.fn.ContextualMenu = function () {
  342. /** Go through each nav bar we've been given. */
  343. return this.each(function () {
  344. var $contextualMenu = $(this);
  345. // Set selected states.
  346. $contextualMenu.on('click', '.ms-ContextualMenu-link:not(.is-disabled)', function(event) {
  347. event.preventDefault();
  348. // Check if multiselect - set selected states
  349. if ( $contextualMenu.hasClass('ms-ContextualMenu--multiselect') ) {
  350. // If already selected, remove selection; if not, add selection
  351. if ( $(this).hasClass('is-selected') ) {
  352. $(this).removeClass('is-selected');
  353. }
  354. else {
  355. $(this).addClass('is-selected');
  356. }
  357. }
  358. // All other contextual menu variants
  359. else {
  360. // Deselect all of the items and close any menus.
  361. $('.ms-ContextualMenu-link')
  362. .removeClass('is-selected')
  363. .siblings('.ms-ContextualMenu')
  364. .removeClass('is-open');
  365. // Select this item.
  366. $(this).addClass('is-selected');
  367. // If this item has a menu, open it.
  368. if ($(this).hasClass('ms-ContextualMenu-link--hasMenu')) {
  369. $(this).siblings('.ms-ContextualMenu:first').addClass('is-open');
  370. // Open the menu without bubbling up the click event,
  371. // which can cause the menu to close.
  372. event.stopPropagation();
  373. }
  374. }
  375. });
  376. });
  377. };
  378. })(jQuery);
  379. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  380. (function ($) {
  381. /**
  382. * DatePicker Plugin
  383. */
  384. $.fn.DatePicker = function (options) {
  385. return this.each(function () {
  386. /** Set up variables and run the Pickadate plugin. */
  387. var $datePicker = $(this);
  388. var $dateField = $datePicker.find('.ms-TextField-field').pickadate($.extend({
  389. // Strings and translations.
  390. weekdaysShort: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
  391. // Don't render the buttons
  392. today: '',
  393. clear: '',
  394. close: '',
  395. // Events
  396. onStart: function() {
  397. initCustomView($datePicker);
  398. },
  399. // Classes
  400. klass: {
  401. // The element states
  402. input: 'ms-DatePicker-input',
  403. active: 'ms-DatePicker-input--active',
  404. // The root picker and states
  405. picker: 'ms-DatePicker-picker',
  406. opened: 'ms-DatePicker-picker--opened',
  407. focused: 'ms-DatePicker-picker--focused',
  408. // The picker holder
  409. holder: 'ms-DatePicker-holder',
  410. // The picker frame, wrapper, and box
  411. frame: 'ms-DatePicker-frame',
  412. wrap: 'ms-DatePicker-wrap',
  413. box: 'ms-DatePicker-dayPicker',
  414. // The picker header
  415. header: 'ms-DatePicker-header',
  416. // Month & year labels
  417. month: 'ms-DatePicker-month',
  418. year: 'ms-DatePicker-year',
  419. // Table of dates
  420. table: 'ms-DatePicker-table',
  421. // Weekday labels
  422. weekdays: 'ms-DatePicker-weekday',
  423. // Day states
  424. day: 'ms-DatePicker-day',
  425. disabled: 'ms-DatePicker-day--disabled',
  426. selected: 'ms-DatePicker-day--selected',
  427. highlighted: 'ms-DatePicker-day--highlighted',
  428. now: 'ms-DatePicker-day--today',
  429. infocus: 'ms-DatePicker-day--infocus',
  430. outfocus: 'ms-DatePicker-day--outfocus',
  431. }
  432. },options||{}));
  433. var $picker = $dateField.pickadate('picker');
  434. /** Respond to built-in picker events. */
  435. $picker.on({
  436. render: function() {
  437. updateCustomView($datePicker);
  438. },
  439. open: function() {
  440. scrollUp($datePicker);
  441. }
  442. });
  443. });
  444. };
  445. /**
  446. * After the Pickadate plugin starts, this function
  447. * adds additional controls to the picker view.
  448. */
  449. function initCustomView($datePicker) {
  450. /** Get some variables ready. */
  451. var $monthControls = $datePicker.find('.ms-DatePicker-monthComponents');
  452. var $goToday = $datePicker.find('.ms-DatePicker-goToday');
  453. var $monthPicker = $datePicker.find('.ms-DatePicker-monthPicker');
  454. var $yearPicker = $datePicker.find('.ms-DatePicker-yearPicker');
  455. var $pickerWrapper = $datePicker.find('.ms-DatePicker-wrap');
  456. var $picker = $datePicker.find('.ms-TextField-field').pickadate('picker');
  457. /** Move the month picker into position. */
  458. $monthControls.appendTo($pickerWrapper);
  459. $goToday.appendTo($pickerWrapper);
  460. $monthPicker.appendTo($pickerWrapper);
  461. $yearPicker.appendTo($pickerWrapper);
  462. /** Update the custom view. */
  463. updateCustomView($datePicker);
  464. /** Move back one month. */
  465. $monthControls.on('click', '.js-prevMonth', function(event) {
  466. event.preventDefault();
  467. var newMonth = $picker.get('highlight').month - 1;
  468. changeHighlightedDate($picker, null, newMonth, null);
  469. });
  470. /** Move ahead one month. */
  471. $monthControls.on('click', '.js-nextMonth', function(event) {
  472. event.preventDefault();
  473. var newMonth = $picker.get('highlight').month + 1;
  474. changeHighlightedDate($picker, null, newMonth, null);
  475. });
  476. /** Move back one year. */
  477. $monthPicker.on('click', '.js-prevYear', function(event) {
  478. event.preventDefault();
  479. var newYear = $picker.get('highlight').year - 1;
  480. changeHighlightedDate($picker, newYear, null, null);
  481. });
  482. /** Move ahead one year. */
  483. $monthPicker.on('click', '.js-nextYear', function(event) {
  484. event.preventDefault();
  485. var newYear = $picker.get('highlight').year + 1;
  486. changeHighlightedDate($picker, newYear, null, null);
  487. });
  488. /** Move back one decade. */
  489. $yearPicker.on('click', '.js-prevDecade', function(event) {
  490. event.preventDefault();
  491. var newYear = $picker.get('highlight').year - 10;
  492. changeHighlightedDate($picker, newYear, null, null);
  493. });
  494. /** Move ahead one decade. */
  495. $yearPicker.on('click', '.js-nextDecade', function(event) {
  496. event.preventDefault();
  497. var newYear = $picker.get('highlight').year + 10;
  498. changeHighlightedDate($picker, newYear, null, null);
  499. });
  500. /** Go to the current date, shown in the day picking view. */
  501. $goToday.click(function(event) {
  502. event.preventDefault();
  503. /** Select the current date, while keeping the picker open. */
  504. var now = new Date();
  505. $picker.set('select', [now.getFullYear(), now.getMonth(), now.getDate()]);
  506. /** Switch to the default (calendar) view. */
  507. $datePicker.removeClass('is-pickingMonths').removeClass('is-pickingYears');
  508. });
  509. /** Change the highlighted month. */
  510. $monthPicker.on('click', '.js-changeDate', function(event) {
  511. event.preventDefault();
  512. /** Get the requested date from the data attributes. */
  513. var newYear = $(this).attr('data-year');
  514. var newMonth = $(this).attr('data-month');
  515. var newDay = $(this).attr('data-day');
  516. /** Update the date. */
  517. changeHighlightedDate($picker, newYear, newMonth, newDay);
  518. /** If we've been in the "picking months" state on mobile, remove that state so we show the calendar again. */
  519. if ($datePicker.hasClass('is-pickingMonths')) {
  520. $datePicker.removeClass('is-pickingMonths');
  521. }
  522. });
  523. /** Change the highlighted year. */
  524. $yearPicker.on('click', '.js-changeDate', function(event) {
  525. event.preventDefault();
  526. /** Get the requested date from the data attributes. */
  527. var newYear = $(this).attr('data-year');
  528. var newMonth = $(this).attr('data-month');
  529. var newDay = $(this).attr('data-day');
  530. /** Update the date. */
  531. changeHighlightedDate($picker, newYear, newMonth, newDay);
  532. /** If we've been in the "picking years" state on mobile, remove that state so we show the calendar again. */
  533. if ($datePicker.hasClass('is-pickingYears')) {
  534. $datePicker.removeClass('is-pickingYears');
  535. }
  536. });
  537. /** Switch to the default state. */
  538. $monthPicker.on('click', '.js-showDayPicker', function() {
  539. $datePicker.removeClass('is-pickingMonths');
  540. $datePicker.removeClass('is-pickingYears');
  541. });
  542. /** Switch to the is-pickingMonths state. */
  543. $monthControls.on('click', '.js-showMonthPicker', function() {
  544. $datePicker.toggleClass('is-pickingMonths');
  545. });
  546. /** Switch to the is-pickingYears state. */
  547. $monthPicker.on('click', '.js-showYearPicker', function() {
  548. $datePicker.toggleClass('is-pickingYears');
  549. });
  550. }
  551. /** Change the highlighted date. */
  552. function changeHighlightedDate($picker, newYear, newMonth, newDay) {
  553. /** All variables are optional. If not provided, default to the current value. */
  554. if (newYear === null) {
  555. newYear = $picker.get('highlight').year;
  556. }
  557. if (newMonth === null) {
  558. newMonth = $picker.get('highlight').month;
  559. }
  560. if (newDay === null) {
  561. newDay = $picker.get('highlight').date;
  562. }
  563. /** Update it. */
  564. $picker.set('highlight', [newYear, newMonth, newDay]);
  565. }
  566. /** Whenever the picker renders, do our own rendering on the custom controls. */
  567. function updateCustomView($datePicker) {
  568. /** Get some variables ready. */
  569. var $monthPicker = $datePicker.find('.ms-DatePicker-monthPicker');
  570. var $yearPicker = $datePicker.find('.ms-DatePicker-yearPicker');
  571. var $picker = $datePicker.find('.ms-TextField-field').pickadate('picker');
  572. /** Set the correct year. */
  573. $monthPicker.find('.ms-DatePicker-currentYear').text($picker.get('view').year);
  574. /** Highlight the current month. */
  575. $monthPicker.find('.ms-DatePicker-monthOption').removeClass('is-highlighted');
  576. $monthPicker.find('.ms-DatePicker-monthOption[data-month="' + $picker.get('highlight').month + '"]').addClass('is-highlighted');
  577. /** Generate the grid of years for the year picker view. */
  578. // Start by removing any existing generated output. */
  579. $yearPicker.find('.ms-DatePicker-currentDecade').remove();
  580. $yearPicker.find('.ms-DatePicker-optionGrid').remove();
  581. // Generate the output by going through the years.
  582. var startingYear = $picker.get('highlight').year - 11;
  583. var decadeText = startingYear + " - " + (startingYear + 11);
  584. var output = '<div class="ms-DatePicker-currentDecade">' + decadeText + '</div>';
  585. output += '<div class="ms-DatePicker-optionGrid">';
  586. for (var year = startingYear; year < (startingYear + 12); year++) {
  587. output += '<span class="ms-DatePicker-yearOption js-changeDate" data-year="' + year + '">' + year +'</span>';
  588. }
  589. output += '</div>';
  590. // Output the title and grid of years generated above.
  591. $yearPicker.append(output);
  592. /** Highlight the current year. */
  593. $yearPicker.find('.ms-DatePicker-yearOption').removeClass('is-highlighted');
  594. $yearPicker.find('.ms-DatePicker-yearOption[data-year="' + $picker.get('highlight').year + '"]').addClass('is-highlighted');
  595. }
  596. /** Scroll the page up so that the field the date picker is attached to is at the top. */
  597. function scrollUp($datePicker) {
  598. $('html, body').animate({
  599. scrollTop: $datePicker.offset().top
  600. }, 367);
  601. }
  602. })(jQuery);
  603. !function(a){"function"==typeof define&&define.amd?define("picker",["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):this.Picker=a(jQuery)}(function(a){function b(f,g,h,k){function l(){return b._.node("div",b._.node("div",b._.node("div",b._.node("div",w.component.nodes(r.open),t.box),t.wrap),t.frame),t.holder)}function m(){u.data(g,w).addClass(t.input).val(u.data("value")?w.get("select",s.format):f.value).on("focus."+r.id+" click."+r.id,p),s.editable||u.on("keydown."+r.id,function(a){var b=a.keyCode,c=/^(8|46)$/.test(b);return 27==b?(w.close(),!1):void((32==b||c||!r.open&&w.component.key[b])&&(a.preventDefault(),a.stopPropagation(),c?w.clear().close():w.open()))}),e(f,{haspopup:!0,expanded:!1,readonly:!1,owns:f.id+"_root"+(w._hidden?" "+w._hidden.id:"")})}function n(){w.$root.on({focusin:function(a){w.$root.removeClass(t.focused),a.stopPropagation()},"mousedown click":function(b){var c=b.target;c!=w.$root.children()[0]&&(b.stopPropagation(),"mousedown"!=b.type||a(c).is(":input")||"OPTION"==c.nodeName||(b.preventDefault(),f.focus()))}}).on("click","[data-pick], [data-nav], [data-clear], [data-close]",function(){var b=a(this),c=b.data(),d=b.hasClass(t.navDisabled)||b.hasClass(t.disabled),e=document.activeElement;e=e&&(e.type||e.href)&&e,(d||e&&!a.contains(w.$root[0],e))&&f.focus(),!d&&c.nav?w.set("highlight",w.component.item.highlight,{nav:c.nav}):!d&&"pick"in c?w.set("select",c.pick).close(!0):c.clear?w.clear().close(!0):c.close&&w.close(!0)}),e(w.$root[0],"hidden",!0)}function o(){var b;s.hiddenName===!0?(b=f.name,f.name=""):(b=["string"==typeof s.hiddenPrefix?s.hiddenPrefix:"","string"==typeof s.hiddenSuffix?s.hiddenSuffix:"_submit"],b=b[0]+f.name+b[1]),w._hidden=a('<input type=hidden name="'+b+'"'+(u.data("value")||f.value?' value="'+w.get("select",s.formatSubmit)+'"':"")+">")[0],u.on("change."+r.id,function(){w._hidden.value=f.value?w.get("select",s.formatSubmit):""}).after(w._hidden)}function p(a){a.stopPropagation(),"focus"==a.type&&w.$root.addClass(t.focused),w.open()}if(!f)return b;var q=!1,r={id:f.id||"P"+Math.abs(~~(Math.random()*new Date))},s=h?a.extend(!0,{},h.defaults,k):k||{},t=a.extend({},b.klasses(),s.klass),u=a(f),v=function(){return this.start()},w=v.prototype={constructor:v,$node:u,start:function(){return r&&r.start?w:(r.methods={},r.start=!0,r.open=!1,r.type=f.type,f.autofocus=f==document.activeElement,f.readOnly=!s.editable,f.id=f.id||r.id,"text"!=f.type&&(f.type="text"),w.component=new h(w,s),w.$root=a(b._.node("div",l(),t.picker,'id="'+f.id+'_root"')),n(),s.formatSubmit&&o(),m(),s.container?a(s.container).append(w.$root):u.after(w.$root),w.on({start:w.component.onStart,render:w.component.onRender,stop:w.component.onStop,open:w.component.onOpen,close:w.component.onClose,set:w.component.onSet}).on({start:s.onStart,render:s.onRender,stop:s.onStop,open:s.onOpen,close:s.onClose,set:s.onSet}),q=c(w.$root.children()[0]),f.autofocus&&w.open(),w.trigger("start").trigger("render"))},render:function(a){return a?w.$root.html(l()):w.$root.find("."+t.box).html(w.component.nodes(r.open)),w.trigger("render")},stop:function(){return r.start?(w.close(),w._hidden&&w._hidden.parentNode.removeChild(w._hidden),w.$root.remove(),u.removeClass(t.input).removeData(g),setTimeout(function(){u.off("."+r.id)},0),f.type=r.type,f.readOnly=!1,w.trigger("stop"),r.methods={},r.start=!1,w):w},open:function(c){return r.open?w:(u.addClass(t.active),e(f,"expanded",!0),setTimeout(function(){w.$root.addClass(t.opened),e(w.$root[0],"hidden",!1)},0),c!==!1&&(r.open=!0,q&&j.css("overflow","hidden").css("padding-right","+="+d()),u.trigger("focus"),i.on("click."+r.id+" focusin."+r.id,function(a){var b=a.target;b!=f&&b!=document&&3!=a.which&&w.close(b===w.$root.children()[0])}).on("keydown."+r.id,function(c){var d=c.keyCode,e=w.component.key[d],g=c.target;27==d?w.close(!0):g!=f||!e&&13!=d?a.contains(w.$root[0],g)&&13==d&&(c.preventDefault(),g.click()):(c.preventDefault(),e?b._.trigger(w.component.key.go,w,[b._.trigger(e)]):w.$root.find("."+t.highlighted).hasClass(t.disabled)||w.set("select",w.component.item.highlight).close())})),w.trigger("open"))},close:function(a){return a&&(u.off("focus."+r.id).trigger("focus"),setTimeout(function(){u.on("focus."+r.id,p)},0)),u.removeClass(t.active),e(f,"expanded",!1),setTimeout(function(){w.$root.removeClass(t.opened+" "+t.focused),e(w.$root[0],"hidden",!0)},0),r.open?(r.open=!1,q&&j.css("overflow","").css("padding-right","-="+d()),i.off("."+r.id),w.trigger("close")):w},clear:function(a){return w.set("clear",null,a)},set:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(d=g&&a.isPlainObject(c)?c:d||{},b){g||(h[b]=c);for(e in h)f=h[e],e in w.component.item&&(void 0===f&&(f=null),w.component.set(e,f,d)),("select"==e||"clear"==e)&&u.val("clear"==e?"":w.get(e,s.format)).trigger("change");w.render()}return d.muted?w:w.trigger("set",h)},get:function(a,c){if(a=a||"value",null!=r[a])return r[a];if("value"==a)return f.value;if(a in w.component.item){if("string"==typeof c){var d=w.component.get(a);return d?b._.trigger(w.component.formats.toString,w.component,[c,d]):""}return w.component.get(a)}},on:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(b){g||(h[b]=c);for(e in h)f=h[e],d&&(e="_"+e),r.methods[e]=r.methods[e]||[],r.methods[e].push(f)}return w},off:function(){var a,b,c=arguments;for(a=0,namesCount=c.length;namesCount>a;a+=1)b=c[a],b in r.methods&&delete r.methods[b];return w},trigger:function(a,c){var d=function(a){var d=r.methods[a];d&&d.map(function(a){b._.trigger(a,w,[c])})};return d("_"+a),d(a),w}};return new v}function c(a){var b,c="position";return a.currentStyle?b=a.currentStyle[c]:window.getComputedStyle&&(b=getComputedStyle(a)[c]),"fixed"==b}function d(){if(j.height()<=h.height())return 0;var b=a('<div style="visibility:hidden;width:100px" />').appendTo("body"),c=b[0].offsetWidth;b.css("overflow","scroll");var d=a('<div style="width:100%" />').appendTo(b),e=d[0].offsetWidth;return b.remove(),c-e}function e(b,c,d){if(a.isPlainObject(c))for(var e in c)f(b,e,c[e]);else f(b,c,d)}function f(a,b,c){a.setAttribute(("role"==b?"":"aria-")+b,c)}function g(b,c){a.isPlainObject(b)||(b={attribute:c}),c="";for(var d in b){var e=("role"==d?"":"aria-")+d,f=b[d];c+=null==f?"":e+'="'+b[d]+'"'}return c}var h=a(window),i=a(document),j=a(document.documentElement);return b.klasses=function(a){return a=a||"picker",{picker:a,opened:a+"--opened",focused:a+"--focused",input:a+"__input",active:a+"__input--active",holder:a+"__holder",frame:a+"__frame",wrap:a+"__wrap",box:a+"__box"}},b._={group:function(a){for(var c,d="",e=b._.trigger(a.min,a);e<=b._.trigger(a.max,a,[e]);e+=a.i)c=b._.trigger(a.item,a,[e]),d+=b._.node(a.node,c[0],c[1],c[2]);return d},node:function(b,c,d,e){return c?(c=a.isArray(c)?c.join(""):c,d=d?' class="'+d+'"':"",e=e?" "+e:"","<"+b+d+e+">"+c+"</"+b+">"):""},lead:function(a){return(10>a?"0":"")+a},trigger:function(a,b,c){return"function"==typeof a?a.apply(b,c||[]):a},digits:function(a){return/\d/.test(a[1])?2:1},isDate:function(a){return{}.toString.call(a).indexOf("Date")>-1&&this.isInteger(a.getUTCDate())},isInteger:function(a){return{}.toString.call(a).indexOf("Number")>-1&&a%1===0},ariaAttr:g},b.extend=function(c,d){a.fn[c]=function(e,f){var g=this.data(c);return"picker"==e?g:g&&"string"==typeof e?b._.trigger(g[e],g,[f]):this.each(function(){var f=a(this);f.data(c)||new b(this,c,d,e)})},a.fn[c].defaults=d.defaults},b}),function(a){"function"==typeof define&&define.amd?define(["picker","jquery"],a):"object"==typeof exports?module.exports=a(require("./picker.js"),require("jquery")):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0],e=d.value,f=a.$node.data("value"),g=f||e,h=f?b.formatSubmit:b.format,i=function(){return d.currentStyle?"rtl"==d.currentStyle.direction:"rtl"==getComputedStyle(a.$root[0]).direction};c.settings=b,c.$node=a.$node,c.queue={min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse navigate create validate",view:"parse create validate viewset",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return a[0]===!0?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),g?c.set("select",g,{format:h}):c.set("select",null).set("highlight",c.item.now),c.key={40:7,38:-7,39:function(){return i()?-1:1},37:function(){return i()?1:-1},go:function(a){var b=c.item.highlight,d=new Date(Date.UTC(b.year,b.month,b.date+a));c.set("highlight",d,{interval:a}),this.render()}},a.on("render",function(){a.$root.find("."+b.klass.selectMonth).on("change",function(){var c=this.value;c&&(a.set("highlight",[a.get("view").year,c,a.get("highlight").date]),a.$root.find("."+b.klass.selectMonth).trigger("focus"))}),a.$root.find("."+b.klass.selectYear).on("change",function(){var c=this.value;c&&(a.set("highlight",[c,a.get("view").month,a.get("highlight").date]),a.$root.find("."+b.klass.selectYear).trigger("focus"))})},1).on("open",function(){var d="";c.disabled(c.get("now"))&&(d=":not(."+b.klass.buttonToday+")"),a.$root.find("button"+d+", select").attr("disabled",!1)},1).on("close",function(){a.$root.find("button, select").attr("disabled",!0)},1)}var d=7,e=6,f=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):a.match(/^(flip|min|max|disable|enable)$/)&&(e.select&&d.disabled(e.select)&&d.set("select",e.select,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,d){var e,g=this;return c=void 0===c?a:c,c==-1/0||1/0==c?e=c:b.isPlainObject(c)&&f.isInteger(c.pick)?c=c.obj:b.isArray(c)?(c=new Date(Date.UTC(c[0],c[1],c[2])),c=f.isDate(c)?c:g.create().obj):c=f.isInteger(c)?g.normalize(new Date(c),d):f.isDate(c)?g.normalize(c,d):g.now(a,c,d),{year:e||c.getUTCFullYear(),month:e||c.getUTCMonth(),date:e||c.getUTCDate(),day:e||c.getUTCDay(),obj:e||c,pick:e||c.getTime()}},c.prototype.createRange=function(a,c){var d=this,e=function(a){return a===!0||b.isArray(a)||f.isDate(a)?d.create(a):a};return f.isInteger(a)||(a=e(a)),f.isInteger(c)||(c=e(c)),f.isInteger(a)&&b.isPlainObject(c)?a=[c.year,c.month,c.date+a]:f.isInteger(c)&&b.isPlainObject(a)&&(c=[a.year,a.month,a.date+c]),{from:e(a),to:e(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b,c){return b=new Date,c&&c.rel&&b.setUTCDate(b.getUTCDate()+c.rel),this.normalize(b,c)},c.prototype.navigate=function(a,c,d){var e,f,g,h,i=b.isArray(c),j=b.isPlainObject(c),k=this.item.view;if(i||j){for(j?(f=c.year,g=c.month,h=c.date):(f=+c[0],g=+c[1],h=+c[2]),d&&d.nav&&k&&k.month!==g&&(f=k.year,g=k.month),e=new Date(Date.UTC(f,g+(d&&d.nav?d.nav:0),1)),f=e.getUTCFullYear(),g=e.getUTCMonth();new Date(Date.UTC(f,g,h)).getUTCMonth()!==g;)h-=1;c=[f,g,h]}return c},c.prototype.normalize=function(a){return a.setUTCHours(0,0,0,0),a},c.prototype.measure=function(a,b){var c=this;return b?"string"==typeof b?b=c.parse(a,b):f.isInteger(b)&&(b=c.now(a,b,{rel:b})):b="min"==a?-1/0:1/0,b},c.prototype.viewset=function(a,b){return this.create([b.year,b.month,1])},c.prototype.validate=function(a,c,d){var e,g,h,i,j=this,k=c,l=d&&d.interval?d.interval:1,m=-1===j.item.enable,n=j.item.min,o=j.item.max,p=m&&j.item.disable.filter(function(a){if(b.isArray(a)){var d=j.create(a).pick;d<c.pick?e=!0:d>c.pick&&(g=!0)}return f.isInteger(a)}).length;if((!d||!d.nav)&&(!m&&j.disabled(c)||m&&j.disabled(c)&&(p||e||g)||!m&&(c.pick<=n.pick||c.pick>=o.pick)))for(m&&!p&&(!g&&l>0||!e&&0>l)&&(l*=-1);j.disabled(c)&&(Math.abs(l)>1&&(c.month<k.month||c.month>k.month)&&(c=k,l=l>0?1:-1),c.pick<=n.pick?(h=!0,l=1,c=j.create([n.year,n.month,n.date+(c.pick===n.pick?0:-1)])):c.pick>=o.pick&&(i=!0,l=-1,c=j.create([o.year,o.month,o.date+(c.pick===o.pick?0:1)])),!h||!i);)c=j.create([c.year,c.month,c.date+l]);return c},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return f.isInteger(d)?a.day===(c.settings.firstDay?d:d-1)%7:b.isArray(d)||f.isDate(d)?a.pick===c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[3]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.parse=function(a,b,c){var d=this,e={};return b&&"string"==typeof b?(c&&c.format||(c=c||{},c.format=d.settings.format),d.formats.toArray(c.format).map(function(a){var c=d.formats[a],g=c?f.trigger(c,d,[b,e]):a.replace(/^!/,"").length;c&&(e[a]=b.substr(0,g)),b=b.substr(g)}),[e.yyyy||e.yy,+(e.mm||e.m)-1,e.dd||e.d]):b},c.prototype.formats=function(){function a(a,b,c){var d=a.match(/\w+/)[0];return c.mm||c.m||(c.m=b.indexOf(d)+1),d.length}function b(a){return a.match(/\w+/)[0].length}return{d:function(a,b){return a?f.digits(a):b.date},dd:function(a,b){return a?2:f.lead(b.date)},ddd:function(a,c){return a?b(a):this.settings.weekdaysShort[c.day]},dddd:function(a,c){return a?b(a):this.settings.weekdaysFull[c.day]},m:function(a,b){return a?f.digits(a):b.month+1},mm:function(a,b){return a?2:f.lead(b.month+1)},mmm:function(b,c){var d=this.settings.monthsShort;return b?a(b,d,c):d[c.month]},mmmm:function(b,c){var d=this.settings.monthsFull;return b?a(b,d,c):d[c.month]},yy:function(a,b){return a?2:(""+b.year).slice(2)},yyyy:function(a,b){return a?4:b.year},toArray:function(a){return a.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return f.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}}}(),c.prototype.isDateExact=function(a,c){var d=this;return f.isInteger(a)&&f.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(f.isDate(a)||b.isArray(a))&&(f.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:b.isPlainObject(a)&&b.isPlainObject(c)?d.isDateExact(a.from,c.from)&&d.isDateExact(a.to,c.to):!1},c.prototype.isDateOverlap=function(a,c){var d=this,e=d.settings.firstDay?1:0;return f.isInteger(a)&&(f.isDate(c)||b.isArray(c))?(a=a%7+e,a===d.create(c).day+1):f.isInteger(c)&&(f.isDate(a)||b.isArray(a))?(c=c%7+e,c===d.create(a).day+1):b.isPlainObject(a)&&b.isPlainObject(c)?d.overlapRanges(a,c):!1},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():c===!1?(d.flipEnable(1),e=[]):c===!0?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,g=0;g<e.length;g+=1)if(d.isDateExact(a,e[g])){c=!0;break}c||(f.isInteger(a)||f.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&e.push(a)}),e},c.prototype.activate=function(a,c){var d=this,e=d.item.disable,g=e.length;return"flip"==c?d.flipEnable():c===!0?(d.flipEnable(1),e=[]):c===!1?(d.flipEnable(-1),e=[]):c.map(function(a){var c,h,i,j;for(i=0;g>i;i+=1){if(h=e[i],d.isDateExact(h,a)){c=e[i]=null,j=!0;break}if(d.isDateOverlap(h,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[3]||c.push("inverted")):f.isDate(a)&&(c=[a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate(),"inverted"]);break}}if(c)for(i=0;g>i;i+=1)if(d.isDateExact(e[i],a)){e[i]=null;break}if(j)for(i=0;g>i;i+=1)if(d.isDateOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.nodes=function(a){var b=this,c=b.settings,g=b.item,h=g.now,i=g.select,j=g.highlight,k=g.view,l=g.disable,m=g.min,n=g.max,o=function(a,b){return c.firstDay&&(a.push(a.shift()),b.push(b.shift())),f.node("thead",f.node("tr",f.group({min:0,max:d-1,i:1,node:"th",item:function(d){return[a[d],c.klass.weekdays,'scope=col title="'+b[d]+'"']}})))}((c.showWeekdaysFull?c.weekdaysFull:c.weekdaysShort).slice(0),c.weekdaysFull.slice(0)),p=function(a){return f.node("div"," ",c.klass["nav"+(a?"Next":"Prev")]+(a&&k.year>=n.year&&k.month>=n.month||!a&&k.year<=m.year&&k.month<=m.month?" "+c.klass.navDisabled:""),"data-nav="+(a||-1)+" "+f.ariaAttr({role:"button",components:b.$node[0].id+"_table"})+' title="'+(a?c.labelMonthNext:c.labelMonthPrev)+'"')},q=function(){var d=c.showMonthsShort?c.monthsShort:c.monthsFull;return c.selectMonths?f.node("select",f.group({min:0,max:11,i:1,node:"option",item:function(a){return[d[a],0,"value="+a+(k.month==a?" selected":"")+(k.year==m.year&&a<m.month||k.year==n.year&&a>n.month?" disabled":"")]}}),c.klass.selectMonth,(a?"":"disabled")+" "+f.ariaAttr({components:b.$node[0].id+"_table"})+' title="'+c.labelMonthSelect+'"'):f.node("div",d[k.month],c.klass.month)},r=function(){var d=k.year,e=c.selectYears===!0?5:~~(c.selectYears/2);if(e){var g=m.year,h=n.year,i=d-e,j=d+e;if(g>i&&(j+=g-i,i=g),j>h){var l=i-g,o=j-h;i-=l>o?o:l,j=h}return f.node("select",f.group({min:i,max:j,i:1,node:"option",item:function(a){return[a,0,"value="+a+(d==a?" selected":"")]}}),c.klass.selectYear,(a?"":"disabled")+" "+f.ariaAttr({components:b.$node[0].id+"_table"})+' title="'+c.labelYearSelect+'"')}return f.node("div",d,c.klass.year)};return f.node("div",(c.selectYears?r()+q():q()+r())+p()+p(1),c.klass.header)+f.node("table",o+f.node("tbody",f.group({min:0,max:e-1,i:1,node:"tr",item:function(a){var e=c.firstDay&&0===b.create([k.year,k.month,1]).day?-7:0;return[f.group({min:d*a-k.day+e+1,max:function(){return this.min+d-1},i:1,node:"td",item:function(a){a=b.create([k.year,k.month,a+(c.firstDay?1:0)]);var d=i&&i.pick==a.pick,e=j&&j.pick==a.pick,g=l&&b.disabled(a)||a.pick<m.pick||a.pick>n.pick;return[f.node("div",a.date,function(b){return b.push(k.month==a.month?c.klass.infocus:c.klass.outfocus),h.pick==a.pick&&b.push(c.klass.now),d&&b.push(c.klass.selected),e&&b.push(c.klass.highlighted),g&&b.push(c.klass.disabled),b.join(" ")}([c.klass.day]),"data-pick="+a.pick+" "+f.ariaAttr({role:"gridcell",selected:d&&b.$node.val()===f.trigger(b.formats.toString,b,[c.format,a])?!0:null,activedescendant:e?!0:null,disabled:g?!0:null})),"",f.ariaAttr({role:"presentation"})]}})]}})),c.klass.table,'id="'+b.$node[0].id+'_table" '+f.ariaAttr({role:"grid",components:b.$node[0].id,readonly:!0}))+f.node("div",f.node("button",c.today,c.klass.buttonToday,"type=button data-pick="+h.pick+(a&&!b.disabled(h)?"":" disabled")+" "+f.ariaAttr({components:b.$node[0].id}))+f.node("button",c.clear,c.klass.buttonClear,"type=button data-clear=1"+(a?"":" disabled")+" "+f.ariaAttr({components:b.$node[0].id}))+f.node("button",c.close,c.klass.buttonClose,"type=button data-close=true "+(a?"":" disabled")+" "+f.ariaAttr({components:b.$node[0].id})),c.klass.footer)},c.defaults=function(a){return{labelMonthNext:"Next month",labelMonthPrev:"Previous month",labelMonthSelect:"Select a month",labelYearSelect:"Select a year",monthsFull:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdaysFull:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],today:"Today",clear:"Clear",close:"Close",format:"d mmmm, yyyy",klass:{table:a+"table",header:a+"header",navPrev:a+"nav--prev",navNext:a+"nav--next",navDisabled:a+"nav--disabled",month:a+"month",year:a+"year",selectMonth:a+"select--month",selectYear:a+"select--year",weekdays:a+"weekday",day:a+"day",disabled:a+"day--disabled",selected:a+"day--selected",highlighted:a+"day--highlighted",now:a+"day--today",infocus:a+"day--infocus",outfocus:a+"day--outfocus",footer:a+"footer",buttonClear:a+"button--clear",buttonToday:a+"button--today",buttonClose:a+"button--close"}}}(a.klasses().picker+"__"),a.extend("pickadate",c)});
  604. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  605. /**
  606. * Dialog Plugin
  607. *
  608. * Adds basic demonstration functionality to .ms-Dialog components.
  609. *
  610. * @param {jQuery Object} One or more .ms-Dialog components
  611. * @return {jQuery Object} The same components (allows for chaining)
  612. */
  613. (function ($) {
  614. $.fn.Dialog = function () {
  615. /** Iterate through the sample buttons, which can be used to open the Dialogs. */
  616. $(".js-DialogAction--open").each(function () {
  617. /** Open the associated dialog on click. */
  618. $(this).on('click', function () {
  619. var target = $(this).data("target");
  620. $(target).show();
  621. });
  622. });
  623. return this.each(function () {
  624. var dialog = this;
  625. /** Have the dialogs hidden for their initial state */
  626. $(dialog).hide();
  627. /** Have the close buttons close the Dialog. */
  628. $(dialog).find(".js-DialogAction--close").each(function() {
  629. $(this).on('click', function () {
  630. $(dialog).hide();
  631. });
  632. });
  633. /** Have the action buttons close the Dialog, though you would usually do some specific action per button. */
  634. $(dialog).find(".ms-Dialog-action").on('click', function () {
  635. $(dialog).hide();
  636. });
  637. });
  638. };
  639. })(jQuery);
  640. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  641. /**
  642. * Facepile Plugin
  643. *
  644. * Adds basic demonstration functionality to .ms-Facepile components.
  645. *
  646. * @param {jQuery Object} One or more .ms-Facepile components
  647. * @return {jQuery Object} The same components (allows for chaining)
  648. */
  649. (function ($) {
  650. $.fn.Facepile = function () {
  651. /** Iterate through each Facepile provided. */
  652. return this.each(function () {
  653. $('.ms-PeoplePicker').PeoplePicker();
  654. $('.ms-Panel').Panel();
  655. var $Facepile = $(this);
  656. var $membersList = $(".ms-Facepile-members");
  657. var $membersCount = $(".ms-Facepile-members > .ms-Facepile-itemBtn").length;
  658. var $panel = $('.ms-Facepile-panel.ms-Panel');
  659. var $panelMain = $panel.find(".ms-Panel-main");
  660. var $picker = $('.ms-PeoplePicker.ms-PeoplePicker--Facepile');
  661. var $pickerMembers = $picker.find('.ms-PeoplePicker-selectedPeople');
  662. var $personaCard = $('.ms-Facepile').find('.ms-PersonaCard');
  663. /** Increment member count and show/hide overflow text */
  664. var incrementMembers = function() {
  665. /** Increment person count by one */
  666. $membersCount += 1;
  667. /** Display a maxiumum of 5 people */
  668. $(".ms-Facepile-members").children(":gt(4)").hide();
  669. /** Display counter after 5 people are present */
  670. if ($membersCount > 5) {
  671. $(".ms-Facepile-itemBtn--overflow").addClass("is-active");
  672. var remainingMembers = $membersCount - 5;
  673. $(".ms-Facepile-overflowText").text("+" + remainingMembers);
  674. }
  675. };
  676. /** Open panel with people picker */
  677. $Facepile.on("click", ".js-addPerson", function() {
  678. $panelMain.css({display: "block"});
  679. $panel.toggleClass("is-open")
  680. .addClass("ms-Panel-animateIn")
  681. .removeClass('ms-Facepile-panel--overflow ms-Panel--right')
  682. .addClass('ms-Facepile-panel--addPerson');
  683. /** Close any open persona cards */
  684. $personaCard.removeClass('is-active').hide();
  685. });
  686. $panel.on("click", ".js-togglePanel", function() {
  687. $panel.toggleClass("is-open")
  688. .addClass("ms-Panel-animateIn");
  689. });
  690. /** Open oveflow panel with list of members */
  691. $Facepile.on("click", ".js-overflowPanel", function() {
  692. $panelMain.css({display: "block"});
  693. $panel.toggleClass("is-open")
  694. .addClass("ms-Panel-animateIn")
  695. .removeClass('ms-Facepile-panel--addPerson')
  696. .addClass('ms-Facepile-panel--overflow ms-Panel--right');
  697. });
  698. /** Display person count on page load */
  699. $(document).ready(function() {
  700. $(".ms-Facepile-overflowText").text("+" + $membersCount);
  701. });
  702. /** Show selected members from PeoplePicker in the Facepile */
  703. $('.ms-PeoplePicker-result').on('click', function() {
  704. var $this = $(this);
  705. var name = $this.find(".ms-Persona-primaryText").html();
  706. var title = $this.find(".ms-Persona-secondaryText").html();
  707. var selectedInitials = (function() {
  708. var nameArray = name.split(' ');
  709. var nameInitials = '';
  710. for (var i = 0; i < nameArray.length; i++) {
  711. nameInitials += nameArray[i].charAt(0);
  712. }
  713. return nameInitials.substring(0,2);
  714. })();
  715. var selectedClasses = $this.find('.ms-Persona-initials').attr('class');
  716. var selectedImage = (function() {
  717. if ($this.find('.ms-Persona-image').length) {
  718. var selectedImageSrc = $this.find('.ms-Persona-image').attr('src');
  719. return '<img class="ms-Persona-image" src="' + selectedImageSrc + '" alt="Persona image">';
  720. } else {
  721. return '';
  722. }
  723. })();
  724. var FacepileItem =
  725. '<button class="ms-Facepile-itemBtn ms-Facepile-itemBtn--member" title="' + name + '">' +
  726. '<div class="ms-Persona ms-Persona--xs">' +
  727. '<div class="ms-Persona-imageArea">' +
  728. '<div class="' + selectedClasses + '">' + selectedInitials + '</div>' +
  729. selectedImage +
  730. '</div>' +
  731. '<div class="ms-Persona-presence"></div>' +
  732. '<div class="ms-Persona-details">' +
  733. '<div class="ms-Persona-primaryText">' + name + '</div>' +
  734. '<div class="ms-Persona-secondaryText">' + title + '</div>' +
  735. '</div>' +
  736. '</div>' +
  737. '</button>';
  738. /** Add new item to members list in Facepile */
  739. $membersList.prepend(FacepileItem);
  740. /** Increment member count */
  741. incrementMembers();
  742. });
  743. /** Remove members in panel people picker */
  744. $pickerMembers.on('click', '.js-selectedRemove', function() {
  745. var memberText = $(this).parent().find('.ms-Persona-primaryText').text();
  746. var $FacepileMember = $membersList.find(".ms-Persona-primaryText:contains(" + memberText + ")").first();
  747. if ($FacepileMember) {
  748. $FacepileMember.parent().closest('.ms-Facepile-itemBtn').remove();
  749. $membersCount -= 1;
  750. /** Display a maxiumum of 5 people */
  751. $(".ms-Facepile-members").children(":lt(5)").show();
  752. /** Display counter after 5 people are present */
  753. if ($membersCount <= 5) {
  754. $(".ms-Facepile-itemBtn--overflow").removeClass("is-active");
  755. } else {
  756. var remainingMembers = $membersCount - 5;
  757. $(".ms-Facepile-overflowText").text("+" + remainingMembers);
  758. }
  759. }
  760. });
  761. /** Show persona card when selecting a Facepile item */
  762. $membersList.on('click', '.ms-Facepile-itemBtn', function() {
  763. var selectedName = $(this).find(".ms-Persona-primaryText").html();
  764. var selectedTitle = $(this).find(".ms-Persona-secondaryText").html();
  765. var selectedInitials = (function() {
  766. var name = selectedName.split(' ');
  767. var nameInitials = '';
  768. for (var i = 0; i < name.length; i++) {
  769. nameInitials += name[i].charAt(0);
  770. }
  771. return nameInitials.substring(0,2);
  772. })();
  773. var selectedClasses = $(this).find('.ms-Persona-initials').attr('class');
  774. var selectedImage = $(this).find('.ms-Persona-image').attr('src');
  775. var $card = $('.ms-PersonaCard');
  776. var $cardName = $card.find('.ms-Persona-primaryText');
  777. var $cardTitle = $card.find('.ms-Persona-secondaryText');
  778. var $cardInitials = $card.find('.ms-Persona-initials');
  779. var $cardImage = $card.find('.ms-Persona-image');
  780. /** Close any open persona cards */
  781. $personaCard.removeClass('is-active');
  782. /** Add data to persona card */
  783. $cardName.text(selectedName);
  784. $cardTitle.text(selectedTitle);
  785. $cardInitials.text(selectedInitials);
  786. $cardInitials.removeClass();
  787. $cardInitials.addClass(selectedClasses);
  788. $cardImage.attr('src', selectedImage);
  789. /** Show persona card */
  790. setTimeout(function() { $personaCard.addClass('is-active'); }, 100);
  791. /** Align persona card on md and above screens */
  792. if ($(window).width() > 480) {
  793. var itemPosition = $(this).offset().left;
  794. var correctedPosition = itemPosition - 26;
  795. $personaCard.css({'left': correctedPosition});
  796. } else {
  797. $personaCard.css({'left': 0, 'top': 'auto', 'position': 'fixed'});
  798. }
  799. });
  800. /** Dismiss persona card when clicking on the document */
  801. $(document).on('click', function(e) {
  802. var $memberBtn = $('.ms-Facepile-itemBtn--member');
  803. if (!$memberBtn.is(e.target) && $memberBtn.has(e.target).length === 0 && !$personaCard.is(e.target) && $personaCard.has(e.target).length === 0) {
  804. $personaCard.removeClass('is-active');
  805. $personaCard.removeAttr('style');
  806. } else {
  807. $personaCard.addClass('is-active');
  808. }
  809. });
  810. });
  811. };
  812. })(jQuery);
  813. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  814. /**
  815. * List Item Plugin
  816. *
  817. * Adds basic demonstration functionality to .ms-ListItem components.
  818. *
  819. * @param {jQuery Object} One or more .ms-ListItem components
  820. * @return {jQuery Object} The same components (allows for chaining)
  821. */
  822. (function ($) {
  823. $.fn.ListItem = function () {
  824. /** Go through each panel we've been given. */
  825. return this.each(function () {
  826. var $listItem = $(this);
  827. /** Detect clicks on selectable list items. */
  828. $listItem.on('click', '.js-toggleSelection', function() {
  829. $(this).parents('.ms-ListItem').toggleClass('is-selected');
  830. });
  831. });
  832. };
  833. })(jQuery);
  834. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  835. /**
  836. * Nav Bar Plugin
  837. */
  838. (function ($) {
  839. $.fn.NavBar = function () {
  840. /** Go through each nav bar we've been given. */
  841. return this.each(function () {
  842. var $navBar = $(this);
  843. // Open the nav bar on mobile.
  844. $navBar.on('click', '.js-openMenu', function(event) {
  845. event.stopPropagation();
  846. $navBar.toggleClass('is-open');
  847. });
  848. // Close the nav bar on mobile.
  849. $navBar.click(function() {
  850. if ($navBar.hasClass('is-open')) {
  851. $navBar.removeClass('is-open');
  852. }
  853. });
  854. // Set selected states and open/close menus.
  855. $navBar.on('click', '.ms-NavBar-item:not(.is-disabled)', function(event) {
  856. var $searchBox = $navBar.find('.ms-NavBar-item.ms-NavBar-item--search .ms-TextField-field');
  857. event.stopPropagation();
  858. // Prevent default actions from firing if links are not found.
  859. if ($(this).children('.ms-NavBar-link').length === 0) {
  860. event.preventDefault();
  861. }
  862. // Deselect all of the items.
  863. $(this).siblings('.ms-NavBar-item').removeClass('is-selected');
  864. // Close and blur the search box if it doesn't have text.
  865. if ($searchBox.length > 0 && $searchBox.val().length === 0) {
  866. $('.ms-NavBar-item.ms-NavBar-item--search').removeClass('is-open').find('.ms-TextField-field').blur();
  867. }
  868. // Does the selected item have a menu?
  869. if ($(this).hasClass('ms-NavBar-item--hasMenu')) {
  870. // First, close any neighboring menus.
  871. $(this).siblings('.ms-NavBar-item--hasMenu').children('.ms-ContextualMenu:first').removeClass('is-open');
  872. // Toggle 'is-open' to open or close it.
  873. $(this).children('.ms-ContextualMenu:first').toggleClass('is-open');
  874. // Toggle 'is-selected' to indicate whether it is active.
  875. $(this).toggleClass('is-selected');
  876. } else {
  877. // Doesn't have a menu, so just select the item.
  878. $(this).addClass('is-selected');
  879. // Close the submenu and any open contextual menus.
  880. $navBar.removeClass('is-open').find('.ms-ContextualMenu').removeClass('is-open');
  881. }
  882. // Is this the search box? Open it up and focus on the search field.
  883. if ($(this).hasClass('ms-NavBar-item--search')) {
  884. $(this).addClass('is-open');
  885. $(this).find('.ms-TextField-field').focus();
  886. // Close any open menus.
  887. $navBar.find('.ms-ContextualMenu:first').removeClass('is-open');
  888. }
  889. });
  890. // Prevent contextual menus from being hidden when clicking on them.
  891. $navBar.on('click', '.ms-NavBar-item .ms-ContextualMenu', function(event) {
  892. event.stopPropagation();
  893. // Collapse the mobile "panel" for nav items.
  894. $(this).removeClass('is-open');
  895. $navBar.removeClass('is-open').find('.ms-NavBar-item--hasMenu').removeClass('is-selected');
  896. });
  897. // Hide any menus and close the search box when clicking anywhere in the document.
  898. $(document).on('click', 'html', function() {
  899. var $searchBox = $navBar.find('.ms-NavBar-item.ms-NavBar-item--search .ms-TextField-field');
  900. $navBar.find('.ms-NavBar-item').removeClass('is-selected').find('.ms-ContextualMenu').removeClass('is-open');
  901. // Close and blur the search box if it doesn't have text.
  902. if ($searchBox.length > 0 && $searchBox.val().length === 0) {
  903. $navBar.find('.ms-NavBar-item.ms-NavBar-item--search').removeClass('is-open').find('.ms-TextField-field').blur();
  904. }
  905. });
  906. });
  907. };
  908. })(jQuery);
  909. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  910. /**
  911. * MessageBanner component
  912. *
  913. * A component to display error messages
  914. *
  915. */
  916. /**
  917. * @namespace fabric
  918. */
  919. var fabric = fabric || {};
  920. /**
  921. *
  922. * @param {HTMLElement} container - the target container for an instance of MessageBanner
  923. * @constructor
  924. */
  925. fabric.MessageBanner = function(container) {
  926. this.container = container;
  927. this.init();
  928. };
  929. fabric.MessageBanner.prototype = (function() {
  930. var _clipper;
  931. var _bufferSize;
  932. var _textContainerMaxWidth = 700;
  933. var _clientWidth;
  934. var _textWidth;
  935. var _initTextWidth;
  936. var _chevronButton;
  937. var _errorBanner;
  938. var _actionButton;
  939. var _closeButton;
  940. var _bufferElementsWidth = 88;
  941. var _bufferElementsWidthSmall = 35;
  942. var SMALL_BREAK_POINT = 480;
  943. /**
  944. * sets styles on resize
  945. */
  946. var _onResize = function() {
  947. _clientWidth = _errorBanner.offsetWidth;
  948. if(window.innerWidth >= SMALL_BREAK_POINT ) {
  949. _resizeRegular();
  950. } else {
  951. _resizeSmall();
  952. }
  953. };
  954. /**
  955. * resize above 480 pixel breakpoint
  956. */
  957. var _resizeRegular = function() {
  958. if ((_clientWidth - _bufferSize) > _initTextWidth && _initTextWidth < _textContainerMaxWidth) {
  959. _textWidth = "auto";
  960. _chevronButton.className = "ms-MessageBanner-expand";
  961. _collapse();
  962. } else {
  963. _textWidth = Math.min((_clientWidth - _bufferSize), _textContainerMaxWidth) + "px";
  964. if(_chevronButton.className.indexOf("is-visible") === -1) {
  965. _chevronButton.className += " is-visible";
  966. }
  967. }
  968. _clipper.style.width = _textWidth;
  969. };
  970. /**
  971. * resize below 480 pixel breakpoint
  972. */
  973. var _resizeSmall = function() {
  974. if (_clientWidth - (_bufferElementsWidthSmall + _closeButton.offsetWidth) > _initTextWidth) {
  975. _textWidth = "auto";
  976. _collapse();
  977. } else {
  978. _textWidth = (_clientWidth - (_bufferElementsWidthSmall + _closeButton.offsetWidth)) + "px";
  979. }
  980. _clipper.style.width = _textWidth;
  981. };
  982. /**
  983. * caches elements and values of the component
  984. */
  985. var _cacheDOM = function(context) {
  986. _errorBanner = context.container;
  987. _clipper = context.container.querySelector('.ms-MessageBanner-clipper');
  988. _chevronButton = context.container.querySelector('.ms-MessageBanner-expand');
  989. _actionButton = context.container.querySelector('.ms-MessageBanner-action');
  990. _bufferSize = _actionButton.offsetWidth + _bufferElementsWidth;
  991. _closeButton = context.container.querySelector('.ms-MessageBanner-close');
  992. };
  993. /**
  994. * expands component to show full error message
  995. */
  996. var _expand = function() {
  997. var icon = _chevronButton.querySelector('.ms-Icon');
  998. _errorBanner.className += " is-expanded";
  999. icon.className = "ms-Icon ms-Icon--chevronsUp";
  1000. };
  1001. /**
  1002. * collapses component to only show truncated message
  1003. */
  1004. var _collapse = function() {
  1005. var icon = _chevronButton.querySelector('.ms-Icon');
  1006. _errorBanner.className = "ms-MessageBanner";
  1007. icon.className = "ms-Icon ms-Icon--chevronsDown";
  1008. };
  1009. var _toggleExpansion = function() {
  1010. if (_errorBanner.className.indexOf("is-expanded") > -1) {
  1011. _collapse();
  1012. } else {
  1013. _expand();
  1014. }
  1015. };
  1016. /**
  1017. * hides banner when close button is clicked
  1018. */
  1019. var _hideBanner = function() {
  1020. if(_errorBanner.className.indexOf("hide") === -1) {
  1021. _errorBanner.className += " hide";
  1022. setTimeout(function() {
  1023. _errorBanner.className = "ms-MessageBanner is-hidden";
  1024. }, 500);
  1025. }
  1026. };
  1027. /**
  1028. * shows banner if the banner is hidden
  1029. */
  1030. var _showBanner = function() {
  1031. _errorBanner.className = "ms-MessageBanner";
  1032. };
  1033. /**
  1034. * sets handlers for resize and button click events
  1035. */
  1036. var _setListeners = function() {
  1037. window.addEventListener('resize', _onResize, false);
  1038. _chevronButton.addEventListener("click", _toggleExpansion, false);
  1039. _closeButton.addEventListener("click", _hideBanner, false);
  1040. };
  1041. /**
  1042. * initializes component
  1043. */
  1044. var init = function() {
  1045. _cacheDOM(this);
  1046. _setListeners();
  1047. _clientWidth = _errorBanner.offsetWidth;
  1048. _initTextWidth = _clipper.offsetWidth;
  1049. _onResize(null);
  1050. };
  1051. return {
  1052. init: init,
  1053. showBanner: _showBanner
  1054. };
  1055. }());
  1056. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  1057. var fabric = fabric || {};
  1058. /**
  1059. * People Picker Plugin
  1060. *
  1061. * Adds basic demonstration functionality to .ms-PeoplePicker components.
  1062. *
  1063. * @param {jQuery Object} One or more .ms-PeoplePicker components
  1064. * @return {jQuery Object} The same components (allows for chaining)
  1065. */
  1066. (function ($) {
  1067. $.fn.PeoplePicker = function () {
  1068. /** Iterate through each people picker provided. */
  1069. return this.each(function () {
  1070. var $peoplePicker = $(this);
  1071. var $searchField = $peoplePicker.find(".ms-PeoplePicker-searchField");
  1072. var $results = $peoplePicker.find(".ms-PeoplePicker-results");
  1073. var $selected = $peoplePicker.find('.ms-PeoplePicker-selected');
  1074. var $selectedPeople = $peoplePicker.find(".ms-PeoplePicker-selectedPeople");
  1075. var $selectedCount = $peoplePicker.find(".ms-PeoplePicker-selectedCount");
  1076. var $peopleList = $peoplePicker.find(".ms-PeoplePicker-peopleList");
  1077. var isActive = false;
  1078. var spinner;
  1079. var $personaCard = $('.ms-PeoplePicker').find('.ms-PersonaCard');
  1080. // Run when focused or clicked
  1081. function peoplePickerActive(event) {
  1082. /** Scroll the view so that the people picker is at the top. */
  1083. $('html, body').animate({
  1084. scrollTop: $peoplePicker.offset().top
  1085. }, 367);
  1086. /** Start by closing any open people pickers. */
  1087. if ( $peoplePicker.hasClass('is-active') ) {
  1088. $peoplePicker.removeClass("is-active");
  1089. }
  1090. /** Display a maxiumum of 5 people in Facepile variant */
  1091. if ($peoplePicker.hasClass('ms-PeoplePicker--Facepile') && $searchField.val() === "") {
  1092. $peopleList.children(":gt(4)").hide();
  1093. }
  1094. /** Animate results and members in Facepile variant. */
  1095. if ($peoplePicker.hasClass('ms-PeoplePicker--Facepile')) {
  1096. // $results.addClass('ms-u-slideDownIn20');
  1097. $selectedPeople.addClass('ms-u-slideDownIn20');
  1098. setTimeout(function() { $results.removeClass('ms-u-slideDownIn20'); $selectedPeople.removeClass('ms-u-slideDownIn20');}, 1000);
  1099. }
  1100. isActive = true;
  1101. /** Stop the click event from propagating, which would just close the dropdown immediately. */
  1102. event.stopPropagation();
  1103. /** Before opening, size the results panel to match the people picker. */
  1104. if (!$peoplePicker.hasClass('ms-PeoplePicker--Facepile')) {
  1105. $results.width($peoplePicker.width() - 2);
  1106. }
  1107. /** Show the $results by setting the people picker to active. */
  1108. $peoplePicker.addClass("is-active");
  1109. /** Temporarily bind an event to the document that will close the people picker when clicking anywhere. */
  1110. $(document).bind("click.peoplepicker", function() {
  1111. $peoplePicker.removeClass('is-active');
  1112. if ($peoplePicker.hasClass('ms-PeoplePicker--Facepile')) {
  1113. $peoplePicker.removeClass('is-searching');
  1114. $('.ms-PeoplePicker-selected').show();
  1115. $('.ms-PeoplePicker-searchMore').removeClass('is-active');
  1116. $searchField.val("");
  1117. }
  1118. $(document).unbind('click.peoplepicker');
  1119. isActive = false;
  1120. });
  1121. }
  1122. /** Set to active when focusing on the input. */
  1123. $peoplePicker.on('focus', '.ms-PeoplePicker-searchField', function(event) {
  1124. peoplePickerActive(event);
  1125. });
  1126. /** Set to active when clicking on the input. */
  1127. $peoplePicker.on('click', '.ms-PeoplePicker-searchField', function(event) {
  1128. peoplePickerActive(event);
  1129. });
  1130. /** Keep the people picker active when clicking within it. */
  1131. $(this).click(function (event) {
  1132. event.stopPropagation();
  1133. });
  1134. /** Add the selected person to the text field or selected list and close the people picker. */
  1135. $results.on('click', '.ms-PeoplePicker-result', function () {
  1136. var $this = $(this);
  1137. var selectedName = $this.find(".ms-Persona-primaryText").html();
  1138. var selectedTitle = $this.find(".ms-Persona-secondaryText").html();
  1139. var selectedInitials = (function() {
  1140. var name = selectedName.split(' ');
  1141. var nameInitials = '';
  1142. for (var i = 0; i < name.length; i++) {
  1143. nameInitials += name[i].charAt(0);
  1144. }
  1145. return nameInitials.substring(0,2);
  1146. })();
  1147. var selectedClasses = $this.find('.ms-Persona-initials').attr('class');
  1148. var selectedImage = (function() {
  1149. if ($this.find('.ms-Persona-image').length) {
  1150. var selectedImageSrc = $this.find('.ms-Persona-image').attr('src');
  1151. return '<img class="ms-Persona-image" src="' + selectedImageSrc + '" alt="Persona image">';
  1152. } else {
  1153. return '';
  1154. }
  1155. })();
  1156. /** Token html */
  1157. var personaHTML = '<div class="ms-PeoplePicker-persona">' +
  1158. '<div class="ms-Persona ms-Persona--xs ms-Persona--square">' +
  1159. '<div class="ms-Persona-imageArea">' +
  1160. '<div class="' + selectedClasses + '">' + selectedInitials + '</div>' +
  1161. selectedImage +
  1162. '</div>' +
  1163. '<div class="ms-Persona-presence"></div>' +
  1164. '<div class="ms-Persona-details">' +
  1165. '<div class="ms-Persona-primaryText">' + selectedName + '</div>' +
  1166. ' </div>' +
  1167. '</div>' +
  1168. '<button class="ms-PeoplePicker-personaRemove">' +
  1169. '<i class="ms-Icon ms-Icon--x"></i>' +
  1170. ' </button>' +
  1171. '</div>';
  1172. /** List item html */
  1173. var personaListItem = '<li class="ms-PeoplePicker-selectedPerson">' +
  1174. '<div class="ms-Persona ms-Persona--sm">' +
  1175. '<div class="ms-Persona-imageArea">' +
  1176. '<div class="' + selectedClasses + '">' + selectedInitials + '</div>' +
  1177. selectedImage +
  1178. '</div>' +
  1179. '<div class="ms-Persona-presence"></div>' +
  1180. '<div class="ms-Persona-details">' +
  1181. '<div class="ms-Persona-primaryText">' + selectedName + '</div>' +
  1182. '<div class="ms-Persona-secondaryText">' + selectedTitle + '</div>' +
  1183. '</div>' +
  1184. '</div>' +
  1185. '<button class="ms-PeoplePicker-resultAction js-selectedRemove"><i class="ms-Icon ms-Icon--x"></i></button>' +
  1186. '</li>';
  1187. /** Tokenize selected persona if not Facepile or memberslist variants */
  1188. if (!$peoplePicker.hasClass('ms-PeoplePicker--Facepile') && !$peoplePicker.hasClass('ms-PeoplePicker--membersList') ) {
  1189. $searchField.before(personaHTML);
  1190. $peoplePicker.removeClass("is-active");
  1191. resizeSearchField($peoplePicker);
  1192. }
  1193. /** Add selected persona to a list if Facepile or memberslist variants */
  1194. else {
  1195. if (!$selected.hasClass('is-active')) {
  1196. $selected.addClass('is-active');
  1197. }
  1198. /** Prepend persona list item html to selected people list */
  1199. $selectedPeople.prepend(personaListItem);
  1200. /** Close the picker */
  1201. $peoplePicker.removeClass("is-active");
  1202. /** Get the total amount of selected personas and display that number */
  1203. var count = $peoplePicker.find('.ms-PeoplePicker-selectedPerson').length;
  1204. $selectedCount.html(count);
  1205. /** Return picker back to default state:
  1206. - Show only the first five results in the people list for when the picker is reopened
  1207. - Make searchMore inactive
  1208. - Clear any search field text
  1209. */
  1210. $peopleList.children().show();
  1211. $peopleList.children(":gt(4)").hide();
  1212. $('.ms-PeoplePicker-searchMore').removeClass('is-active');
  1213. $searchField.val("");
  1214. }
  1215. });
  1216. /** Remove the persona when clicking the personaRemove button. */
  1217. $peoplePicker.on('click', '.ms-PeoplePicker-personaRemove', function() {
  1218. $(this).parents('.ms-PeoplePicker-persona').remove();
  1219. /** Make the search field 100% width if all personas have been removed */
  1220. if ( $('.ms-PeoplePicker-persona').length === 0 ) {
  1221. $peoplePicker.find('.ms-PeoplePicker-searchField').outerWidth('100%');
  1222. } else {
  1223. resizeSearchField($peoplePicker);
  1224. }
  1225. });
  1226. /** Trigger additional searching when clicking the search more area. */
  1227. $results.on('click', '.js-searchMore', function() {
  1228. var $searchMore = $(this);
  1229. var primaryLabel = $searchMore.find(".ms-PeoplePicker-searchMorePrimary");
  1230. var originalPrimaryLabelText = primaryLabel.html();
  1231. var searchFieldText = $searchField.val();
  1232. /** Change to searching state. */
  1233. $searchMore.addClass("is-searching");
  1234. primaryLabel.html("Searching for " + searchFieldText);
  1235. /** Attach Spinner */
  1236. if (!spinner) {
  1237. spinner = new fabric.Spinner($searchMore.get(0));
  1238. } else {
  1239. spinner.start();
  1240. }
  1241. /** Show all results in Facepile variant */
  1242. if($peoplePicker.hasClass('ms-PeoplePicker--Facepile')) {
  1243. setTimeout(function() {$peopleList.children().show();}, 1500);
  1244. }
  1245. /** Return the original state. */
  1246. setTimeout(function() {
  1247. $searchMore.removeClass("is-searching");
  1248. primaryLabel.html(originalPrimaryLabelText);
  1249. spinner.stop();
  1250. }, 1500);
  1251. });
  1252. /** Remove a result using the action icon. */
  1253. $results.on('click', '.js-resultRemove', function(event) {
  1254. event.stopPropagation();
  1255. $(this).parent(".ms-PeoplePicker-result").remove();
  1256. });
  1257. /** Expand a result if more details are available. */
  1258. $results.on('click', '.js-resultExpand', function(event) {
  1259. event.stopPropagation();
  1260. $(this).parent(".ms-PeoplePicker-result").toggleClass("is-expanded");
  1261. });
  1262. /** Remove a selected person using the action icon. */
  1263. $selectedPeople.on('click', '.js-selectedRemove', function(event) {
  1264. event.stopPropagation();
  1265. $(this).parent(".ms-PeoplePicker-selectedPerson").remove();
  1266. var count = $peoplePicker.find('.ms-PeoplePicker-selectedPerson').length;
  1267. $selectedCount.html(count);
  1268. if ($peoplePicker.find('.ms-PeoplePicker-selectedPerson').length === 0) {
  1269. $selected.removeClass('is-active');
  1270. }
  1271. });
  1272. var filterResults = function(results, currentSuggestion, currentValueExists) {
  1273. return results.find('.ms-Persona-primaryText').filter(function() {
  1274. if (currentValueExists) {
  1275. return $(this).text().toLowerCase() === currentSuggestion;
  1276. } else {
  1277. return $(this).text().toLowerCase() !== currentSuggestion;
  1278. }
  1279. }).parents('.ms-PeoplePicker-peopleListItem');
  1280. };
  1281. /** Search people picker items */
  1282. $peoplePicker.on('keyup', '.ms-PeoplePicker-searchField', function(evt) {
  1283. var suggested = [];
  1284. var newSuggestions = [];
  1285. var $pickerResult = $results.find('.ms-Persona-primaryText');
  1286. $peoplePicker.addClass('is-searching');
  1287. /** Hide members */
  1288. $selected.hide();
  1289. /** Show 5 results */
  1290. $peopleList.children(":lt(5)").show();
  1291. /** Show searchMore button */
  1292. $('.ms-PeoplePicker-searchMore').addClass('is-active');
  1293. /** Get array of suggested people */
  1294. $pickerResult.each(function() { suggested.push($(this).text()); });
  1295. /** Iterate over array to find matches and show matching items */
  1296. for (var i = 0; i < suggested.length; i++) {
  1297. var currentPersona = suggested[i].toLowerCase();
  1298. var currentValue = evt.target.value.toLowerCase();
  1299. var currentSuggestion;
  1300. if (currentPersona.indexOf(currentValue) > -1) {
  1301. currentSuggestion = suggested[i].toLowerCase();
  1302. newSuggestions.push(suggested[i]);
  1303. filterResults($results, currentSuggestion, true).show();
  1304. } else {
  1305. filterResults($results, currentSuggestion, false).hide();
  1306. }
  1307. }
  1308. /** Show members and hide searchmore when field is empty */
  1309. if ($(this).val() === "") {
  1310. $peoplePicker.removeClass('is-searching');
  1311. $selected.show();
  1312. $('.ms-PeoplePicker-searchMore').removeClass('is-active');
  1313. $selectedPeople.addClass('ms-u-slideDownIn20');
  1314. setTimeout(function() { $selectedPeople.removeClass('ms-u-slideDownIn20');}, 1000);
  1315. $peopleList.children(":gt(4)").hide();
  1316. }
  1317. });
  1318. /** Show persona card when clicking a persona in the members list */
  1319. $selectedPeople.on('click', '.ms-Persona', function() {
  1320. var selectedName = $(this).find(".ms-Persona-primaryText").html();
  1321. var selectedTitle = $(this).find(".ms-Persona-secondaryText").html();
  1322. var selectedInitials = (function() {
  1323. var name = selectedName.split(' ');
  1324. var nameInitials = '';
  1325. for (var i = 0; i < name.length; i++) {
  1326. nameInitials += name[i].charAt(0);
  1327. }
  1328. return nameInitials.substring(0,2);
  1329. })();
  1330. var selectedClasses = $(this).find('.ms-Persona-initials').attr('class');
  1331. var selectedImage = $(this).find('.ms-Persona-image').attr('src');
  1332. var $card = $('.ms-PersonaCard');
  1333. var $cardName = $card.find('.ms-Persona-primaryText');
  1334. var $cardTitle = $card.find('.ms-Persona-secondaryText');
  1335. var $cardInitials = $card.find('.ms-Persona-initials');
  1336. var $cardImage = $card.find('.ms-Persona-image');
  1337. /** Close any open persona cards */
  1338. $personaCard.removeClass('is-active');
  1339. /** Add data to persona card */
  1340. $cardName.text(selectedName);
  1341. $cardTitle.text(selectedTitle);
  1342. $cardInitials.text(selectedInitials);
  1343. $cardInitials.removeClass();
  1344. $cardInitials.addClass(selectedClasses);
  1345. $cardImage.attr('src', selectedImage);
  1346. /** Show persona card */
  1347. setTimeout(function() {
  1348. $personaCard.addClass('is-active');
  1349. setTimeout(function(){$personaCard.css({'animation-name': 'none'});}, 300);
  1350. }, 100);
  1351. /** Align persona card on md and above screens */
  1352. if ($(window).width() > 480) {
  1353. var itemPositionTop = $(this).offset().top;
  1354. var correctedPositionTop = itemPositionTop + 10;
  1355. $personaCard.css({'top': correctedPositionTop, 'left': 0});
  1356. } else {
  1357. $personaCard.css({'top': 'auto'});
  1358. }
  1359. });
  1360. /** Dismiss persona card when clicking on the document */
  1361. $(document).on('click', function(e) {
  1362. var $memberBtn = $('.ms-PeoplePicker-selectedPerson').find('.ms-Persona');
  1363. if (!$memberBtn.is(e.target) && !$personaCard.is(e.target) && $personaCard.has(e.target).length === 0) {
  1364. $personaCard.removeClass('is-active');
  1365. setTimeout(function(){$personaCard.removeAttr('style');}, 300);
  1366. } else {
  1367. $personaCard.addClass('is-active');
  1368. }
  1369. });
  1370. });
  1371. };
  1372. /** Resize the search field to match the search box */
  1373. function resizeSearchField($peoplePicker) {
  1374. var $searchBox = $peoplePicker.find('.ms-PeoplePicker-searchBox');
  1375. // Where is the right edge of the search box?
  1376. var searchBoxLeftEdge = $searchBox.position().left;
  1377. var searchBoxWidth = $searchBox.outerWidth();
  1378. var searchBoxRightEdge = searchBoxLeftEdge + searchBoxWidth;
  1379. // Where is the right edge of the last persona component?
  1380. var $lastPersona = $searchBox.find('.ms-PeoplePicker-persona:last');
  1381. var lastPersonaLeftEdge = $lastPersona.offset().left;
  1382. var lastPersonaWidth = $lastPersona.outerWidth();
  1383. var lastPersonaRightEdge = lastPersonaLeftEdge + lastPersonaWidth;
  1384. // Adjust the width of the field to fit the remaining space.
  1385. var newFieldWidth = searchBoxRightEdge - lastPersonaRightEdge - 7;
  1386. // Don't let the field get too tiny.
  1387. if (newFieldWidth < 100) {
  1388. newFieldWidth = "100%";
  1389. }
  1390. // Set the width of the search field
  1391. $peoplePicker.find('.ms-PeoplePicker-searchField').outerWidth(newFieldWidth);
  1392. }
  1393. })(jQuery);
  1394. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  1395. /**
  1396. * Panel Plugin
  1397. *
  1398. * Adds basic demonstration functionality to .ms-Panel components.
  1399. *
  1400. * @param {jQuery Object} One or more .ms-Panel components
  1401. * @return {jQuery Object} The same components (allows for chaining)
  1402. */
  1403. (function ($) {
  1404. $.fn.Panel = function () {
  1405. var pfx = ["webkit", "moz", "MS", "o", ""];
  1406. // Prefix function
  1407. function prefixedEvent(element, type, callback) {
  1408. for (var p = 0; p < pfx.length; p++) {
  1409. if (!pfx[p]) { type = type.toLowerCase(); }
  1410. element.addEventListener(pfx[p]+type, callback, false);
  1411. }
  1412. }
  1413. /** Go through each panel we've been given. */
  1414. return this.each(function () {
  1415. var $panel = $(this);
  1416. var $panelMain = $panel.find(".ms-Panel-main");
  1417. /** Hook to open the panel. */
  1418. $(".ms-PanelAction-close").on("click", function() {
  1419. // Display Panel first, to allow animations
  1420. $panel.addClass("ms-Panel-animateOut");
  1421. });
  1422. $(".ms-PanelAction-open").on("click", function() {
  1423. // Display Panel first, to allow animations
  1424. $panel.addClass("is-open");
  1425. // Add animation class
  1426. $panel.addClass("ms-Panel-animateIn");
  1427. });
  1428. prefixedEvent($panelMain[0], 'AnimationEnd', function(event) {
  1429. if (event.animationName.indexOf('Out') > -1) {
  1430. // Hide and Prevent ms-Panel-main from being interactive
  1431. $panel.removeClass('is-open');
  1432. // Remove animating classes for the next time we open panel
  1433. $panel.removeClass('ms-Panel-animateIn ms-Panel-animateOut');
  1434. }
  1435. });
  1436. });
  1437. };
  1438. })(jQuery);
  1439. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  1440. /**
  1441. * Persona Card Plugin
  1442. *
  1443. * Adds basic demonstration functionality to .ms-PersonaCard components.
  1444. *
  1445. * @param {jQuery Object} One or more .ms-PersonaCard components
  1446. * @return {jQuery Object} The same components (allows for chaining)
  1447. */
  1448. (function ($) {
  1449. $.fn.PersonaCard = function () {
  1450. /** Go through each file picker we've been given. */
  1451. return this.each(function () {
  1452. var $personaCard = $(this);
  1453. /** When selecting an action, show its details. */
  1454. $personaCard.on('click', '.ms-PersonaCard-action', function() {
  1455. /** Select the correct tab. */
  1456. $personaCard.find('.ms-PersonaCard-action').removeClass('is-active');
  1457. $(this).addClass('is-active');
  1458. /** Function for switching selected item into view by adding a class to ul. */
  1459. var updateForItem = function(wrapper, item) {
  1460. var previousItem = wrapper.className + "";
  1461. var detail = item.charAt(0).toUpperCase() + item.slice(1);
  1462. var nextItem = "ms-PersonaCard-detail" + detail;
  1463. if (previousItem !== nextItem){
  1464. wrapper.classList.remove(previousItem);
  1465. wrapper.classList.add(nextItem);
  1466. }
  1467. };
  1468. /** Get id of selected item */
  1469. var el = $(this).attr('id');
  1470. /** Add detail class to ul to switch it into view. */
  1471. updateForItem($(this).parent().next().find('#detailList')[0], el);
  1472. /** Display the corresponding details. */
  1473. var requestedAction = $(this).attr('id');
  1474. $personaCard.find('.ms-PersonaCard-actionDetails').removeClass('is-active');
  1475. $personaCard.find('#' + requestedAction + '.ms-PersonaCard-actionDetails').addClass('is-active');
  1476. });
  1477. /** Toggle more details. */
  1478. $personaCard.on('click', '.ms-PersonaCard-detailExpander', function() {
  1479. $(this).parent('.ms-PersonaCard-actionDetails').toggleClass('is-collapsed');
  1480. });
  1481. });
  1482. };
  1483. })(jQuery);
  1484. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  1485. /**
  1486. * Pivot Plugin
  1487. *
  1488. * Adds basic demonstration functionality to .ms-Pivot components.
  1489. *
  1490. * @param {jQuery Object} One or more .ms-Pivot components
  1491. * @return {jQuery Object} The same components (allows for chaining)
  1492. */
  1493. (function ($) {
  1494. $.fn.Pivot = function () {
  1495. /** Go through each pivot we've been given. */
  1496. return this.each(function () {
  1497. var $pivotContainer = $(this);
  1498. /** When clicking/tapping a link, select it. */
  1499. $pivotContainer.on('click', '.ms-Pivot-link', function(event) {
  1500. event.preventDefault();
  1501. /** Check if current selection has elipses child element **/
  1502. var $elipsisCheck = $(this).find('.ms-Pivot-ellipsis');
  1503. /** Only execute when no elipses element can be found **/
  1504. if($elipsisCheck.length === 0){
  1505. $(this).siblings('.ms-Pivot-link').removeClass('is-selected');
  1506. $(this).addClass('is-selected');
  1507. }
  1508. });
  1509. });
  1510. };
  1511. })(jQuery);
  1512. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  1513. /**
  1514. * ProgressIndicator component
  1515. *
  1516. * A component for outputting determinate progress
  1517. *
  1518. */
  1519. /**
  1520. * @namespace fabric
  1521. */
  1522. var fabric = fabric || {};
  1523. /**
  1524. *
  1525. * @param {HTMLDivElement} container - the target container for an instance of ProgressIndicator
  1526. * @constructor
  1527. */
  1528. fabric.ProgressIndicator = function(container) {
  1529. this.container = container;
  1530. this.cacheDOM();
  1531. };
  1532. fabric.ProgressIndicator.prototype = (function() {
  1533. var _progress;
  1534. var _width;
  1535. var _itemName;
  1536. var _total;
  1537. var _itemDescription;
  1538. var _progressBar;
  1539. /**
  1540. * Sets the progress percentage for a determinate
  1541. * operation. Either use this or setProgress
  1542. * and setTotal as setProgressPercent assumes
  1543. * you've done a percentage calculation before
  1544. * injecting it into the function
  1545. * @param {number} percent - a floating point number from 0 to 1
  1546. */
  1547. var setProgressPercent = function(percent) {
  1548. _progressBar.style.width = Math.round(_width * percent) + "px";
  1549. };
  1550. /**
  1551. * Sets the progress for a determinate operation.
  1552. * Use this in combination with setTotal.
  1553. * @param {number} progress
  1554. */
  1555. var setProgress = function(progress) {
  1556. _progress = progress;
  1557. var percentage = _progress / _total;
  1558. this.setProgressPercent(percentage);
  1559. };
  1560. /**
  1561. * Sets the total file size, etc. for a
  1562. * determinate operation. Use this in
  1563. * combination with setProgress
  1564. * @param {number} total
  1565. */
  1566. var setTotal = function(total) {
  1567. _total = total;
  1568. };
  1569. /**
  1570. * Sets the text for the title or label
  1571. * of an instance
  1572. * @param {string} name
  1573. */
  1574. var setName = function(name) {
  1575. _itemName.innerHTML = name;
  1576. };
  1577. /**
  1578. * Sets the text for a description
  1579. * of an instance
  1580. * @param {string} name
  1581. */
  1582. var setDescription = function(description) {
  1583. _itemDescription.innerHTML = description;
  1584. };
  1585. /**
  1586. * caches elements and values of the component
  1587. *
  1588. */
  1589. var cacheDOM = function() {
  1590. _itemName = this.container.querySelector('.ms-ProgressIndicator-itemName') || null; //an itemName element is optional
  1591. _itemDescription = this.container.querySelector('.ms-ProgressIndicator-itemDescription') || null; //an itemDescription element is optional
  1592. _progressBar = this.container.querySelector('.ms-ProgressIndicator-progressBar');
  1593. _width = this.container.querySelector('.ms-ProgressIndicator-itemProgress').offsetWidth;
  1594. };
  1595. return {
  1596. setProgressPercent: setProgressPercent,
  1597. setName: setName,
  1598. setDescription: setDescription,
  1599. setProgress: setProgress,
  1600. setTotal: setTotal,
  1601. cacheDOM: cacheDOM
  1602. };
  1603. }());
  1604. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  1605. /**
  1606. * Spinner Component
  1607. *
  1608. * An animating activity indicator.
  1609. *
  1610. */
  1611. /**
  1612. * @namespace fabric
  1613. */
  1614. var fabric = fabric || {};
  1615. /**
  1616. * @param {HTMLDOMElement} target - The element the Spinner will attach itself to.
  1617. */
  1618. fabric.Spinner = function(target) {
  1619. var _target = target;
  1620. var eightSize = 0.179;
  1621. var circleObjects = [];
  1622. var animationSpeed = 90;
  1623. var interval;
  1624. var spinner;
  1625. var numCircles;
  1626. var offsetSize;
  1627. var fadeIncrement = 0;
  1628. var parentSize;
  1629. /**
  1630. * @function start - starts or restarts the animation sequence
  1631. * @memberOf fabric.Spinner
  1632. */
  1633. function start() {
  1634. interval = setInterval(function() {
  1635. var i = circleObjects.length;
  1636. while(i--) {
  1637. _fade(circleObjects[i]);
  1638. }
  1639. }, animationSpeed);
  1640. }
  1641. /**
  1642. * @function stop - stops the animation sequence
  1643. * @memberOf fabric.Spinner
  1644. */
  1645. function stop() {
  1646. clearInterval(interval);
  1647. }
  1648. //private methods
  1649. function _init() {
  1650. //for backwards compatibility
  1651. if (_target.className.indexOf("ms-Spinner") === -1) {
  1652. spinner = document.createElement("div");
  1653. spinner.className = "ms-Spinner";
  1654. _target.appendChild(spinner);
  1655. } else {
  1656. spinner = _target;
  1657. }
  1658. offsetSize = eightSize;
  1659. numCircles = 8;
  1660. parentSize = spinner.className.indexOf("large") > -1 ? 28 : 20;
  1661. _createCirclesAndArrange();
  1662. _initializeOpacities();
  1663. start();
  1664. }
  1665. function _initializeOpacities() {
  1666. var i = 0;
  1667. var j = 1;
  1668. var opacity;
  1669. fadeIncrement = 1 / numCircles;
  1670. for (i; i < numCircles; i++) {
  1671. var circleObject = circleObjects[i];
  1672. opacity = (fadeIncrement * j++);
  1673. _setOpacity(circleObject.element, opacity);
  1674. }
  1675. }
  1676. function _fade(circleObject) {
  1677. var opacity = _getOpacity(circleObject.element) - fadeIncrement;
  1678. if (opacity <= 0) {
  1679. opacity = 1;
  1680. }
  1681. _setOpacity(circleObject.element, opacity);
  1682. }
  1683. function _getOpacity(element) {
  1684. return parseFloat(window.getComputedStyle(element).getPropertyValue("opacity"));
  1685. }
  1686. function _setOpacity(element, opacity) {
  1687. element.style.opacity = opacity;
  1688. }
  1689. function _createCircle() {
  1690. var circle = document.createElement('div');
  1691. circle.className = "ms-Spinner-circle";
  1692. circle.style.width = circle.style.height = parentSize * offsetSize + "px";
  1693. return circle;
  1694. }
  1695. function _createCirclesAndArrange() {
  1696. var angle = 0;
  1697. var offset = parentSize * offsetSize;
  1698. var step = (2 * Math.PI) / numCircles;
  1699. var i = numCircles;
  1700. var circleObject;
  1701. var radius = (parentSize - offset) * 0.5;
  1702. while (i--) {
  1703. var circle = _createCircle();
  1704. var x = Math.round(parentSize * 0.5 + radius * Math.cos(angle) - circle.clientWidth * 0.5) - offset * 0.5;
  1705. var y = Math.round(parentSize * 0.5 + radius * Math.sin(angle) - circle.clientHeight * 0.5) - offset * 0.5;
  1706. spinner.appendChild(circle);
  1707. circle.style.left = x + 'px';
  1708. circle.style.top = y + 'px';
  1709. angle += step;
  1710. circleObject = { element:circle, j:i };
  1711. circleObjects.push(circleObject);
  1712. }
  1713. }
  1714. _init();
  1715. return {
  1716. start:start,
  1717. stop:stop
  1718. };
  1719. };
  1720. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  1721. /**
  1722. * SearchBox Plugin
  1723. *
  1724. * Adds basic demonstration functionality to .ms-SearchBox components.
  1725. *
  1726. * @param {jQuery Object} One or more .ms-SearchBox components
  1727. * @return {jQuery Object} The same components (allows for chaining)
  1728. */
  1729. (function ($) {
  1730. $.fn.SearchBox = function () {
  1731. /** Iterate through each text field provided. */
  1732. return this.each(function () {
  1733. // Set cancel to false
  1734. var cancel = false;
  1735. var $searchField = $(this).find('.ms-SearchBox-field');
  1736. /** SearchBox focus - hide label and show cancel button */
  1737. $searchField.on('focus', function() {
  1738. /** Hide the label on focus. */
  1739. $(this).siblings('.ms-SearchBox-label').hide();
  1740. // Show cancel button by adding is-active class
  1741. $(this).parent('.ms-SearchBox').addClass('is-active');
  1742. });
  1743. /** 'hovering' class allows for more fine grained control of hover state */
  1744. $searchField.on('mouseover', function() {
  1745. $searchField.addClass('hovering');
  1746. });
  1747. $searchField.on('mouseout', function() {
  1748. $searchField.removeClass('hovering');
  1749. });
  1750. // If cancel button is selected, change cancel value to true
  1751. $(this).find('.ms-SearchBox-closeButton').on('mousedown', function() {
  1752. cancel = true;
  1753. });
  1754. /** Show the label again when leaving the field. */
  1755. $(this).find('.ms-SearchBox-field').on('blur', function() {
  1756. // If cancel button is selected remove the text and show the label
  1757. if (cancel) {
  1758. $(this).val('');
  1759. $searchField.addClass('hovering');
  1760. }
  1761. var $searchBox = $(this).parent('.ms-SearchBox');
  1762. // Prevents inputfield from gaining focus too soon
  1763. setTimeout(function() {
  1764. // Remove is-active class - hides cancel button
  1765. $searchBox.removeClass('is-active');
  1766. }, 10);
  1767. /** Only do this if no text was entered. */
  1768. if ($(this).val().length === 0 ) {
  1769. $(this).siblings('.ms-SearchBox-label').show();
  1770. }
  1771. // Reset cancel to false
  1772. cancel = false;
  1773. });
  1774. });
  1775. };
  1776. })(jQuery);
  1777. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  1778. /**
  1779. * Text Field Plugin
  1780. *
  1781. * Adds basic demonstration functionality to .ms-TextField components.
  1782. *
  1783. * @param {jQuery Object} One or more .ms-TextField components
  1784. * @return {jQuery Object} The same components (allows for chaining)
  1785. */
  1786. (function ($) {
  1787. $.fn.TextField = function () {
  1788. /** Iterate through each text field provided. */
  1789. return this.each(function () {
  1790. /** Does it have a placeholder? */
  1791. if ($(this).hasClass("ms-TextField--placeholder")) {
  1792. /** Hide the label on click. */
  1793. $(this).on('click', function () {
  1794. $(this).find('.ms-Label').hide();
  1795. });
  1796. /** Show the label again when leaving the field. */
  1797. $(this).find('.ms-TextField-field').on('blur', function () {
  1798. /** Only do this if no text was entered. */
  1799. if ($(this).val().length === 0) {
  1800. $(this).siblings('.ms-Label').show();
  1801. }
  1802. });
  1803. }
  1804. /** Underlined - adding/removing a focus class */
  1805. if ($(this).hasClass('ms-TextField--underlined')) {
  1806. /** Add is-active class - changes border color to theme primary */
  1807. $(this).find('.ms-TextField-field').on('focus', function() {
  1808. $(this).parent('.ms-TextField--underlined').addClass('is-active');
  1809. });
  1810. /** Remove is-active on blur of textfield */
  1811. $(this).find('.ms-TextField-field').on('blur', function() {
  1812. $(this).parent('.ms-TextField--underlined').removeClass('is-active');
  1813. });
  1814. }
  1815. });
  1816. };
  1817. })(jQuery);
  1818. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
  1819. /**
  1820. * Dropdown Plugin
  1821. *
  1822. * Given .ms-Dropdown containers with generic <select> elements inside, this plugin hides the original
  1823. * dropdown and creates a new "fake" dropdown that can more easily be styled across browsers.
  1824. *
  1825. * @param {jQuery Object} One or more .ms-Dropdown containers, each with a dropdown (.ms-Dropdown-select)
  1826. * @return {jQuery Object} The same containers (allows for chaining)
  1827. */
  1828. (function ($) {
  1829. $.fn.Dropdown = function () {
  1830. /** Go through each dropdown we've been given. */
  1831. return this.each(function () {
  1832. var $dropdownWrapper = $(this),
  1833. $originalDropdown = $dropdownWrapper.children('.ms-Dropdown-select'),
  1834. $originalDropdownOptions = $originalDropdown.children('option'),
  1835. newDropdownTitle = '',
  1836. newDropdownItems = '',
  1837. newDropdownSource = '';
  1838. /** Go through the options to fill up newDropdownTitle and newDropdownItems. */
  1839. $originalDropdownOptions.each(function (index, option) {
  1840. /** If the option is selected, it should be the new dropdown's title. */
  1841. if (option.selected) {
  1842. newDropdownTitle = option.text;
  1843. }
  1844. /** Add this option to the list of items. */
  1845. newDropdownItems += '<li class="ms-Dropdown-item' + ( (option.disabled) ? ' is-disabled"' : '"' ) + '>' + option.text + '</li>';
  1846. });
  1847. /** Insert the replacement dropdown. */
  1848. newDropdownSource = '<span class="ms-Dropdown-title">' + newDropdownTitle + '</span><ul class="ms-Dropdown-items">' + newDropdownItems + '</ul>';
  1849. $dropdownWrapper.append(newDropdownSource);
  1850. function _openDropdown(evt) {
  1851. if (!$dropdownWrapper.hasClass('is-disabled')) {
  1852. /** First, let's close any open dropdowns on this page. */
  1853. $dropdownWrapper.find('.is-open').removeClass('is-open');
  1854. /** Stop the click event from propagating, which would just close the dropdown immediately. */
  1855. evt.stopPropagation();
  1856. /** Before opening, size the items list to match the dropdown. */
  1857. var dropdownWidth = $(this).parents(".ms-Dropdown").width();
  1858. $(this).next(".ms-Dropdown-items").css('width', dropdownWidth + 'px');
  1859. /** Go ahead and open that dropdown. */
  1860. $dropdownWrapper.toggleClass('is-open');
  1861. $('.ms-Dropdown').each(function(){
  1862. if ($(this)[0] !== $dropdownWrapper[0]) {
  1863. $(this).removeClass('is-open');
  1864. }
  1865. });
  1866. /** Temporarily bind an event to the document that will close this dropdown when clicking anywhere. */
  1867. $(document).bind("click.dropdown", function() {
  1868. $dropdownWrapper.removeClass('is-open');
  1869. $(document).unbind('click.dropdown');
  1870. });
  1871. }
  1872. }
  1873. /** Toggle open/closed state of the dropdown when clicking its title. */
  1874. $dropdownWrapper.on('click', '.ms-Dropdown-title', function(event) {
  1875. _openDropdown(event);
  1876. });
  1877. /** Keyboard accessibility */
  1878. $dropdownWrapper.on('keyup', function(event) {
  1879. var keyCode = event.keyCode || event.which;
  1880. // Open dropdown on enter or arrow up or arrow down and focus on first option
  1881. if (!$(this).hasClass('is-open')) {
  1882. if (keyCode === 13 || keyCode === 38 || keyCode === 40) {
  1883. _openDropdown(event);
  1884. if (!$(this).find('.ms-Dropdown-item').hasClass('is-selected')) {
  1885. $(this).find('.ms-Dropdown-item:first').addClass('is-selected');
  1886. }
  1887. }
  1888. }
  1889. else if ($(this).hasClass('is-open')) {
  1890. // Up arrow focuses previous option
  1891. if (keyCode === 38) {
  1892. if ($(this).find('.ms-Dropdown-item.is-selected').prev().siblings().size() > 0) {
  1893. $(this).find('.ms-Dropdown-item.is-selected').removeClass('is-selected').prev().addClass('is-selected');
  1894. }
  1895. }
  1896. // Down arrow focuses next option
  1897. if (keyCode === 40) {
  1898. if ($(this).find('.ms-Dropdown-item.is-selected').next().siblings().size() > 0) {
  1899. $(this).find('.ms-Dropdown-item.is-selected').removeClass('is-selected').next().addClass('is-selected');
  1900. }
  1901. }
  1902. // Enter to select item
  1903. if (keyCode === 13) {
  1904. if (!$dropdownWrapper.hasClass('is-disabled')) {
  1905. // Item text
  1906. var selectedItemText = $(this).find('.ms-Dropdown-item.is-selected').text();
  1907. $(this).find('.ms-Dropdown-title').html(selectedItemText);
  1908. /** Update the original dropdown. */
  1909. $originalDropdown.find("option").each(function(key, value) {
  1910. if (value.text === selectedItemText) {
  1911. $(this).prop('selected', true);
  1912. } else {
  1913. $(this).prop('selected', false);
  1914. }
  1915. });
  1916. $originalDropdown.change();
  1917. $(this).removeClass('is-open');
  1918. }
  1919. }
  1920. }
  1921. // Close dropdown on esc
  1922. if (keyCode === 27) {
  1923. $(this).removeClass('is-open');
  1924. }
  1925. });
  1926. /** Select an option from the dropdown. */
  1927. $dropdownWrapper.on('click', '.ms-Dropdown-item', function () {
  1928. if (!$dropdownWrapper.hasClass('is-disabled')) {
  1929. /** Deselect all items and select this one. */
  1930. $(this).siblings('.ms-Dropdown-item').removeClass('is-selected');
  1931. $(this).addClass('is-selected');
  1932. /** Update the replacement dropdown's title. */
  1933. $(this).parents().siblings('.ms-Dropdown-title').html($(this).text());
  1934. /** Update the original dropdown. */
  1935. var selectedItemText = $(this).text();
  1936. $originalDropdown.find("option").each(function(key, value) {
  1937. if (value.text === selectedItemText) {
  1938. $(this).prop('selected', true);
  1939. } else {
  1940. $(this).prop('selected', false);
  1941. }
  1942. });
  1943. $originalDropdown.change();
  1944. }
  1945. });
  1946. });
  1947. };
  1948. })(jQuery);