drg_cms 0.5.10 → 0.5.10.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 731ea3ef7879ed33a901605b0a9dddb861d1ec31
4
- data.tar.gz: 8760d04c45460f00c4083babcb75470d7bdd5b5b
3
+ metadata.gz: 13427f3d66b3e41332787f5e5a1b9136c65874d7
4
+ data.tar.gz: cb7dd4a48763fc5da35b1e6f009f29687ebd4449
5
5
  SHA512:
6
- metadata.gz: 46394f7291cc085caf7957769d8f91bbf6ad3e1e282b6a83f49d7c32a7910c00e66b60855bb8cc3ee01259ef93c946158b93eed46d84cf585ba262d55b68b7f7
7
- data.tar.gz: dd46dc3424bb88f5053f1d2e9d313f12f71553127754147ea4de7719645d57c6cd3b7c2f1c57baebaef489a05347efee310c85ab97d3dadeaf99aebd6aab418e
6
+ metadata.gz: 4ae87d5b1417d792d1c253f5d623b032c6b8a0b19e08b89efe1e2631b4c6488acd5cdf55891ef937edec4e049da3970d28ab1e197eda1efb101f2b8d40abb80f
7
+ data.tar.gz: 2cce2a337d7da3f95dda769dfb330ba03d7b5e14481749326522618a7853c67138feaf26bb73fbbc4e0396940838d7a0056708aeb9d187fddcf9be454c5b9616
data/History.log CHANGED
@@ -4,6 +4,7 @@ New features for DRG CMS version 0.5.10
4
4
  jQuery javascript library forced to jQuery2
5
5
  Choices for select fields are now UTF-8 sorted since MongoDB does not provide utf sorting.
6
6
  Placeholder text added for text_autocomplete field. It can also be defined in form field html options.
7
+ Filters option can now have "like" keyword for fields that are not defined on form. For example created_by like user_id.
7
8
 
8
9
  Bugs resolved for DRG CMS version 0.5.10
9
10
 
