[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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(' ', '') 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 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |