refinerycms-tags 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/public/images/refinery/ui-bg_glass_75_22a7f2_1x400.png +0 -0
- data/public/javascripts/jquery.tagsinput.js +973 -0
- data/public/javascripts/jquery.tagsinput.min.js +15 -0
- data/public/stylesheets/jquery.tagsinput.css +63 -0
- metadata +13 -16
- data/app/controllers/admin/tags_controller.rb~ +0 -6
- data/app/views/shared/admin/_tag_editor.html.erb~ +0 -16
- data/config/locales/en.yml~ +0 -5
- data/config/locales/es.yml~ +0 -5
- data/config/locales/lolcat.yml~ +0 -5
- data/config/routes.rb~ +0 -9
- data/lib/refinerycms-tags.rb~ +0 -26
Binary file
|
@@ -0,0 +1,973 @@
|
|
1
|
+
/*
|
2
|
+
* jQuery UI Autocomplete 1.8.17
|
3
|
+
*
|
4
|
+
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
5
|
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
6
|
+
* http://jquery.org/license
|
7
|
+
*
|
8
|
+
* http://docs.jquery.com/UI/Autocomplete
|
9
|
+
*
|
10
|
+
* Depends:
|
11
|
+
* jquery.ui.core.js
|
12
|
+
* jquery.ui.widget.js
|
13
|
+
* jquery.ui.position.js
|
14
|
+
*/
|
15
|
+
(function( $, undefined ) {
|
16
|
+
|
17
|
+
// used to prevent race conditions with remote data sources
|
18
|
+
var requestIndex = 0;
|
19
|
+
|
20
|
+
$.widget( "ui.autocomplete", {
|
21
|
+
options: {
|
22
|
+
appendTo: "body",
|
23
|
+
autoFocus: false,
|
24
|
+
delay: 300,
|
25
|
+
minLength: 1,
|
26
|
+
position: {
|
27
|
+
my: "left top",
|
28
|
+
at: "left bottom",
|
29
|
+
collision: "none"
|
30
|
+
},
|
31
|
+
source: null
|
32
|
+
},
|
33
|
+
|
34
|
+
pending: 0,
|
35
|
+
|
36
|
+
_create: function() {
|
37
|
+
var self = this,
|
38
|
+
doc = this.element[ 0 ].ownerDocument,
|
39
|
+
suppressKeyPress;
|
40
|
+
|
41
|
+
this.element
|
42
|
+
.addClass( "ui-autocomplete-input" )
|
43
|
+
.attr( "autocomplete", "off" )
|
44
|
+
// TODO verify these actually work as intended
|
45
|
+
.attr({
|
46
|
+
role: "textbox",
|
47
|
+
"aria-autocomplete": "list",
|
48
|
+
"aria-haspopup": "true"
|
49
|
+
})
|
50
|
+
.bind( "keydown.autocomplete", function( event ) {
|
51
|
+
if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) {
|
52
|
+
return;
|
53
|
+
}
|
54
|
+
|
55
|
+
suppressKeyPress = false;
|
56
|
+
var keyCode = $.ui.keyCode;
|
57
|
+
switch( event.keyCode ) {
|
58
|
+
case keyCode.PAGE_UP:
|
59
|
+
self._move( "previousPage", event );
|
60
|
+
break;
|
61
|
+
case keyCode.PAGE_DOWN:
|
62
|
+
self._move( "nextPage", event );
|
63
|
+
break;
|
64
|
+
case keyCode.UP:
|
65
|
+
self._move( "previous", event );
|
66
|
+
// prevent moving cursor to beginning of text field in some browsers
|
67
|
+
event.preventDefault();
|
68
|
+
break;
|
69
|
+
case keyCode.DOWN:
|
70
|
+
self._move( "next", event );
|
71
|
+
// prevent moving cursor to end of text field in some browsers
|
72
|
+
event.preventDefault();
|
73
|
+
break;
|
74
|
+
case keyCode.ENTER:
|
75
|
+
case keyCode.NUMPAD_ENTER:
|
76
|
+
// when menu is open and has focus
|
77
|
+
if ( self.menu.active ) {
|
78
|
+
// #6055 - Opera still allows the keypress to occur
|
79
|
+
// which causes forms to submit
|
80
|
+
suppressKeyPress = true;
|
81
|
+
event.preventDefault();
|
82
|
+
}
|
83
|
+
//passthrough - ENTER and TAB both select the current element
|
84
|
+
case keyCode.TAB:
|
85
|
+
if ( !self.menu.active ) {
|
86
|
+
return;
|
87
|
+
}
|
88
|
+
self.menu.select( event );
|
89
|
+
break;
|
90
|
+
case keyCode.ESCAPE:
|
91
|
+
self.element.val( self.term );
|
92
|
+
self.close( event );
|
93
|
+
break;
|
94
|
+
default:
|
95
|
+
// keypress is triggered before the input value is changed
|
96
|
+
clearTimeout( self.searching );
|
97
|
+
self.searching = setTimeout(function() {
|
98
|
+
// only search if the value has changed
|
99
|
+
if ( self.term != self.element.val() ) {
|
100
|
+
self.selectedItem = null;
|
101
|
+
self.search( null, event );
|
102
|
+
}
|
103
|
+
}, self.options.delay );
|
104
|
+
break;
|
105
|
+
}
|
106
|
+
})
|
107
|
+
.bind( "keypress.autocomplete", function( event ) {
|
108
|
+
if ( suppressKeyPress ) {
|
109
|
+
suppressKeyPress = false;
|
110
|
+
event.preventDefault();
|
111
|
+
}
|
112
|
+
})
|
113
|
+
.bind( "focus.autocomplete", function() {
|
114
|
+
if ( self.options.disabled ) {
|
115
|
+
return;
|
116
|
+
}
|
117
|
+
|
118
|
+
self.selectedItem = null;
|
119
|
+
self.previous = self.element.val();
|
120
|
+
})
|
121
|
+
.bind( "blur.autocomplete", function( event ) {
|
122
|
+
if ( self.options.disabled ) {
|
123
|
+
return;
|
124
|
+
}
|
125
|
+
|
126
|
+
clearTimeout( self.searching );
|
127
|
+
// clicks on the menu (or a button to trigger a search) will cause a blur event
|
128
|
+
self.closing = setTimeout(function() {
|
129
|
+
self.close( event );
|
130
|
+
self._change( event );
|
131
|
+
}, 150 );
|
132
|
+
});
|
133
|
+
this._initSource();
|
134
|
+
this.response = function() {
|
135
|
+
return self._response.apply( self, arguments );
|
136
|
+
};
|
137
|
+
this.menu = $( "<ul></ul>" )
|
138
|
+
.addClass( "ui-autocomplete" )
|
139
|
+
.appendTo( $( this.options.appendTo || "body", doc )[0] )
|
140
|
+
// prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
|
141
|
+
.mousedown(function( event ) {
|
142
|
+
// clicking on the scrollbar causes focus to shift to the body
|
143
|
+
// but we can't detect a mouseup or a click immediately afterward
|
144
|
+
// so we have to track the next mousedown and close the menu if
|
145
|
+
// the user clicks somewhere outside of the autocomplete
|
146
|
+
var menuElement = self.menu.element[ 0 ];
|
147
|
+
if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
|
148
|
+
setTimeout(function() {
|
149
|
+
$( document ).one( 'mousedown', function( event ) {
|
150
|
+
if ( event.target !== self.element[ 0 ] &&
|
151
|
+
event.target !== menuElement &&
|
152
|
+
!$.ui.contains( menuElement, event.target ) ) {
|
153
|
+
self.close();
|
154
|
+
}
|
155
|
+
});
|
156
|
+
}, 1 );
|
157
|
+
}
|
158
|
+
|
159
|
+
// use another timeout to make sure the blur-event-handler on the input was already triggered
|
160
|
+
setTimeout(function() {
|
161
|
+
clearTimeout( self.closing );
|
162
|
+
}, 13);
|
163
|
+
})
|
164
|
+
.menu({
|
165
|
+
focus: function( event, ui ) {
|
166
|
+
var item = ui.item.data( "item.autocomplete" );
|
167
|
+
if ( false !== self._trigger( "focus", event, { item: item } ) ) {
|
168
|
+
// use value to match what will end up in the input, if it was a key event
|
169
|
+
if ( /^key/.test(event.originalEvent.type) ) {
|
170
|
+
self.element.val( item.value );
|
171
|
+
}
|
172
|
+
}
|
173
|
+
},
|
174
|
+
selected: function( event, ui ) {
|
175
|
+
var item = ui.item.data( "item.autocomplete" ),
|
176
|
+
previous = self.previous;
|
177
|
+
|
178
|
+
// only trigger when focus was lost (click on menu)
|
179
|
+
if ( self.element[0] !== doc.activeElement ) {
|
180
|
+
self.element.focus();
|
181
|
+
self.previous = previous;
|
182
|
+
// #6109 - IE triggers two focus events and the second
|
183
|
+
// is asynchronous, so we need to reset the previous
|
184
|
+
// term synchronously and asynchronously :-(
|
185
|
+
setTimeout(function() {
|
186
|
+
self.previous = previous;
|
187
|
+
self.selectedItem = item;
|
188
|
+
}, 1);
|
189
|
+
}
|
190
|
+
|
191
|
+
if ( false !== self._trigger( "select", event, { item: item } ) ) {
|
192
|
+
self.element.val( item.value );
|
193
|
+
}
|
194
|
+
// reset the term after the select event
|
195
|
+
// this allows custom select handling to work properly
|
196
|
+
self.term = self.element.val();
|
197
|
+
|
198
|
+
self.close( event );
|
199
|
+
self.selectedItem = item;
|
200
|
+
},
|
201
|
+
blur: function( event, ui ) {
|
202
|
+
// don't set the value of the text field if it's already correct
|
203
|
+
// this prevents moving the cursor unnecessarily
|
204
|
+
if ( self.menu.element.is(":visible") &&
|
205
|
+
( self.element.val() !== self.term ) ) {
|
206
|
+
self.element.val( self.term );
|
207
|
+
}
|
208
|
+
}
|
209
|
+
})
|
210
|
+
.zIndex( this.element.zIndex() + 1 )
|
211
|
+
// workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
|
212
|
+
.css({ top: 0, left: 0 })
|
213
|
+
.hide()
|
214
|
+
.data( "menu" );
|
215
|
+
if ( $.fn.bgiframe ) {
|
216
|
+
this.menu.element.bgiframe();
|
217
|
+
}
|
218
|
+
// turning off autocomplete prevents the browser from remembering the
|
219
|
+
// value when navigating through history, so we re-enable autocomplete
|
220
|
+
// if the page is unloaded before the widget is destroyed. #7790
|
221
|
+
self.beforeunloadHandler = function() {
|
222
|
+
self.element.removeAttr( "autocomplete" );
|
223
|
+
};
|
224
|
+
$( window ).bind( "beforeunload", self.beforeunloadHandler );
|
225
|
+
},
|
226
|
+
|
227
|
+
destroy: function() {
|
228
|
+
this.element
|
229
|
+
.removeClass( "ui-autocomplete-input" )
|
230
|
+
.removeAttr( "autocomplete" )
|
231
|
+
.removeAttr( "role" )
|
232
|
+
.removeAttr( "aria-autocomplete" )
|
233
|
+
.removeAttr( "aria-haspopup" );
|
234
|
+
this.menu.element.remove();
|
235
|
+
$( window ).unbind( "beforeunload", this.beforeunloadHandler );
|
236
|
+
$.Widget.prototype.destroy.call( this );
|
237
|
+
},
|
238
|
+
|
239
|
+
_setOption: function( key, value ) {
|
240
|
+
$.Widget.prototype._setOption.apply( this, arguments );
|
241
|
+
if ( key === "source" ) {
|
242
|
+
this._initSource();
|
243
|
+
}
|
244
|
+
if ( key === "appendTo" ) {
|
245
|
+
this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
|
246
|
+
}
|
247
|
+
if ( key === "disabled" && value && this.xhr ) {
|
248
|
+
this.xhr.abort();
|
249
|
+
}
|
250
|
+
},
|
251
|
+
|
252
|
+
_initSource: function() {
|
253
|
+
var self = this,
|
254
|
+
array,
|
255
|
+
url;
|
256
|
+
if ( $.isArray(this.options.source) ) {
|
257
|
+
array = this.options.source;
|
258
|
+
this.source = function( request, response ) {
|
259
|
+
response( $.ui.autocomplete.filter(array, request.term) );
|
260
|
+
};
|
261
|
+
} else if ( typeof this.options.source === "string" ) {
|
262
|
+
url = this.options.source;
|
263
|
+
this.source = function( request, response ) {
|
264
|
+
if ( self.xhr ) {
|
265
|
+
self.xhr.abort();
|
266
|
+
}
|
267
|
+
self.xhr = $.ajax({
|
268
|
+
url: url,
|
269
|
+
data: request,
|
270
|
+
dataType: "json",
|
271
|
+
autocompleteRequest: ++requestIndex,
|
272
|
+
success: function( data, status ) {
|
273
|
+
if ( this.autocompleteRequest === requestIndex ) {
|
274
|
+
response( data );
|
275
|
+
}
|
276
|
+
},
|
277
|
+
error: function() {
|
278
|
+
if ( this.autocompleteRequest === requestIndex ) {
|
279
|
+
response( [] );
|
280
|
+
}
|
281
|
+
}
|
282
|
+
});
|
283
|
+
};
|
284
|
+
} else {
|
285
|
+
this.source = this.options.source;
|
286
|
+
}
|
287
|
+
},
|
288
|
+
|
289
|
+
search: function( value, event ) {
|
290
|
+
value = value != null ? value : this.element.val();
|
291
|
+
|
292
|
+
// always save the actual value, not the one passed as an argument
|
293
|
+
this.term = this.element.val();
|
294
|
+
|
295
|
+
if ( value.length < this.options.minLength ) {
|
296
|
+
return this.close( event );
|
297
|
+
}
|
298
|
+
|
299
|
+
clearTimeout( this.closing );
|
300
|
+
if ( this._trigger( "search", event ) === false ) {
|
301
|
+
return;
|
302
|
+
}
|
303
|
+
|
304
|
+
return this._search( value );
|
305
|
+
},
|
306
|
+
|
307
|
+
_search: function( value ) {
|
308
|
+
this.pending++;
|
309
|
+
this.element.addClass( "ui-autocomplete-loading" );
|
310
|
+
|
311
|
+
this.source( { term: value }, this.response );
|
312
|
+
},
|
313
|
+
|
314
|
+
_response: function( content ) {
|
315
|
+
if ( !this.options.disabled && content && content.length ) {
|
316
|
+
content = this._normalize( content );
|
317
|
+
this._suggest( content );
|
318
|
+
this._trigger( "open" );
|
319
|
+
} else {
|
320
|
+
this.close();
|
321
|
+
}
|
322
|
+
this.pending--;
|
323
|
+
if ( !this.pending ) {
|
324
|
+
this.element.removeClass( "ui-autocomplete-loading" );
|
325
|
+
}
|
326
|
+
},
|
327
|
+
|
328
|
+
close: function( event ) {
|
329
|
+
clearTimeout( this.closing );
|
330
|
+
if ( this.menu.element.is(":visible") ) {
|
331
|
+
this.menu.element.hide();
|
332
|
+
this.menu.deactivate();
|
333
|
+
this._trigger( "close", event );
|
334
|
+
}
|
335
|
+
},
|
336
|
+
|
337
|
+
_change: function( event ) {
|
338
|
+
if ( this.previous !== this.element.val() ) {
|
339
|
+
this._trigger( "change", event, { item: this.selectedItem } );
|
340
|
+
}
|
341
|
+
},
|
342
|
+
|
343
|
+
_normalize: function( items ) {
|
344
|
+
// assume all items have the right format when the first item is complete
|
345
|
+
if ( items.length && items[0].label && items[0].value ) {
|
346
|
+
return items;
|
347
|
+
}
|
348
|
+
return $.map( items, function(item) {
|
349
|
+
if ( typeof item === "string" ) {
|
350
|
+
return {
|
351
|
+
label: item,
|
352
|
+
value: item
|
353
|
+
};
|
354
|
+
}
|
355
|
+
return $.extend({
|
356
|
+
label: item.label || item.value,
|
357
|
+
value: item.value || item.label
|
358
|
+
}, item );
|
359
|
+
});
|
360
|
+
},
|
361
|
+
|
362
|
+
_suggest: function( items ) {
|
363
|
+
var ul = this.menu.element
|
364
|
+
.empty()
|
365
|
+
.zIndex( this.element.zIndex() + 1 );
|
366
|
+
this._renderMenu( ul, items );
|
367
|
+
// TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
|
368
|
+
this.menu.deactivate();
|
369
|
+
this.menu.refresh();
|
370
|
+
|
371
|
+
// size and position menu
|
372
|
+
ul.show();
|
373
|
+
this._resizeMenu();
|
374
|
+
ul.position( $.extend({
|
375
|
+
of: this.element
|
376
|
+
}, this.options.position ));
|
377
|
+
|
378
|
+
if ( this.options.autoFocus ) {
|
379
|
+
this.menu.next( new $.Event("mouseover") );
|
380
|
+
}
|
381
|
+
},
|
382
|
+
|
383
|
+
_resizeMenu: function() {
|
384
|
+
var ul = this.menu.element;
|
385
|
+
ul.outerWidth( Math.max(
|
386
|
+
// Firefox wraps long text (possibly a rounding bug)
|
387
|
+
// so we add 1px to avoid the wrapping (#7513)
|
388
|
+
ul.width( "" ).outerWidth() + 1,
|
389
|
+
this.element.outerWidth()
|
390
|
+
) );
|
391
|
+
},
|
392
|
+
|
393
|
+
_renderMenu: function( ul, items ) {
|
394
|
+
var self = this;
|
395
|
+
$.each( items, function( index, item ) {
|
396
|
+
self._renderItem( ul, item );
|
397
|
+
});
|
398
|
+
},
|
399
|
+
|
400
|
+
_renderItem: function( ul, item) {
|
401
|
+
return $( "<li></li>" )
|
402
|
+
.data( "item.autocomplete", item )
|
403
|
+
.append( $( "<a></a>" ).text( item.label ) )
|
404
|
+
.appendTo( ul );
|
405
|
+
},
|
406
|
+
|
407
|
+
_move: function( direction, event ) {
|
408
|
+
if ( !this.menu.element.is(":visible") ) {
|
409
|
+
this.search( null, event );
|
410
|
+
return;
|
411
|
+
}
|
412
|
+
if ( this.menu.first() && /^previous/.test(direction) ||
|
413
|
+
this.menu.last() && /^next/.test(direction) ) {
|
414
|
+
this.element.val( this.term );
|
415
|
+
this.menu.deactivate();
|
416
|
+
return;
|
417
|
+
}
|
418
|
+
this.menu[ direction ]( event );
|
419
|
+
},
|
420
|
+
|
421
|
+
widget: function() {
|
422
|
+
return this.menu.element;
|
423
|
+
}
|
424
|
+
});
|
425
|
+
|
426
|
+
$.extend( $.ui.autocomplete, {
|
427
|
+
escapeRegex: function( value ) {
|
428
|
+
return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
429
|
+
},
|
430
|
+
filter: function(array, term) {
|
431
|
+
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
|
432
|
+
return $.grep( array, function(value) {
|
433
|
+
return matcher.test( value.label || value.value || value );
|
434
|
+
});
|
435
|
+
}
|
436
|
+
});
|
437
|
+
|
438
|
+
}( jQuery ));
|
439
|
+
|
440
|
+
/*
|
441
|
+
* jQuery UI Menu (not officially released)
|
442
|
+
*
|
443
|
+
* This widget isn't yet finished and the API is subject to change. We plan to finish
|
444
|
+
* it for the next release. You're welcome to give it a try anyway and give us feedback,
|
445
|
+
* as long as you're okay with migrating your code later on. We can help with that, too.
|
446
|
+
*
|
447
|
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
448
|
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
449
|
+
* http://jquery.org/license
|
450
|
+
*
|
451
|
+
* http://docs.jquery.com/UI/Menu
|
452
|
+
*
|
453
|
+
* Depends:
|
454
|
+
* jquery.ui.core.js
|
455
|
+
* jquery.ui.widget.js
|
456
|
+
*/
|
457
|
+
(function($) {
|
458
|
+
|
459
|
+
$.widget("ui.menu", {
|
460
|
+
_create: function() {
|
461
|
+
var self = this;
|
462
|
+
this.element
|
463
|
+
.addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
|
464
|
+
.attr({
|
465
|
+
role: "listbox",
|
466
|
+
"aria-activedescendant": "ui-active-menuitem"
|
467
|
+
})
|
468
|
+
.click(function( event ) {
|
469
|
+
if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
|
470
|
+
return;
|
471
|
+
}
|
472
|
+
// temporary
|
473
|
+
event.preventDefault();
|
474
|
+
self.select( event );
|
475
|
+
});
|
476
|
+
this.refresh();
|
477
|
+
},
|
478
|
+
|
479
|
+
refresh: function() {
|
480
|
+
var self = this;
|
481
|
+
|
482
|
+
// don't refresh list items that are already adapted
|
483
|
+
var items = this.element.children("li:not(.ui-menu-item):has(a)")
|
484
|
+
.addClass("ui-menu-item")
|
485
|
+
.attr("role", "menuitem");
|
486
|
+
|
487
|
+
items.children("a")
|
488
|
+
.addClass("ui-corner-all")
|
489
|
+
.attr("tabindex", -1)
|
490
|
+
// mouseenter doesn't work with event delegation
|
491
|
+
.mouseenter(function( event ) {
|
492
|
+
self.activate( event, $(this).parent() );
|
493
|
+
})
|
494
|
+
.mouseleave(function() {
|
495
|
+
self.deactivate();
|
496
|
+
});
|
497
|
+
},
|
498
|
+
|
499
|
+
activate: function( event, item ) {
|
500
|
+
this.deactivate();
|
501
|
+
if (this.hasScroll()) {
|
502
|
+
var offset = item.offset().top - this.element.offset().top,
|
503
|
+
scroll = this.element.scrollTop(),
|
504
|
+
elementHeight = this.element.height();
|
505
|
+
if (offset < 0) {
|
506
|
+
this.element.scrollTop( scroll + offset);
|
507
|
+
} else if (offset >= elementHeight) {
|
508
|
+
this.element.scrollTop( scroll + offset - elementHeight + item.height());
|
509
|
+
}
|
510
|
+
}
|
511
|
+
this.active = item.eq(0)
|
512
|
+
.children("a")
|
513
|
+
.addClass("ui-state-hover")
|
514
|
+
.attr("id", "ui-active-menuitem")
|
515
|
+
.end();
|
516
|
+
this._trigger("focus", event, { item: item });
|
517
|
+
},
|
518
|
+
|
519
|
+
deactivate: function() {
|
520
|
+
if (!this.active) { return; }
|
521
|
+
|
522
|
+
this.active.children("a")
|
523
|
+
.removeClass("ui-state-hover")
|
524
|
+
.removeAttr("id");
|
525
|
+
this._trigger("blur");
|
526
|
+
this.active = null;
|
527
|
+
},
|
528
|
+
|
529
|
+
next: function(event) {
|
530
|
+
this.move("next", ".ui-menu-item:first", event);
|
531
|
+
},
|
532
|
+
|
533
|
+
previous: function(event) {
|
534
|
+
this.move("prev", ".ui-menu-item:last", event);
|
535
|
+
},
|
536
|
+
|
537
|
+
first: function() {
|
538
|
+
return this.active && !this.active.prevAll(".ui-menu-item").length;
|
539
|
+
},
|
540
|
+
|
541
|
+
last: function() {
|
542
|
+
return this.active && !this.active.nextAll(".ui-menu-item").length;
|
543
|
+
},
|
544
|
+
|
545
|
+
move: function(direction, edge, event) {
|
546
|
+
if (!this.active) {
|
547
|
+
this.activate(event, this.element.children(edge));
|
548
|
+
return;
|
549
|
+
}
|
550
|
+
var next = this.active[direction + "All"](".ui-menu-item").eq(0);
|
551
|
+
if (next.length) {
|
552
|
+
this.activate(event, next);
|
553
|
+
} else {
|
554
|
+
this.activate(event, this.element.children(edge));
|
555
|
+
}
|
556
|
+
},
|
557
|
+
|
558
|
+
// TODO merge with previousPage
|
559
|
+
nextPage: function(event) {
|
560
|
+
if (this.hasScroll()) {
|
561
|
+
// TODO merge with no-scroll-else
|
562
|
+
if (!this.active || this.last()) {
|
563
|
+
this.activate(event, this.element.children(".ui-menu-item:first"));
|
564
|
+
return;
|
565
|
+
}
|
566
|
+
var base = this.active.offset().top,
|
567
|
+
height = this.element.height(),
|
568
|
+
result = this.element.children(".ui-menu-item").filter(function() {
|
569
|
+
var close = $(this).offset().top - base - height + $(this).height();
|
570
|
+
// TODO improve approximation
|
571
|
+
return close < 10 && close > -10;
|
572
|
+
});
|
573
|
+
|
574
|
+
// TODO try to catch this earlier when scrollTop indicates the last page anyway
|
575
|
+
if (!result.length) {
|
576
|
+
result = this.element.children(".ui-menu-item:last");
|
577
|
+
}
|
578
|
+
this.activate(event, result);
|
579
|
+
} else {
|
580
|
+
this.activate(event, this.element.children(".ui-menu-item")
|
581
|
+
.filter(!this.active || this.last() ? ":first" : ":last"));
|
582
|
+
}
|
583
|
+
},
|
584
|
+
|
585
|
+
// TODO merge with nextPage
|
586
|
+
previousPage: function(event) {
|
587
|
+
if (this.hasScroll()) {
|
588
|
+
// TODO merge with no-scroll-else
|
589
|
+
if (!this.active || this.first()) {
|
590
|
+
this.activate(event, this.element.children(".ui-menu-item:last"));
|
591
|
+
return;
|
592
|
+
}
|
593
|
+
|
594
|
+
var base = this.active.offset().top,
|
595
|
+
height = this.element.height();
|
596
|
+
result = this.element.children(".ui-menu-item").filter(function() {
|
597
|
+
var close = $(this).offset().top - base + height - $(this).height();
|
598
|
+
// TODO improve approximation
|
599
|
+
return close < 10 && close > -10;
|
600
|
+
});
|
601
|
+
|
602
|
+
// TODO try to catch this earlier when scrollTop indicates the last page anyway
|
603
|
+
if (!result.length) {
|
604
|
+
result = this.element.children(".ui-menu-item:first");
|
605
|
+
}
|
606
|
+
this.activate(event, result);
|
607
|
+
} else {
|
608
|
+
this.activate(event, this.element.children(".ui-menu-item")
|
609
|
+
.filter(!this.active || this.first() ? ":last" : ":first"));
|
610
|
+
}
|
611
|
+
},
|
612
|
+
|
613
|
+
hasScroll: function() {
|
614
|
+
return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight");
|
615
|
+
},
|
616
|
+
|
617
|
+
select: function( event ) {
|
618
|
+
this._trigger("selected", event, { item: this.active });
|
619
|
+
}
|
620
|
+
});
|
621
|
+
|
622
|
+
}(jQuery));
|
623
|
+
|
624
|
+
/*
|
625
|
+
|
626
|
+
jQuery Tags Input Plugin 1.3.3
|
627
|
+
|
628
|
+
Copyright (c) 2011 XOXCO, Inc
|
629
|
+
|
630
|
+
Documentation for this plugin lives here:
|
631
|
+
http://xoxco.com/clickable/jquery-tags-input
|
632
|
+
|
633
|
+
Licensed under the MIT license:
|
634
|
+
http://www.opensource.org/licenses/mit-license.php
|
635
|
+
|
636
|
+
ben@xoxco.com
|
637
|
+
|
638
|
+
*/
|
639
|
+
|
640
|
+
(function($) {
|
641
|
+
|
642
|
+
var delimiter = new Array();
|
643
|
+
var tags_callbacks = new Array();
|
644
|
+
$.fn.doAutosize = function(o){
|
645
|
+
var minWidth = $(this).data('minwidth'),
|
646
|
+
maxWidth = $(this).data('maxwidth'),
|
647
|
+
val = '',
|
648
|
+
input = $(this),
|
649
|
+
testSubject = $('#'+$(this).data('tester_id'));
|
650
|
+
|
651
|
+
if (val === (val = input.val())) {return;}
|
652
|
+
|
653
|
+
// Enter new content into testSubject
|
654
|
+
var escaped = val.replace(/&/g, '&').replace(/\s/g,' ').replace(/</g, '<').replace(/>/g, '>');
|
655
|
+
testSubject.html(escaped);
|
656
|
+
// Calculate new width + whether to change
|
657
|
+
var testerWidth = testSubject.width(),
|
658
|
+
newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
|
659
|
+
currentWidth = input.width(),
|
660
|
+
isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
|
661
|
+
|| (newWidth > minWidth && newWidth < maxWidth);
|
662
|
+
|
663
|
+
// Animate width
|
664
|
+
if (isValidWidthChange) {
|
665
|
+
input.width(newWidth);
|
666
|
+
}
|
667
|
+
|
668
|
+
|
669
|
+
};
|
670
|
+
$.fn.resetAutosize = function(options){
|
671
|
+
// alert(JSON.stringify(options));
|
672
|
+
var minWidth = $(this).data('minwidth') || options.minInputWidth || $(this).width(),
|
673
|
+
maxWidth = $(this).data('maxwidth') || options.maxInputWidth || ($(this).closest('.tagsinput').width() - options.inputPadding),
|
674
|
+
val = '',
|
675
|
+
input = $(this),
|
676
|
+
testSubject = $('<tester/>').css({
|
677
|
+
position: 'absolute',
|
678
|
+
top: -9999,
|
679
|
+
left: -9999,
|
680
|
+
width: 'auto',
|
681
|
+
fontSize: input.css('fontSize'),
|
682
|
+
fontFamily: input.css('fontFamily'),
|
683
|
+
fontWeight: input.css('fontWeight'),
|
684
|
+
letterSpacing: input.css('letterSpacing'),
|
685
|
+
whiteSpace: 'nowrap'
|
686
|
+
}),
|
687
|
+
testerId = $(this).attr('id')+'_autosize_tester';
|
688
|
+
if(! $('#'+testerId).length > 0){
|
689
|
+
testSubject.attr('id', testerId);
|
690
|
+
testSubject.appendTo('body');
|
691
|
+
}
|
692
|
+
|
693
|
+
input.data('minwidth', minWidth);
|
694
|
+
input.data('maxwidth', maxWidth);
|
695
|
+
input.data('tester_id', testerId);
|
696
|
+
input.css('width', minWidth);
|
697
|
+
};
|
698
|
+
|
699
|
+
$.fn.addTag = function(value,options) {
|
700
|
+
options = jQuery.extend({focus:false,callback:true},options);
|
701
|
+
this.each(function() {
|
702
|
+
var id = $(this).attr('id');
|
703
|
+
|
704
|
+
var tagslist = $(this).val().split(delimiter[id]);
|
705
|
+
if (tagslist[0] == '') {
|
706
|
+
tagslist = new Array();
|
707
|
+
}
|
708
|
+
|
709
|
+
value = jQuery.trim(value);
|
710
|
+
|
711
|
+
if (options.unique) {
|
712
|
+
var skipTag = $(tagslist).tagExist(value);
|
713
|
+
if(skipTag == true) {
|
714
|
+
//Marks fake input as not_valid to let styling it
|
715
|
+
$('#'+id+'_tag').addClass('not_valid');
|
716
|
+
}
|
717
|
+
} else {
|
718
|
+
var skipTag = false;
|
719
|
+
}
|
720
|
+
|
721
|
+
if (value !='' && skipTag != true) {
|
722
|
+
$('<span>').addClass('tag').append(
|
723
|
+
$('<span>').text(value).append(' '),
|
724
|
+
$('<a>', {
|
725
|
+
href : '#',
|
726
|
+
title : 'Removing tag',
|
727
|
+
text : 'x'
|
728
|
+
}).click(function () {
|
729
|
+
return $('#' + id).removeTag(escape(value));
|
730
|
+
})
|
731
|
+
).insertBefore('#' + id + '_addTag');
|
732
|
+
|
733
|
+
tagslist.push(value);
|
734
|
+
|
735
|
+
$('#'+id+'_tag').val('');
|
736
|
+
if (options.focus) {
|
737
|
+
$('#'+id+'_tag').focus();
|
738
|
+
} else {
|
739
|
+
$('#'+id+'_tag').blur();
|
740
|
+
}
|
741
|
+
|
742
|
+
$.fn.tagsInput.updateTagsField(this,tagslist);
|
743
|
+
|
744
|
+
if (options.callback && tags_callbacks[id] && tags_callbacks[id]['onAddTag']) {
|
745
|
+
var f = tags_callbacks[id]['onAddTag'];
|
746
|
+
f.call(this, value);
|
747
|
+
}
|
748
|
+
if(tags_callbacks[id] && tags_callbacks[id]['onChange'])
|
749
|
+
{
|
750
|
+
var i = tagslist.length;
|
751
|
+
var f = tags_callbacks[id]['onChange'];
|
752
|
+
f.call(this, $(this), tagslist[i-1]);
|
753
|
+
}
|
754
|
+
}
|
755
|
+
|
756
|
+
});
|
757
|
+
|
758
|
+
return false;
|
759
|
+
};
|
760
|
+
|
761
|
+
$.fn.removeTag = function(value) {
|
762
|
+
value = unescape(value);
|
763
|
+
this.each(function() {
|
764
|
+
var id = $(this).attr('id');
|
765
|
+
|
766
|
+
var old = $(this).val().split(delimiter[id]);
|
767
|
+
|
768
|
+
$('#'+id+'_tagsinput .tag').remove();
|
769
|
+
str = '';
|
770
|
+
for (i=0; i< old.length; i++) {
|
771
|
+
if (old[i]!=value) {
|
772
|
+
str = str + delimiter[id] +old[i];
|
773
|
+
}
|
774
|
+
}
|
775
|
+
|
776
|
+
$.fn.tagsInput.importTags(this,str);
|
777
|
+
|
778
|
+
if (tags_callbacks[id] && tags_callbacks[id]['onRemoveTag']) {
|
779
|
+
var f = tags_callbacks[id]['onRemoveTag'];
|
780
|
+
f.call(this, value);
|
781
|
+
}
|
782
|
+
});
|
783
|
+
|
784
|
+
return false;
|
785
|
+
};
|
786
|
+
|
787
|
+
$.fn.tagExist = function(val) {
|
788
|
+
return (jQuery.inArray(val, $(this)) >= 0); //true when tag exists, false when not
|
789
|
+
};
|
790
|
+
|
791
|
+
// clear all existing tags and import new ones from a string
|
792
|
+
$.fn.importTags = function(str) {
|
793
|
+
id = $(this).attr('id');
|
794
|
+
$('#'+id+'_tagsinput .tag').remove();
|
795
|
+
$.fn.tagsInput.importTags(this,str);
|
796
|
+
}
|
797
|
+
|
798
|
+
$.fn.tagsInput = function(options) {
|
799
|
+
var settings = jQuery.extend({
|
800
|
+
interactive:true,
|
801
|
+
defaultText:'add a tag',
|
802
|
+
minChars:0,
|
803
|
+
width:'300px',
|
804
|
+
height:'100px',
|
805
|
+
autocomplete: {selectFirst: false },
|
806
|
+
'hide':true,
|
807
|
+
'delimiter':',',
|
808
|
+
'unique':true,
|
809
|
+
removeWithBackspace:true,
|
810
|
+
placeholderColor:'#666666',
|
811
|
+
autosize: true,
|
812
|
+
comfortZone: 20,
|
813
|
+
inputPadding: 6*2
|
814
|
+
},options);
|
815
|
+
|
816
|
+
this.each(function() {
|
817
|
+
if (settings.hide) {
|
818
|
+
$(this).hide();
|
819
|
+
}
|
820
|
+
|
821
|
+
var id = $(this).attr('id')
|
822
|
+
|
823
|
+
var data = jQuery.extend({
|
824
|
+
pid:id,
|
825
|
+
real_input: '#'+id,
|
826
|
+
holder: '#'+id+'_tagsinput',
|
827
|
+
input_wrapper: '#'+id+'_addTag',
|
828
|
+
fake_input: '#'+id+'_tag'
|
829
|
+
},settings);
|
830
|
+
|
831
|
+
delimiter[id] = data.delimiter;
|
832
|
+
|
833
|
+
if (settings.onAddTag || settings.onRemoveTag || settings.onChange) {
|
834
|
+
tags_callbacks[id] = new Array();
|
835
|
+
tags_callbacks[id]['onAddTag'] = settings.onAddTag;
|
836
|
+
tags_callbacks[id]['onRemoveTag'] = settings.onRemoveTag;
|
837
|
+
tags_callbacks[id]['onChange'] = settings.onChange;
|
838
|
+
}
|
839
|
+
|
840
|
+
var markup = '<div id="'+id+'_tagsinput" class="tagsinput"><div id="'+id+'_addTag">';
|
841
|
+
|
842
|
+
if (settings.interactive) {
|
843
|
+
markup = markup + '<input id="'+id+'_tag" value="" data-default="'+settings.defaultText+'" />';
|
844
|
+
}
|
845
|
+
|
846
|
+
markup = markup + '</div><div class="tags_clear"></div></div>';
|
847
|
+
|
848
|
+
$(markup).insertAfter(this);
|
849
|
+
|
850
|
+
$(data.holder).css('width',settings.width);
|
851
|
+
$(data.holder).css('height',settings.height);
|
852
|
+
|
853
|
+
if ($(data.real_input).val()!='') {
|
854
|
+
$.fn.tagsInput.importTags($(data.real_input),$(data.real_input).val());
|
855
|
+
}
|
856
|
+
if (settings.interactive) {
|
857
|
+
$(data.fake_input).val($(data.fake_input).attr('data-default'));
|
858
|
+
$(data.fake_input).css('color',settings.placeholderColor);
|
859
|
+
$(data.fake_input).resetAutosize(settings);
|
860
|
+
|
861
|
+
$(data.holder).bind('click',data,function(event) {
|
862
|
+
$(event.data.fake_input).focus();
|
863
|
+
});
|
864
|
+
|
865
|
+
$(data.fake_input).bind('focus',data,function(event) {
|
866
|
+
if ($(event.data.fake_input).val()==$(event.data.fake_input).attr('data-default')) {
|
867
|
+
$(event.data.fake_input).val('');
|
868
|
+
}
|
869
|
+
$(event.data.fake_input).css('color','#000000');
|
870
|
+
});
|
871
|
+
|
872
|
+
if (settings.autocomplete_url != undefined) {
|
873
|
+
autocomplete_options = {source: settings.autocomplete_url};
|
874
|
+
for (attrname in settings.autocomplete) {
|
875
|
+
autocomplete_options[attrname] = settings.autocomplete[attrname];
|
876
|
+
}
|
877
|
+
|
878
|
+
if (jQuery.Autocompleter !== undefined) {
|
879
|
+
$(data.fake_input).autocomplete(settings.autocomplete_url, settings.autocomplete);
|
880
|
+
$(data.fake_input).bind('result',data,function(event,data,formatted) {
|
881
|
+
if (data) {
|
882
|
+
$('#'+id).addTag(data[0] + "",{focus:true,unique:(settings.unique)});
|
883
|
+
}
|
884
|
+
});
|
885
|
+
} else if (jQuery.ui.autocomplete !== undefined) {
|
886
|
+
$(data.fake_input).autocomplete(autocomplete_options);
|
887
|
+
$(data.fake_input).bind('autocompleteselect',data,function(event,ui) {
|
888
|
+
$(event.data.real_input).addTag(ui.item.value,{focus:true,unique:(settings.unique)});
|
889
|
+
return false;
|
890
|
+
});
|
891
|
+
}
|
892
|
+
|
893
|
+
|
894
|
+
} else {
|
895
|
+
// if a user tabs out of the field, create a new tag
|
896
|
+
// this is only available if autocomplete is not used.
|
897
|
+
$(data.fake_input).bind('blur',data,function(event) {
|
898
|
+
var d = $(this).attr('data-default');
|
899
|
+
if ($(event.data.fake_input).val()!='' && $(event.data.fake_input).val()!=d) {
|
900
|
+
if( (event.data.minChars <= $(event.data.fake_input).val().length) && (!event.data.maxChars || (event.data.maxChars >= $(event.data.fake_input).val().length)) )
|
901
|
+
$(event.data.real_input).addTag($(event.data.fake_input).val(),{focus:true,unique:(settings.unique)});
|
902
|
+
} else {
|
903
|
+
$(event.data.fake_input).val($(event.data.fake_input).attr('data-default'));
|
904
|
+
$(event.data.fake_input).css('color',settings.placeholderColor);
|
905
|
+
}
|
906
|
+
return false;
|
907
|
+
});
|
908
|
+
|
909
|
+
}
|
910
|
+
// if user types a comma, create a new tag
|
911
|
+
$(data.fake_input).bind('keypress',data,function(event) {
|
912
|
+
if (event.which==event.data.delimiter.charCodeAt(0) || event.which==13 ) {
|
913
|
+
event.preventDefault();
|
914
|
+
if( (event.data.minChars <= $(event.data.fake_input).val().length) && (!event.data.maxChars || (event.data.maxChars >= $(event.data.fake_input).val().length)) )
|
915
|
+
$(event.data.real_input).addTag($(event.data.fake_input).val(),{focus:true,unique:(settings.unique)});
|
916
|
+
$(event.data.fake_input).resetAutosize(settings);
|
917
|
+
return false;
|
918
|
+
} else if (event.data.autosize) {
|
919
|
+
$(event.data.fake_input).doAutosize(settings);
|
920
|
+
|
921
|
+
}
|
922
|
+
});
|
923
|
+
//Delete last tag on backspace
|
924
|
+
data.removeWithBackspace && $(data.fake_input).bind('keydown', function(event)
|
925
|
+
{
|
926
|
+
if(event.keyCode == 8 && $(this).val() == '')
|
927
|
+
{
|
928
|
+
event.preventDefault();
|
929
|
+
var last_tag = $(this).closest('.tagsinput').find('.tag:last').text();
|
930
|
+
var id = $(this).attr('id').replace(/_tag$/, '');
|
931
|
+
last_tag = last_tag.replace(/[\s]+x$/, '');
|
932
|
+
$('#' + id).removeTag(escape(last_tag));
|
933
|
+
$(this).trigger('focus');
|
934
|
+
}
|
935
|
+
});
|
936
|
+
$(data.fake_input).blur();
|
937
|
+
|
938
|
+
//Removes the not_valid class when user changes the value of the fake input
|
939
|
+
if(data.unique) {
|
940
|
+
$(data.fake_input).keydown(function(event){
|
941
|
+
if(event.keyCode == 8 || String.fromCharCode(event.which).match(/\w+|[áéíóúÁÉÍÓÚñÑ,/]+/)) {
|
942
|
+
$(this).removeClass('not_valid');
|
943
|
+
}
|
944
|
+
});
|
945
|
+
}
|
946
|
+
} // if settings.interactive
|
947
|
+
return false;
|
948
|
+
});
|
949
|
+
|
950
|
+
return this;
|
951
|
+
|
952
|
+
};
|
953
|
+
|
954
|
+
$.fn.tagsInput.updateTagsField = function(obj,tagslist) {
|
955
|
+
var id = $(obj).attr('id');
|
956
|
+
$(obj).val(tagslist.join(delimiter[id]));
|
957
|
+
};
|
958
|
+
|
959
|
+
$.fn.tagsInput.importTags = function(obj,val) {
|
960
|
+
$(obj).val('');
|
961
|
+
var id = $(obj).attr('id');
|
962
|
+
var tags = val.split(delimiter[id]);
|
963
|
+
for (i=0; i<tags.length; i++) {
|
964
|
+
$(obj).addTag(tags[i],{focus:false,callback:false});
|
965
|
+
}
|
966
|
+
if(tags_callbacks[id] && tags_callbacks[id]['onChange'])
|
967
|
+
{
|
968
|
+
var f = tags_callbacks[id]['onChange'];
|
969
|
+
f.call(obj, obj, tags[i]);
|
970
|
+
}
|
971
|
+
};
|
972
|
+
|
973
|
+
})(jQuery);
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* jQuery UI Autocomplete 1.8.17
|
3
|
+
*
|
4
|
+
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
5
|
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
6
|
+
* http://jquery.org/license
|
7
|
+
*
|
8
|
+
* http://docs.jquery.com/UI/Autocomplete
|
9
|
+
*
|
10
|
+
* Depends:
|
11
|
+
* jquery.ui.core.js
|
12
|
+
* jquery.ui.widget.js
|
13
|
+
* jquery.ui.position.js
|
14
|
+
*/(function(a,b){var c=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var b=this,c=this.element[0].ownerDocument,d;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!b.options.disabled&&!b.element.propAttr("readOnly")){d=!1;var e=a.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:b._move("previousPage",c);break;case e.PAGE_DOWN:b._move("nextPage",c);break;case e.UP:b._move("previous",c),c.preventDefault();break;case e.DOWN:b._move("next",c),c.preventDefault();break;case e.ENTER:case e.NUMPAD_ENTER:b.menu.active&&(d=!0,c.preventDefault());case e.TAB:if(!b.menu.active)return;b.menu.select(c);break;case e.ESCAPE:b.element.val(b.term),b.close(c);break;default:clearTimeout(b.searching),b.searching=setTimeout(function(){b.term!=b.element.val()&&(b.selectedItem=null,b.search(null,c))},b.options.delay)}}}).bind("keypress.autocomplete",function(a){d&&(d=!1,a.preventDefault())}).bind("focus.autocomplete",function(){b.options.disabled||(b.selectedItem=null,b.previous=b.element.val())}).bind("blur.autocomplete",function(a){b.options.disabled||(clearTimeout(b.searching),b.closing=setTimeout(function(){b.close(a),b._change(a)},150))}),this._initSource(),this.response=function(){return b._response.apply(b,arguments)},this.menu=a("<ul></ul>").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",c)[0]).mousedown(function(c){var d=b.menu.element[0];a(c.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(c){c.target!==b.element[0]&&c.target!==d&&!a.ui.contains(d,c.target)&&b.close()})},1),setTimeout(function(){clearTimeout(b.closing)},13)}).menu({focus:function(a,c){var d=c.item.data("item.autocomplete");!1!==b._trigger("focus",a,{item:d})&&/^key/.test(a.originalEvent.type)&&b.element.val(d.value)},selected:function(a,d){var e=d.item.data("item.autocomplete"),f=b.previous;b.element[0]!==c.activeElement&&(b.element.focus(),b.previous=f,setTimeout(function(){b.previous=f,b.selectedItem=e},1)),!1!==b._trigger("select",a,{item:e})&&b.element.val(e.value),b.term=b.element.val(),b.close(a),b.selectedItem=e},blur:function(a,c){b.menu.element.is(":visible")&&b.element.val()!==b.term&&b.element.val(b.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"),a.fn.bgiframe&&this.menu.element.bgiframe(),b.beforeunloadHandler=function(){b.element.removeAttr("autocomplete")},a(window).bind("beforeunload",b.beforeunloadHandler)},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"),this.menu.element.remove(),a(window).unbind("beforeunload",this.beforeunloadHandler),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b==="source"&&this._initSource(),b==="appendTo"&&this.menu.element.appendTo(a(c||"body",this.element[0].ownerDocument)[0]),b==="disabled"&&c&&this.xhr&&this.xhr.abort()},_initSource:function(){var b=this,d,e;a.isArray(this.options.source)?(d=this.options.source,this.source=function(b,c){c(a.ui.autocomplete.filter(d,b.term))}):typeof this.options.source=="string"?(e=this.options.source,this.source=function(d,f){b.xhr&&b.xhr.abort(),b.xhr=a.ajax({url:e,data:d,dataType:"json",autocompleteRequest:++c,success:function(a,b){this.autocompleteRequest===c&&f(a)},error:function(){this.autocompleteRequest===c&&f([])}})}):this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val(),this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==!1)return this._search(a)},_search:function(a){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.source({term:a},this.response)},_response:function(a){!this.options.disabled&&a&&a.length?(a=this._normalize(a),this._suggest(a),this._trigger("open")):this.close(),this.pending--,this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.deactivate(),this._trigger("close",a))},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(b){if(b.length&&b[0].label&&b[0].value)return b;return a.map(b,function(b){if(typeof b=="string")return{label:b,value:b};return a.extend({label:b.label||b.value,value:b.value||b.label},b)})},_suggest:function(b){var c=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(c,b),this.menu.deactivate(),this.menu.refresh(),c.show(),this._resizeMenu(),c.position(a.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(new a.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(b,c){var d=this;a.each(c,function(a,c){d._renderItem(b,c)})},_renderItem:function(b,c){return a("<li></li>").data("item.autocomplete",c).append(a("<a></a>").text(c.label)).appendTo(b)},_move:function(a,b){if(!this.menu.element.is(":visible"))this.search(null,b);else{if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term),this.menu.deactivate();return}this.menu[a](b)}},widget:function(){return this.menu.element}}),a.extend(a.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(b,c){var d=new RegExp(a.ui.autocomplete.escapeRegex(c),"i");return a.grep(b,function(a){return d.test(a.label||a.value||a)})}})})(jQuery),function(a){a.widget("ui.menu",{_create:function(){var b=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){!a(c.target).closest(".ui-menu-item a").length||(c.preventDefault(),b.select(c))}),this.refresh()},refresh:function(){var b=this,c=this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem");c.children("a").addClass("ui-corner-all").attr("tabindex",-1).mouseenter(function(c){b.activate(c,a(this).parent())}).mouseleave(function(){b.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var c=b.offset().top-this.element.offset().top,d=this.element.scrollTop(),e=this.element.height();c<0?this.element.scrollTop(d+c):c>=e&&this.element.scrollTop(d+c-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end(),this._trigger("focus",a,{item:b})},deactivate:function(){!this.active||(this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null)},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,c){if(!this.active)this.activate(c,this.element.children(b));else{var d=this.active[a+"All"](".ui-menu-item").eq(0);d.length?this.activate(c,d):this.activate(c,this.element.children(b))}},nextPage:function(b){if(this.hasScroll()){if(!this.active||this.last()){this.activate(b,this.element.children(".ui-menu-item:first"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c-d+a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:last")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(b){if(this.hasScroll()){if(!this.active||this.first()){this.activate(b,this.element.children(".ui-menu-item:last"));return}var c=this.active.offset().top,d=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c+d-a(this).height();return b<10&&b>-10}),result.length||(result=this.element.children(".ui-menu-item:first")),this.activate(b,result)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[a.fn.prop?"prop":"attr"]("scrollHeight")},select:function(a){this._trigger("selected",a,{item:this.active})}})}(jQuery);
|
15
|
+
(function(a){var b=new Array;var c=new Array;a.fn.doAutosize=function(b){var c=a(this).data("minwidth"),d=a(this).data("maxwidth"),e="",f=a(this),g=a("#"+a(this).data("tester_id"));if(e===(e=f.val())){return}var h=e.replace(/&/g,"&").replace(/\s/g," ").replace(/</g,"<").replace(/>/g,">");g.html(h);var i=g.width(),j=i+b.comfortZone>=c?i+b.comfortZone:c,k=f.width(),l=j<k&&j>=c||j>c&&j<d;if(l){f.width(j)}};a.fn.resetAutosize=function(b){var c=a(this).data("minwidth")||b.minInputWidth||a(this).width(),d=a(this).data("maxwidth")||b.maxInputWidth||a(this).closest(".tagsinput").width()-b.inputPadding,e="",f=a(this),g=a("<tester/>").css({position:"absolute",top:-9999,left:-9999,width:"auto",fontSize:f.css("fontSize"),fontFamily:f.css("fontFamily"),fontWeight:f.css("fontWeight"),letterSpacing:f.css("letterSpacing"),whiteSpace:"nowrap"}),h=a(this).attr("id")+"_autosize_tester";if(!a("#"+h).length>0){g.attr("id",h);g.appendTo("body")}f.data("minwidth",c);f.data("maxwidth",d);f.data("tester_id",h);f.css("width",c)};a.fn.addTag=function(d,e){e=jQuery.extend({focus:false,callback:true},e);this.each(function(){var f=a(this).attr("id");var g=a(this).val().split(b[f]);if(g[0]==""){g=new Array}d=jQuery.trim(d);if(e.unique){var h=a(g).tagExist(d);if(h==true){a("#"+f+"_tag").addClass("not_valid")}}else{var h=false}if(d!=""&&h!=true){a("<span>").addClass("tag").append(a("<span>").text(d).append(" "),a("<a>",{href:"#",title:"Removing tag",text:"x"}).click(function(){return a("#"+f).removeTag(escape(d))})).insertBefore("#"+f+"_addTag");g.push(d);a("#"+f+"_tag").val("");if(e.focus){a("#"+f+"_tag").focus()}else{a("#"+f+"_tag").blur()}a.fn.tagsInput.updateTagsField(this,g);if(e.callback&&c[f]&&c[f]["onAddTag"]){var i=c[f]["onAddTag"];i.call(this,d)}if(c[f]&&c[f]["onChange"]){var j=g.length;var i=c[f]["onChange"];i.call(this,a(this),g[j-1])}}});return false};a.fn.removeTag=function(d){d=unescape(d);this.each(function(){var e=a(this).attr("id");var f=a(this).val().split(b[e]);a("#"+e+"_tagsinput .tag").remove();str="";for(i=0;i<f.length;i++){if(f[i]!=d){str=str+b[e]+f[i]}}a.fn.tagsInput.importTags(this,str);if(c[e]&&c[e]["onRemoveTag"]){var g=c[e]["onRemoveTag"];g.call(this,d)}});return false};a.fn.tagExist=function(b){return jQuery.inArray(b,a(this))>=0};a.fn.importTags=function(b){id=a(this).attr("id");a("#"+id+"_tagsinput .tag").remove();a.fn.tagsInput.importTags(this,b)};a.fn.tagsInput=function(d){var e=jQuery.extend({interactive:true,defaultText:"add a tag",minChars:0,width:"300px",height:"100px",autocomplete:{selectFirst:false},hide:true,delimiter:",",unique:true,removeWithBackspace:true,placeholderColor:"#666666",autosize:true,comfortZone:20,inputPadding:6*2},d);this.each(function(){if(e.hide){a(this).hide()}var d=a(this).attr("id");var f=jQuery.extend({pid:d,real_input:"#"+d,holder:"#"+d+"_tagsinput",input_wrapper:"#"+d+"_addTag",fake_input:"#"+d+"_tag"},e);b[d]=f.delimiter;if(e.onAddTag||e.onRemoveTag||e.onChange){c[d]=new Array;c[d]["onAddTag"]=e.onAddTag;c[d]["onRemoveTag"]=e.onRemoveTag;c[d]["onChange"]=e.onChange}var g='<div id="'+d+'_tagsinput" class="tagsinput"><div id="'+d+'_addTag">';if(e.interactive){g=g+'<input id="'+d+'_tag" value="" data-default="'+e.defaultText+'" />'}g=g+'</div><div class="tags_clear"></div></div>';a(g).insertAfter(this);a(f.holder).css("width",e.width);a(f.holder).css("height",e.height);if(a(f.real_input).val()!=""){a.fn.tagsInput.importTags(a(f.real_input),a(f.real_input).val())}if(e.interactive){a(f.fake_input).val(a(f.fake_input).attr("data-default"));a(f.fake_input).css("color",e.placeholderColor);a(f.fake_input).resetAutosize(e);a(f.holder).bind("click",f,function(b){a(b.data.fake_input).focus()});a(f.fake_input).bind("focus",f,function(b){if(a(b.data.fake_input).val()==a(b.data.fake_input).attr("data-default")){a(b.data.fake_input).val("")}a(b.data.fake_input).css("color","#000000")});if(e.autocomplete_url!=undefined){autocomplete_options={source:e.autocomplete_url};for(attrname in e.autocomplete){autocomplete_options[attrname]=e.autocomplete[attrname]}if(jQuery.Autocompleter!==undefined){a(f.fake_input).autocomplete(e.autocomplete_url,e.autocomplete);a(f.fake_input).bind("result",f,function(b,c,f){if(c){a("#"+d).addTag(c[0]+"",{focus:true,unique:e.unique})}})}else if(jQuery.ui.autocomplete!==undefined){a(f.fake_input).autocomplete(autocomplete_options);a(f.fake_input).bind("autocompleteselect",f,function(b,c){a(b.data.real_input).addTag(c.item.value,{focus:true,unique:e.unique});return false})}}else{a(f.fake_input).bind("blur",f,function(b){var c=a(this).attr("data-default");if(a(b.data.fake_input).val()!=""&&a(b.data.fake_input).val()!=c){if(b.data.minChars<=a(b.data.fake_input).val().length&&(!b.data.maxChars||b.data.maxChars>=a(b.data.fake_input).val().length))a(b.data.real_input).addTag(a(b.data.fake_input).val(),{focus:true,unique:e.unique})}else{a(b.data.fake_input).val(a(b.data.fake_input).attr("data-default"));a(b.data.fake_input).css("color",e.placeholderColor)}return false})}a(f.fake_input).bind("keypress",f,function(b){if(b.which==b.data.delimiter.charCodeAt(0)||b.which==13){b.preventDefault();if(b.data.minChars<=a(b.data.fake_input).val().length&&(!b.data.maxChars||b.data.maxChars>=a(b.data.fake_input).val().length))a(b.data.real_input).addTag(a(b.data.fake_input).val(),{focus:true,unique:e.unique});a(b.data.fake_input).resetAutosize(e);return false}else if(b.data.autosize){a(b.data.fake_input).doAutosize(e)}});f.removeWithBackspace&&a(f.fake_input).bind("keydown",function(b){if(b.keyCode==8&&a(this).val()==""){b.preventDefault();var c=a(this).closest(".tagsinput").find(".tag:last").text();var d=a(this).attr("id").replace(/_tag$/,"");c=c.replace(/[\s]+x$/,"");a("#"+d).removeTag(escape(c));a(this).trigger("focus")}});a(f.fake_input).blur();if(f.unique){a(f.fake_input).keydown(function(b){if(b.keyCode==8||String.fromCharCode(b.which).match(/\w+|[áéíóúÁÉÍÓÚñÑ,/]+/)){a(this).removeClass("not_valid")}})}}return false});return this};a.fn.tagsInput.updateTagsField=function(c,d){var e=a(c).attr("id");a(c).val(d.join(b[e]))};a.fn.tagsInput.importTags=function(d,e){a(d).val("");var f=a(d).attr("id");var g=e.split(b[f]);for(i=0;i<g.length;i++){a(d).addTag(g[i],{focus:false,callback:false})}if(c[f]&&c[f]["onChange"]){var h=c[f]["onChange"];h.call(d,d,g[i])}}})(jQuery);
|
@@ -0,0 +1,63 @@
|
|
1
|
+
div.tagsinput { border:1px solid #CCC; background: #FFF; padding:5px; width:300px; height:100px; overflow-y: auto;}
|
2
|
+
div.tagsinput span.tag { border: 1px solid #1C89C7; -moz-border-radius:2px; -webkit-border-radius:2px; display: block; float: left; padding: 5px; text-decoration:none; background: #22a7f2; color: #fff; margin-right: 5px; margin-bottom:5px;font-family: helvetica; font-size:13px;}
|
3
|
+
div.tagsinput span.tag span { color: #fff; }
|
4
|
+
div.tagsinput span.tag a { font-weight: bold; color: #fff; text-decoration:none; font-size: 11px; }
|
5
|
+
div.tagsinput input { width:80px; margin:0px; font-family: helvetica; font-size: 13px; border:1px solid transparent; padding:5px; background: transparent; color: #000; outline:0px; margin-right:5px; margin-bottom:5px; }
|
6
|
+
div.tagsinput div { display:block; float: left; }
|
7
|
+
.tags_clear { clear: both; width: 100%; height: 0px; }
|
8
|
+
.not_valid {background: #FBD8DB !important; color: #90111A !important;}
|
9
|
+
#content div.tagsinput span.tag a { border-bottom: none; }
|
10
|
+
/*
|
11
|
+
* jQuery UI Menu 1.8.17
|
12
|
+
*
|
13
|
+
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
14
|
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
15
|
+
* http://jquery.org/license
|
16
|
+
*
|
17
|
+
* http://docs.jquery.com/UI/Menu#theming
|
18
|
+
*/
|
19
|
+
.ui-menu {
|
20
|
+
list-style:none;
|
21
|
+
padding: 2px;
|
22
|
+
margin: 0;
|
23
|
+
display:block;
|
24
|
+
float: left;
|
25
|
+
}
|
26
|
+
.ui-menu .ui-menu {
|
27
|
+
margin-top: -3px;
|
28
|
+
}
|
29
|
+
.ui-menu .ui-menu-item {
|
30
|
+
margin:0;
|
31
|
+
padding: 0;
|
32
|
+
zoom: 1;
|
33
|
+
float: left;
|
34
|
+
clear: left;
|
35
|
+
width: 100%;
|
36
|
+
}
|
37
|
+
.ui-menu .ui-menu-item a {
|
38
|
+
text-decoration:none;
|
39
|
+
display:block;
|
40
|
+
padding:.2em .4em;
|
41
|
+
line-height:1.5;
|
42
|
+
zoom:1;
|
43
|
+
}
|
44
|
+
.ui-menu .ui-menu-item a.ui-state-hover,
|
45
|
+
.ui-menu .ui-menu-item a.ui-state-active {
|
46
|
+
font-weight: normal;
|
47
|
+
margin: -1px;
|
48
|
+
}
|
49
|
+
/*
|
50
|
+
* jQuery UI Autocomplete 1.8.17
|
51
|
+
*
|
52
|
+
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
53
|
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
54
|
+
* http://jquery.org/license
|
55
|
+
*
|
56
|
+
* http://docs.jquery.com/UI/Autocomplete#theming
|
57
|
+
*/
|
58
|
+
.ui-autocomplete { position: absolute; cursor: default; border: 1px solid #aaaaaa; background: #ffffff; color: #222222; }
|
59
|
+
.ui-autocomplete a { color: #222222; }
|
60
|
+
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #22a7f2 url(/images/refinery/ui-bg_glass_75_22a7f2_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
|
61
|
+
|
62
|
+
/* workarounds */
|
63
|
+
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: refinerycms-tags
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 1
|
10
|
+
version: 1.0.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Sergio Cambra
|
@@ -42,22 +42,19 @@ extensions: []
|
|
42
42
|
extra_rdoc_files: []
|
43
43
|
|
44
44
|
files:
|
45
|
-
-
|
46
|
-
-
|
47
|
-
- lib/tasks/tags.rake
|
48
|
-
- lib/refinerycms-tags.rb~
|
45
|
+
- app/controllers/admin/tags_controller.rb
|
46
|
+
- app/views/shared/admin/_tag_editor.html.erb
|
49
47
|
- config/locales/en.yml
|
50
|
-
- config/locales/en.yml~
|
51
|
-
- config/locales/lolcat.yml
|
52
48
|
- config/locales/es.yml
|
53
|
-
- config/locales/lolcat.yml
|
54
|
-
- config/locales/es.yml~
|
49
|
+
- config/locales/lolcat.yml
|
55
50
|
- config/routes.rb
|
56
|
-
-
|
57
|
-
-
|
58
|
-
-
|
59
|
-
-
|
60
|
-
-
|
51
|
+
- lib/generators/refinerycms_tags_generator.rb
|
52
|
+
- lib/refinerycms-tags.rb
|
53
|
+
- lib/tasks/tags.rake
|
54
|
+
- public/images/refinery/ui-bg_glass_75_22a7f2_1x400.png
|
55
|
+
- public/javascripts/jquery.tagsinput.js
|
56
|
+
- public/javascripts/jquery.tagsinput.min.js
|
57
|
+
- public/stylesheets/jquery.tagsinput.css
|
61
58
|
homepage: http://github.com/scambra/refinerycms-tags
|
62
59
|
licenses: []
|
63
60
|
|
@@ -1,16 +0,0 @@
|
|
1
|
-
<span class="label_with_help">
|
2
|
-
<%= f.label field -%>
|
3
|
-
<%= refinery_help_tag t('.tag_help') %>
|
4
|
-
</span>
|
5
|
-
<%= f.text_area field %>
|
6
|
-
<%
|
7
|
-
unless @tag_editor_included
|
8
|
-
@tag_editor_included = true
|
9
|
-
content_for :after_javascript_libraries, javascript_include_tag("jquery.tagsinput#{'.min' unless Rails.env.development?}.js")
|
10
|
-
content_for :stylesheets, stylesheet_link_tag('jquery.tagsinput.css')
|
11
|
-
end
|
12
|
-
debugger
|
13
|
-
autocomplete_url ||= admin_tags_path if autocomplete
|
14
|
-
default_text ||= '.default_text'
|
15
|
-
content_for :javascripts, javascript_tag("$(document).ready(function() { $('##{f.object_name}_#{field}').tagsInput({defaultText: '#{t default_text}'#{', autocomplete_url: ' + autocomplete_url.to_json if autocomplete}}); })")
|
16
|
-
%>
|
data/config/locales/en.yml~
DELETED
data/config/locales/es.yml~
DELETED
data/config/locales/lolcat.yml~
DELETED
data/config/routes.rb~
DELETED
data/lib/refinerycms-tags.rb~
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'refinerycms-base'
|
2
|
-
|
3
|
-
module Refinery
|
4
|
-
module Tags
|
5
|
-
|
6
|
-
class << self
|
7
|
-
attr_accessor :root
|
8
|
-
def root
|
9
|
-
@root ||= Pathname.new(File.expand_path('../../', __FILE__))
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
class Engine < Rails::Engine
|
14
|
-
initializer "static assets" do |app|
|
15
|
-
app.middleware.insert_after ::ActionDispatch::Static, ::ActionDispatch::Static, "#{root}/public"
|
16
|
-
end
|
17
|
-
|
18
|
-
config.after_initialize do
|
19
|
-
Refinery::Plugin.register do |plugin|
|
20
|
-
plugin.name = "tags"
|
21
|
-
plugin.pathname = root
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|