@@ -0,0 +1,459 @@
1
+ /*
2
+ * SelectMultiple v0.1
3
+ * Copyright (c) 2015 krazedkrish( Shalil Awaley )
4
+ *
5
+ * This program is free software. It comes without any warranty, to
6
+ * the extent permitted by applicable law. You can redistribute it
7
+ * and/or modify it under the terms of the MIT LICENSE.
8
+ * See https://en.wikipedia.org/wiki/MIT_License for more details.
9
+ */
10
+
11
+ !function ($) {
12
+
13
+ "use strict";
14
+
15
+
16
+ /* SELECTMULTIPLE CLASS DEFINITION
17
+ * ====================== */
18
+
19
+ var SelectMultiple = function (element, options) {
20
+ this.options = options;
21
+ this.$element = $(element);
22
+ this.$container = $('<div/>', { 'class': "ms-container" });
23
+ this.$selectableContainer = $('<div/>', { 'class': 'ms-selectable' });
24
+ this.$selectableUl = $('<ul/>', { 'class': "ms-list", 'tabindex' : '-1' });
25
+ this.scrollTo = 0;
26
+ this.elemsSelector = 'li';
27
+ };
28
+
29
+ SelectMultiple.prototype = {
30
+ constructor: SelectMultiple,
31
+
32
+ init: function(){
33
+ var that = this,
34
+ ms = this.$element;
35
+
36
+ if (ms.next('.ms-container').length === 0){
37
+ ms.css({ position: 'absolute', left: '-9999px' });
38
+ ms.attr('id', ms.attr('id') ? ms.attr('id') : Math.ceil(Math.random()*1000)+'selectmultiple');
39
+ this.$container.attr('id', 'ms-'+ms.attr('id'));
40
+ this.$container.addClass(that.options.cssClass);
41
+ ms.find('option').each(function(){
42
+ that.generateLisFromOption(this);
43
+ });
44
+
45
+
46
+ if (that.options.selectableHeader){
47
+ that.$selectableContainer.append(that.options.selectableHeader);
48
+ }
49
+ that.$selectableContainer.append(that.$selectableUl);
50
+ if (that.options.selectableFooter){
51
+ that.$selectableContainer.append(that.options.selectableFooter);
52
+ }
53
+
54
+
55
+ that.$container.append(that.$selectableContainer);
56
+ ms.after(that.$container);
57
+
58
+ that.activeMouse(that.$selectableUl);
59
+ that.activeKeyboard(that.$selectableUl);
60
+
61
+ var action = that.options.dblClick ? 'dblclick' : 'click';
62
+
63
+ that.$selectableUl.on(action, '.ms-elem-selectable', function(){
64
+ that.select($(this).data('ms-value'));
65
+ });
66
+
67
+
68
+ ms.on('focus', function(){
69
+ that.$selectableUl.focus();
70
+ })
71
+ }
72
+
73
+ var selectedValues = ms.find('option:selected').map(function(){ return $(this).val(); }).get();
74
+ that.select(selectedValues, 'init');
75
+
76
+ if (typeof that.options.afterInit === 'function') {
77
+ that.options.afterInit.call(this, this.$container);
78
+ }
79
+ },
80
+
81
+ 'generateLisFromOption' : function(option, index, $container){
82
+ var that = this,
83
+ ms = that.$element,
84
+ attributes = "",
85
+ $option = $(option);
86
+
87
+ for (var cpt = 0; cpt < option.attributes.length; cpt++){
88
+ var attr = option.attributes[cpt];
89
+
90
+ if(attr.name !== 'value' && attr.name !== 'disabled'){
91
+ attributes += attr.name+'="'+attr.value+'" ';
92
+ }
93
+ }
94
+ var selectableLi = $('<li '+attributes+'><span>'+that.escapeHTML($option.text())+'</span><span class="pull-right ms-elem-selected">✔</span></li>'),
95
+ selectedLi = selectableLi.clone(),
96
+ value = $option.val(),
97
+ elementId = that.sanitize(value);
98
+
99
+ selectableLi.children('.ms-elem-selected').hide();
100
+
101
+ selectableLi
102
+ .data('ms-value', value)
103
+ .addClass('ms-elem-selectable')
104
+ .attr('id', elementId+'-selectable');
105
+
106
+
107
+ if ($option.prop('disabled') || ms.prop('disabled')){
108
+ selectableLi.addClass(that.options.disabledClass);
109
+ }
110
+
111
+ var $optgroup = $option.parent('optgroup');
112
+
113
+ if ($optgroup.length > 0){
114
+ var optgroupLabel = $optgroup.attr('label'),
115
+ optgroupId = that.sanitize(optgroupLabel),
116
+ $selectableOptgroup = that.$selectableUl.find('#optgroup-selectable-'+optgroupId);
117
+
118
+ if ($selectableOptgroup.length === 0){
119
+ var optgroupContainerTpl = '<li class="ms-optgroup-container"></li>',
120
+ optgroupTpl = '<ul class="ms-optgroup"><li class="ms-optgroup-label"><span>'+optgroupLabel+'</span></li></ul>';
121
+
122
+ $selectableOptgroup = $(optgroupContainerTpl);
123
+ $selectableOptgroup.attr('id', 'optgroup-selectable-'+optgroupId);
124
+ $selectableOptgroup.append($(optgroupTpl));
125
+ if (that.options.selectableOptgroup){
126
+ $selectableOptgroup.find('.ms-optgroup-label').on('click', function(){
127
+ var values = $optgroup.children(':not(:selected, :disabled)').map(function(){ return $(this).val() }).get();
128
+ that.select(values);
129
+ });
130
+ }
131
+ that.$selectableUl.append($selectableOptgroup);
132
+ }
133
+ index = index == undefined ? $selectableOptgroup.find('ul').children().length : index + 1;
134
+ selectableLi.insertAt(index, $selectableOptgroup.children());
135
+ } else {
136
+ index = index == undefined ? that.$selectableUl.children().length : index;
137
+
138
+ selectableLi.insertAt(index, that.$selectableUl);
139
+ }
140
+ },
141
+
142
+ 'addOption' : function(options){
143
+ var that = this;
144
+
145
+ if (options.value !== undefined && options.value !== null){
146
+ options = [options];
147
+ }
148
+ $.each(options, function(index, option){
149
+ if (option.value !== undefined && option.value !== null &&
150
+ that.$element.find("option[value='"+option.value+"']").length === 0){
151
+ var $option = $('<option value="'+option.value+'">'+option.text+'</option>'),
152
+ index = parseInt((typeof option.index === 'undefined' ? that.$element.children().length : option.index)),
153
+ $container = option.nested == undefined ? that.$element : $("optgroup[label='"+option.nested+"']")
154
+
155
+ $option.insertAt(index, $container);
156
+ that.generateLisFromOption($option.get(0), index, option.nested);
157
+ }
158
+ })
159
+ },
160
+
161
+ 'escapeHTML' : function(text){
162
+ return $("<div>").text(text).html();
163
+ },
164
+
165
+ 'activeKeyboard' : function($list){
166
+ var that = this;
167
+
168
+ $list.on('focus', function(){
169
+ $(this).addClass('ms-focus');
170
+ })
171
+ .on('blur', function(){
172
+ $(this).removeClass('ms-focus');
173
+ })
174
+ .on('keydown', function(e){
175
+ switch (e.which) {
176
+ case 40:
177
+ case 38:
178
+ e.preventDefault();
179
+ e.stopPropagation();
180
+ that.moveHighlight($(this), (e.which === 38) ? -1 : 1);
181
+ return;
182
+ case 9:
183
+ if(that.$element.is('[tabindex]')){
184
+ e.preventDefault();
185
+ var tabindex = parseInt(that.$element.attr('tabindex'), 10);
186
+ tabindex = (e.shiftKey) ? tabindex-1 : tabindex+1;
187
+ $('[tabindex="'+(tabindex)+'"]').focus();
188
+ return;
189
+ }else{
190
+ if(e.shiftKey){
191
+ that.$element.trigger('focus');
192
+ }
193
+ }
194
+ }
195
+ if($.inArray(e.which, that.options.keySelect) > -1){
196
+ e.preventDefault();
197
+ e.stopPropagation();
198
+ that.selectHighlighted($list);
199
+ return;
200
+ }
201
+ });
202
+ },
203
+
204
+ 'moveHighlight': function($list, direction){
205
+ var $elems = $list.find(this.elemsSelector),
206
+ $currElem = $elems.filter('.ms-hover'),
207
+ $nextElem = null,
208
+ elemHeight = $elems.first().outerHeight(),
209
+ containerHeight = $list.height(),
210
+ containerSelector = '#'+this.$container.prop('id');
211
+
212
+ $elems.removeClass('ms-hover');
213
+ if (direction === 1){ // DOWN
214
+
215
+ $nextElem = $currElem.nextAll(this.elemsSelector).first();
216
+ if ($nextElem.length === 0){
217
+ var $optgroupUl = $currElem.parent();
218
+
219
+ if ($optgroupUl.hasClass('ms-optgroup')){
220
+ var $optgroupLi = $optgroupUl.parent(),
221
+ $nextOptgroupLi = $optgroupLi.next(':visible');
222
+
223
+ if ($nextOptgroupLi.length > 0){
224
+ $nextElem = $nextOptgroupLi.find(this.elemsSelector).first();
225
+ } else {
226
+ $nextElem = $elems.first();
227
+ }
228
+ } else {
229
+ $nextElem = $elems.first();
230
+ }
231
+ }
232
+ } else if (direction === -1){ // UP
233
+
234
+ $nextElem = $currElem.prevAll(this.elemsSelector).first();
235
+ if ($nextElem.length === 0){
236
+ var $optgroupUl = $currElem.parent();
237
+
238
+ if ($optgroupUl.hasClass('ms-optgroup')){
239
+ var $optgroupLi = $optgroupUl.parent(),
240
+ $prevOptgroupLi = $optgroupLi.prev(':visible');
241
+
242
+ if ($prevOptgroupLi.length > 0){
243
+ $nextElem = $prevOptgroupLi.find(this.elemsSelector).last();
244
+ } else {
245
+ $nextElem = $elems.last();
246
+ }
247
+ } else {
248
+ $nextElem = $elems.last();
249
+ }
250
+ }
251
+ }
252
+ if ($nextElem.length > 0){
253
+ $nextElem.addClass('ms-hover');
254
+ var scrollTo = $list.scrollTop() + $nextElem.position().top -
255
+ containerHeight / 2 + elemHeight / 2;
256
+
257
+ $list.scrollTop(scrollTo);
258
+ }
259
+ },
260
+
261
+ 'selectHighlighted' : function($list){
262
+ var $elems = $list.find(this.elemsSelector),
263
+ $highlightedElem = $elems.filter('.ms-hover').first();
264
+
265
+ if ($highlightedElem.length > 0){
266
+ if ($list.parent().hasClass('ms-selectable')){
267
+ this.select($highlightedElem.data('ms-value'));
268
+ } else {
269
+ this.deselect($highlightedElem.data('ms-value'));
270
+ }
271
+ $elems.removeClass('ms-hover');
272
+ }
273
+ },
274
+
275
+ 'activeMouse' : function($list){
276
+ var that = this;
277
+
278
+ $('body').on('mouseenter', that.elemsSelector, function(){
279
+ $(this).parents('.ms-container').find(that.elemsSelector).removeClass('ms-hover');
280
+ $(this).addClass('ms-hover');
281
+ });
282
+
283
+ $('body').on('mouseleave', that.elemsSelector, function () {
284
+ $(this).parents('.ms-container').find(that.elemsSelector).removeClass('ms-hover');;
285
+ });
286
+ },
287
+
288
+ 'refresh' : function() {
289
+ this.destroy();
290
+ this.$element.selectMultiple(this.options);
291
+ },
292
+
293
+ 'destroy' : function(){
294
+ $("#ms-"+this.$element.attr("id")).remove();
295
+ this.$element.css('position', '').css('left', '')
296
+ this.$element.removeData('selectmultiple');
297
+ },
298
+
299
+ 'select' : function(value, method){
300
+ if (typeof value === 'string'){ value = [value]; }
301
+
302
+ var that = this,
303
+ ms = this.$element,
304
+ msIds = $.map(value, function(val){ return(that.sanitize(val)); }),
305
+ selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable').filter(':not(.'+that.options.disabledClass+')'),
306
+ options = ms.find('option:not(:disabled)').filter(function(){ return($.inArray(this.value, value) > -1); });
307
+
308
+ if (method === 'init'){
309
+ selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable');
310
+ }
311
+
312
+ if (selectables.length > 0){
313
+ selectables.addClass('ms-selected').children('.ms-elem-selected').show();
314
+
315
+ if (method !== 'init' && options.prop('selected') == true) {
316
+ that.deselect(value, method);
317
+ return;
318
+ }
319
+
320
+ options.prop('selected', true);
321
+
322
+ var selectableOptgroups = that.$selectableUl.children('.ms-optgroup-container');
323
+ if (selectableOptgroups.length > 0){
324
+ selectableOptgroups.each(function(){
325
+ var selectablesLi = $(this).find('.ms-elem-selectable');
326
+ if (that.options.hideOptGroupLabelOnAllSelected !== false && selectablesLi.length === selectablesLi.filter('.ms-selected').length){
327
+ $(this).find('.ms-optgroup-label').hide();
328
+ }
329
+ });
330
+
331
+ }
332
+ if (method !== 'init'){
333
+ ms.trigger('change');
334
+ if (typeof that.options.afterSelect === 'function') {
335
+ that.options.afterSelect.call(this, value);
336
+ }
337
+ }
338
+ }
339
+ },
340
+
341
+ 'deselect' : function(value, method){
342
+ if (typeof value === 'string'){ value = [value]; }
343
+
344
+ var that = this,
345
+ ms = this.$element,
346
+ msIds = $.map(value, function(val){ return(that.sanitize(val)); }),
347
+ selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable'),
348
+ options = ms.find('option').filter(function(){ return($.inArray(this.value, value) > -1); });
349
+
350
+ selectables.removeClass('ms-selected').children('.ms-elem-selected').hide();
351
+ options.prop('selected', false);
352
+
353
+ var selectableOptgroups = that.$selectableUl.children('.ms-optgroup-container');
354
+ if (selectableOptgroups.length > 0){
355
+ selectableOptgroups.each(function(){
356
+ var selectablesLi = $(this).find('.ms-elem-selectable');
357
+ if (selectablesLi.filter(':not(.ms-selected)').length > 0){
358
+ $(this).find('.ms-optgroup-label').show();
359
+ }
360
+ });
361
+
362
+ }
363
+ if (method !== 'init'){
364
+ ms.trigger('change');
365
+ if (typeof that.options.afterDeselect === 'function') {
366
+ that.options.afterDeselect.call(this, value);
367
+ }
368
+ }
369
+ },
370
+
371
+ 'select_all' : function(){
372
+ var ms = this.$element,
373
+ values = ms.val();
374
+
375
+ ms.find('option:not(":disabled")').prop('selected', true);
376
+ this.$selectableUl.find('.ms-elem-selectable').filter(':not(.'+this.options.disabledClass+')').addClass('ms-selected').children('.ms-elem-selected').show();
377
+ if(this.options.hideOptGroupLabelOnAllSelected !== false){
378
+ this.$selectableUl.find('.ms-optgroup-label').hide();
379
+ }
380
+ ms.trigger('change');
381
+ if (typeof this.options.afterSelect === 'function') {
382
+ var selectedValues = $.grep(ms.val(), function(item){
383
+ return $.inArray(item, values) < 0;
384
+ });
385
+ this.options.afterSelect.call(this, selectedValues);
386
+ }
387
+ },
388
+
389
+ 'deselect_all' : function(){
390
+ var ms = this.$element,
391
+ values = ms.val();
392
+
393
+ ms.find('option').prop('selected', false);
394
+ this.$selectableUl.find('.ms-elem-selectable').removeClass('ms-selected').children('.ms-elem-selected').hide();
395
+ this.$selectableUl.find('.ms-optgroup-label').show();
396
+ this.$selectableUl.focus();
397
+ ms.trigger('change');
398
+ if (typeof this.options.afterDeselect === 'function') {
399
+ this.options.afterDeselect.call(this, values);
400
+ }
401
+ },
402
+
403
+ sanitize: function(value){
404
+ var hash = 0, i, character;
405
+ if (value.length == 0) return hash;
406
+ var ls = 0;
407
+ for (i = 0, ls = value.length; i < ls; i++) {
408
+ character = value.charCodeAt(i);
409
+ hash = ((hash<<5)-hash)+character;
410
+ hash |= 0; // Convert to 32bit integer
411
+ }
412
+ return hash;
413
+ }
414
+ };
415
+
416
+ /* SELECTMULTIPLE PLUGIN DEFINITION
417
+ * ======================= */
418
+
419
+ $.fn.selectMultiple = function () {
420
+ var option = arguments[0],
421
+ args = arguments;
422
+
423
+ return this.each(function () {
424
+ var $this = $(this),
425
+ data = $this.data('selectmultiple'),
426
+ options = $.extend({}, $.fn.selectMultiple.defaults, $this.data(), typeof option === 'object' && option);
427
+
428
+ if (!data){ $this.data('selectmultiple', (data = new SelectMultiple(this, options))); }
429
+
430
+ if (typeof option === 'string'){
431
+ data[option](args[1]);
432
+ } else {
433
+ data.init();
434
+ }
435
+ });
436
+ };
437
+
438
+ $.fn.selectMultiple.defaults = {
439
+ keySelect: [32],
440
+ selectableOptgroup: false,
441
+ disabledClass : 'disabled',
442
+ dblClick : false,
443
+ cssClass: '',
444
+ hideOptGroupLabelOnAllSelected: true
445
+ };
446
+
447
+ $.fn.selectMultiple.Constructor = SelectMultiple;
448
+
449
+ $.fn.insertAt = function(index, $parent) {
450
+ return this.each(function() {
451
+ if (index === 0) {
452
+ $parent.prepend(this);
453
+ } else {
454
+ $parent.children().eq(index - 1).after(this);
455
+ }
456
+ });
457
+ }
458
+
459
+ }(window.jQuery);
@@ -26,7 +26,8 @@
26
26
  //= #require drg_cms/elfinder/js/elfinder.min.js
