right-rails 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.textile +50 -0
- data/Rakefile +23 -0
- data/generators/right_rails/right_rails_generator.rb +41 -0
- data/generators/right_rails/templates/iframed.html.erb +10 -0
- data/generators/right_scaffold/right_scaffold_generator.rb +53 -0
- data/generators/right_scaffold/templates/controller.rb +99 -0
- data/generators/right_scaffold/templates/helper.rb +2 -0
- data/generators/right_scaffold/templates/layout.html.erb +18 -0
- data/generators/right_scaffold/templates/style.css +54 -0
- data/generators/right_scaffold/templates/view__form.html.erb +16 -0
- data/generators/right_scaffold/templates/view__item.html.erb +13 -0
- data/generators/right_scaffold/templates/view_edit.html.erb +6 -0
- data/generators/right_scaffold/templates/view_index.html.erb +9 -0
- data/generators/right_scaffold/templates/view_new.html.erb +5 -0
- data/generators/right_scaffold/templates/view_show.html.erb +10 -0
- data/init.rb +12 -0
- data/javascripts/right-autocompleter-src.js +303 -0
- data/javascripts/right-autocompleter.js +9 -0
- data/javascripts/right-behavior-src.js +240 -0
- data/javascripts/right-behavior.js +8 -0
- data/javascripts/right-calendar-src.js +855 -0
- data/javascripts/right-calendar.js +9 -0
- data/javascripts/right-dnd-src.js +555 -0
- data/javascripts/right-dnd.js +9 -0
- data/javascripts/right-effects-src.js +425 -0
- data/javascripts/right-effects.js +6 -0
- data/javascripts/right-events-src.js +369 -0
- data/javascripts/right-events.js +6 -0
- data/javascripts/right-json-src.js +176 -0
- data/javascripts/right-json.js +6 -0
- data/javascripts/right-lightbox-src.js +597 -0
- data/javascripts/right-lightbox.js +9 -0
- data/javascripts/right-rails-src.js +269 -0
- data/javascripts/right-rails.js +9 -0
- data/javascripts/right-rater-src.js +248 -0
- data/javascripts/right-rater.js +9 -0
- data/javascripts/right-selectable-src.js +507 -0
- data/javascripts/right-selectable.js +7 -0
- data/javascripts/right-slider-src.js +291 -0
- data/javascripts/right-slider.js +7 -0
- data/javascripts/right-sortable-src.js +221 -0
- data/javascripts/right-sortable.js +9 -0
- data/javascripts/right-src.js +4939 -0
- data/javascripts/right-tabs-src.js +776 -0
- data/javascripts/right-tabs.js +6 -0
- data/javascripts/right-tooltips-src.js +130 -0
- data/javascripts/right-tooltips.js +9 -0
- data/javascripts/right-ui-i18n-de.js +29 -0
- data/javascripts/right-ui-i18n-en-us.js +11 -0
- data/javascripts/right-ui-i18n-es.js +29 -0
- data/javascripts/right-ui-i18n-fr.js +29 -0
- data/javascripts/right-ui-i18n-jp.js +33 -0
- data/javascripts/right-ui-i18n-ru.js +29 -0
- data/javascripts/right-ui-i18n-uk.js +29 -0
- data/javascripts/right.js +10 -0
- data/lib/right-rails.rb +11 -0
- data/lib/right_rails/controller_extensions.rb +85 -0
- data/lib/right_rails/helpers/basic.rb +111 -0
- data/lib/right_rails/helpers/forms.rb +239 -0
- data/lib/right_rails/helpers/misc.rb +164 -0
- data/lib/right_rails/helpers/rails.rb +166 -0
- data/lib/right_rails/helpers.rb +5 -0
- data/lib/right_rails/java_script_generator.rb +313 -0
- data/lib/right_rails.rb +6 -0
- data/spec/lib/right_rails/controller_extensions_spec.rb +60 -0
- data/spec/lib/right_rails/helpers/basic_spec.rb +74 -0
- data/spec/lib/right_rails/helpers/forms_spec.rb +51 -0
- data/spec/lib/right_rails/helpers/misc_spec.rb +120 -0
- data/spec/lib/right_rails/helpers/rails_spec.rb +149 -0
- data/spec/lib/right_rails/java_script_generator_spec.rb +317 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +15 -0
- metadata +128 -0
@@ -0,0 +1,291 @@
|
|
1
|
+
/**
|
2
|
+
* RightJS UI Slider unit (http://rightjs.org/ui/slider)
|
3
|
+
*
|
4
|
+
* Copyright (C) 2009 Nikolay V. Nemshilov aka St.
|
5
|
+
*/
|
6
|
+
if (!self.RightJS || !self.Draggable) throw "Gimme RightJS w/ DnD";
|
7
|
+
|
8
|
+
/**
|
9
|
+
* RightJS UI Slider unit
|
10
|
+
*
|
11
|
+
* Copyright (C) 2009 Nikolay V. Nemshilov aka St.
|
12
|
+
*/
|
13
|
+
var Slider = new Class(Observer, {
|
14
|
+
extend: {
|
15
|
+
EVENTS: $w('change'),
|
16
|
+
|
17
|
+
Options: {
|
18
|
+
min: 0, // the min value
|
19
|
+
max: 100, // the max value
|
20
|
+
snap: 0, // the values threshold
|
21
|
+
value: null, // start value, if null then the min value will be used
|
22
|
+
direction: 'x', // slider direction 'x', 'y'
|
23
|
+
update: null, // reference to an element to update
|
24
|
+
round: 0 // the number of symbols after the decimal pointer
|
25
|
+
},
|
26
|
+
|
27
|
+
rescan: function() {
|
28
|
+
$$('div.right-slider').each(function(element) {
|
29
|
+
if (!element._slider) {
|
30
|
+
new Slider(element);
|
31
|
+
}
|
32
|
+
});
|
33
|
+
}
|
34
|
+
},
|
35
|
+
|
36
|
+
/**
|
37
|
+
* basic constructor
|
38
|
+
* USAGE:
|
39
|
+
* new Slider('element-id'[, {options}]);
|
40
|
+
* new Slider({options});
|
41
|
+
*
|
42
|
+
* @param mixed slider element reference or options
|
43
|
+
* @param Object options
|
44
|
+
*/
|
45
|
+
initialize: function() {
|
46
|
+
var args = $A(arguments);
|
47
|
+
this.element = (args[0] && !isHash(args[0])) ? $(args.shift()) : this.build();
|
48
|
+
|
49
|
+
this.$super(isHash(args[0]) ? args[0] : eval('('+this.element.get('data-slider-options')+')'));
|
50
|
+
|
51
|
+
if (this.options.update) this.assignTo(this.options.update);
|
52
|
+
|
53
|
+
this.element._slider = this.init();
|
54
|
+
},
|
55
|
+
|
56
|
+
// basic desctructor
|
57
|
+
destroy: function() {
|
58
|
+
this.handle.undoDraggable();
|
59
|
+
delete(this.element._slider);
|
60
|
+
return this;
|
61
|
+
},
|
62
|
+
|
63
|
+
/**
|
64
|
+
* The value setter
|
65
|
+
*
|
66
|
+
* NOTE: will get snapped according to the options
|
67
|
+
*
|
68
|
+
* @param mixed string or number value
|
69
|
+
* @return Slider this
|
70
|
+
*/
|
71
|
+
setValue: function(value) {
|
72
|
+
var value = isString(value) ? value.toFloat() : value;
|
73
|
+
|
74
|
+
// rounding the value according to the options
|
75
|
+
var base = Math.pow(10, this.options.round);
|
76
|
+
value = (value * base).round() / base;
|
77
|
+
|
78
|
+
// checking the value constraings
|
79
|
+
if (this.options.snap) {
|
80
|
+
var snap = this.options.snap;
|
81
|
+
var diff = value % snap;
|
82
|
+
value = diff < snap/2 ? value - diff : value - diff + snap;
|
83
|
+
}
|
84
|
+
if (value < this.options.min) value = this.options.min;
|
85
|
+
if (value > this.options.max) value = this.options.max;
|
86
|
+
|
87
|
+
this.moveTo(value);
|
88
|
+
|
89
|
+
if (value !== this.value) {
|
90
|
+
this.fire('change', this.value = value);
|
91
|
+
}
|
92
|
+
|
93
|
+
return this;
|
94
|
+
},
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Returns the value
|
98
|
+
*
|
99
|
+
* @return Float number
|
100
|
+
*/
|
101
|
+
getValue: function() {
|
102
|
+
return this.value;
|
103
|
+
},
|
104
|
+
|
105
|
+
/**
|
106
|
+
* Sets the minimal value and rebuilds the dimensions cache
|
107
|
+
*
|
108
|
+
* @param Number optional value to reset
|
109
|
+
* @return Slider this
|
110
|
+
*/
|
111
|
+
reset: function(value) {
|
112
|
+
return this.precalc().setValue([value, this.options.value, this.options.min].compact()[0]);
|
113
|
+
},
|
114
|
+
|
115
|
+
/**
|
116
|
+
* Inserts the widget into the element
|
117
|
+
*
|
118
|
+
* @param mixed element reference
|
119
|
+
* @param String optional position
|
120
|
+
* @return Slider this
|
121
|
+
*/
|
122
|
+
insertTo: function(element, position) {
|
123
|
+
this.element.insertTo(element, position);
|
124
|
+
return this.reset(this.value);
|
125
|
+
},
|
126
|
+
|
127
|
+
/**
|
128
|
+
* Assigns the slider to feed an input element on change
|
129
|
+
*
|
130
|
+
* @param mixed an input element reference
|
131
|
+
* @return Slider this
|
132
|
+
*/
|
133
|
+
assignTo: function(element) {
|
134
|
+
var assign = function(element, value) {
|
135
|
+
if (element = $(element)) {
|
136
|
+
if (value === undefined || value === null) value = '';
|
137
|
+
element[element.setValue ? 'setValue' : 'update'](''+value);
|
138
|
+
}
|
139
|
+
}.curry(element);
|
140
|
+
|
141
|
+
var connect = function(element, object) {
|
142
|
+
var element = $(element);
|
143
|
+
if (element && element.onChange) {
|
144
|
+
element.onChange(function() {
|
145
|
+
this.setValue(element.value);
|
146
|
+
}.bind(object));
|
147
|
+
}
|
148
|
+
}.curry(element);
|
149
|
+
|
150
|
+
if ($(element)) {
|
151
|
+
assign(this.value);
|
152
|
+
connect(this);
|
153
|
+
} else {
|
154
|
+
document.onReady(function() {
|
155
|
+
assign(this.value);
|
156
|
+
connect(this);
|
157
|
+
}.bind(this));
|
158
|
+
}
|
159
|
+
|
160
|
+
return this.onChange(assign);
|
161
|
+
},
|
162
|
+
|
163
|
+
// protected
|
164
|
+
|
165
|
+
// inits the slider handle and resets the whole thing
|
166
|
+
init: function() {
|
167
|
+
this.handle = this.element.first('div.right-slider-handle')
|
168
|
+
.makeDraggable({
|
169
|
+
onBefore: this.prepare.bind(this),
|
170
|
+
onDrag: this.dragged.bind(this)
|
171
|
+
});
|
172
|
+
|
173
|
+
// make it jump to the position
|
174
|
+
this.element.onClick(this.clicked.bind(this));
|
175
|
+
|
176
|
+
if (this.options.direction == 'y') {
|
177
|
+
this.element.addClass('right-slider-vertical');
|
178
|
+
} else {
|
179
|
+
this.options.direction = this.element.hasClass('right-slider-vertical') ? 'y' : 'x';
|
180
|
+
}
|
181
|
+
|
182
|
+
// fixing the manual position calculations for Konqueror
|
183
|
+
if (this.konqFix = (RightJS.version < '1.5.0' && !this.handle.getBoundingClientRect)) {
|
184
|
+
var parent = this.element;
|
185
|
+
var old_dims = this.handle.dimensions;
|
186
|
+
this.handle.dimensions = function() {
|
187
|
+
var dims = old_dims.call(this);
|
188
|
+
var subset = parent.dimensions();
|
189
|
+
|
190
|
+
dims.top += subset.top;
|
191
|
+
dims.left += subset.left;
|
192
|
+
|
193
|
+
return dims;
|
194
|
+
};
|
195
|
+
}
|
196
|
+
|
197
|
+
|
198
|
+
return this.reset();
|
199
|
+
},
|
200
|
+
|
201
|
+
// builds the slider prorgrammatically
|
202
|
+
build: function() {
|
203
|
+
return $E('div', {'class': 'right-slider'}).insert($E('div', {'class': 'right-slider-handle'}));
|
204
|
+
},
|
205
|
+
|
206
|
+
// callback for the eleemnt on-click event to make the slider to jump there
|
207
|
+
clicked: function(event) {
|
208
|
+
event.stop();
|
209
|
+
this.precalc().moveTo(this.value);
|
210
|
+
|
211
|
+
var position = event.position();
|
212
|
+
var element = this.dimensions;
|
213
|
+
|
214
|
+
var position = (this.horizontal ? position.x - element.left : position.y - element.top) - this.offset;
|
215
|
+
|
216
|
+
if (position > this.space) position = this.space;
|
217
|
+
else if (position < 0) position = 0;
|
218
|
+
|
219
|
+
this.setPosition(position);
|
220
|
+
},
|
221
|
+
|
222
|
+
// callback for the element dragg
|
223
|
+
dragged: function(draggable, event) {
|
224
|
+
this.setPosition(draggable.element.style[this.horizontal ? 'left' : 'top'].toFloat());
|
225
|
+
},
|
226
|
+
|
227
|
+
// callback for the draggable before event
|
228
|
+
prepare: function(draggable) {
|
229
|
+
// moving the slider to the beginning position
|
230
|
+
this.precalc().moveTo(this.value);
|
231
|
+
|
232
|
+
var offset = this.offset;
|
233
|
+
var element = this.dimensions;
|
234
|
+
var options = draggable.options;
|
235
|
+
options.range = {};
|
236
|
+
|
237
|
+
// calculating the ranges
|
238
|
+
if ((options.axis = this.options.direction) == 'x') {
|
239
|
+
options.range.x = [element.left + offset, element.left + element.width - offset];
|
240
|
+
if (this.konqFix) options.range.x[0] -= element.left;
|
241
|
+
} else {
|
242
|
+
options.range.y = [element.top + offset, element.top + element.height - offset];
|
243
|
+
if (this.konqFix) options.range.y[0] -= element.top;
|
244
|
+
}
|
245
|
+
|
246
|
+
// calculating the snapping range
|
247
|
+
if (this.options.snap) {
|
248
|
+
options.snap = this.space / (this.options.max - this.options.min) * this.options.snap;
|
249
|
+
}
|
250
|
+
},
|
251
|
+
|
252
|
+
// sets the slider value by the handle position
|
253
|
+
setPosition: function(position) {
|
254
|
+
if (!this.horizontal) position = this.space - position;
|
255
|
+
var value = position / this.space * (this.options.max - this.options.min) + this.options.min;
|
256
|
+
|
257
|
+
this.setValue(value);
|
258
|
+
},
|
259
|
+
|
260
|
+
// moves the slider to the given position
|
261
|
+
moveTo: function(value) {
|
262
|
+
var position = this.space / (this.options.max - this.options.min) * (value - this.options.min);
|
263
|
+
|
264
|
+
if (!this.horizontal) position = this.space - position;
|
265
|
+
|
266
|
+
this.handle.style[this.horizontal ? 'left' : 'top'] = position + 'px';
|
267
|
+
|
268
|
+
return this;
|
269
|
+
},
|
270
|
+
|
271
|
+
// precalculates dimensions, direction and offset for further use
|
272
|
+
precalc: function() {
|
273
|
+
var handle = this.handle.setStyle({left:'0', top:'0'}).dimensions();
|
274
|
+
|
275
|
+
this.dimensions = this.element.dimensions();
|
276
|
+
this.horizontal = this.options.direction == 'x';
|
277
|
+
this.offset = this.horizontal ? handle.left - this.dimensions.left : handle.top - this.dimensions.top;
|
278
|
+
this.space = (this.horizontal ? this.dimensions.width - handle.width : this.dimensions.height - handle.height) - this.offset * 2;
|
279
|
+
|
280
|
+
return this;
|
281
|
+
}
|
282
|
+
});
|
283
|
+
|
284
|
+
/**
|
285
|
+
* Document onReady hook for sliders
|
286
|
+
*
|
287
|
+
* Copyright (C) Nikolay V. Nemshilov aka St.
|
288
|
+
*/
|
289
|
+
document.onReady(Slider.rescan);
|
290
|
+
|
291
|
+
document.write("<style type=\"text/css\">div.right-slider,div.right-slider-handle{margin:0;padding:0;border:none;background:none}div.right-slider{height:0.4em;width:20em;border:1px solid #CCC;background:#EEE;-moz-border-radius:.2em;-webkit-border-radius:.2em;position:relative;margin:.6em 0;display:inline-block;*display:inline;*zoom:1;vertical-align:middle}div.right-slider-handle{position:absolute;left:0;top:0;cursor:pointer;width:4pt;height:1em;margin-top:-0.4em;margin-left:0.1em;background:#CCC;border:1px solid #AAA;-moz-border-radius:.2em;-webkit-border-radius:.2em}div.right-slider-vertical{height:10em;width:0.4em;margin:0 .3em}div.right-slider-vertical div.right-slider-handle{margin:0;margin-left:-0.4em;margin-top:0.1em;height:4pt;width:1em}</style>");
|
@@ -0,0 +1,7 @@
|
|
1
|
+
/**
|
2
|
+
* RightJS UI Slider unit (http://rightjs.org/ui/slider)
|
3
|
+
*
|
4
|
+
* Copyright (C) 2009 Nikolay V. Nemshilov aka St.
|
5
|
+
*/
|
6
|
+
if (!self.RightJS || !self.Draggable) throw "Gimme RightJS w/ DnD";
|
7
|
+
eval((function(s,d){for(var i=d.length-1;i>-1;i--)if(d[i])s=s.replace(new RegExp(i,'g'),d[i]);return s})("14 50=78 83(Observer,{extend:{EVENTS:$w('69'),Options:{32:0,48:100,37:0,21:65,25:'x',40:65,53:0},67:9(){$$('30.17-12').each(9(e){if(!e._12)78 50(e)})}},75ialize:9(){14 a=$A(arguments);7.13=(a[0]&&!70(a[0]))?$(a.shift()):7.74();7.$super(70(a[0])?a[0]:eval('('+7.13.get('data-12-8')+')'));if(7.8.40)7.54(7.8.40);7.13._12=7.75()},destroy:9(){7.16.undo82();delete(7.13._12);18 7},24:9(v){14 v=isString(v)?v.59():v;14 b=Math.pow(10,7.8.53);v=(v*b).53()/b;if(7.8.37){14 s=7.8.37;14 d=v % s;v=d<s/2?v-d:v-d+s}if(v<7.8.32)v=7.8.32;if(v>7.8.48)v=7.8.48;7.39(v);if(v!==7.21)7.fire('69',7.21=v);18 7},getValue:9(){18 7.21},55:9(v){18 7.35().24([v,7.8.21,7.8.32].compact()[0])},52:9(e,p){7.13.52(e,p);18 7.55(7.21)},54:9(b){14 a=9(e,v){if(e=$(e)){if(v===undefined||v===65)v='';e[e.24?'24':'40'](''+v)}}.72(b);14 c=9(e,o){14 e=$(e);if(e&&e.44)e.44(9(){7.24(e.21)}.45(o))}.72(b);if($(b)){a(7.21);c(7)}51 42.64(9(){a(7.21);c(7)}.45(7));18 7.44(a)},75:9(){7.16=7.13.first('30.17-12-16').make82({onBefore:7.56.45(7),onDrag:7.63.45(7)});7.13.onClick(7.61.45(7));if(7.8.25=='y')7.13.add83('17-12-29');51 7.8.25=7.13.has83('17-12-29')?'y':'x';if(7.46=(RightJS.version<'1.5.0'&&!7.16.getBoundingClientRect)){14 p=7.13;14 o=7.16.11;7.16.11=9(){14 d=o.call(7);14 s=p.11();d.22+=s.22;d.19+=s.19;18 d}}18 7.55()},74:9(){18 $E('30',{'71':'17-12'}).insert($E('30',{'71':'17-12-16'}))},61:9(a){a.s22();7.35().39(7.21);14 p=a.43();14 e=7.11;14 p=(7.15?p.x-e.19:p.y-e.22)-7.41;if(p>7.28)p=7.28;51 if(p<0)p=0;7.33(p)},63:9(d,e){7.33(d.13.49[7.15?'19':'22'].59())},56:9(d){7.35().39(7.21);14 o=7.41;14 e=7.11;14 a=d.8;a.36={};if((a.axis=7.8.25)=='x'){a.36.x=[e.19+o,e.19+e.31-o];if(7.46)a.36.x[0]-=e.19}51{a.36.y=[e.22+o,e.22+e.27-o];if(7.46)a.36.y[0]-=e.22}if(7.8.37)a.37=7.28/(7.8.48-7.8.32)*7.8.37},33:9(p){if(!7.15)p=7.28-p;14 v=p/7.28*(7.8.48-7.8.32)+7.8.32;7.24(v)},39:9(v){14 p=7.28/(7.8.48-7.8.32)*(v-7.8.32);if(!7.15)p=7.28-p;7.16.49[7.15?'19':'22']=p+'px';18 7},35:9(){14 h=7.16.setStyle({19:'0',22:'0'}).11();7.11=7.13.11();7.15=7.8.25=='x';7.41=7.15?h.19-7.11.19:h.22-7.11.22;7.28=(7.15?7.11.31-h.31:7.11.27-h.27)-7.41*2;18 7}});42.64(50.67);42.write(\"<49 type=\\\"text/css\\\">30.17-12,30.17-12-16{23:0;padding:0;26:76;34:76}30.17-12{27:0.62;31:20em;26:81 73 #77;34:#EEE;-79-26-38:.58;-66-26-38:.58;43:relative;23:.6em 0;60:68-block;*60:68;*zoom:1;29-align:middle}30.17-12-16{43:absolute;19:0;22:0;cursor:pointer;31:80;27:57;23-22:-0.62;23-19:0.57;34:#77;26:81 73 #AAA;-79-26-38:.58;-66-26-38:.58}30.17-12-29{27:10em;31:0.62;23:0 .3em}30.17-12-29 30.17-12-16{23:0;23-19:-0.62;23-22:0.57;27:80;31:57}</49>\");",",,,,,,,this,options,function,,dimensions,slider,element,var,horizontal,handle,right,return,left,,value,top,margin,setValue,direction,border,height,space,vertical,div,width,min,setPosition,background,precalc,range,snap,radius,moveTo,update,offset,document,position,onChange,bind,konqFix,_slider,max,style,Slider,else,insertTo,round,assignTo,reset,prepare,1em,2em,toFloat,display,clicked,4em,dragged,onReady,null,webkit,rescan,inline,change,isHash,class,curry,solid,build,init,none,CCC,new,moz,4pt,1px,Draggable,Class".split(",")));
|
@@ -0,0 +1,221 @@
|
|
1
|
+
/**
|
2
|
+
* Sortable feature for RightJS (requires the Drag'n'Drop feature)
|
3
|
+
*
|
4
|
+
* See http://rightjs.org/ui/sortable
|
5
|
+
*
|
6
|
+
* Copyright (C) Nikolay V. Nemshilov aka St.
|
7
|
+
*/
|
8
|
+
if (!Draggable) throw "Gimme Draggable";
|
9
|
+
|
10
|
+
/**
|
11
|
+
* The Sortable unit
|
12
|
+
*
|
13
|
+
* Copyright (C) Nikolay V. Nemshilov aka St.
|
14
|
+
*/
|
15
|
+
var Sortable = new Class(Observer, {
|
16
|
+
extend: {
|
17
|
+
EVENTS: $w('update'),
|
18
|
+
|
19
|
+
Options: {
|
20
|
+
direction: 'auto', // 'auto', 'vertical', 'horizontal', 'x', 'y'
|
21
|
+
|
22
|
+
tags: 'li', // the list items tag name
|
23
|
+
|
24
|
+
url: null, // the Xhr requests url address, might contain the '%{id}' placeholder
|
25
|
+
method: 'put', // the Xhr requests method
|
26
|
+
|
27
|
+
Xhr: {}, // additional Xhr options
|
28
|
+
|
29
|
+
idParam: 'id', // the id value name
|
30
|
+
posParam: 'position', // the position value name
|
31
|
+
parseId: true, // if the id attribute should be converted into an integer before sending
|
32
|
+
|
33
|
+
relName: 'sortable' // the auto-discovery feature key
|
34
|
+
},
|
35
|
+
|
36
|
+
// scans through the page for auto-discoverable sortables
|
37
|
+
rescan: function() {
|
38
|
+
var key = Sortable.Options.relName;
|
39
|
+
var reg = new RegExp('^'+key+'\\[(.+?)\\]');
|
40
|
+
|
41
|
+
$$('ul[rel^="'+key+'"], ol[rel^="'+key+'"]').each(function(element) {
|
42
|
+
if (!element._sortable) {
|
43
|
+
var data = element.get('data-'+key+'-options');
|
44
|
+
var options = eval('('+data+')') || {};
|
45
|
+
|
46
|
+
var url = element.get('rel').match(reg);
|
47
|
+
if (url) {
|
48
|
+
options.url = url[1];
|
49
|
+
}
|
50
|
+
|
51
|
+
new Sortable(element, options);
|
52
|
+
}
|
53
|
+
});
|
54
|
+
}
|
55
|
+
},
|
56
|
+
|
57
|
+
/**
|
58
|
+
* basic constructor
|
59
|
+
*
|
60
|
+
* @param mixed element reference
|
61
|
+
* @param Object options
|
62
|
+
*/
|
63
|
+
initialize: function(element, options) {
|
64
|
+
this.element = $(element);
|
65
|
+
this.$super(options);
|
66
|
+
|
67
|
+
this.element._sortable = this.init().onUpdate('tryXhr');
|
68
|
+
},
|
69
|
+
|
70
|
+
// detaches all the events out of the elemnts
|
71
|
+
destroy: function() {
|
72
|
+
this.getItems.each(function(item) {
|
73
|
+
item.undoDraggable().undoDroppable();
|
74
|
+
});
|
75
|
+
delete(this.element._sortable);
|
76
|
+
|
77
|
+
return this;
|
78
|
+
},
|
79
|
+
|
80
|
+
// callback for the moved elements
|
81
|
+
moved: function(element) {
|
82
|
+
var items = this.getItems();
|
83
|
+
var position = items.indexOf(element);
|
84
|
+
|
85
|
+
if (position > -1 && position != element.current_position) {
|
86
|
+
this.fire('update', element, position);
|
87
|
+
|
88
|
+
items.each(function(item, index) {
|
89
|
+
item.current_position = index;
|
90
|
+
});
|
91
|
+
}
|
92
|
+
},
|
93
|
+
|
94
|
+
// tries to send an Xhr request about the element relocation
|
95
|
+
tryXhr: function(element, position) {
|
96
|
+
if (this.options.url) {
|
97
|
+
var url = this.options.url, params = {};
|
98
|
+
|
99
|
+
// building the Xhr request options
|
100
|
+
var options = Object.merge({
|
101
|
+
method: this.options.method,
|
102
|
+
params: {}
|
103
|
+
}, this.options.Xhr);
|
104
|
+
|
105
|
+
// grabbing the id
|
106
|
+
var id = element.id || '';
|
107
|
+
if (this.options.parseId && id) {
|
108
|
+
id = id.match(/\d+/) || '';
|
109
|
+
}
|
110
|
+
|
111
|
+
// assigning the parameters
|
112
|
+
if (url.include('%{id}')) {
|
113
|
+
url = url.replace('%{id}', id);
|
114
|
+
} else {
|
115
|
+
params[this.options.idParam] = id;
|
116
|
+
}
|
117
|
+
params[this.options.posParam] = position;
|
118
|
+
|
119
|
+
// merging the params with possible Xhr params
|
120
|
+
if (isString(options.params)) options.params += '&'+Object.toQueryString(params);
|
121
|
+
else options.params = Object.merge(options.params, params);
|
122
|
+
|
123
|
+
// calling the server
|
124
|
+
Xhr.load(url, options);
|
125
|
+
}
|
126
|
+
},
|
127
|
+
|
128
|
+
// protected
|
129
|
+
|
130
|
+
// inits the sortable unit
|
131
|
+
init: function() {
|
132
|
+
var items = this.getItems();
|
133
|
+
|
134
|
+
if (items.length) {
|
135
|
+
var callback = this.moved.bind(this);
|
136
|
+
|
137
|
+
// guessing the direction
|
138
|
+
var direction = this.options.direction != 'auto' ? this.options.direction :
|
139
|
+
['left', 'right'].include(items[0].getStyle('float')) ? 'x' : 'y';
|
140
|
+
|
141
|
+
// the draggable options
|
142
|
+
var drag_options = {
|
143
|
+
range: this.element,
|
144
|
+
axis: direction,
|
145
|
+
revert: true,
|
146
|
+
revertDuration: 0,
|
147
|
+
onStop: function() {
|
148
|
+
callback(this.element);
|
149
|
+
}
|
150
|
+
};
|
151
|
+
|
152
|
+
// the droppable options
|
153
|
+
var drop_options = {
|
154
|
+
overlap: direction,
|
155
|
+
containtment: items,
|
156
|
+
onHover: function(draggable) {
|
157
|
+
// calculating the swapping direction
|
158
|
+
var drag_dims = draggable.element.dimensions();
|
159
|
+
var this_dims = this.element.dimensions();
|
160
|
+
|
161
|
+
var before = draggable.axisY ? (
|
162
|
+
drag_dims.top > this_dims.top
|
163
|
+
) : (
|
164
|
+
drag_dims.left > this_dims.left
|
165
|
+
);
|
166
|
+
|
167
|
+
this.element.insert(draggable.clone, before ? 'before' : 'after');
|
168
|
+
}
|
169
|
+
};
|
170
|
+
|
171
|
+
// processing the items
|
172
|
+
items.each(function(item, index) {
|
173
|
+
item.makeDraggable(drag_options).makeDroppable(drop_options).current_position = index;
|
174
|
+
});
|
175
|
+
}
|
176
|
+
|
177
|
+
return this;
|
178
|
+
},
|
179
|
+
|
180
|
+
// returns the list of the items
|
181
|
+
getItems: function() {
|
182
|
+
return this.element.subNodes(this.options.tags);
|
183
|
+
}
|
184
|
+
|
185
|
+
|
186
|
+
});
|
187
|
+
|
188
|
+
/**
|
189
|
+
* Document level hooks for sortables
|
190
|
+
*
|
191
|
+
* Copyright (C) Nikolay V. Nemshilov aka St.
|
192
|
+
*/
|
193
|
+
document.onReady(Sortable.rescan);
|
194
|
+
|
195
|
+
/**
|
196
|
+
* Element level features for the Sortable unit
|
197
|
+
*
|
198
|
+
* Copyright (C) Nikolay V. Nemshilov aka St.
|
199
|
+
*/
|
200
|
+
Element.addMethods({
|
201
|
+
/**
|
202
|
+
* Tries to make a sortable unit out of the element
|
203
|
+
*
|
204
|
+
* @param Object options
|
205
|
+
* @return Element this
|
206
|
+
*/
|
207
|
+
makeSortable: function(options) {
|
208
|
+
new Sortable(this, options);
|
209
|
+
return this;
|
210
|
+
},
|
211
|
+
|
212
|
+
/**
|
213
|
+
* Destroy the sortable functionality on the element
|
214
|
+
*
|
215
|
+
* @return Element this
|
216
|
+
*/
|
217
|
+
undoSortable: function() {
|
218
|
+
if (this._sortable) this._sortable.destroy();
|
219
|
+
return this;
|
220
|
+
}
|
221
|
+
});
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/**
|
2
|
+
* Sortable feature for RightJS (requires the Drag'n'Drop feature)
|
3
|
+
*
|
4
|
+
* See http://rightjs.org/ui/sortable
|
5
|
+
*
|
6
|
+
* Copyright (C) Nikolay V. Nemshilov aka St.
|
7
|
+
*/
|
8
|
+
if (!Draggable) throw "Gimme Draggable";
|
9
|
+
eval((function(s,d){for(var i=d.length-1;i>-1;i--)if(d[i])s=s.replace(new RegExp(i,'g'),d[i]);return s})("5 9=26 Class(Observer,{extend:{EVENTS:$w('28'),23:{13:'39',37:'li',19:null,15:'put',32:{},21:'id',18:'position',22:40,20:'sortable'},29:3(){5 k=9.23.20;5 r=26 RegExp('^'+k+'\\\\[(.+?)\\\\]');$$('ul[35^=\"'+k+'\"], ol[35^=\"'+k+'\"]').17(3(e){if(!e.8){5 d=e.42('data-'+k+'-4');5 o=eval('('+d+')')||{};5 u=e.42('35').31(r);if(u)o.19=u[1];26 9(e,o)}})}},38ialize:3(e,o){2.6=$(e);2.$super(o);2.6.8=2.38().onUpdate('30')},24:3(){2.10.17(3(i){i.undo43().undo44()});delete(2.6.8);12 2},33:3(e){5 b=2.10();5 p=b.indexOf(e);if(p>-1&&p!=e.7){2.fire('28',e,p);b.17(3(a,i){a.7=i})}},30:3(e,a){if(2.4.19){5 u=2.4.19,p={};5 o=16.34({15:2.4.15,11:{}},2.4.32);5 i=e.id||'';if(2.4.22&&i)i=i.31(/\\d+/)||'';if(u.25('%{id}'))u=u.replace('%{id}',i);36 p[2.4.21]=i;p[2.4.18]=a;if(is45(o.11))o.11+='&'+16.toQuery45(p);36 o.11=16.34(o.11,p);32.load(u,o)}},38:3(){5 h=2.10();if(h.length){5 c=2.33.bind(2);5 e=2.4.13!='39'?2.4.13:['27','right'].25(h[0].42Style('float'))?'x':'y';5 f={range:2.6,axis:e,revert:40,revertDuration:0,onS41:3(){c(2.6)}};5 g={overlap:e,containtment:h,onHover:3(a){5 d=a.6.14();5 t=2.6.14();5 b=a.axisY?(d.41>t.41):(d.27>t.27);2.6.insert(a.clone,b?'before':'after')}};h.17(3(a,i){a.make43(f).make44(g).7=i})}12 2},10:3(){12 2.6.subNodes(2.4.37)}});document.onReady(9.29);Element.addMethods({make9:3(o){26 9(2,o);12 2},undo9:3(){if(2.8)2.8.24();12 2}});",",,this,function,options,var,element,current_position,_sortable,Sortable,getItems,params,return,direction,dimensions,method,Object,each,posParam,url,relName,idParam,parseId,Options,destroy,include,new,left,update,rescan,tryXhr,match,Xhr,moved,merge,rel,else,tags,init,auto,true,top,get,Draggable,Droppable,String".split(",")));
|