bhf 0.4.2.2 → 0.4.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/app/controllers/bhf/application_controller.rb +2 -2
  2. data/app/controllers/bhf/embed_entries_controller.rb +8 -8
  3. data/app/controllers/bhf/entries_controller.rb +10 -10
  4. data/app/controllers/bhf/pages_controller.rb +2 -2
  5. data/app/helpers/bhf/application_helper.rb +3 -3
  6. data/app/helpers/bhf/entries_helper.rb +4 -4
  7. data/app/views/bhf/_user.haml +2 -2
  8. data/app/views/bhf/application/index.haml +1 -1
  9. data/app/views/bhf/entries/_form.haml +5 -5
  10. data/app/views/bhf/entries/_validation_errors.haml +1 -1
  11. data/app/views/bhf/entries/form/belongs_to/_account_scope.haml +1 -1
  12. data/app/views/bhf/entries/form/belongs_to/_radio.haml +1 -1
  13. data/app/views/bhf/entries/form/belongs_to/_select.haml +2 -2
  14. data/app/views/bhf/entries/form/belongs_to/_static.haml +1 -1
  15. data/app/views/bhf/entries/form/column/_array.haml +2 -2
  16. data/app/views/bhf/entries/form/column/_date.haml +1 -1
  17. data/app/views/bhf/entries/form/column/_file.haml +2 -2
  18. data/app/views/bhf/entries/form/column/_markdown.haml +2 -2
  19. data/app/views/bhf/entries/form/column/_multiple_fields.haml +1 -1
  20. data/app/views/bhf/entries/form/column/_number.haml +1 -1
  21. data/app/views/bhf/entries/form/column/_static.haml +1 -1
  22. data/app/views/bhf/entries/form/column/_wysiwyg.haml +1 -1
  23. data/app/views/bhf/entries/form/embeds_many/_static.haml +5 -5
  24. data/app/views/bhf/entries/form/embeds_one/_static.haml +5 -5
  25. data/app/views/bhf/entries/form/has_and_belongs_to_many/_account_scope.haml +1 -1
  26. data/app/views/bhf/entries/form/has_and_belongs_to_many/_static.haml +1 -1
  27. data/app/views/bhf/entries/form/has_many/_static.haml +4 -4
  28. data/app/views/bhf/entries/form/has_one/_account_scope.haml +1 -1
  29. data/app/views/bhf/entries/form/has_one/_static.haml +4 -4
  30. data/app/views/bhf/helper/_flash.haml +1 -1
  31. data/app/views/bhf/helper/_frontend_edit.haml +1 -1
  32. data/app/views/bhf/helper/_node.haml +3 -3
  33. data/app/views/bhf/helper/_reflection_node.haml +2 -2
  34. data/app/views/bhf/pages/_platform.haml +15 -15
  35. data/app/views/bhf/pages/_search.haml +7 -7
  36. data/app/views/bhf/pages/macro/belongs_to/_default.haml +1 -1
  37. data/app/views/bhf/pages/macro/column/_date.haml +1 -1
  38. data/app/views/bhf/pages/macro/column/_text.haml +1 -1
  39. data/app/views/bhf/pages/macro/embeds_many/_default.haml +1 -1
  40. data/app/views/bhf/pages/macro/embeds_one/_default.haml +1 -1
  41. data/app/views/bhf/pages/macro/has_and_belongs_to_many/_default.haml +1 -1
  42. data/app/views/bhf/pages/macro/has_many/_default.haml +1 -1
  43. data/app/views/bhf/pages/macro/has_one/_default.haml +1 -1
  44. data/app/views/bhf/pages/show.haml +1 -1
  45. data/app/views/kaminari/bhf/_next_page.html.haml +1 -1
  46. data/app/views/kaminari/bhf/_page.html.haml +1 -1
  47. data/app/views/kaminari/bhf/_prev_page.html.haml +1 -1
  48. data/app/views/layouts/bhf/application.haml +10 -11
  49. data/app/views/layouts/bhf/quick_edit.haml +2 -2
  50. data/config/routes.rb +6 -6
  51. data/lib/bhf/active_record/upload.rb +1 -1
  52. data/lib/bhf/form.rb +1 -1
  53. data/lib/bhf/i18n.rb +3 -3
  54. data/lib/bhf/mongoid/document.rb +2 -2
  55. data/lib/bhf/pagination.rb +14 -14
  56. data/lib/bhf/platform.rb +17 -17
  57. data/lib/bhf/view_helpers.rb +1 -1
  58. data/vendor/assets/images/bhf/ajax_loader.gif +0 -0
  59. data/vendor/assets/images/bhf/bg.png +0 -0
  60. data/vendor/assets/images/bhf/mooeditable-toolbarbuttons-tango.png +0 -0
  61. data/vendor/assets/images/bhf/pictos.png +0 -0
  62. data/vendor/assets/images/bhf/small_ajax_loader.gif +0 -0
  63. data/vendor/assets/images/bhf/small_ajax_loader_h.gif +0 -0
  64. data/vendor/assets/images/bhf/wmd-buttons.png +0 -0
  65. data/vendor/assets/images/logo_bhf.png +0 -0
  66. data/vendor/assets/javascripts/bhf/application.js +280 -0
  67. data/vendor/assets/javascripts/bhf/classes/AjaxEdit.js +104 -0
  68. data/vendor/assets/javascripts/bhf/classes/Ajaxify.js +63 -0
  69. data/vendor/assets/javascripts/bhf/classes/ArrayFields.js +25 -0
  70. data/vendor/assets/javascripts/bhf/classes/BrowserUpdate.js +185 -0
  71. data/vendor/assets/javascripts/bhf/classes/Datepicker.js +38 -0
  72. data/vendor/assets/javascripts/bhf/classes/MooEditable.js +1549 -0
  73. data/vendor/assets/javascripts/bhf/classes/MultipleFields.js +50 -0
  74. data/vendor/assets/javascripts/bhf_includes/wmd.js +1 -1
  75. data/vendor/assets/stylesheets/bhf/MooEditable.css.scss +176 -0
  76. data/vendor/assets/stylesheets/bhf/application.css.sass +1067 -0
  77. data/vendor/assets/stylesheets/bhf/functions.css.sass +137 -0
  78. data/vendor/assets/stylesheets/bhf/reset.css.sass +32 -0
  79. data/vendor/assets/stylesheets/bhf/typo.css.scss +62 -0
  80. metadata +24 -3