27
27
  //= #require drg_cms/elfinder/js/proxy/elFinderSupportVer1.js
28
28
 
29
- //= #require drg_cms/jquery.the-modal.js
30
29
  //= require drg_cms/jquery.bpopup.min.js
30
+ //= require drg_cms/select-multiple
31
+
31
32
 
32
33
 
@@ -0,0 +1,93 @@
1
+ .ms-container{
2
+ width: 200px;
3
+ }
4
+
5
+ .ms-container:after{
6
+ content: ".";
7
+ display: block;
8
+ height: 0;
9
+ line-height: 0;
10
+ font-size: 0;
11
+ clear: both;
12
+ min-height: 0;
13
+ visibility: hidden;
14
+ }
15
+
16
+ .ms-container .ms-selectable, .ms-container .ms-selection{
17
+ background: #fff;
18
+ color: #555555;
19
+ /*float: left;*/
20
+ }
21
+
22
+ .ms-container .ms-list{
23
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
24
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
25
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
26
+ -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
27
+ -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
28
+ -ms-transition: border linear 0.2s, box-shadow linear 0.2s;
29
+ -o-transition: border linear 0.2s, box-shadow linear 0.2s;
30
+ transition: border linear 0.2s, box-shadow linear 0.2s;
31
+ border: 1px solid #ccc;
32
+ -webkit-border-radius: 3px;
33
+ -moz-border-radius: 3px;
34
+ border-radius: 3px;
35
+ position: relative;
36
+ height: 200px;
37
+ padding: 0;
38
+ overflow-y: auto;
39
+ }
40
+
41
+ .ms-container .ms-list.ms-focus{
42
+ border-color: rgba(82, 168, 236, 0.8);
43
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
44
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
45
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
46
+ outline: 0;
47
+ outline: thin dotted \9;
48
+ }
49
+
50
+ .ms-container ul{
51
+ margin: 0;
52
+ list-style-type: none;
53
+ padding: 0;
54
+ }
55
+
56
+ .ms-container .ms-optgroup-container{
57
+ width: 100%;
58
+ }
59
+
60
+ .ms-container .ms-optgroup-label{
61
+ margin: 0;
62
+ padding: 5px 0px 0px 5px;
63
+ cursor: pointer;
64
+ color: #999;
65
+ }
66
+
67
+ .ms-container .ms-selectable li.ms-elem-selectable{
68
+ border-bottom: 1px #eee solid;
69
+ padding: 2px 10px;
70
+ color: #555;
71
+ font-size: 14px;
72
+ }
73
+
74
+ .ms-container .ms-selectable li.ms-hover{
75
+ cursor: pointer;
76
+ color: #fff;
77
+ text-decoration: none;
78
+ background-color: #08c;
79
+ }
80
+
81
+ .ms-container .ms-selectable li.disabled{
82
+ background-color: #eee;
83
+ color: #aaa;
84
+ cursor: text;
85
+ }
86
+
87
+ .ms-container .ms-selectable li span.ms-elem-selected {
88
+ display: none;
89
+ }
90
+
91
+ .pull-right.ms-elem-selected{
92
+ float: right;
93
+ }
@@ -10,4 +10,5 @@
10
10
  *
