[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/message/yui/src/messenger/js/ -> sendmessage.js (source)

   1  // This file is part of Moodle - http://moodle.org/
   2  //
   3  // Moodle is free software: you can redistribute it and/or modify
   4  // it under the terms of the GNU General Public License as published by
   5  // the Free Software Foundation, either version 3 of the License, or
   6  // (at your option) any later version.
   7  //
   8  // Moodle is distributed in the hope that it will be useful,
   9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11  // GNU General Public License for more details.
  12  //
  13  // You should have received a copy of the GNU General Public License
  14  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  15  /* global CSSR, SELECTORS */
  16  
  17  /**
  18   * Send message dialog.
  19   *
  20   * @module     moodle-core_message-messenger
  21   * @package    core_message
  22   * @copyright  2015 Frédéric Massart - FMCorz.net
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  CSSR.SENDMSGDIALOG = {
  27      ACCESSHIDE: 'accesshide',
  28      ACTIONS: 'message-actions',
  29      FOOTER: 'message-footer',
  30      HIDDEN: 'hidden',
  31      HISTORYLINK: 'message-history',
  32      INPUT: 'message-input',
  33      INPUTAREA: 'message-area',
  34      NOTICE: 'message-notice',
  35      NOTICEAREA: 'message-notice-area',
  36      PREFIX: 'core_message-messenger-sendmessage',
  37      SENDBTN: 'message-send',
  38      WRAPPER: 'message-wrapper'
  39  };
  40  
  41  SELECTORS.SENDMSGDIALOG = {
  42      FORM: 'form',
  43      HISTORYLINK: '.message-history',
  44      INPUT: '.message-input',
  45      NOTICE: '.message-notice div',
  46      NOTICEAREA: '.message-notice-area',
  47      SENDBTN: '.message-send'
  48  };
  49  
  50  /**
  51   * Send message dialog.
  52   *
  53   * @namespace M.core_message
  54   * @class SENDMSGDIALOG
  55   * @constructor
  56   */
  57  var SENDMSGDIALOG = function() {
  58      SENDMSGDIALOG.superclass.constructor.apply(this, arguments);
  59  };
  60  Y.namespace('M.core_message.messenger').sendMessage = Y.extend(SENDMSGDIALOG, M.core.dialogue, {
  61  
  62      _bb: null,
  63      _sendLock: false,
  64      _hide: null,
  65      /**
  66       * Initializer.
  67       *
  68       * @method initializer
  69       */
  70      initializer: function() {
  71          var tpl,
  72              content;
  73  
  74          this._bb = this.get('boundingBox');
  75          this._hide = this.hide;
  76  
  77          // Prepare the content area.
  78          tpl = Y.Handlebars.compile(
  79              '<form action="#" id="messageform">' +
  80                  '<div class="{{CSSR.INPUTAREA}}">' +
  81                      '<label class="{{CSSR.ACCESSHIDE}}" for="{{id}}">{{labelStr}}</label>' +
  82                      '<textarea class="{{CSSR.INPUT}}" id="{{id}}"></textarea>' +
  83                      '<div class="{{CSSR.NOTICEAREA}}" style="display: none;" aria-live="assertive">' +
  84                          '<div class="{{CSSR.NOTICE}}"><div></div></div>' +
  85                      '</div>' +
  86                  '</div>' +
  87                  '<div class="{{CSSR.ACTIONS}}">' +
  88                      '<input type="submit" value="{{sendStr}}" class="{{CSSR.SENDBTN}}">' +
  89                      '<a href="#" class="{{CSSR.HISTORYLINK}}">{{viewHistoryStr}}</a>' +
  90                      '<div style="clear: both;"></div>' +
  91                  '</div>' +
  92              '</form>'
  93          );
  94          content = Y.Node.create(
  95              tpl({
  96                  CSSR: CSSR.SENDMSGDIALOG,
  97                  id: Y.guid(),
  98                  labelStr: M.util.get_string('messagetosend', 'core_message'),
  99                  loadingIcon: M.util.image_url('i/loading', 'moodle'),
 100                  sendStr: M.util.get_string('sendmessage', 'core_message'),
 101                  viewHistoryStr: M.util.get_string('viewconversation', 'core_message')
 102              })
 103          );
 104          this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE);
 105  
 106          // Use standard dialogue class name. This removes the default styling of the footer.
 107          this._bb.one('.moodle-dialogue-wrap').addClass('moodle-dialogue-content');
 108  
 109          // Set the events listeners.
 110          this._setEvents();
 111      },
 112  
 113      /**
 114       * Prepare the dialog for a user.
 115       *
 116       * @method prepareForUser
 117       * @param  {Number} userid   The user ID.
 118       * @param  {String} fullname The user full name.
 119       */
 120      prepareForUser: function(userid, fullname) {
 121          var title;
 122  
 123          this.set('userid', userid);
 124          this.set('fullname', fullname);
 125  
 126          // Prepare the title.
 127          title = Y.Node.create('<h1>' + Y.Escape.html(fullname) + '</h1>');
 128          this.setStdModContent(Y.WidgetStdMod.HEADER, title, Y.WidgetStdMod.REPLACE);
 129  
 130          // Update the link to the conversation.
 131          this._bb.one(SELECTORS.SENDMSGDIALOG.HISTORYLINK)
 132              .set('href', M.cfg.wwwroot + '/message/index.php?id=' + this.get('userid'));
 133  
 134          // Set the content as empty and lock send.
 135          this._bb.one(SELECTORS.SENDMSGDIALOG.INPUT).set('value', '');
 136  
 137          // Register form with formchangechecker
 138          Y.use('moodle-core-formchangechecker', function() {
 139              M.core_formchangechecker.init({formid: "messageform"});
 140          });
 141      },
 142  
 143      /**
 144       * Send the message to the user.
 145       *
 146       * @method sendMessage
 147       * @param  {String} message The message to be sent.
 148       */
 149      sendMessage: function(message) {
 150          if (this._sendLock) {
 151              // Do not proceed if the lock is active.
 152              return;
 153          }
 154  
 155          if (!message || !this._validateMessage(message)) {
 156              // Do not send falsy messages.
 157              return;
 158          }
 159  
 160          // Actually send the message.
 161          this._ioSend = Y.io(this.get('url'), {
 162              method: 'POST',
 163              data: {
 164                  sesskey: M.cfg.sesskey,
 165                  action: 'sendmessage',
 166                  userid: this.get('userid'),
 167                  message: message
 168              },
 169              on: {
 170                  start: function() {
 171                      var img = '<img alt="" role="presentation" src="' + M.util.image_url('i/loading_small', 'moodle') + '">';
 172                      this.setSendLock(true);
 173                      this.showNotice(img + ' ' + M.util.get_string('sendingmessage', 'core_message'));
 174                  },
 175                  success: function(id, response) {
 176                      var data = null;
 177  
 178                      try {
 179                          data = Y.JSON.parse(response.responseText);
 180                          if (data.error) {
 181                              this.hideNotice();
 182                              new M.core.ajaxException(data);
 183                              return;
 184                          }
 185                      } catch (e) {
 186                          this.hideNotice();
 187                          new M.core.exception(e);
 188                          return;
 189                      }
 190  
 191                      // Show a success message.
 192                      this.showNotice(M.util.get_string('messagesent', 'core_message'));
 193  
 194                      // Hide the dialog.
 195                      Y.later(1300, this, function() {
 196                          this.setSendLock(false);
 197                          this.hideNotice();
 198                          this.hide();
 199                      });
 200                  },
 201                  failure: function() {
 202                      this.setSendLock(false);
 203                      this.hideNotice();
 204                      new M.core.alert({
 205                          title: M.util.get_string('error', 'core'),
 206                          message: M.util.get_string('errorwhilesendingmessage', 'core_message')
 207                      });
 208                  }
 209              },
 210              context: this
 211          });
 212      },
 213  
 214      /**
 215       * Override the default hide function.
 216       * @method hide
 217       */
 218      hide: function() {
 219          var self = this;
 220  
 221          if (!M.core_formchangechecker.get_form_dirty_state()) {
 222              return SENDMSGDIALOG.superclass.hide.call(this, arguments);
 223          }
 224  
 225          Y.use('moodle-core-notification-confirm', function() {
 226              var confirm = new M.core.confirm({
 227                  title: M.util.get_string('confirm', 'moodle'),
 228                  question: M.util.get_string('changesmadereallygoaway', 'moodle'),
 229                  yesLabel: M.util.get_string('confirm', 'moodle'),
 230                  noLabel: M.util.get_string('cancel', 'moodle')
 231              });
 232              confirm.on('complete-yes', function() {
 233                  M.core_formchangechecker.reset_form_dirty_state();
 234                  confirm.hide();
 235                  confirm.destroy();
 236                  return SENDMSGDIALOG.superclass.hide.call(this, arguments);
 237              }, self);
 238          });
 239      },
 240  
 241      /**
 242       * Show a notice.
 243       *
 244       * @method hideNotice.
 245       */
 246      hideNotice: function() {
 247          this._bb.one(SELECTORS.SENDMSGDIALOG.NOTICEAREA).hide();
 248      },
 249  
 250      /**
 251       * Show a notice.
 252       *
 253       * @param {String} html String to show.
 254       * @method showNotice.
 255       */
 256      showNotice: function(html) {
 257          this._bb.one(SELECTORS.SENDMSGDIALOG.NOTICE).setHTML(html);
 258          this._bb.one(SELECTORS.SENDMSGDIALOG.NOTICEAREA).show();
 259      },
 260  
 261      /**
 262       * Set the send lock.
 263       *
 264       * We do not lock the send button because that would cause a focus change on screenreaders
 265       * which then conflicts with the aria-live region reading out that we are sending a message.
 266       *
 267       * @method setSendLock
 268       * @param  {Boolean} lock When true, enables the lock.
 269       */
 270      setSendLock: function(lock) {
 271          if (lock) {
 272              this._sendLock = true;
 273          } else {
 274              this._sendLock = false;
 275          }
 276      },
 277  
 278      /**
 279       * Register the events.
 280       *
 281       * @method _setEvents.
 282       */
 283      _setEvents: function() {
 284          // Form submit.
 285          this._bb.one(SELECTORS.SENDMSGDIALOG.FORM).on('submit', function(e) {
 286              var message = this._bb.one(SELECTORS.SENDMSGDIALOG.INPUT).get('value');
 287              e.preventDefault();
 288              this.sendMessage(message);
 289          }, this);
 290      },
 291  
 292      /**
 293       * Validates a message.
 294       *
 295       * @method _validateMessage
 296       * @param  {String} message A message to be validated.
 297       */
 298      _validateMessage: function(message) {
 299          var trimmed;
 300          if (!message) {
 301              return false;
 302          }
 303  
 304          // Basic validation.
 305          trimmed = message.replace(' ', '')
 306                           .replace('&nbsp;', '')
 307                           .replace(/(<br\s*\/?>(<\/br\s*\/?>)?)+/, '')
 308                           .trim();
 309  
 310          return trimmed.length > 1;
 311      }
 312  
 313  }, {
 314      NAME: 'core_message-messenger-sendmessage',
 315      CSS_PREFIX: CSSR.SENDMSGDIALOG.PREFIX,
 316      ATTRS: {
 317  
 318          /**
 319           * Fullname of the user.
 320           *
 321           * @attribute fullname
 322           * @default ''
 323           * @type String
 324           */
 325          fullname: {
 326              validator: Y.Lang.isString,
 327              value: ''
 328          },
 329  
 330          /**
 331           * URL to the message Ajax actions.
 332           *
 333           * @attribute url
 334           * @default null
 335           * @type String
 336           */
 337          url: {
 338              validator: Y.Lang.isString,
 339              value: null
 340          },
 341  
 342          /**
 343           * User ID this dialog interacts with.
 344           *
 345           * @attribute userid
 346           * @default 0
 347           * @type Number
 348           */
 349          userid: {
 350              validator: Y.Lang.isNumber,
 351              value: 0
 352          }
 353      }
 354  });
 355  
 356  Y.Base.modifyAttrs(Y.namespace('M.core_message.messenger.sendMessage'), {
 357  
 358      /**
 359       * List of extra classes.
 360       *
 361       * @attribute extraClasses
 362       * @default ['core_message-messenger-sendmessage']
 363       * @type Array
 364       */
 365      extraClasses: {
 366          value: ['core_message-messenger-sendmessage']
 367      },
 368  
 369      /**
 370       * Whether to focus on the target that caused the Widget to be shown.
 371       *
 372       * @attribute focusOnPreviousTargetAfterHide
 373       * @default true
 374       * @type Node
 375       */
 376      focusOnPreviousTargetAfterHide: {
 377          value: true
 378      },
 379  
 380      /**
 381       *
 382       * Width.
 383       *
 384       * @attribute width
 385       * @default '260px'
 386       * @type String|Number
 387       */
 388      width: {
 389          value: '360px'
 390      },
 391  
 392      /**
 393       * Boolean indicating whether or not the Widget is visible.
 394       *
 395       * @attribute visible
 396       * @default false
 397       * @type Boolean
 398       */
 399      visible: {
 400          value: false
 401      },
 402  
 403     /**
 404      * Whether the widget should be modal or not.
 405      *
 406      * @attribute modal
 407      * @type Boolean
 408      * @default true
 409      */
 410      modal: {
 411          value: true
 412      },
 413  
 414     /**
 415      * Whether the widget should be draggable or not.
 416      *
 417      * @attribute draggable
 418      * @type Boolean
 419      * @default false
 420      */
 421      draggable: {
 422          value: false
 423      },
 424  
 425      /**
 426       * Whether to display the dialogue centrally on the screen.
 427       *
 428       * @attribute center
 429       * @type Boolean
 430       * @default false
 431       */
 432      center: {
 433          value: true
 434      }
 435  
 436  });


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1