inlinedform.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // A inlined form is used to provide a quick edition of single field for a given
  2. // document. Clicking on a edit button should display the form to edit the field
  3. // value. The form can then be submited, or just closed.
  4. //
  5. // When the form is closed we save non-submitted values in memory to avoid any
  6. // data loss.
  7. //
  8. // Usage:
  9. //
  10. // +inlineForm
  11. // // the content when the form is open
  12. // else
  13. // // the content when the form is close (optional)
  14. // We can only have one inlined form element opened at a time
  15. // XXX Could we avoid using a global here ? This is used in Mousetrap
  16. // keyboard.js
  17. currentlyOpenedForm = new ReactiveVar(null);
  18. BlazeComponent.extendComponent({
  19. template: function() {
  20. return 'inlinedForm';
  21. },
  22. mixins: function() {
  23. return [Mixins.CachedValue];
  24. },
  25. onCreated: function() {
  26. this.isOpen = new ReactiveVar(false);
  27. },
  28. open: function() {
  29. // Close currently opened form, if any
  30. if (currentlyOpenedForm.get() !== null) {
  31. currentlyOpenedForm.get().close();
  32. }
  33. this.isOpen.set(true);
  34. currentlyOpenedForm.set(this);
  35. },
  36. close: function() {
  37. this.saveValue();
  38. this.isOpen.set(false);
  39. currentlyOpenedForm.set(null);
  40. },
  41. getValue: function() {
  42. return this.isOpen.get() && this.find('textarea,input[type=text]').value;
  43. },
  44. saveValue: function() {
  45. this.callFirstWith(this, 'setCache', this.getValue());
  46. },
  47. events: function() {
  48. return [{
  49. 'click .js-close-inlined-form': this.close,
  50. 'click .js-open-inlined-form': this.open,
  51. // Close the inlined form by pressing escape.
  52. //
  53. // Keydown (and not keypress) in necessary here because the `keyCode`
  54. // property is consistent in all browsers, (there is not keyCode for the
  55. // `keypress` event in firefox)
  56. 'keydown form input, keydown form textarea': function(evt) {
  57. if (evt.keyCode === 27) {
  58. evt.preventDefault();
  59. this.close();
  60. }
  61. },
  62. // Pressing Ctrl+Enter should submit the form
  63. 'keydown form textarea': function(evt) {
  64. if (evt.keyCode === 13 && (evt.metaKey || evt.ctrlKey)) {
  65. $(evt.currentTarget).parents('form:first').submit();
  66. }
  67. },
  68. // Close the inlined form when after its submission
  69. submit: function() {
  70. var self = this;
  71. // XXX Swith to an arrow function here when we'll have ES6
  72. if (this.currentData().autoclose !== false) {
  73. Tracker.afterFlush(function() {
  74. self.close();
  75. self.callFirstWith(self, 'resetCache');
  76. });
  77. }
  78. }
  79. }];
  80. }
  81. }).register('inlinedForm');