11
11
  *= require drg_cms/drg_cms
12
12
  *= require font-awesome
13
+
13
14
  */
@@ -10,13 +10,13 @@
10
10
  *
11
11
  *= require drg_cms/drg_cms
12
12
  *= require drg_cms/jquery.datetimepicker.css
13
+ *= require drg_cms/select-multiple
13
14
  *= #require jquery-ui/all
14
15
  *= require jquery-ui/tooltip
15
16
  *= require jquery-ui/autocomplete
16
17
  *= #require ../javascripts/drg_cms/elfinder/css/elfinder.min.css
17
18
  *= #require ../javascripts/drg_cms/elfinder/css/theme.css
18
19
  *= require font-awesome
19
- *= #require drg_cms/the-modal.css
20
20
  */
21
21
 
22
22
  /* Required for link buttons to look alike */
@@ -195,6 +195,15 @@ def check_filter_options() #:nodoc:
195
195
  model
196
196
  end
197
197
  end
198
+ =begin
199
+ # TODO Use only fields requested. Higly experimental but necessary in some scenarios
200
+ if (columns = @form['result_set']['columns'])
201
+ cols = []
202
+ columns.each { |k,v| cols << v['name'] }
203
+ p '*',cols,'*'
204
+ @records = @records.only(cols)
205
+ end
206
+ =end
198
207
  # pagination if required
