ws-forms.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. "use strict";
  2. (function($) {
  3. $(document).ready(function() {
  4. function checkPropsExist(obj, props) {
  5. if(typeof obj !== 'object' || ! props) {
  6. throw new Error('checkPropsExist was called with wrong arguments');
  7. }
  8. props = typeof props === 'string' ? [props] : props;
  9. for(let p = 0 ; p < props.length ; p++) {
  10. const prop = props[p];
  11. if(! obj[prop]) {
  12. throw new Error('obj does not have a `' + prop + '` parameter: please provide it.');
  13. }
  14. }
  15. }
  16. function makeFormView(elemId, options) {
  17. var callbacks = ['onSubmitAddPromise', 'onAddSuccess', 'onAddError'];
  18. // Fallback options & options.events
  19. checkPropsExist(options, callbacks)
  20. options.events = options.events || {};
  21. // Define events and optionally extend them with those
  22. // provided in options.events
  23. _ws.makeView(elemId, {
  24. init: function() {
  25. const self = this;
  26. this.$btn = this.$elem.find('.add-btn');
  27. this.$form = this.$elem.find('form');
  28. this.$input = this.$form.find('input[name="title"]');
  29. callbacks.forEach(function(cbName) {
  30. self[cbName] = options[cbName].bind(self);
  31. });
  32. if(options.postInit) {
  33. (options.postInit.bind(this))();
  34. }
  35. },
  36. reset: function() {
  37. this.$btn.addClass('in');
  38. this.$form.removeClass('in');
  39. this.$input.val('');
  40. },
  41. render: function() {
  42. this.$btn.removeClass('in');
  43. this.$form.addClass('in');
  44. this.$input.focus();
  45. },
  46. events: {
  47. 'click .add-btn': function() {
  48. this.render();
  49. },
  50. 'click .icon-cross': function() {
  51. this.$form.removeClass('in');
  52. this.$btn.addClass('in');
  53. },
  54. 'submit form': function(e) {
  55. const self = this;
  56. e.preventDefault();
  57. if(this.cantSubmit) {
  58. this.$input
  59. .removeClass('input-success input-warning')
  60. .addClass('input-error');
  61. _ws.notify('error', this.cantSubmit);
  62. return;
  63. }
  64. var title = this.$input.val();
  65. // rp.post('/collections', { title: title })
  66. self.onSubmitAddPromise(title)
  67. .then(function(data) {
  68. self.onAddSuccess(data);
  69. self.reset();
  70. })
  71. .catch(function(err) {
  72. console.error(err);
  73. self.onAddError(err);
  74. self.reset();
  75. });
  76. }
  77. }
  78. });
  79. }
  80. makeFormView('add-repo', {
  81. onSubmitAddPromise: function(title) {
  82. return rp.post('/repos', { title: title });
  83. },
  84. onAddSuccess: function(repo) {
  85. _ws.repos.push(repo);
  86. _ws.ui.menuRepo.render({ repos: _ws.repos });
  87. _ws.notify('success', 'Collection créée: ' + repo.title);
  88. _ws.navigateTo('/' + repo.path);
  89. },
  90. onAddError: function(err) {
  91. _ws.notify('error', 'Impossible de créer la collection: ' + err.message);
  92. }
  93. });
  94. makeFormView('add-example', {
  95. onSubmitAddPromise: function(title) {
  96. return rp.post('/' + _ws.repo.path + '/examples', { title: title });
  97. },
  98. onAddSuccess: function(example) {
  99. _ws.notify('success', 'Exemple crée: ' + example.title);
  100. _ws.navigateTo('/' + _ws.repo.path + '/' + example.slug);
  101. // console.log('##### addExample success', _ws, _ws.ui.menuExample.$elem.find('ul[data-id="' + example.category + '"]') )
  102. _ws.ui.menuExample.addExampleLink(example, '/' + _ws.repo.path + '/' + example.slug);
  103. _ws.ui.shortcutExample.addExampleLink(example, '/' + _ws.repo.path + '/' + example.slug);
  104. },
  105. onAddError: function(err) {
  106. _ws.notify('error', "Impossible de créer l'exemple: " + err.message);
  107. }
  108. });
  109. makeFormView(
  110. 'add-file',
  111. {
  112. onSubmitAddPromise: function(name) {
  113. return rp.post('/' + _ws.repo.path + '/examples/' + _ws.example.slug + '/files', { name: name });
  114. },
  115. onAddSuccess: function(file) {
  116. _ws.notify('success', 'Fichier crée: ' + file.name);
  117. _ws.files.push(file);
  118. _ws.ui.tabs.render({ files: _ws.files });
  119. },
  120. onAddError: function(err) {
  121. _ws.notify('error', "Impossible de créer le fichier: " + err.message);
  122. },
  123. postInit: function() {
  124. function onKeyup(e) {
  125. var filename = this.$input.val();
  126. var bits = filename.split('.');
  127. var lastIdx = bits.length - 1;
  128. this.cantSubmit = '';
  129. // show warning if no extension has been provided
  130. if(bits.length < 2) {
  131. this.$input
  132. .removeClass('input-success input-error')
  133. .addClass('input-warning');
  134. this.cantSubmit = 'Impossible de valider: extension (.html/.js/.css) manquante';
  135. return;
  136. }
  137. // show error if provided extension is invalid
  138. else {
  139. var ext = (bits[lastIdx]).toLowerCase();
  140. if( ['html', 'js', 'css'].indexOf( ext ) === -1 ) {
  141. this.cantSubmit = 'Impossible de valider: extension ' + ext + ' invalide (autorisées: .html/.js/.css)';
  142. }
  143. else if(bits[0] === '') {
  144. this.cantSubmit = "Le premier caractère du nom de fichier doit être autre chose qu'un point";
  145. }
  146. if( this.cantSubmit ) {
  147. this.$input
  148. .removeClass('input-success input-warning')
  149. .addClass('input-error');
  150. return;
  151. }
  152. }
  153. this.$input.addClass('input-success');
  154. this.cantSubmit = undefined;
  155. }
  156. this.$input.on('keyup', onKeyup.bind(this));
  157. }
  158. }
  159. );
  160. });
  161. })(jQuery);