ninjaModal.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /**
  2. * Definition of the NinjaModal class.
  3. *
  4. * @param data (object) The default data to be passed into the class.
  5. * data.width (int) The width of the modal.
  6. * data.class (string) The class to be applied to the modal.
  7. * data.closeOnClick (string/bool) The click options to close the modal.
  8. * data.closeOnEsc (bool) Whether or not to close the modal on escape.
  9. * data.title (string) The title of the modal.
  10. * data.content (string) The content of the modal.
  11. * data.btnPrimary (object) Information about the primary button of the modal.
  12. * btnPrimary.text (string) The text content of the button.
  13. * btnPrimary.class (string) The class to be added to the button.
  14. * btnPrimary.callback (function) The function to be called when the button is clicked.
  15. * data.btnSecondary (object) Information about the secondary button of the modal.
  16. * btnSecondary.text (string) The text content of the button.
  17. * btnSecondary.class (string) The class to be added to the button.
  18. * btnSecondary.callback (function) The function to be called when the button is clicked.
  19. * data.useProgressBar (bool) Whether or not this modal needs the progress bar.
  20. * data.loadingText (string) The text to be shown while the progress bar is visible.
  21. */
  22. function NinjaModal ( data ) {
  23. // Setup our modal settings.
  24. this.settings = {
  25. width: ( 'undefined' != typeof data.width ? data.width : 400 ),
  26. class: ( 'undefined' != typeof data.class ? data.class : 'dashboard-modal' ),
  27. closeOnClick: ( 'undefined' != typeof data.closeOnClick ? data.closeOnClick : 'body' ),
  28. closeOnEsc: ( 'undefined' != typeof data.closeOnEsc ? data.closeOnEsc : true )
  29. }
  30. // Setup our title.
  31. this.title = ( 'undefined' != typeof data.title ? data.title : '' );
  32. // Setup our content.
  33. this.content = ( 'undefined' != typeof data.content ? data.content : '' );
  34. // See if we need buttons.
  35. this.buttons = {};
  36. this.buttons.primary = {};
  37. this.buttons.secondary = {};
  38. this.buttons.primary.data = ( 'undefined' != typeof data.btnPrimary ? data.btnPrimary : false );
  39. this.buttons.secondary.data = ( 'undefined' != typeof data.btnSecondary ? data.btnSecondary : false );
  40. // See if we need the progress bar.
  41. this.useProgressBar = ( 'undefined' != typeof data.useProgressBar ? data.useProgressBar : false );
  42. if ( this.useProgressBar ) {
  43. // TODO: translate
  44. this.loadingText = ( 'undefined' != typeof data.loadingText ? data.loadingText : 'Loading...' );
  45. }
  46. // Declare our popup item.
  47. this.popup;
  48. // Declare our button booleans.
  49. this.hasPrimary = false;
  50. this.hasSecondary = false;
  51. // Initialize the popup.
  52. this.initModal();
  53. // Show the popup.
  54. this.toggleModal( true );
  55. }
  56. /**
  57. * Function to destory the modal.
  58. */
  59. NinjaModal.prototype.destroy = function () {
  60. this.popup.destroy();
  61. }
  62. /**
  63. * Function to increment the progress bar.
  64. *
  65. * @param max (int) The maximum percentage of complete the progress bar can be.
  66. */
  67. NinjaModal.prototype.incrementProgress = function ( max ) {
  68. var progressBar = document.getElementById( 'nf-progress-bar-slider-' + this.popup.dataId );
  69. // Get our current progress.
  70. var currentProgress = progressBar.offsetWidth / progressBar.parentElement.offsetWidth * 100;
  71. // If we've not already passed the max value...
  72. if ( max > currentProgress ) {
  73. // Increase the progress by 1 step.
  74. currentProgress = Number( currentProgress ) + 1;
  75. this.setProgress( currentProgress );
  76. }
  77. }
  78. /**
  79. * Function to initialize the buttons.
  80. */
  81. NinjaModal.prototype.initButtons = function () {
  82. // If we have data for a primary button...
  83. if ( this.buttons.primary.data ) {
  84. // Create the button.
  85. var primary = document.createElement( 'div' );
  86. primary.id = 'nf-button-primary-' + this.popup.dataId;
  87. primary.classList.add( 'nf-button', 'primary', 'pull-right' );
  88. // If we have a class...
  89. if ( this.buttons.primary.data.class ) {
  90. // Add it to the class list.
  91. primary.classList.add( this.buttons.primary.data.class );
  92. }
  93. // If we were given button text...
  94. if ( 'undefined' != typeof this.buttons.primary.data.text ) {
  95. // Use it.
  96. primary.innerHTML = this.buttons.primary.data.text;
  97. } // Otherwise... (We were not given text.)
  98. else {
  99. // Use default text.
  100. // TODO: translate
  101. primary.innerHTML = 'Confirm';
  102. }
  103. this.buttons.primary.dom = primary;
  104. // Attach the callback.
  105. this.buttons.primary.callback = this.buttons.primary.data.callback;
  106. // Record that we have a primary button.
  107. this.hasPrimary = true;
  108. // Garbage collection...
  109. delete this.buttons.primary.data;
  110. }
  111. // If we have data for a secondary button...
  112. if ( this.buttons.secondary.data ) {
  113. // Create the button.
  114. var secondary = document.createElement( 'div' );
  115. secondary.id = 'nf-button-secondary-' + this.popup.dataId;
  116. secondary.classList.add( 'nf-button', 'secondary' );
  117. // If we have a class...
  118. if ( this.buttons.secondary.data.class ) {
  119. // Add it to the class list.
  120. secondary.classList.add( this.buttons.secondary.data.class );
  121. }
  122. // If we were given button text...
  123. if ( 'undefined' != typeof this.buttons.secondary.data.text ) {
  124. // Use it.
  125. secondary.innerHTML = this.buttons.secondary.data.text;
  126. } // Otherwise... (We were not given text.)
  127. else {
  128. // Use default text.
  129. // TODO: translate
  130. secondary.innerHTML = 'Cancel';
  131. }
  132. this.buttons.secondary.dom = secondary;
  133. // Attach the callback.
  134. this.buttons.secondary.callback = this.buttons.secondary.data.callback;
  135. // Record that we have a secondary button.
  136. this.hasSecondary = true;
  137. // Garbage collection...
  138. delete this.buttons.secondary.data;
  139. }
  140. }
  141. /**
  142. * Function to initialize the popup modal.
  143. */
  144. NinjaModal.prototype.initModal = function () {
  145. // Save the context of this for callbacks.
  146. var that = this;
  147. // Setup our popup.
  148. this.popup = new jBox( 'Modal', {
  149. width: this.settings.width,
  150. addClass: this.settings.class,
  151. overlay: true,
  152. closeOnClick: this.settings.closeOnClick,
  153. closeOnEsc: this.settings.closeOnEsc,
  154. onOpen: function() {
  155. // If we have a primary button...
  156. if ( that.hasPrimary ) {
  157. // Attach the callback.
  158. jQuery( this.content ).find( '#nf-button-primary-' + this.dataId ).click( that.buttons.primary.callback );
  159. }
  160. // If we have a secondary button...
  161. if ( that.hasSecondary ) {
  162. // Attach the callback.
  163. jQuery( this.content ).find( '#nf-button-secondary-' + this.dataId ).click( that.buttons.secondary.callback );
  164. }
  165. },
  166. } );
  167. // Setup our data id to keep the DOM ids unique.
  168. this.popup.dataId = this.popup.id.replace( 'jBoxID', '' );
  169. // Render the title.
  170. this.renderTitle();
  171. // Initialize the buttons (if they exist).
  172. this.initButtons();
  173. // Render the content.
  174. this.renderContent();
  175. }
  176. /**
  177. * Function to toggle the display of the action block.
  178. *
  179. * @param show (bool) Whether to show the block.
  180. */
  181. NinjaModal.prototype.maybeShowActions = function ( show ) {
  182. if ( this.hasPrimary || this.hasSecondary ) {
  183. if ( show ) {
  184. document.getElementById( 'nf-action-block-' + this.popup.dataId ).style.display = 'block';
  185. }
  186. else {
  187. document.getElementById( 'nf-action-block-' + this.popup.dataId ).style.display = 'none';
  188. }
  189. }
  190. }
  191. /**
  192. * Function to toggle the display of the progress block.
  193. *
  194. * @param show (bool) Whether to show the block.
  195. */
  196. NinjaModal.prototype.maybeShowProgress = function ( show ) {
  197. if ( this.useProgressBar ) {
  198. if ( show ) {
  199. document.getElementById( 'nf-progress-block-' + this.popup.dataId ).style.display = 'block';
  200. }
  201. else {
  202. document.getElementById( 'nf-progress-block-' + this.popup.dataId ).style.display = 'none';
  203. }
  204. }
  205. }
  206. /**
  207. * Function to append the content to the popup.
  208. */
  209. NinjaModal.prototype.renderContent = function () {
  210. // Delcare our template.
  211. var contentBox = document.createElement( 'div' );
  212. contentBox.classList.add( 'message' );
  213. contentBox.style.padding = '0px 20px 20px 20px';
  214. // Import our content.
  215. contentBox.innerHTML = this.content;
  216. // If we were told to use the progress bar...
  217. if ( this.useProgressBar ) {
  218. // Define our progress block.
  219. var progressBlock = document.createElement( 'div' );
  220. progressBlock.id = 'nf-progress-block-' + this.popup.dataId;
  221. progressBlock.style.display = 'none';
  222. // Define our progress bar.
  223. var progressBar = document.createElement( 'div' );
  224. progressBar.classList.add( 'nf-progress-bar' );
  225. var progressSlider = document.createElement( 'div' );
  226. progressSlider.id = 'nf-progress-bar-slider-' + this.popup.dataId;
  227. progressSlider.classList.add( 'nf-progress-bar-slider' );
  228. progressBar.appendChild( progressSlider );
  229. progressBlock.appendChild( progressBar );
  230. // Define our loading text.
  231. var loadingText = document.createElement( 'p' );
  232. loadingText.style.color = '#1ea9ea';
  233. loadingText.style.fontWeight = 'bold';
  234. loadingText.innerHTML = this.loadingText;
  235. progressBlock.appendChild( loadingText );
  236. // Append it to the content box.
  237. contentBox.appendChild( progressBlock );
  238. }
  239. // If we have buttons...
  240. if ( this.hasPrimary || this.hasSecondary ) {
  241. // Define our action block.
  242. var actionBlock = document.createElement( 'div' );
  243. actionBlock.id = 'nf-action-block-' + this.popup.dataId;
  244. actionBlock.classList.add( 'buttons' );
  245. // Insert the primary button, if one exists.
  246. if ( this.hasPrimary ) actionBlock.appendChild( this.buttons.primary.dom );
  247. // Insert the secondary button, if one exists.
  248. if ( this.hasSecondary ) actionBlock.appendChild( this.buttons.secondary.dom );
  249. // Append it to the content box.
  250. contentBox.appendChild( actionBlock );
  251. this.popup.onOpen = function() {
  252. this.buttons.primary.dom.onclick = this.buttons.primary.callback;
  253. this.buttons.secondary.dom.onclick = this.buttons.secondary.callback;
  254. }
  255. }
  256. // Set our content.
  257. this.popup.setContent( document.createElement( 'div' ).appendChild( contentBox ).parentElement.innerHTML );
  258. }
  259. /**
  260. * Function to append the title to the popup.
  261. */
  262. NinjaModal.prototype.renderTitle = function () {
  263. // If we have a title...
  264. if ( '' != this.title ) {
  265. // Set our title.
  266. this.popup.setTitle( this.title );
  267. }
  268. }
  269. /**
  270. * Function to set the value of the progress bar.
  271. *
  272. * @param percent (int) The value to set the progress bar to.
  273. */
  274. NinjaModal.prototype.setProgress = function ( percent ) {
  275. // Update the width of the element as a percentage.
  276. var progressBar = document.getElementById( 'nf-progress-bar-slider-' + this.popup.dataId );
  277. progressBar.style.width = percent + '%';
  278. }
  279. /**
  280. * Function to toggle the visibility of the popup.
  281. *
  282. * @param show (bool) Whether or not to show the popup.
  283. */
  284. NinjaModal.prototype.toggleModal = function ( show ) {
  285. // If we were told to show the modal...
  286. if ( show ) {
  287. // Open it.
  288. this.popup.open();
  289. } // Otherwise... (We were told to hide it.)
  290. else {
  291. // Close it.
  292. this.popup.close();
  293. }
  294. }
  295. /**
  296. * Function to update the content of the popup.
  297. *
  298. * @param content (string) The new content.
  299. */
  300. NinjaModal.prototype.updateContent = function ( content ) {
  301. // Set the new content.
  302. this.content = content;
  303. // Re-render.
  304. this.renderContent();
  305. }
  306. /**
  307. * Function to update the title of the popup.
  308. *
  309. * @param title (string) The new title.
  310. */
  311. NinjaModal.prototype.updateTitle = function ( title ) {
  312. // Set the new title.
  313. this.title = title;
  314. // Re-render.
  315. this.renderTitle();
  316. }