199
208
  per_page = (@form['result_set']['per_page'] || 30).to_i
200
209
  if per_page > 0
@@ -393,6 +402,12 @@ def create
393
402
  end
394
403
  #
395
404
  if params['id'].nil? # create record
405
+ # Prevent double form submit
406
+ params[:form_time_stamp] = params[:form_time_stamp].to_i
407
+ session[:form_time_stamp] ||= 0
408
+ return index if params[:form_time_stamp] <= session[:form_time_stamp]
409
+ session[:form_time_stamp] = params[:form_time_stamp]
410
+ #
396
411
  create_new_empty_record
397
412
  params[:return_to] = 'index' if params[:commit] == t('drgcms.save&back') # save & back
398
413
  if save_data
@@ -70,7 +70,7 @@ def dc_user_has_role(role)
70
70
  role = DcPolicyRole.find_by(name: rol)
71
71
  role = DcPolicyRole.find_by(system_name: rol) if role.nil?
72
72
  end
73
- return false if role.nil?
73
+ return false if role.nil? or session[:user_roles].nil?
74
74
  # role is found in user_roles
75
75
  session[:user_roles].include?(role._id)
76
76
  end
@@ -200,7 +200,7 @@ def dc_user_can(permission, table=params[:table])
200
200
  end
201
201
  # Sometimes anonymous user is allowed to use cmsedit. Search for system default role.
202
202
  #TODO This might not be the best idea. Check in the future.
203
- if session[:user_roles].nil?
203
+ if session[:user_roles].nil? or session[:user_roles] == []
204
204
  guest = DcUserRole.find_by(:system_name => 'guest')
205
205
  session[:user_roles] = guest ? [guest.id] : []
206
206
  end
@@ -294,6 +294,8 @@ def dc_process_default_request()
294
294
  dc_set_options(@site.settings)
295
295
  # HOMEPAGE. When no parameters is set
296
296
  params[:path] = @site.homepage_link if params[:id].nil? and params[:path].nil?
297
+ # some other process request. It shoud fail if not defined
298
+ return eval(@site.request_processor) if !@site.request_processor.blank?
297
299
  # Search for page
298
300
  pageclass = @site.page_table.classify.constantize
299
301
  if params[:id]
@@ -359,11 +361,13 @@ end
359
361
  # # Just a reminder: request.session_options[:skip] = true
360
362
  ##########################################################################
361
363
  def dc_single_sitedoc_request
362
- session[:edit_mode] ||= 0
363
- @site = dc_get_site
364
- # @site is not defined. render 404 error
365
- return dc_render_404('Site!') unless @site
366
- dc_set_options(@site.settings)
364
+ if @site.nil?
365
+ session[:edit_mode] ||= 0
366
+ @site = dc_get_site
367
+ # @site is not defined. render 404 error
368
+ return dc_render_404('Site!') unless @site
369
+ dc_set_options(@site.settings)
370
+ end
367
371
  # HOMEPAGE. When no parameters is set
368
372
  params[:path] = @site.homepage_link if params[:path].nil?
369
373
  @parts = @site.dc_parts
@@ -85,6 +85,7 @@ result_set:
85
85
  4:
86
86
  name: active
87
87
  eval: dc_icon4_boolean
88
+ eval: dc_name4_value
88
89
 
89
90
  form:
90
91
  title:
@@ -133,6 +134,7 @@ form:
133
134
  40:
134
135
  name: dc_site_id
135
136
  type: select
137
+ multiple: true || 1
136
138
  eval: dc_choices4('model','description_field_name','_id')
137
139
  eval: ModelName.choices4_site
138
140
  html:
@@ -57,14 +57,18 @@ form:
57
57
  type: text_field
58
58
  size: 50
59
59
  70:
60
- name: files_directory
60
+ name: request_processor
61
61
  type: text_field
62
62
  size: 50
63
63
  80:
64
+ name: files_directory
65
+ type: text_field
66
+ size: 50
67
+ 90:
64
68
  name: logo
65
69
  type: file_select
66
70
  size: 50
67
- 90:
71
+ 100:
68
72
  name: active
69
73
  type: check_box
70
74
  size: 50
@@ -101,7 +101,7 @@ EOT
101
101
  s = session[@form['table']]
102
102
  if s and s[:filter]
103
103
  caption << '&nbsp;&nbsp;' + dc_link_to(nil,'remove lg', {controller: 'cmsedit',
104
- filter: 'off', table: @form['table']}, { title: t('drgcms.filter_off')+s[:filter]})
104
+ filter: 'off', table: @form['table']}, { title: DcFilter.title4_filter_off(s[:filter]) })
105
105
  end
106
106
  caption
107
107
  # new
@@ -161,7 +161,7 @@ def dc_div_filter()
161
161
 
162
162
  </td>
163
163
  <td class="dc-link dc-animate drgcms_popup_submit" data-url="#{url}">#{fa_icon('check-square-o')} #{t('drgcms.filter_on')}</td>
164
- <td class="dc-link dc-animate">#{dc_link_to('drgcms.filter_off','close', {action: 'index', filter: 'off', :table => @form['table']}) }</td>
164
+ <td class="dc-link dc-animate">#{dc_link_to('drgcms.filter_off','close', {action: :index, filter: 'off', table: @form['table'], formname: params['formname']}) }</td>
165
165
  </table>
166
166
  </div>
167
167
  EOT
@@ -188,7 +188,8 @@ def dc_link_or_ajax(yaml, parms) #:nodoc:
188
188
  rest = {}
189
189
  rest['method'] = yaml['method'] || yaml['request'] || 'get'
190
190
  rest['caption'] = yaml['caption'] || yaml['text']
191
- rest['class'] = (yaml['type'] == 'link' ? 'dc-link' : 'dc-link-ajax') + ' dc-animate'
191
+ # rest['class'] = (yaml['type'] == 'link' ? 'dc-link' : 'dc-link-ajax') + ' dc-animate'
192
+ rest['class'] = 'dc-animate'
192
193
  rest['title'] = yaml['title']
193
194
 
194
195
  dc_deprecate "Form: result_set:action:text directive will be deprecated. Use caption instead of text." if yaml['text']
@@ -373,55 +374,55 @@ end
373
374
  ############################################################################
