jquerypp-rails 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +24 -0
- data/Rakefile +2 -0
- data/jquerypp-rails.gemspec +20 -0
- data/lib/jquerypp/generators/jquerypp/install/install_generator.rb +49 -0
- data/lib/jquerypp/rails/engine.rb +8 -0
- data/lib/jquerypp/rails/version.rb +6 -0
- data/lib/jquerypp/rails.rb +8 -0
- data/lib/jquerypp-rails.rb +1 -0
- data/vendor/assets/javascripts/jquerypp.js +5419 -0
- data/vendor/assets/javascripts/lib/jquery.animate.js +326 -0
- data/vendor/assets/javascripts/lib/jquery.compare.js +75 -0
- data/vendor/assets/javascripts/lib/jquery.cookie.js +118 -0
- data/vendor/assets/javascripts/lib/jquery.dimensions.js +191 -0
- data/vendor/assets/javascripts/lib/jquery.event.default.js +115 -0
- data/vendor/assets/javascripts/lib/jquery.event.destroyed.js +23 -0
- data/vendor/assets/javascripts/lib/jquery.event.drag.js +727 -0
- data/vendor/assets/javascripts/lib/jquery.event.drop.js +457 -0
- data/vendor/assets/javascripts/lib/jquery.event.fastfix.js +95 -0
- data/vendor/assets/javascripts/lib/jquery.event.hover.js +266 -0
- data/vendor/assets/javascripts/lib/jquery.event.key.js +156 -0
- data/vendor/assets/javascripts/lib/jquery.event.livehack.js +174 -0
- data/vendor/assets/javascripts/lib/jquery.event.pause.js +92 -0
- data/vendor/assets/javascripts/lib/jquery.event.resize.js +47 -0
- data/vendor/assets/javascripts/lib/jquery.event.swipe.js +133 -0
- data/vendor/assets/javascripts/lib/jquery.fills.js +249 -0
- data/vendor/assets/javascripts/lib/jquery.form_params.js +167 -0
- data/vendor/assets/javascripts/lib/jquery.lang.json.js +196 -0
- data/vendor/assets/javascripts/lib/jquery.lang.vector.js +214 -0
- data/vendor/assets/javascripts/lib/jquery.range.js +861 -0
- data/vendor/assets/javascripts/lib/jquery.selection.js +232 -0
- data/vendor/assets/javascripts/lib/jquery.styles.js +103 -0
- data/vendor/assets/javascripts/lib/jquery.within.js +94 -0
- metadata +81 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
// Dependencies:
|
2
|
+
//
|
3
|
+
// - jquery.event.resize.js
|
4
|
+
// - jquery/event/reverse/reverse.js
|
5
|
+
|
6
|
+
(function( $ ) {
|
7
|
+
var
|
8
|
+
// bind on the window window resizes to happen
|
9
|
+
win = $(window),
|
10
|
+
windowWidth = 0,
|
11
|
+
windowHeight = 0,
|
12
|
+
timer;
|
13
|
+
|
14
|
+
$(function() {
|
15
|
+
windowWidth = win.width();
|
16
|
+
windowHeight = win.height();
|
17
|
+
});
|
18
|
+
|
19
|
+
$.event.reverse('resize', {
|
20
|
+
handler : function(ev, data) {
|
21
|
+
var isWindow = this === window;
|
22
|
+
|
23
|
+
// if we are the window and a real resize has happened
|
24
|
+
// then we check if the dimensions actually changed
|
25
|
+
// if they did, we will wait a brief timeout and
|
26
|
+
// trigger resize on the window
|
27
|
+
// this is for IE, to prevent window resize 'infinate' loop issues
|
28
|
+
if ( isWindow && ev.originalEvent ) {
|
29
|
+
var width = win.width(),
|
30
|
+
height = win.height();
|
31
|
+
|
32
|
+
|
33
|
+
if ((width != windowWidth || height != windowHeight)) {
|
34
|
+
//update the new dimensions
|
35
|
+
windowWidth = width;
|
36
|
+
windowHeight = height;
|
37
|
+
clearTimeout(timer)
|
38
|
+
timer = setTimeout(function() {
|
39
|
+
win.trigger("resize");
|
40
|
+
}, 1);
|
41
|
+
|
42
|
+
}
|
43
|
+
return true;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
});
|
47
|
+
})(jQuery)
|
@@ -0,0 +1,133 @@
|
|
1
|
+
// Dependencies:
|
2
|
+
//
|
3
|
+
// - jquery.event.swipe.js
|
4
|
+
// - jquery.event.livehack.js
|
5
|
+
|
6
|
+
(function($){
|
7
|
+
var isPhantom = /Phantom/.test(navigator.userAgent),
|
8
|
+
supportTouch = !isPhantom && "ontouchend" in document,
|
9
|
+
scrollEvent = "touchmove scroll",
|
10
|
+
// Use touch events or map it to mouse events
|
11
|
+
touchStartEvent = supportTouch ? "touchstart" : "mousedown",
|
12
|
+
touchStopEvent = supportTouch ? "touchend" : "mouseup",
|
13
|
+
touchMoveEvent = supportTouch ? "touchmove" : "mousemove",
|
14
|
+
data = function(event){
|
15
|
+
var d = event.originalEvent.touches ?
|
16
|
+
event.originalEvent.touches[ 0 ] :
|
17
|
+
event;
|
18
|
+
return {
|
19
|
+
time: (new Date).getTime(),
|
20
|
+
coords: [ d.pageX, d.pageY ],
|
21
|
+
origin: $( event.target )
|
22
|
+
};
|
23
|
+
};
|
24
|
+
|
25
|
+
/**
|
26
|
+
* @add jQuery.event.swipe
|
27
|
+
*/
|
28
|
+
var swipe = $.event.swipe = {
|
29
|
+
/**
|
30
|
+
* @attribute delay
|
31
|
+
* Delay is the upper limit of time the swipe motion can take in milliseconds. This defaults to 500.
|
32
|
+
*
|
33
|
+
* A user must perform the swipe motion in this much time.
|
34
|
+
*/
|
35
|
+
delay : 500,
|
36
|
+
/**
|
37
|
+
* @attribute max
|
38
|
+
* The maximum distance the pointer must travel in pixels. The default is 75 pixels.
|
39
|
+
*/
|
40
|
+
max : 75,
|
41
|
+
/**
|
42
|
+
* @attribute min
|
43
|
+
* The minimum distance the pointer must travel in pixels. The default is 30 pixels.
|
44
|
+
*/
|
45
|
+
min : 30
|
46
|
+
};
|
47
|
+
|
48
|
+
$.event.setupHelper( [
|
49
|
+
|
50
|
+
/**
|
51
|
+
* @hide
|
52
|
+
* @attribute swipe
|
53
|
+
*/
|
54
|
+
"swipe",
|
55
|
+
/**
|
56
|
+
* @hide
|
57
|
+
* @attribute swipeleft
|
58
|
+
*/
|
59
|
+
'swipeleft',
|
60
|
+
/**
|
61
|
+
* @hide
|
62
|
+
* @attribute swiperight
|
63
|
+
*/
|
64
|
+
'swiperight',
|
65
|
+
/**
|
66
|
+
* @hide
|
67
|
+
* @attribute swipeup
|
68
|
+
*/
|
69
|
+
'swipeup',
|
70
|
+
/**
|
71
|
+
* @hide
|
72
|
+
* @attribute swipedown
|
73
|
+
*/
|
74
|
+
'swipedown'], touchStartEvent, function(ev){
|
75
|
+
var
|
76
|
+
// update with data when the event was started
|
77
|
+
start = data(ev),
|
78
|
+
stop,
|
79
|
+
delegate = ev.delegateTarget || ev.currentTarget,
|
80
|
+
selector = ev.handleObj.selector,
|
81
|
+
entered = this;
|
82
|
+
|
83
|
+
function moveHandler(event){
|
84
|
+
if ( !start ) {
|
85
|
+
return;
|
86
|
+
}
|
87
|
+
// update stop with the data from the current event
|
88
|
+
stop = data(event);
|
89
|
+
|
90
|
+
// prevent scrolling
|
91
|
+
if ( Math.abs( start.coords[0] - stop.coords[0] ) > 10 ) {
|
92
|
+
event.preventDefault();
|
93
|
+
}
|
94
|
+
};
|
95
|
+
|
96
|
+
// Attach to the touch move events
|
97
|
+
$(document.documentElement).bind(touchMoveEvent, moveHandler)
|
98
|
+
.one(touchStopEvent, function(event){
|
99
|
+
$(this).unbind( touchMoveEvent, moveHandler);
|
100
|
+
// if start and stop contain data figure out if we have a swipe event
|
101
|
+
if ( start && stop ) {
|
102
|
+
// calculate the distance between start and stop data
|
103
|
+
var deltaX = Math.abs(start.coords[0] - stop.coords[0]),
|
104
|
+
deltaY = Math.abs(start.coords[1] - stop.coords[1]),
|
105
|
+
distance = Math.sqrt(deltaX*deltaX+deltaY*deltaY);
|
106
|
+
|
107
|
+
// check if the delay and distance are matched
|
108
|
+
if ( stop.time - start.time < swipe.delay && distance >= swipe.min ) {
|
109
|
+
var events = ['swipe'];
|
110
|
+
// check if we moved horizontally
|
111
|
+
if( deltaX >= swipe.min && deltaY < swipe.min) {
|
112
|
+
// based on the x coordinate check if we moved left or right
|
113
|
+
events.push( start.coords[0] > stop.coords[0] ? "swipeleft" : "swiperight" );
|
114
|
+
} else
|
115
|
+
// check if we moved vertically
|
116
|
+
if(deltaY >= swipe.min && deltaX < swipe.min){
|
117
|
+
// based on the y coordinate check if we moved up or down
|
118
|
+
events.push( start.coords[1] < stop.coords[1] ? "swipedown" : "swipeup" );
|
119
|
+
}
|
120
|
+
|
121
|
+
// trigger swipe events on this guy
|
122
|
+
$.each($.event.find(delegate, events, selector), function(){
|
123
|
+
this.call(entered, ev, {start : start, end: stop})
|
124
|
+
})
|
125
|
+
|
126
|
+
}
|
127
|
+
}
|
128
|
+
// reset start and stop
|
129
|
+
start = stop = undefined;
|
130
|
+
})
|
131
|
+
});
|
132
|
+
|
133
|
+
})(jQuery)
|
@@ -0,0 +1,249 @@
|
|
1
|
+
// Dependencies:
|
2
|
+
//
|
3
|
+
// - jquery.fills.js
|
4
|
+
// - jquery.event.resize.js
|
5
|
+
// - jquery.dimensions.js
|
6
|
+
// - jquery/event/reverse/reverse.js
|
7
|
+
// - jquery.styles.js
|
8
|
+
|
9
|
+
(function( $ ) {
|
10
|
+
//evil things we should ignore
|
11
|
+
var matches = /script|td/,
|
12
|
+
|
13
|
+
// if we are trying to fill the page
|
14
|
+
isThePage = function( el ) {
|
15
|
+
return el === document || el === document.documentElement || el === window || el === document.body
|
16
|
+
},
|
17
|
+
//if something lets margins bleed through
|
18
|
+
bleeder = function( el ) {
|
19
|
+
if ( el[0] == window ) {
|
20
|
+
return false;
|
21
|
+
}
|
22
|
+
var styles = el.styles('borderBottomWidth', 'paddingBottom')
|
23
|
+
return !parseInt(styles.borderBottomWidth) && !parseInt(styles.paddingBottom)
|
24
|
+
},
|
25
|
+
//gets the bottom of this element
|
26
|
+
bottom = function( el, offset ) {
|
27
|
+
//where offsetTop starts
|
28
|
+
return el.outerHeight() + offset(el);
|
29
|
+
}
|
30
|
+
pageOffset = function( el ) {
|
31
|
+
return el.offset().top
|
32
|
+
},
|
33
|
+
offsetTop = function( el ) {
|
34
|
+
return el[0].offsetTop;
|
35
|
+
},
|
36
|
+
inFloat = function( el, parent ) {
|
37
|
+
while ( el && el != parent ) {
|
38
|
+
var flt = $(el).css('float')
|
39
|
+
if ( flt == 'left' || flt == 'right' ) {
|
40
|
+
return flt;
|
41
|
+
}
|
42
|
+
el = el.parentNode
|
43
|
+
}
|
44
|
+
},
|
45
|
+
/**
|
46
|
+
* @function jQuery.fn.fills
|
47
|
+
* @parent jQuery.fills
|
48
|
+
* @test jquery/dom/fills/funcunit.html
|
49
|
+
* @plugin jquery/dom/fills
|
50
|
+
*
|
51
|
+
* Fills a parent element's height with the current element.
|
52
|
+
* This is extremely useful for complex layout, especially when you want to account for line-wrapping.
|
53
|
+
*
|
54
|
+
* ## Basic Example
|
55
|
+
*
|
56
|
+
* If you have the following html:
|
57
|
+
*
|
58
|
+
* <div id='box'>
|
59
|
+
* <p>I am a long heading.</p>
|
60
|
+
* <div id='child'>I'm a child.</div>
|
61
|
+
* </div>
|
62
|
+
*
|
63
|
+
* The follow makes `#child` fill up `#box`:
|
64
|
+
*
|
65
|
+
* $('#child').can_ui_layout_fill("#box")
|
66
|
+
*
|
67
|
+
* ## Limitations
|
68
|
+
*
|
69
|
+
* Fill currently does not well with:
|
70
|
+
*
|
71
|
+
* - Bleeding margins - Where margins leak through parent elements
|
72
|
+
* because the parent elements do not have a padding or border.
|
73
|
+
*
|
74
|
+
* - Tables - You shouldn't be using tables to do layout anyway.
|
75
|
+
*
|
76
|
+
* - Floated Elements - the child element has `float: left` or `float: right`
|
77
|
+
*
|
78
|
+
*
|
79
|
+
* @param {HTMLElement|selector|Object} [parent] the parent element
|
80
|
+
* to fill, defaults to the element's parent.
|
81
|
+
*
|
82
|
+
* The following fills the parent to `#child`:
|
83
|
+
*
|
84
|
+
* $('#child').fills()
|
85
|
+
*
|
86
|
+
* A selector can also be pased. This selector is passed to jQuery's
|
87
|
+
* closet method. The following matches the first `#parent` element that
|
88
|
+
* is a parentNode of `#child`:
|
89
|
+
*
|
90
|
+
* $('#child').fills("#parent")
|
91
|
+
*
|
92
|
+
* An element or window can also be passed. The following will make
|
93
|
+
* `#child` big enough so the entire window is filled:
|
94
|
+
*
|
95
|
+
* $('#child').fills(window)
|
96
|
+
*
|
97
|
+
* If you pass an object, the following options are available:
|
98
|
+
*
|
99
|
+
* - __parent__ - The parent element selector or jQuery object
|
100
|
+
* - __className__ - A class name to add to the element that fills
|
101
|
+
* - __all__ - Reset the parents height when resizing
|
102
|
+
*
|
103
|
+
* @return {jQuery} the original jQuery collection for chaining.
|
104
|
+
*/
|
105
|
+
filler = $.fn.fills = function( parent ) {
|
106
|
+
var options = parent;
|
107
|
+
options || (options = {});
|
108
|
+
if(typeof options == 'string'){
|
109
|
+
options = this.closest(options)
|
110
|
+
}
|
111
|
+
if ( options.jquery || options.nodeName ) {
|
112
|
+
options = {parent: options };
|
113
|
+
}
|
114
|
+
// Set the parent
|
115
|
+
options.parent || (options.parent = $(this).parent());
|
116
|
+
options.parent = $(options.parent)
|
117
|
+
|
118
|
+
// setup stuff on every element
|
119
|
+
if(options.className) {
|
120
|
+
this.addClass(options.className)
|
121
|
+
}
|
122
|
+
|
123
|
+
var thePage = isThePage(options.parent[0]);
|
124
|
+
|
125
|
+
if ( thePage ) {
|
126
|
+
options.parent = $(window)
|
127
|
+
}
|
128
|
+
|
129
|
+
this.each(function(){
|
130
|
+
var evData = {
|
131
|
+
filler: $(this),
|
132
|
+
inFloat: inFloat(this, thePage ? document.body : options.parent[0]),
|
133
|
+
options: options
|
134
|
+
},
|
135
|
+
cb = function() {
|
136
|
+
filler.parentResize.apply(this, arguments)
|
137
|
+
}
|
138
|
+
// Attach to the `resize` event
|
139
|
+
$(options.parent).bind('resize', evData, cb);
|
140
|
+
|
141
|
+
$(this).bind('destroyed', evData, function( ev ) {
|
142
|
+
if(options.className) {
|
143
|
+
$(ev.target).removeClass(options.className)
|
144
|
+
}
|
145
|
+
$(options.parent).unbind('resize', cb)
|
146
|
+
});
|
147
|
+
|
148
|
+
});
|
149
|
+
|
150
|
+
// resize to get things going
|
151
|
+
var func = function() {
|
152
|
+
options.parent.resize();
|
153
|
+
}
|
154
|
+
|
155
|
+
if ( $.isReady ) {
|
156
|
+
func();
|
157
|
+
} else {
|
158
|
+
$(func)
|
159
|
+
}
|
160
|
+
return this;
|
161
|
+
};
|
162
|
+
|
163
|
+
|
164
|
+
$.extend(filler, {
|
165
|
+
parentResize : function( ev ) {
|
166
|
+
if (ev.data.filler.is(':hidden')) {
|
167
|
+
return;
|
168
|
+
}
|
169
|
+
|
170
|
+
var parent = $(this),
|
171
|
+
isWindow = this == window,
|
172
|
+
container = (isWindow ? $(document.body) : parent),
|
173
|
+
|
174
|
+
//if the parent bleeds margins, we don't care what the last element's margin is
|
175
|
+
isBleeder = bleeder(parent),
|
176
|
+
children = container.children().filter(function() {
|
177
|
+
if ( matches.test(this.nodeName.toLowerCase()) ) {
|
178
|
+
return false;
|
179
|
+
}
|
180
|
+
|
181
|
+
var get = $.styles(this, ['position', 'display']);
|
182
|
+
return get.position !== "absolute" && get.position !== "fixed"
|
183
|
+
&& get.display !== "none" && !jQuery.expr.filters.hidden(this)
|
184
|
+
}),
|
185
|
+
last = children.eq(-1),
|
186
|
+
first,
|
187
|
+
parentHeight = parent.height() - (isWindow ? parseInt(container.css('marginBottom'), 10) || 0 : 0),
|
188
|
+
currentSize;
|
189
|
+
var div = '<div style="height: 0px; line-height:0px;overflow:hidden;' + (ev.data.inFloat ? 'clear: both' : '') + ';"/>'
|
190
|
+
|
191
|
+
if ( isBleeder ) {
|
192
|
+
//temporarily add a small div to use to figure out the 'bleed-through' margin
|
193
|
+
//of the last element
|
194
|
+
last = $(div).appendTo(container);
|
195
|
+
|
196
|
+
}
|
197
|
+
|
198
|
+
//for performance, we want to figure out the currently used height of the parent element
|
199
|
+
// as quick as possible
|
200
|
+
// we can use either offsetTop or offset depending ...
|
201
|
+
if ( last && last.length > 0 ) {
|
202
|
+
if ( last.offsetParent()[0] === container[0] ) {
|
203
|
+
|
204
|
+
currentSize = last[0].offsetTop + last.outerHeight();
|
205
|
+
} else if (last.offsetParent()[0] === container.offsetParent()[0]) {
|
206
|
+
// add pos abs for IE7 but
|
207
|
+
// might need to adjust for the addition of first's hheight
|
208
|
+
var curLast =last[0].offsetTop;
|
209
|
+
first = $(div).prependTo(container);
|
210
|
+
|
211
|
+
currentSize = ( curLast + last.outerHeight() ) - first[0].offsetTop;
|
212
|
+
|
213
|
+
first.remove();
|
214
|
+
} else {
|
215
|
+
// add first so we know where to start from .. do not bleed in this case
|
216
|
+
first = $(div).prependTo(container);
|
217
|
+
|
218
|
+
currentSize = ( last.offset().top + last.outerHeight() ) - first.offset().top;
|
219
|
+
first.remove();
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
// what the difference between the parent height and what we are going to take up is
|
224
|
+
var delta = parentHeight - currentSize,
|
225
|
+
// the current height of the object
|
226
|
+
fillerHeight = ev.data.filler.height();
|
227
|
+
|
228
|
+
//adjust the height
|
229
|
+
if ( ev.data.options.all ) {
|
230
|
+
// we don't care about anything else, we are likely absolutely positioned
|
231
|
+
// we need to fill the parent width
|
232
|
+
// temporarily collapse, then expand
|
233
|
+
ev.data.filler.height(0).width(0);
|
234
|
+
var parentWidth = parent.width(),
|
235
|
+
parentHeight = parent.height();
|
236
|
+
|
237
|
+
ev.data.filler.outerHeight(parentHeight);
|
238
|
+
ev.data.filler.outerWidth(parentWidth);
|
239
|
+
} else {
|
240
|
+
ev.data.filler.height(fillerHeight + delta)
|
241
|
+
}
|
242
|
+
|
243
|
+
//remove the temporary element
|
244
|
+
if ( isBleeder ) {
|
245
|
+
last.remove();
|
246
|
+
}
|
247
|
+
}
|
248
|
+
});
|
249
|
+
})(jQuery)
|
@@ -0,0 +1,167 @@
|
|
1
|
+
// - jquery.form_params.js
|
2
|
+
(function( $ ) {
|
3
|
+
var
|
4
|
+
// use to parse bracket notation like my[name][attribute]
|
5
|
+
keyBreaker = /[^\[\]]+/g,
|
6
|
+
// converts values that look like numbers and booleans and removes empty strings
|
7
|
+
convertValue = function( value ) {
|
8
|
+
if ( $.isNumeric( value )) {
|
9
|
+
return parseFloat( value );
|
10
|
+
} else if ( value === 'true') {
|
11
|
+
return true;
|
12
|
+
} else if ( value === 'false' ) {
|
13
|
+
return false;
|
14
|
+
} else if ( value === '' ) {
|
15
|
+
return undefined;
|
16
|
+
}
|
17
|
+
return value;
|
18
|
+
},
|
19
|
+
// Access nested data
|
20
|
+
nestData = function( elem, type, data, parts, value, seen, fullName ) {
|
21
|
+
var name = parts.shift();
|
22
|
+
// Keep track of the dot separated fullname. Used to uniquely track seen values
|
23
|
+
// and if they should be converted to an array or not
|
24
|
+
fullName = fullName ? fullName + '.' + name : name;
|
25
|
+
|
26
|
+
if (parts.length ) {
|
27
|
+
if ( ! data[ name ] ) {
|
28
|
+
data[ name ] = {};
|
29
|
+
}
|
30
|
+
|
31
|
+
// Recursive call
|
32
|
+
nestData( elem, type, data[ name ], parts, value, seen, fullName);
|
33
|
+
} else {
|
34
|
+
|
35
|
+
// Handle same name case, as well as "last checkbox checked"
|
36
|
+
// case
|
37
|
+
if ( fullName in seen && type != "radio" && ! $.isArray( data[ name ] )) {
|
38
|
+
if ( name in data ) {
|
39
|
+
data[ name ] = [ data[name] ];
|
40
|
+
} else {
|
41
|
+
data[ name ] = [];
|
42
|
+
}
|
43
|
+
} else {
|
44
|
+
seen[ fullName ] = true;
|
45
|
+
}
|
46
|
+
|
47
|
+
// Finally, assign data
|
48
|
+
if ( ( type == "radio" || type == "checkbox" ) && ! elem.is(":checked") ) {
|
49
|
+
return
|
50
|
+
}
|
51
|
+
|
52
|
+
if ( ! data[ name ] ) {
|
53
|
+
data[ name ] = value;
|
54
|
+
} else {
|
55
|
+
data[ name ].push( value );
|
56
|
+
}
|
57
|
+
|
58
|
+
|
59
|
+
}
|
60
|
+
|
61
|
+
};
|
62
|
+
|
63
|
+
/**
|
64
|
+
* @function jQuery.fn.formParams
|
65
|
+
* @parent jQuery.formParams
|
66
|
+
* @plugin jquery/dom/form_params
|
67
|
+
* @test jquery/dom/form_params/qunit.html
|
68
|
+
*
|
69
|
+
* Returns a JavaScript object for values in a form.
|
70
|
+
* It creates nested objects by using bracket notation in the form element name.
|
71
|
+
*
|
72
|
+
* @param {Object} [params] If an object is passed, the form will be repopulated
|
73
|
+
* with the values of the object based on the name of the inputs within
|
74
|
+
* the form
|
75
|
+
* @param {Boolean} [convert=false] True if strings that look like numbers
|
76
|
+
* and booleans should be converted and if empty string should not be added
|
77
|
+
* to the result.
|
78
|
+
* @return {Object} An object of name-value pairs.
|
79
|
+
*/
|
80
|
+
$.fn.extend({
|
81
|
+
formParams: function( params ) {
|
82
|
+
|
83
|
+
var convert;
|
84
|
+
|
85
|
+
// Quick way to determine if something is a boolean
|
86
|
+
if ( !! params === params ) {
|
87
|
+
convert = params;
|
88
|
+
params = null;
|
89
|
+
}
|
90
|
+
|
91
|
+
if ( params ) {
|
92
|
+
return this.setParams( params );
|
93
|
+
} else {
|
94
|
+
return this.getParams( convert );
|
95
|
+
}
|
96
|
+
},
|
97
|
+
setParams: function( params ) {
|
98
|
+
|
99
|
+
// Find all the inputs
|
100
|
+
this.find("[name]").each(function() {
|
101
|
+
|
102
|
+
var value = params[ $(this).attr("name") ],
|
103
|
+
$this;
|
104
|
+
|
105
|
+
// Don't do all this work if there's no value
|
106
|
+
if ( value !== undefined ) {
|
107
|
+
$this = $(this);
|
108
|
+
|
109
|
+
// Nested these if statements for performance
|
110
|
+
if ( $this.is(":radio") ) {
|
111
|
+
if ( $this.val() == value ) {
|
112
|
+
$this.attr("checked", true);
|
113
|
+
}
|
114
|
+
} else if ( $this.is(":checkbox") ) {
|
115
|
+
// Convert single value to an array to reduce
|
116
|
+
// complexity
|
117
|
+
value = $.isArray( value ) ? value : [value];
|
118
|
+
if ( $.inArray( $this.val(), value ) > -1) {
|
119
|
+
$this.attr("checked", true);
|
120
|
+
}
|
121
|
+
} else {
|
122
|
+
$this.val( value );
|
123
|
+
}
|
124
|
+
}
|
125
|
+
});
|
126
|
+
},
|
127
|
+
getParams: function( convert ) {
|
128
|
+
var data = {},
|
129
|
+
// This is used to keep track of the checkbox names that we've
|
130
|
+
// already seen, so we know that we should return an array if
|
131
|
+
// we see it multiple times. Fixes last checkbox checked bug.
|
132
|
+
seen = {},
|
133
|
+
current;
|
134
|
+
|
135
|
+
this.find("[name]:not(:disabled)").each(function() {
|
136
|
+
var $this = $(this),
|
137
|
+
type = $this.attr("type"),
|
138
|
+
name = $this.attr("name"),
|
139
|
+
value = $this.val(),
|
140
|
+
parts;
|
141
|
+
|
142
|
+
// Don't accumulate submit buttons and nameless elements
|
143
|
+
if ( type == "submit" || ! name ) {
|
144
|
+
return;
|
145
|
+
}
|
146
|
+
|
147
|
+
// Figure out name parts
|
148
|
+
parts = name.match( keyBreaker );
|
149
|
+
if ( ! parts.length ) {
|
150
|
+
parts = [name];
|
151
|
+
}
|
152
|
+
|
153
|
+
// Convert the value
|
154
|
+
if ( convert ) {
|
155
|
+
value = convertValue( value );
|
156
|
+
}
|
157
|
+
|
158
|
+
// Assign data recursively
|
159
|
+
nestData( $this, type, data, parts, value, seen );
|
160
|
+
|
161
|
+
});
|
162
|
+
|
163
|
+
return data;
|
164
|
+
}
|
165
|
+
});
|
166
|
+
|
167
|
+
})(jQuery)
|