Commit 529a151564647cef24d5bf3dd5ebd210b3f53ebe

Autohide notifications

  - Added a separate Notification View to handle notifications, which is much
    cleaner than hardcoding bunch of template calls here and there.
  - Notification View now autohides notifs after a certain delay
  • Diff rendering mode:
  • inline
  • side by side

mouchak/static/css/editor.css

72 position: absolute;72 position: absolute;
73 left: 33%;73 left: 33%;
74 top: 0px;74 top: 0px;
75 text-align: center;
75}76}
76.ace-mouchak {77.ace-mouchak {
77 position: relative;78 position: relative;

mouchak/static/js/editor.js

60 return false;60 return false;
61 }61 }
62 var id = $(event.target).parent('.remove').attr('for');62 var id = $(event.target).parent('.remove').attr('for');
63 var success_template = _.template($('#success-notif').html());
64 var fail_template = _.template($('#fail-notif').html());
65 //console.log('remove', id);63 //console.log('remove', id);
66 M.pages.get(id).destroy({64 M.pages.get(id).destroy({
67 success: function(model, response) {65 success: function(model, response) {
70 if(M.editor.pageview) {70 if(M.editor.pageview) {
71 M.editor.pageview.remove();71 M.editor.pageview.remove();
72 }72 }
73 $('#notifications').html(success_template({
74 title: 'Deleted',
75 msg: ''
76 }));
73 M.editor.notifs.show('success', 'Deleted', '');
77 },74 },
78 error: function(model, xhr) {75 error: function(model, xhr) {
79 M.editor.hideOverlay();76 M.editor.hideOverlay();
80 console.log('failed', model, xhr);77 console.log('failed', model, xhr);
81 $('#notifications').html(fail_template({
82 title: 'Error',
83 msg: 'Failed to delete. Please try again.'
84 }));
78 var msg = 'Failed to delete. Please try again.';
79 M.editor.notifs.show('fail', 'Error!', msg);
85 }80 }
86 });81 });
87 M.editor.showOverlay();82 M.editor.showOverlay();
232 return false;232 return false;
233 },233 },
234 updatePage: function() {234 updatePage: function() {
235 var success_template = _.template($('#success-notif').html());
236 var fail_template = _.template($('#fail-notif').html());
237
238 var name = $('#name').val();235 var name = $('#name').val();
239 var title = $('#title').val();236 var title = $('#title').val();
240 var children = $('#children').val();237 var children = $('#children').val();
261 //model.id = response.page.id;261 //model.id = response.page.id;
262 //console.log(model);262 //console.log(model);
263 M.pagelistview.render();263 M.pagelistview.render();
264 $('#notifications').html(success_template({
265 title: 'Saved',
266 msg: ''
267 }));
264 M.editor.notifs.show('success', 'Saved', '');
268 },265 },
269 error: function(model, xhr) {266 error: function(model, xhr) {
270 M.editor.hideOverlay();267 M.editor.hideOverlay();
271 model.set(response.page);268 model.set(response.page);
272 console.log('failed', model, xhr);269 console.log('failed', model, xhr);
273 $('#notifications').html(fail_template({
274 title: 'Error!',
275 msg: 'Something went wrong, and the page could not be updated'
276 }));
270 var msg = 'Something went wrong, and the page could not be updated';
271 M.editor.notifs.show('fail', 'Error!', msg);
277 }272 }
278 });273 });
279 M.editor.showOverlay();274 M.editor.showOverlay();
348 }));348 }));
349 if(this.model.get('src')) {349 if(this.model.get('src')) {
350 var plugin_type = this.model.get('plugin_type');350 var plugin_type = this.model.get('plugin_type');
351 plugin_type = (plugin_type === 'js') ? 'javascript': 'css';
351 plugin_type = (plugin_type === 'js') ? 'javascript' : 'css';
352 this.model.getCode(function(data) {352 this.model.getCode(function(data) {
353 $('#plugin-edit').html(escapeHtml(data));353 $('#plugin-edit').html(escapeHtml(data));
354 M.editor.code.init('plugin-edit', plugin_type);354 M.editor.code.init('plugin-edit', plugin_type);
513 },513 },
514 saveMenu: function() {514 saveMenu: function() {
515 //console.log('saving menu..');515 //console.log('saving menu..');
516 var success_template = _.template($('#success-notif').html());
517 var fail_template = _.template($('#fail-notif').html());
518
519 if($('#custom-menu').is(':checked')) {516 if($('#custom-menu').is(':checked')) {
520 var html = $('#menu').val().trim() || '';517 var html = $('#menu').val().trim() || '';
521 this.model.set({'customMenu': true, 'html': html});518 this.model.set({'customMenu': true, 'html': html});
526 success: function(model, response) {526 success: function(model, response) {
527 //console.log(model, response);527 //console.log(model, response);
528 M.editor.hideOverlay();528 M.editor.hideOverlay();
529 $('#notifications').html(success_template({
530 title: 'Saved',
531 msg: ''
532 }));
529 M.editor.notifs.show('success', 'Saved', '');
533530
534 },531 },
535 error: function(xhr, response) {532 error: function(xhr, response) {
536 M.editor.hideOverlay();533 M.editor.hideOverlay();
537 $('#notifications').html(fail_template({
538 title: 'Error!',
539 msg: 'Something went wrong, and the page could not be updated'
540 }));
534 var msg = 'Something went wrong, and the page could not be updated';
535 M.editor.notifs.show('fail', 'Error!', msg);
541 }536 }
542 });537 });
543 //alert('end of save menu');538 //alert('end of save menu');
540 }540 }
541 });541 });
542542
543 /* Notification view */
544 var NotificationView = Backbone.View.extend({
545 initialize: function(opts) {
546 try {
547 this.el = opts.el;
548 }
549 catch(e) {
550 throw new Error(this.usage());
551 return;
552 }
553 this.template = _.template($('#notif-template').html());
554 this.el = opts.el;
555 this.delayTime = opts.delay || 3000; // a default delay value
556 },
557 render: function(type, title, msg) {
558 $(this.el).html(this.template({
559 type: (type === 'fail') ? 'danger' : 'success',
560 title: title,
561 msg: msg
562 //autohide the notif after a delay
563 })).show(200).delay(this.delayTime).hide(500);
564 },
565 usage: function() {
566 return 'Missing or invalid parameters.\n Valid Params: '+
567 '\n@el: (required) a JQuery HTML element, inside which the notifaction'+
568 ' will be rendered'+
569 '\n@delay: (optional) a delay time, after which the notification'+
570 ' will be hidden';
571 }
572 });
543573
574 /* The global editor object.
575 * All high-level editor operations are defined here.
576 */
544 M.editor = {577 M.editor = {
545 init: function() {578 init: function() {
546 M.pages = new Pages(M.site_content.content);579 M.pages = new Pages(M.site_content.content);
547 var pagelistview = new PageListView();
548 pagelistview.render();
549 /*M.pages.on('add', function(page) {
550 pagelistview.render();
551 });*/
552 M.pagelistview = pagelistview;
580 M.pagelistview = new PageListView();
581 M.pagelistview.render();
582 // initialize the notfications for the editor
583 this.notifs.notifview = new NotificationView({
584 el: $('#notifications'),
585 });
553 },586 },
587 // the wysiwig editor sub-object
554 wysiwyg: {588 wysiwyg: {
555 init: function($selector) {589 init: function($selector) {
556 tinymce.init({590 tinymce.init({
613 cleanUp: function($selector) {613 cleanUp: function($selector) {
614 }614 }
615 },615 },
616 // the code editor
616 code: {617 code: {
617 _editor: false,618 _editor: false,
618 init: function(id, mode) {619 init: function(id, mode) {
632 return data;632 return data;
633 },633 },
634 cleanUp: function(id) {634 cleanUp: function(id) {
635 }
636 },
637 //editor notifications
638 notifs: {
639 // init the notif view when the DOM is ready, in editor.init
640 notifview: null,
641 show: function(type, title, msg) {
642 this.notifview.render(type, title, msg);
635 }643 }
636 },644 },
637 showOverlay: function() {645 showOverlay: function() {

mouchak/templates/editor.html

367 </script>367 </script>
368368
369 <!-- notification templates -->369 <!-- notification templates -->
370 <script type="text/template" id="success-notif">
371 <div class="alert alert-success">
370 <script type="text/template" id="notif-template">
371 <div class="alert alert-<%= type %>">
372 <button type="button" class="close" data-dismiss="alert">&times;</button>372 <button type="button" class="close" data-dismiss="alert">&times;</button>
373 <h4> <%= title %> </h4>373 <h4> <%= title %> </h4>
374 <%= msg %>374 <%= msg %>
375 </div>375 </div>
376 </script>376 </script>
377377
378 <script type="text/template" id="fail-notif">
379 <div class="alert alert-danger">
380 <button type="button" class="close" data-dismiss="alert">&times;</button>
381 <h4> <%= title %> </h4>
382 <%= msg %>
383 </div>
384 </script>
385{% endblock %}378{% endblock %}