374
375
  def dc_columns_for_result(document)
375
376
  html = ''
376
- if (columns = @form['result_set']['columns'])
377
- columns.each do |k,v|
378
- session[:form_processing] = "result_set:columns: #{k}=#{v}"
377
+ return html unless @form['result_set']['columns']
378
+ #
379
+ @form['result_set']['columns'].each do |k,v|
380
+ session[:form_processing] = "result_set:columns: #{k}=#{v}"
379
381
  # convert shortcut to hash
380
- v = {'name' => v} if v.class == String
382
+ v = {'name' => v} if v.class == String
381
383
  # eval
382
- value = if v['eval']
383
- if v['eval'].match('dc_name4_id')
384
- a = v['eval'].split(',')
385
- if a.size == 3
386
- dc_name4_id(a[1], a[2], nil, document[ v['name'] ])
387
- else
388
- dc_name4_id(a[1], a[2], a[3], document[ v['name'] ])
389
- end
390
- elsif v['eval'].match('dc_name4_value')
391
- dc_name4_value( @form['table'], v['name'], document[ v['name'] ] )
392
- elsif v['eval'].match('eval ')
393
- # evaluate with specified parameters
384
+ value = if v['eval']
385
+ if v['eval'].match('dc_name4_id')
386
+ a = v['eval'].split(',')
387
+ if a.size == 3
388
+ dc_name4_id(a[1], a[2], nil, document[ v['name'] ])
394
389
  else