Binary file
@@ -0,0 +1,280 @@
1
+ //= require ./mootools-core-1.3.2-full-compat-yc.js
2
+ //= require ./mootools-more-1.3.2.1.js
3
+ //= require mootools_ujs
4
+ //= require_tree ./classes/
5
+
6
+ window.addEvent('domready', function(){
7
+ var ajaxNote = new Ajaxify();
8
+ var lang = document.html.get('lang');
9
+ if (lang === 'en') {
10
+ lang = 'en-US';
11
+ }
12
+ else {
13
+ lang = lang+'-'+lang.toUpperCase();
14
+ }
15
+ Locale.use(lang);
16
+ var wysiwyg = [];
17
+ var setupJsForm = function(scope){
18
+ scope.getElements('.wysiwyg').each(function(elem){
19
+ wysiwyg.push(elem.mooEditable());
20
+ });
21
+
22
+ scope.getElements('.multiple_fields').each(function(elem){
23
+ new MultipleFields(elem);
24
+ });
25
+ scope.getElements('.array_holder').each(function(elem){
26
+ new ArrayFields(elem);
27
+ });
28
+
29
+ var dateFormat = Locale.get('Date.shortDate').replace(/%/g, '');
30
+ var timeFormat = 'H:i'; // Locale.get('Date.shortTime').replace(/%/g, '')
31
+ var dateMonths = Locale.get('Date.months');
32
+ var dateDays = Locale.get('Date.days');
33
+ new DatePicker(scope.getElements('.picker.datetime, .picker.timestamp'), {
34
+ allowEmpty: true,
35
+ inputOutputFormat: 'Y-m-d H:i',
36
+ months: dateMonths,
37
+ days: dateDays,
38
+ timePicker: true,
39
+ format: dateFormat+' '+timeFormat
40
+ });
41
+ new DatePicker(scope.getElements('.picker.date'), {
42
+ allowEmpty: true,
43
+ inputOutputFormat: 'Y-m-d H:i',
44
+ months: dateMonths,
45
+ days: dateDays,
46
+ format: dateFormat
47
+ });
48
+ new DatePicker(scope.getElements('.picker.time'), {
49
+ allowEmpty: true,
50
+ inputOutputFormat: 'Y-m-d H:i',
51
+ months: dateMonths,
52
+ days: dateDays,
53
+ timePickerOnly: true,
54
+ format: timeFormat
55
+ });
56
+ };
57
+
58
+ // TODO: disable more ajax calls while ajax is loading
59
+ var quickEdit = new AjaxEdit({
60
+ holderParent: $('content'),
61
+ onStartRequest: function(form){
62
+ ajaxNote.loading();
63
+ },
64
+ onFormInjected: function(form){
65
+ setupJsForm(form);
66
+ scrollContent();
67
+ ajaxNote.success();
68
+ },
69
+ onSave: function(form){
70
+ ajaxNote.success();
71
+ },
72
+ onBeforeSubmit: function(){
73
+ ajaxNote.loading();
74
+ wysiwyg.each(function(elem){
75
+ elem.saveContent();
76
+ });
77
+ }
78
+ });
79
+
80
+ var platforms = document.body.getElements('.platform');
81
+ var mainForm = document.id('main_form');
82
+
83
+ if (platforms.length) {
84
+ var setupSortables = function(scope){
85
+ new Sortables(scope.getElements('.sortable'), {
86
+ handle: '.handle',
87
+ onStart: function(element, clone){
88
+ element.addClass('dragged');
89
+ },
90
+ onComplete: function(element){
91
+ element.removeClass('dragged');
92
+ new Request({
93
+ method: 'put',
94
+ url: this.element.getParent('tbody').get('data-sort-url')
95
+ }).send({data: {order: this.serialize()}});
96
+ }
97
+ });
98
+ };
99
+ var updatePlatform = function(href, platform, callback){
100
+ ajaxNote.loading();
101
+ new Request.HTML({
102
+ method: 'get',
103
+ url: href,
104
+ onSuccess: function(a, b, html){
105
+ platform.innerHTML = html;
106
+ if (callback) {
107
+ callback.call();
108
+ }
109
+ setupSortables(platform);
110
+ ajaxNote.success();
111
+ windowHight = document.body.clientHeight;
112
+ }
113
+ }).send();
114
+ };
115
+
116
+ platforms.addEvents({
117
+ 'click:relay(.pagination a, thead a)': function(e){
118
+ e.preventDefault();
119
+ updatePlatform(this.get('href'), this.getParent('.platform'));
120
+ },
121
+ 'submit:relay(.search)': function(e){
122
+ ajaxNote.loading();
123
+ e.preventDefault();
124
+ var parent = this.getParent('.platform');
125
+ var hidden_search = e.target.getElement('.hidden_search');
126
+ if (hidden_search) {
127
+ hidden_search.destroy();
128
+ }
129
+
130
+ new Request.HTML({
131
+ method: 'get',
132
+ url: this.get('action'),
133
+ onSuccess: function(a, b, html){
134
+ parent.innerHTML = html;
135
+ setupSortables(parent);
136
+ ajaxNote.success();
137
+ }
138
+ }).send({data: this});
139
+ },
140
+ 'click:relay(.quick_edit)': function(e){
141
+ e.preventDefault();
142
+ quickEdit.startEdit(this, this.getParent('tr'));
143
+ },
144
+ 'click:relay(.action a)': function(e){
145
+ this.addClass('clicked');
146
+ },
147
+ 'click:relay(.delete)': function(e){
148
+ e.target.addEvents({
149
+ 'ajax:success': function(html){
150
+ this.getParent('tr').dispose();
151
+ },
152
+ 'ajax:failure': function(html){
153
+ alert('Something went wrong!');
154
+ }
155
+ });
156
+ }
157
+ });
158
+
159
+ quickEdit.addEvents({
160
+ successAndChange: function(json){
161
+ var tr = this.wrapElement;
162
+ tr.getElements('td').each(function(td){
163
+ var name = td.get('data-column-name');
164
+ if ( ! name) { return; }
165
+ var a = td.getElement('a.quick_edit');
166
+ (a ? a : td).innerHTML = json[name] || '';
167
+ });
168
+ },
169
+ successAndNext: function(json){
170
+ var tr = this.wrapElement;
171
+ var nextTr = tr.getNext('tr');
172
+
173
+ if (nextTr) {
174
+ quickEdit.startEdit(nextTr.getElement('a'), nextTr);
175
+ }
176
+ else {
177
+ var platform = tr.getParent('.platform');
178
+ var loadMore = platform.getElement('.load_more');
179
+ if (loadMore) {
180
+ trIndex = tr.getParent('tbody').getElements('tr').indexOf(tr);
181
+ updatePlatform(loadMore.get('href'), platform, function(){
182
+ platform.getElements('tbody tr').each(function(newTr, index){
183
+ if (trIndex === index) {
184
+ nextTr = newTr.getNext('tr');
185
+ quickEdit.startEdit(nextTr.getElement('a'), nextTr);
186
+ }
187
+ });
188
+ });
189
+ }
190
+ else {
191
+ nextTr = platform.getElements('tbody tr')[0];
192
+ quickEdit.startEdit(nextTr.getElement('a'), nextTr);
193
+ }
194
+ }
195
+ }
196
+ });
197
+ setupSortables(document.body);
198
+ }
199
+ else if (mainForm) {
200
+ setupJsForm(mainForm);
201
+
202
+ mainForm.addEvents({
203
+ 'click:relay(.quick_edit)': function(e){
204
+ e.preventDefault();
205
+ quickEdit.startEdit(this);
206
+ },
207
+ 'click:relay(.delete)': function(e){
208
+ e.target.addEvents({
209
+ 'ajax:success': function(html){
210
+ var relation = e.target.getParent('.relation');
211
+ if (relation.getElements('li').length < 2) {
212
+ relation.getPrevious('.empty').removeClass('hide');
213
+ if (relation.hasClass('has_one') || relation.hasClass('embeds_one')) {
214
+ relation.getNext('.add_field').removeClass('hide');
215
+ }
216
+ }
217
+ e.target.getParent('li').dispose();
218
+ },
219
+ 'ajax:failure': function(html){
220
+ alert('Something went wrong!');
221
+ }
222
+ });
223
+ }
224
+ });
225
+
226
+ quickEdit.addEvents({
227
+ successAndAdd: function(json){
228
+ var relation = this.wrapElement.getPrevious('.relation');
229
+ relation.getPrevious('.empty').addClass('hide');
230
+ if (relation.hasClass('has_one') || relation.hasClass('embeds_one')) {
231
+ relation.getNext('.add_field').addClass('hide');
232
+ }
233
+ relation.adopt(
234
+ new Element('li').adopt(
235
+ new Element('a.quick_edit', {text: json.to_bhf_s || '', href: json.edit_path})
236
+ )
237
+ );
238
+ },
239
+ successAndChange: function(json){
240
+ this.wrapElement.set('text', json.to_bhf_s || '');
241
+ },
242
+ successAndNext: function(json){
243
+ var a = this.wrapElement;
244
+ var li = a.getParent('li');
245
+ if ( ! li) {
246
+ this.close();
247
+ return;
248
+ }
249
+ var holder = li.getNext('li');
250
+
251
+ if ( ! holder) {
252
+ holder = li.getParent('ul');
253
+ }
254
+ quickEdit.startEdit(holder.getElement('a'));
255
+ }
256
+ });
257
+ }
258
+ var windowHight = document.body.clientHeight;
259
+ window.onresize = function(e){
260
+ windowHight = document.body.clientHeight;
261
+ };
262
+ var scrollContent = function(){
263
+ var innerForm = quickEdit.holder.getElement('form');
264
+ if ( ! innerForm) { return; }
265
+ var scroll = document.body.scrollTop-70;
266
+ if (scroll < 10) {
267
+ scroll = 10;
268
+ }
269
+ if (scroll + innerForm.getSize().y > windowHight) { return; }
270
+ quickEdit.holder.setStyle('padding-top', scroll);
271
+ };
272
+ window.onscroll = scrollContent;
273
+
274
+ var fm = $('flash_massages');
275
+ if (fm) {
276
+ fm.addClass('show').removeClass.delay(4000, fm, 'show');
277
+ }
278
+
279
+ new BrowserUpdate({vs:{i:8,f:3,o:10.01,s:2,n:9}});
280
+ });
@@ -0,0 +1,104 @@
1
+ var AjaxEdit = new Class({
2
+ version: 0.2,
3
+
4
+ options: {
5
+ holderParent: document.body
6
+ },
7
+
8
+ Implements: [Options, Events],
9
+
10
+ holder: new Element('div.quick_edit_holder'),
11
+
12
+ initialize: function(_options) {
13
+ this.setOptions(_options);
14
+ this.holder.addEvents({
15
+ 'click:relay(.open)': function(e){
16
+ e.preventDefault();
17
+ location.href = (this.wrapElement.getElement('a') || this.wrapElement).get('href');
18
+ }.bind(this),
19
+ 'click:relay(.cancel)': function(e){
20
+ e.preventDefault();
21
+ this.close();
22
+ }.bind(this),
23
+ 'click:relay(.save_and_next)': function(e){
24
+ e.preventDefault();
25
+ this.submit(this.newEntry ? ['successAndAdd'] : ['successAndChange', 'successAndNext']);
26
+ }.bind(this),
27
+ 'click:relay(.save)': function(e){
28
+ e.preventDefault();
29
+ this.submit(this.newEntry ? ['successAndAdd'] : ['successAndChange']);
30
+ }.bind(this),
31
+ 'submit:relay(form)': function(e){
32
+ e.preventDefault();
33
+ this.submit(this.newEntry ? ['successAndAdd'] : ['successAndChange']);
34
+ }.bind(this)
35
+ });
36
+ },
37
+
38
+ startEdit: function(element, wrapElement){
39
+ this.clean();
40
+ this.wrapElement = wrapElement ? wrapElement : element;
41
+ this.wrapElement.addClass('live_edit');
42
+ this.newEntry = this.wrapElement.hasClass('add_field');
43
+
44
+ this.fireEvent('startRequest');
45
+ new Request.HTML({
46
+ method: 'get',
47
+ evalScripts: false,
48
+ url: element.get('href'),
49
+ onSuccess: function(responseTree, responseElements, responseHTML, responseJavaScript){
50
+ this.injectForm(responseHTML);
51
+ eval(responseJavaScript);
52
+ }.bind(this)
53
+ }).send();
54
+ },
55
+
56
+ submit: function(eventNames){
57
+ var form = this.holder.getElement('form');
58
+ this.fireEvent('beforeSubmit');
59
+
60
+ new Request.JSON({
61
+ method: form.get('method'),
62
+ url: form.get('action'),
63
+ evalScripts: true,
64
+ onRequest: function(){
65
+ this.disableButtons();
66
+ }.bind(this),
67
+ onFailure: function(invalidForm){
68
+ this.injectForm(invalidForm.response);
69
+ invalidForm.response.stripScripts(function(script){
70
+ eval(script);
71
+ });
72
+ }.bind(this),
73
+ onSuccess: function(json){
74
+ if ( ! eventNames.contains('successAndNext')) {
75
+ this.close();
76
+ }
77
+ eventNames.each(function(eventName){
78
+ this.fireEvent(eventName, [json]);
79
+ }.bind(this));
80
+ this.fireEvent('save');
81
+ }.bind(this)
82
+ }).send({data: form});
83
+ },
84
+
85
+ disableButtons: function(){
86
+ this.holder.getElements('.open, .cancel, .save_and_next, .save').set('disabled', 'disabled');
87
+ },
88
+
89
+ clean: function(){
90
+ document.body.getElements('.live_edit').removeClass('live_edit');
91
+ },
92
+
93
+ close: function(){
94
+ this.clean();
95
+ this.holder.dispose();
96
+ },
97
+
98
+ injectForm: function(form){
99
+ this.holder.innerHTML = form;
100
+ this.holder.inject(this.options.holderParent);
101
+
102
+ this.fireEvent('formInjected', [this.holder]);
103
+ }
104
+ });
@@ -0,0 +1,63 @@
1
+ var Ajaxify = new Class({
2
+ version: 0.2,
3
+
4
+ Implements: [Options, Events],
5
+
6
+ options: {
7
+ events: {
8
+ loading: {
9
+ name: 'ajax:loading',
10
+ text: 'Loading…'
11
+ },
12
+ success: {
13
+ name: 'ajax:success',
14
+ text: 'Changes successfully saved!'
15
+ },
16
+ failure: {
17
+ name: 'ajax:failure',
18
+ text: 'Oops, something went wrong…'
19
+ }
20
+ },
21
+ holder: new Element('div#ajax_holder'),
22
+ fadeOutDuration: 2000
23
+ },
24
+
25
+ initialize: function(_options) {
26
+ this.setOptions(_options);
27
+ this.holder = this.options.holder.inject(document.body);
28
+ },
29
+
30
+ applyEvents: function(el){
31
+ el = document.id(el || document.body);
32
+ var apply = function(action, callback) {
33
+ el.getElements('[data-remote="true"]').addEvent(action, callback);
34
+ };
35
+
36
+ apply(this.options.events.loading.name, this.loading.bind(this));
37
+ apply(this.options.events.success.name, this.success.bind(this));
38
+ apply(this.options.events.failure.name, this.failure.bind(this));
39
+ },
40
+
41
+ loading: function(xhr){
42
+ this.setMessage('loading', false);
43
+ },
44
+ success: function(xhr){
45
+ this.setMessage('success', true);
46
+ },
47
+ failure: function(xhr){
48
+ this.setMessage('failure', true);
49
+ },
50
+
51
+ setMessage: function(status, fadeOut) {
52
+ this.holder
53
+ .set('text', this.options.events[status].text)
54
+ .set('class', status);
55
+
56
+ if (fadeOut) {
57
+ this.holder.addClass('fadeout');
58
+ setTimeout(function(){
59
+ this.holder.erase('class');
60
+ }.bind(this), this.options.fadeOutDuration);
61
+ }
62
+ }
63
+ });