You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FeedbackWindow.js 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /* global $, APP, interfaceConfig, AJS */
  2. /* jshint -W101 */
  3. const selector = '#aui-feedback-dialog';
  4. /**
  5. * Toggles the appropriate css class for the given number of stars, to
  6. * indicate that those stars have been clicked/selected.
  7. *
  8. * @param starCount the number of stars, for which to toggle the css class
  9. */
  10. let toggleStars = function(starCount) {
  11. $('#stars > a').each(function(index, el) {
  12. if (index <= starCount) {
  13. el.classList.add("starHover");
  14. } else
  15. el.classList.remove("starHover");
  16. });
  17. };
  18. /**
  19. * Constructs the html for the detailed feedback window.
  20. *
  21. * @returns {string} the contructed html string
  22. */
  23. let constructDetailedFeedbackHtml = function() {
  24. return `
  25. <div class="aui-dialog2-content feedback__content">
  26. <div class="feedback__details">
  27. <p>${APP.translation.translateString("dialog.sorryFeedback")}</p>
  28. <br/><br/>
  29. <textarea id="feedbackTextArea" rows="10" cols="50" autofocus></textarea>
  30. </div>
  31. </div>
  32. <footer class="aui-dialog2-footer feedback__footer">
  33. <div class="aui-dialog2-footer-actions">
  34. <button id="dialog-close-button" class="aui-button aui-button_close">Close</button>
  35. <button id="dialog-submit-button" class="aui-button aui-button_submit">Submit</button>
  36. </div>
  37. </footer>
  38. `;
  39. };
  40. /**
  41. * Constructs the html for the rated feedback window.
  42. *
  43. * @returns {string} the contructed html string
  44. */
  45. let createRateFeedbackHTML = function (Feedback) {
  46. let rateExperience
  47. = APP.translation.translateString('dialog.rateExperience'),
  48. feedbackHelp = APP.translation.translateString('dialog.feedbackHelp'),
  49. feedbackQuestion = (Feedback.feedbackScore < 0)
  50. ? `<p><br/>${APP.translation.translateString('dialog.feedbackQuestion')}</p>`
  51. : '';
  52. let starClassName = (interfaceConfig.ENABLE_FEEDBACK_ANIMATION)
  53. ? "icon-star shake-rotate"
  54. : "icon-star";
  55. return `
  56. <div class="aui-dialog2-content feedback__content">
  57. ${feedbackQuestion}
  58. <form action="javascript:false;" onsubmit="return false;">
  59. <div class="feedback__rating">
  60. <h2>${ rateExperience }</h2>
  61. <p class="star-label">&nbsp;</p>
  62. <div id="stars" class="feedback-stars">
  63. <a class="star-btn">
  64. <i class=${ starClassName }></i>
  65. </a>
  66. <a class="star-btn">
  67. <i class=${ starClassName }></i>
  68. </a>
  69. <a class="star-btn">
  70. <i class=${ starClassName }></i>
  71. </a>
  72. <a class="star-btn">
  73. <i class=${ starClassName }></i>
  74. </a>
  75. <a class="star-btn">
  76. <i class=${ starClassName }></i>
  77. </a>
  78. </div>
  79. <p>&nbsp;</p>
  80. <p>${ feedbackHelp }</p>
  81. </div>
  82. </form>
  83. </div>
  84. `;
  85. };
  86. /**
  87. * Callback for Rate Feedback
  88. *
  89. * @param Feedback
  90. */
  91. let onLoadRateFunction = function (Feedback) {
  92. $('#stars > a').each((index, el) => {
  93. el.onmouseover = function(){
  94. toggleStars(index);
  95. };
  96. el.onmouseleave = function(){
  97. toggleStars(Feedback.feedbackScore - 1);
  98. };
  99. el.onclick = function(){
  100. Feedback.feedbackScore = index + 1;
  101. // If the feedback is less than 3 stars we're going to
  102. // ask the user for more information.
  103. if (Feedback.feedbackScore > 3) {
  104. APP.conference.sendFeedback(Feedback.feedbackScore, "");
  105. Feedback.hide();
  106. } else {
  107. Feedback.setState('detailed_feedback');
  108. }
  109. };
  110. });
  111. // Init stars to correspond to previously entered feedback.
  112. if (Feedback.feedbackScore > 0) {
  113. toggleStars(Feedback.feedbackScore - 1);
  114. }
  115. };
  116. /**
  117. * Callback for Detailed Feedback
  118. *
  119. * @param Feedback
  120. */
  121. let onLoadDetailedFunction = function(Feedback) {
  122. let submitBtn = Feedback.$el.find('#dialog-submit-button');
  123. let closeBtn = Feedback.$el.find('#dialog-close-button');
  124. if (submitBtn && submitBtn.length) {
  125. submitBtn.on('click', (e) => {
  126. e.preventDefault();
  127. Feedback.onFeedbackSubmitted();
  128. });
  129. }
  130. if (closeBtn && closeBtn.length) {
  131. closeBtn.on('click', (e) => {
  132. e.preventDefault();
  133. Feedback.hide();
  134. });
  135. }
  136. $('#feedbackTextArea').focus();
  137. };
  138. /**
  139. * @class Dialog
  140. *
  141. */
  142. export default class Dialog {
  143. constructor(options) {
  144. this.feedbackScore = -1;
  145. this.onCloseCallback = null;
  146. this.states = {
  147. rate_feedback: {
  148. getHtml: createRateFeedbackHTML,
  149. onLoad: onLoadRateFunction
  150. },
  151. detailed_feedback: {
  152. getHtml: constructDetailedFeedbackHtml,
  153. onLoad: onLoadDetailedFunction
  154. }
  155. };
  156. this.state = options.state || 'rate_feedback';
  157. this.window = AJS.dialog2(selector, {
  158. closeOnOutsideClick: true
  159. });
  160. this.$el = this.window.$el;
  161. this.setState();
  162. }
  163. setState(state) {
  164. let newState = state || this.state;
  165. let htmlStr = this.states[newState].getHtml(this);
  166. this.$el.html(htmlStr);
  167. this.states[newState].onLoad(this);
  168. }
  169. show(cb) {
  170. this.setState('rate_feedback');
  171. if (typeof cb == 'function') {
  172. this.onCloseCallback = cb;
  173. }
  174. this.window.show();
  175. }
  176. hide() {
  177. this.window.hide();
  178. if (this.onCloseCallback) {
  179. this.onCloseCallback();
  180. this.onCloseCallback = null;
  181. }
  182. }
  183. onFeedbackSubmitted() {
  184. let message = this.$el.find('textarea').val();
  185. let self = this;
  186. if (message && message.length > 0) {
  187. APP.conference.sendFeedback(
  188. self.feedbackScore,
  189. message);
  190. }
  191. this.hide();
  192. }
  193. }