395
- if v['params']
396
- if v['params'] == 'document' # pass document as parameter when all
397
- eval( "#{v['eval']} document")
398
- else # list of fields delimeted by ,
399
- params = v['params'].chomp.split(',').inject('') do |result,e|
400
- result << (e.match(/\.|\:|\(/) ? e : "document['#{e.strip}']") + ','
401
- end
402
- params.chomp!(',')
403
- eval( "#{v['eval']} #{params}")
390
+ dc_name4_id(a[1], a[2], a[3], document[ v['name'] ])
391
+ end
392
+ elsif v['eval'].match('dc_name4_value')
393
+ dc_name4_value( @form['table'], v['name'], document[ v['name'] ] )
394
+ elsif v['eval'].match('eval ')
395
+ # evaluate with specified parameters
396
+ else
397
+ if v['params']
398
+ if v['params'] == 'document' # pass document as parameter when all
399
+ eval( "#{v['eval']} document")
400
+ else # list of fields delimeted by ,
401
+ params = v['params'].chomp.split(',').inject('') do |result,e|
402
+ result << (e.match(/\.|\:|\(/) ? e : "document['#{e.strip}']") + ','
404
403
  end
405
- else
406
- eval( "#{v['eval']} '#{document[ v['name'] ]}'")
404
+ params.chomp!(',')
405
+ eval( "#{v['eval']} #{params}")
407
406
  end
407
+ else
408
+ eval( "#{v['eval']} '#{document[ v['name'] ]}'")
408
409
  end
410
+ end
409
411
  # as field
410
- elsif document.respond_to?(v['name'])
411
- dc_format_value(document.send( v['name'] ), v['format'])
412
+ elsif document.respond_to?(v['name'])
413
+ dc_format_value(document.send( v['name'] ), v['format'])
412
414
  # as hash (dc_dummy)
413
- elsif document.class == Hash
414
- document[ v['name'] ]
415
+ elsif document.class == Hash
416
+ document[ v['name'] ]
415
417
  # error
416
- else
417
- "!!! #{v['name']}"
418
- end
419
- #
420
- td = '<td '
421
- td << dc_style_or_class('class',v['td_class'],value,document)
422
- td << dc_style_or_class('style',v['td_style'] || v['style'],value,document)
423
- html << "#{td}>#{value}</td>"
418
+ else
419
+ "!!! #{v['name']}"
424
420
  end
421
+ #
422
+ td = '<td '
423
+ td << dc_style_or_class('class',v['td_class'],value,document)
424
+ td << dc_style_or_class('style',v['td_style'] || v['style'],value,document)
425
+ html << "#{td}>#{value}</td>"
425
426
  end
426
427
  html.html_safe
427
428
  end
@@ -585,6 +586,19 @@ def dc_actions_for_form()
585
586
  c.html_safe
586
587
  end
587
588
 
589
+ ############################################################################
590
+ # Create background div and table definitions for result set.
591
+ ############################################################################
592
+ def dc_background_for_result
593
+ html = '<div class="dc-result-div" '
594
+ html << (@form['result_set']['table_style'] ? "style=\"overflow-x: scroll;\" >" : '>')
595
+ html << "\n"
596
+ #
597
+ html << "<table class=\"dc-result #{@form['result_set']['table_class']}\" "
598
+ html << (@form['result_set']['table_style'] ? "style=\"#{@form['result_set']['table_style']}\" >" : '>')
599
+ html.html_safe
600
+ end
601
+
588
602
  ############################################################################
589
603
  # Checks if value is defined and sets default. If values are sent it also checks
590
604
  # if value is found in values. If not it will report error and set value to default.
@@ -735,7 +749,9 @@ def dc_fields_for_form()
735
749
  html << tdata
736
750
  end
737
751
  # add last_updated_at hidden field so controller can check if record was updated in during editing
738
- html << hidden_field(nil, :last_updated_at, :value => @record.updated_at.to_i) if @record.respond_to?(:updated_at)
752
+ html << hidden_field(nil, :last_updated_at, value: @record.updated_at.to_i) if @record.respond_to?(:updated_at)
753
+ # add form time stamp to prevent double form submit
754
+ html << hidden_field(nil, :form_time_stamp, value: Time.now.to_i)
739
755
  html.html_safe
740
756
  end
741
757
 
@@ -572,6 +572,25 @@ def dc_name4_value(model, field, value)
572
572
  ''
573
573
  end
574
574
 
575
+ ############################################################################
576
+ # Return choices for field in model if choices are defined in localization text.
577
+ #
578
+ # Parameters:
579
+ # [model] String. Table (collection) model name (lowercase).
580
+ # [field] String. Field name used.
581
+ #
582
+ # Example:
583
+ # dc_choices4_field('dc_user', 'state' )
584
+ #
585
+ # Returns:
586
+ # Array. Choices for select input field
587
+ ############################################################################
588
+ def dc_choices4_field(model, field)
589
+ c = t('helpers.label.' + model + '.choices4_' + field )
590
+ return ['error'] if c.match( 'translation missing' )
591
+ c.chomp.split(',').inject([]) {|r,v| r << v.split(':') }
592
+ end
593
+
575
594
  ############################################################################
576
595
  # Will return descriptive text for id key when field in one table (collection) has belongs_to
577
596
  # relation to other table.
File without changes
@@ -58,6 +58,10 @@ def self.get_filter(filter)
58
58
  #
59
59
  model = yaml['table'].classify.constantize
60
60
  field = yaml['field'] == 'id' ? '_id' : yaml['field'] # must be
61
+ # if empty required
62
+ if yaml['operation'] == 'empty'
63
+ return model.in(field => [nil,''])
64
+ end
61
65
  # if value == NIL no filter is necessary
62
66
  return nil if yaml['value'].class == String and yaml['value'] == '#NIL'
63
67
 
@@ -175,4 +179,19 @@ def self.menu_filter(parent)
175
179
  html << '<li id="open_drgcms_filter">' + I18n.t('drgcms.filter_set') + '</li>'
176
180
  html << '</ul>'
177
181
  end
182
+
183
+ ######################################################################
184
+ # Creates title for turn filter off, which consists of displaying curently
185
+ # active filter and text to turn it off.
186
+ ######################################################################
187
+ def self.title4_filter_off(filter_yaml)
188
+ filter = YAML.load(filter_yaml)
189
+ operations = I18n.t('drgcms.choices4_filter_operators').chomp.split(',').inject([]) {|r,v| r << v.split(':') }
190
+ operation = ''
191
+ operations.each{|a| (operation = a.first; break) if a.last == filter['operation']}
192
+ #
193
+ '[ ' + I18n.t("helpers.label.#{filter['table']}.#{filter['field']}") +
194
+ " ] #{operation} [ #{filter['value'].to_s} ] : #{I18n.t('drgcms.filter_off')}"
195
+ end
196
+
178
197
  end
@@ -43,6 +43,7 @@ included do
43
43
  field :page_class, type: String, default: 'DcPage'
44
44
  field :site_layout, type: String, default: 'content'
45
45
  field :menu_class, type: String, default: 'DcSimpleMenu'
46
+ field :request_processor, type: String
46
47
  field :files_directory, type: String
47
48
  field :logo, type: String
48
49
  field :active, type: Boolean, default: true
@@ -107,6 +107,25 @@ def self.choices4_country()
107
107
  @@countries
108
108
  end
109
109
 
110
+ ##########################################################################
111
+ # Performs ligically test on passed email parameter.
112
+ #
113
+ # Parameters:
114
+ # [email] String: e-mail address
115
+ #
116
+ # Returns:
117
+ # Boolean: True if parameter is logically valid email address.
118
+ #
119
+ # Example:
120
+ # if !DcUser.is_email?(params[:email])
121
+ # flash[:error] = 'e-Mail address is not valid!'
122
+ # end
123
+ #
124
+ ##########################################################################
125
+ def self.is_email?(email)
126
+ email.to_s =~ /^[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/
127
+ end
128
+
110
129
  end
111
130
  end
112
131
 
@@ -607,13 +607,27 @@ end
607
607
  def ro_standard
608
608
  value = @record.respond_to?(@yaml['name']) ? @record[@yaml['name']] : nil
609
609
  return self if value.nil?
610
- #
611
- get_choices.each do |choice|
612
- if choice.class == Array
613
- return super(choice.first) if choice.last.to_s == value.to_s
614
- else
615
- return super(choice) if choice.to_s == value.to_s
616
- end
610
+ #
611
+ choices = get_choices()
612
+ if value.class == Array # multiple choices
613
+ html = ''
614
+ value.each do |element|
615
+ choices.each do |choice|
616
+ if choice.to_s == element.to_s
617
+ html << '<br>' if html.size > 0
618
+ html << "#{element.to_s}"
619
+ end
620
+ end
621
+ end
622
+ return super(html)
623
+ else
624
+ choices.each do |choice|
625
+ if choice.class == Array
626
+ return super(choice.first) if choice.last.to_s == value.to_s
627
+ else
628
+ return super(choice) if choice.to_s == value.to_s
629
+ end
630
+ end
617
631
  end
618
632
  super('')
619
633
  end
@@ -624,10 +638,15 @@ end
624
638
  def render
625
639
  return ro_standard if @readonly
626
640
  set_initial_value('html','selected')
627
- #
641
+ #
628
642
  @yaml['html'].symbolize_keys!
629
- record = record_text_for(@yaml['name'])
630
- @html << @parent.select(record, @yaml['name'], get_choices, @yaml['html'])
643
+ record = record_text_for(@yaml['name'])
644
+ if @yaml['multiple']
645
+ @html << @parent.select(record, @yaml['name'], get_choices, @yaml['html'], {multiple: true})
646
+ @js << "$('##{record}_#{@yaml['name']}').selectMultiple();"
647
+ else
648
+ @html << @parent.select(record, @yaml['name'], get_choices, @yaml['html'])
649
+ end
631
650
  self
632
651
  end
633
652
 
@@ -4,8 +4,7 @@
4
4
  <%= dc_table_title_for_result @records %>
5
5
 
6
6
  <% unless @records.nil? %>
7
- <table class="dc-result <%= @form['result_set']['table_class'] %>"
8
- style="<%= @form['result_set']['table_style'] %> ">
7
+ <%= dc_background_for_result %>
9
8
  <tr><%= dc_header_for_result %></tr>
10
9
 
11
10
  <% for document in @records %>
@@ -16,6 +15,7 @@
16
15
  <% end %>
17
16
 
18
17
  </table>
18
+ </div>
19
19
  <% end %>
20
20
 
21
21
  </div>
@@ -84,7 +84,7 @@ en:
84
84
  updated_at: Updated at
85
85
  new_record: New record
86
86
 
87
- choices4_filter_operators: 'Equal to:eq,Contains:like,Greater then:gt,Less then:lt'
87
+ choices4_filter_operators: 'Equal to:eq,Contains:like,Greater then:gt,Less then:lt,Is empty:empty'
88
88
 
89
89
  browse_collections: Browse all collections
90
90
 
@@ -84,7 +84,7 @@ sl:
84
84
  updated_at: Spremenjeno
85
85
  new_record: Nov zapis
86
86
 
87
- choices4_filter_operators: 'Je enak:eq,Vsebuje:like,Je večji od:gt,Je manjši od:lt'
87
+ choices4_filter_operators: 'Je enak:eq,Vsebuje:like,Je večji od:gt,Je manjši od:lt,Je prazen:empty'
88
88
 
89
89
  browse_collections: Brskanje po definicijah zbirk
90
90
 
@@ -60,6 +60,7 @@ en:
60
60
  alias_for: Alias for
61
61
  rails_view: Rails view
62
62
  design: Standard design
63
+ request_processor: Request processor
63
64
 
64
65
  dc_design:
65
66
  tabletitle: Designs
@@ -523,6 +524,7 @@ en:
523
524
  rails_view: Rails view filename used as standard design
524
525
  design: Standard design can also be defined at the site level
525
526
  dc_parts: Parts contained in site
527
+ request_processor: Method which will provide output instead of dc_process_default_request
526
528
 
527
529
  dc_user:
528
530
  username: Username
@@ -50,6 +50,7 @@ sl:
50
50
  menu_class: Razred menija
51
51
  site_layout: Rails layout
52
52
  files_directory: Mapa z datotekami
53
+ request_processor: Metoda zahtevka
53
54
  logo: Logotip
54
55
  dc_policies: Politike za dostop
55
56
  active: Aktivna
@@ -528,6 +529,7 @@ sl:
528
529
  rails_view: Rails view datoteka uporabljena za standard dizajn
529
530
  design: Standard dizajn lahko definirate tudi pri spletišču
530
531
  dc_parts: Sestavni elementi strani
532
+ request_processor: Ime ruby metode, ki bo klicana namesto dc_process_default_request
531
533
 
532
534
  dc_design:
533
535
  name: Unikatno ime za dizajn. Pomembno za iskanje
data/drg_cms.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.md", "History.log", "drg_cms.gemspec"]
19
19
  s.test_files = Dir["test/**/*"]
20
20
 
21
- s.add_dependency 'rails' #, '~> 3.2.16'
21
+ s.add_dependency 'rails', '~> 4'
22
22
  s.add_dependency 'jquery-rails'
23
23
  s.add_dependency 'jquery-ui-rails'
24
24
 
@@ -1,4 +1,4 @@
1
1
  module DrgCms #:nodoc:
2
2
  # drg_cms gem version
3
- VERSION = "0.5.10"
3
+ VERSION = "0.5.10.7"
4
4
  end
@@ -15,7 +15,7 @@ def create_form_file
15
15
  @model = file_name.classify.constantize rescue nil
16
16
  return (p "Model #{file_name.classify} not found! Aborting.") if @model.nil?
17
17
  #
18
- yml = top_level_options + index_options + result_set_options + form_top_options + form_fields_options
18
+ yml = top_level_options + index_options + result_set_options + form_top_options + form_fields_options + localize_options
19
19
  create_file "app/forms/#{formname}.yml", yml
20
20
  end
21
21
 
@@ -153,11 +153,10 @@ def form_field(field, index, offset)
153
153
  yml << ' '*offset + "name: #{field}\n"
154
154
  yml << ' '*offset + "type: #{type}\n"
155
155
  yml << ' '*offset + eval if eval.size > 0
156
- yml << ' '*offset + "html:\n"
157
- offset += 2
158
- if type == 'text_field'
159
- yml << ' '*offset + "size: 50\n"
160
- else
156
+ yml << ' '*offset + "size: 50\n" if type == 'text_field'
157
+ if type == 'select'
158
+ yml << ' '*offset + "html:\n"
159
+ offset += 2
161
160
  yml << ' '*offset + "include_blank: true\n"
162
161
  end
163
162
  yml
@@ -213,5 +212,29 @@ def form_fields_options
213
212
  end
214
213
  yml
215
214
  end
215
+
216
+ ###########################################################################
217
+ #
218
+ ###########################################################################
219
+ def localize_options
220
+ forbidden = ['_id','created_by','updated_by','created_at','updated_at']
221
+ yml =<<EOT
222
+
223
+ #################################################################
224
+ # Localization
225
+ en:
226
+ helpers:
227
+ label:
228
+ #{file_name}:
229
+ tabletitle:
230
+ choices4_ :
231
+
232
+ EOT
233
+ @model.attribute_names.each do |attr_name|
234
+ next if forbidden.include?(attr_name)
235
+ yml << " #{attr_name}: \n"
236
+ end
237
+ yml
238
+ end
216
239
 
217
240
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drg_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.10
4
+ version: 0.5.10.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damjan Rems
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-24 00:00:00.000000000 Z
11
+ date: 2016-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: jquery-rails
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -172,12 +172,14 @@ files:
172
172
  - app/assets/javascripts/drg_cms/jquery-migrate.js
173
173
  - app/assets/javascripts/drg_cms/jquery.bpopup.min.js
174
174
  - app/assets/javascripts/drg_cms/jquery.datetimepicker.js
175
+ - app/assets/javascripts/drg_cms/select-multiple.js
175
176
  - app/assets/javascripts/drg_cms/some_scripts.js
176
177
  - app/assets/javascripts/drg_cms_application.js
177
178
  - app/assets/javascripts/drg_cms_cms.js
178
179
  - app/assets/stylesheets/drg_cms/drg_cms.css
179
180
  - app/assets/stylesheets/drg_cms/jquery-ui.css
180
181
  - app/assets/stylesheets/drg_cms/jquery.datetimepicker.css
182
+ - app/assets/stylesheets/drg_cms/select-multiple.css
181
183
  - app/assets/stylesheets/drg_cms/th-bg.png
182
184
  - app/assets/stylesheets/drg_cms/theme.css
183
185
  - app/assets/stylesheets/drg_cms_application.css
@@ -365,7 +367,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
365
367
  version: '0'
366
368
  requirements: []
367
369
  rubyforge_project:
368
- rubygems_version: 2.2.5
370
+ rubygems_version: 2.5.1
369
371
  signing_key:
370
372
  specification_version: 4
371
373
  summary: 'DRG CMS: Rapid web application development tool for Ruby, Rails and MongoDB'