angularstrap-rails 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +41 -0
- data/Rakefile +1 -0
- data/angularstrap-rails.gemspec +15 -0
- data/lib/angularstrap-rails.rb +8 -0
- data/lib/angularstrap-rails/version.rb +5 -0
- data/vendor/assets/javascripts/angular-strap.js +975 -0
- data/vendor/assets/javascripts/angular-strap/bootstrap-datepicker.js +1046 -0
- data/vendor/assets/javascripts/angular-strap/bootstrap-select.js +457 -0
- data/vendor/assets/javascripts/angular-strap/bootstrap-timepicker.js +888 -0
- data/vendor/assets/stylesheets/angular-strap/bootstrap-datepicker.css +301 -0
- data/vendor/assets/stylesheets/angular-strap/bootstrap-select.css +160 -0
- data/vendor/assets/stylesheets/angular-strap/bootstrap-timepicker.css +121 -0
- metadata +61 -0
@@ -0,0 +1,457 @@
|
|
1
|
+
!function($) {
|
2
|
+
var Selectpicker = function(element, options, e) {
|
3
|
+
if (e ) {
|
4
|
+
e.stopPropagation();
|
5
|
+
e.preventDefault();
|
6
|
+
}
|
7
|
+
this.$element = $(element);
|
8
|
+
this.$newElement = null;
|
9
|
+
this.button = null;
|
10
|
+
|
11
|
+
//Merge defaults, options and data-attributes to make our options
|
12
|
+
this.options = $.extend({}, $.fn.selectpicker.defaults, this.$element.data(), typeof options == 'object' && options);
|
13
|
+
|
14
|
+
//If we have no title yet, check the attribute 'title' (this is missed by jq as its not a data-attribute
|
15
|
+
if(this.options.title==null)
|
16
|
+
this.options.title = this.$element.attr('title');
|
17
|
+
|
18
|
+
//Expose public methods
|
19
|
+
this.val = Selectpicker.prototype.val;
|
20
|
+
this.render = Selectpicker.prototype.render;
|
21
|
+
this.refresh = Selectpicker.prototype.refresh;
|
22
|
+
this.selectAll = Selectpicker.prototype.selectAll;
|
23
|
+
this.deselectAll = Selectpicker.prototype.deselectAll;
|
24
|
+
this.init();
|
25
|
+
};
|
26
|
+
|
27
|
+
Selectpicker.prototype = {
|
28
|
+
|
29
|
+
constructor: Selectpicker,
|
30
|
+
|
31
|
+
init: function (e) {
|
32
|
+
if (!this.options.container) {
|
33
|
+
this.$element.hide();
|
34
|
+
} else {
|
35
|
+
this.$element.css('visibility','hidden');
|
36
|
+
};
|
37
|
+
this.multiple = this.$element.prop('multiple');
|
38
|
+
var classList = this.$element.attr('class') !== undefined ? this.$element.attr('class').split(/\s+/) : '';
|
39
|
+
var id = this.$element.attr('id');
|
40
|
+
this.$element.after( this.createView() );
|
41
|
+
this.$newElement = this.$element.next('.bootstrap-select');
|
42
|
+
if (this.options.container) {
|
43
|
+
this.selectPosition();
|
44
|
+
}
|
45
|
+
this.button = this.$newElement.find('> button');
|
46
|
+
if (id !== undefined) {
|
47
|
+
this.button.attr('id', id);
|
48
|
+
$('label[for="' + id + '"]').click( $.proxy(this, function(){ this.$newElement.find('button#'+id).focus(); }))
|
49
|
+
}
|
50
|
+
for (var i = 0; i < classList.length; i++) {
|
51
|
+
if(classList[i] != 'selectpicker') {
|
52
|
+
this.$newElement.addClass(classList[i]);
|
53
|
+
}
|
54
|
+
}
|
55
|
+
//If we are multiple, then add the show-tick class by default
|
56
|
+
if(this.multiple) {
|
57
|
+
this.$newElement.addClass('show-tick');
|
58
|
+
}
|
59
|
+
this.button.addClass(this.options.style);
|
60
|
+
this.checkDisabled();
|
61
|
+
this.checkTabIndex();
|
62
|
+
this.clickListener();
|
63
|
+
|
64
|
+
//Listen for updates to the DOM and re render...
|
65
|
+
this.$element.bind('DOMNodeInserted DOMNodeRemoved', $.proxy(this.refresh, this));
|
66
|
+
|
67
|
+
this.render();
|
68
|
+
this.setSize();
|
69
|
+
},
|
70
|
+
|
71
|
+
createDropdown: function() {
|
72
|
+
var drop =
|
73
|
+
"<div class='btn-group bootstrap-select'>" +
|
74
|
+
"<button class='btn dropdown-toggle clearfix' data-toggle='dropdown'>" +
|
75
|
+
"<span class='filter-option pull-left'></span> " +
|
76
|
+
"<span class='caret'></span>" +
|
77
|
+
"</button>" +
|
78
|
+
"<ul class='dropdown-menu' role='menu'>" +
|
79
|
+
"</ul>" +
|
80
|
+
"</div>";
|
81
|
+
|
82
|
+
return $(drop);
|
83
|
+
},
|
84
|
+
|
85
|
+
|
86
|
+
createView: function() {
|
87
|
+
var $drop = this.createDropdown();
|
88
|
+
var $li = this.createLi();
|
89
|
+
$drop.find('ul').append($li);
|
90
|
+
return $drop;
|
91
|
+
},
|
92
|
+
|
93
|
+
reloadLi: function() {
|
94
|
+
//Remove all children.
|
95
|
+
this.destroyLi();
|
96
|
+
//Re build
|
97
|
+
$li = this.createLi();
|
98
|
+
this.$newElement.find('ul').append( $li );
|
99
|
+
},
|
100
|
+
|
101
|
+
destroyLi:function() {
|
102
|
+
this.$newElement.find('li').remove();
|
103
|
+
},
|
104
|
+
|
105
|
+
createLi: function() {
|
106
|
+
|
107
|
+
var _this = this;
|
108
|
+
var _li = [];
|
109
|
+
var _liA = [];
|
110
|
+
var _liHtml = '';
|
111
|
+
|
112
|
+
this.$element.find('option').each(function(){
|
113
|
+
_li.push($(this).text());
|
114
|
+
});
|
115
|
+
|
116
|
+
this.$element.find('option').each(function(index) {
|
117
|
+
//Get the class and text for the option
|
118
|
+
var optionClass = $(this).attr("class") !== undefined ? $(this).attr("class") : '';
|
119
|
+
var text = $(this).text();
|
120
|
+
var subtext = $(this).data('subtext') !== undefined ? '<small class="muted">'+$(this).data('subtext')+'</small>' : '';
|
121
|
+
|
122
|
+
//Append any subtext to the main text.
|
123
|
+
text+=subtext;
|
124
|
+
|
125
|
+
if ($(this).parent().is('optgroup') && $(this).data('divider') != true) {
|
126
|
+
if ($(this).index() == 0) {
|
127
|
+
//Get the opt group label
|
128
|
+
var label = $(this).parent().attr('label');
|
129
|
+
var labelSubtext = $(this).parent().data('subtext') !== undefined ? '<small class="muted">'+$(this).parent().data('subtext')+'</small>' : '';
|
130
|
+
label += labelSubtext;
|
131
|
+
|
132
|
+
if ($(this)[0].index != 0) {
|
133
|
+
_liA.push(
|
134
|
+
'<div class="div-contain"><div class="divider"></div></div>'+
|
135
|
+
'<dt>'+label+'</dt>'+
|
136
|
+
_this.createA(text, "opt " + optionClass )
|
137
|
+
);
|
138
|
+
} else {
|
139
|
+
_liA.push(
|
140
|
+
'<dt>'+label+'</dt>'+
|
141
|
+
_this.createA(text, "opt " + optionClass ));
|
142
|
+
}
|
143
|
+
} else {
|
144
|
+
_liA.push( _this.createA(text, "opt " + optionClass ) );
|
145
|
+
}
|
146
|
+
} else if ($(this).data('divider') == true) {
|
147
|
+
_liA.push('<div class="div-contain"><div class="divider"></div></div>');
|
148
|
+
} else {
|
149
|
+
_liA.push( _this.createA(text, optionClass ) );
|
150
|
+
}
|
151
|
+
});
|
152
|
+
|
153
|
+
if (_li.length > 0) {
|
154
|
+
for (var i = 0; i < _li.length; i++) {
|
155
|
+
var $option = this.$element.find('option').eq(i);
|
156
|
+
_liHtml += "<li rel=" + i + ">" + _liA[i] + "</li>";
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
160
|
+
//If we dont have a selected item, and we dont have a title, select the first element so something is set in the button
|
161
|
+
if(this.$element.find('option:selected').length==0 && !_this.options.title) {
|
162
|
+
this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');
|
163
|
+
}
|
164
|
+
|
165
|
+
return $(_liHtml);
|
166
|
+
},
|
167
|
+
|
168
|
+
createA:function(test, classes) {
|
169
|
+
return '<a tabindex="-1" href="#" class="'+classes+'">' +
|
170
|
+
'<span class="pull-left">' + test + '</span>' +
|
171
|
+
'<i class="icon-ok check-mark"></i>' +
|
172
|
+
'</a>';
|
173
|
+
|
174
|
+
},
|
175
|
+
|
176
|
+
render:function() {
|
177
|
+
var _this = this;
|
178
|
+
|
179
|
+
//Update the LI to match the SELECT
|
180
|
+
this.$element.find('option').each(function(index) {
|
181
|
+
_this.setDisabled(index, $(this).is(':disabled') || $(this).parent().is(':disabled') );
|
182
|
+
_this.setSelected(index, $(this).is(':selected') );
|
183
|
+
});
|
184
|
+
|
185
|
+
var selectedItems = this.$element.find('option:selected').map(function(index,value) {
|
186
|
+
if($(this).attr('title')!=undefined) {
|
187
|
+
return $(this).attr('title');
|
188
|
+
} else {
|
189
|
+
return $(this).text();
|
190
|
+
}
|
191
|
+
}).toArray();
|
192
|
+
|
193
|
+
//Convert all the values into a comma delimited string
|
194
|
+
var title = selectedItems.join(", ");
|
195
|
+
|
196
|
+
//If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..
|
197
|
+
if(_this.multiple && _this.options.selectedTextFormat.indexOf('count') > -1) {
|
198
|
+
var max = _this.options.selectedTextFormat.split(">");
|
199
|
+
if( (max.length>1 && selectedItems.length > max[1]) || (max.length==1 && selectedItems.length>=2)) {
|
200
|
+
title = selectedItems.length +' of ' + this.$element.find('option').length + ' selected';
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
//If we dont have a title, then use the default, or if nothing is set at all, use the not selected text
|
205
|
+
if(!title) {
|
206
|
+
title = _this.options.title != undefined ? _this.options.title : _this.options.noneSelectedText;
|
207
|
+
}
|
208
|
+
|
209
|
+
_this.$newElement.find('.filter-option').html( title );
|
210
|
+
},
|
211
|
+
|
212
|
+
setSize:function() {
|
213
|
+
var _this = this;
|
214
|
+
var menu = this.$newElement.find('.dropdown-menu');
|
215
|
+
var menuA = menu.find('li > a');
|
216
|
+
var liHeight = this.$newElement.addClass('open').find('.dropdown-menu li > a').outerHeight();
|
217
|
+
this.$newElement.removeClass('open');
|
218
|
+
var divHeight = menu.find('li .divider').outerHeight(true);
|
219
|
+
var selectOffset_top = this.$newElement.offset().top;
|
220
|
+
var selectHeight = this.$newElement.outerHeight();
|
221
|
+
var menuPadding = parseInt(menu.css('padding-top')) + parseInt(menu.css('padding-bottom')) + parseInt(menu.css('border-top-width')) + parseInt(menu.css('border-bottom-width'));
|
222
|
+
if (this.options.size == 'auto') {
|
223
|
+
function getSize() {
|
224
|
+
var selectOffset_top_scroll = selectOffset_top - $(window).scrollTop();
|
225
|
+
var windowHeight = window.innerHeight;
|
226
|
+
var menuExtras = menuPadding + parseInt(menu.css('margin-top')) + parseInt(menu.css('margin-bottom')) + 2;
|
227
|
+
var selectOffset_bot = windowHeight - selectOffset_top_scroll - selectHeight - menuExtras;
|
228
|
+
menuHeight = selectOffset_bot;
|
229
|
+
if (_this.$newElement.hasClass('dropup')) {
|
230
|
+
menuHeight = selectOffset_top_scroll - menuExtras;
|
231
|
+
}
|
232
|
+
if ((menu.find('li').length + menu.find('dt').length) > 3) {
|
233
|
+
minHeight = liHeight*3 + menuExtras - 2;
|
234
|
+
} else {
|
235
|
+
minHeight = 0;
|
236
|
+
}
|
237
|
+
menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'auto', 'min-height' : minHeight + 'px'});
|
238
|
+
}
|
239
|
+
getSize();
|
240
|
+
$(window).resize(getSize);
|
241
|
+
$(window).scroll(getSize);
|
242
|
+
} else if (this.options.size && this.options.size != 'auto' && menu.find('li').length > this.options.size) {
|
243
|
+
var optIndex = menu.find("li > *").filter(':not(.div-contain)').slice(0,this.options.size).last().parent().index();
|
244
|
+
var divLength = menu.find("li").slice(0,optIndex + 1).find('.div-contain').length;
|
245
|
+
menuHeight = liHeight*this.options.size + divLength*divHeight + menuPadding;
|
246
|
+
menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'auto'});
|
247
|
+
}
|
248
|
+
|
249
|
+
//Set width of select
|
250
|
+
if (this.options.width == 'auto') {
|
251
|
+
this.$newElement.find('.dropdown-menu').css('min-width','0');
|
252
|
+
var ulWidth = this.$newElement.find('.dropdown-menu').css('width');
|
253
|
+
this.$newElement.css('width',ulWidth);
|
254
|
+
if (this.options.container) {
|
255
|
+
this.$element.css('width',ulWidth);
|
256
|
+
}
|
257
|
+
} else if (this.options.width && this.options.width != 'auto') {
|
258
|
+
this.$newElement.css('width',this.options.width);
|
259
|
+
if (this.options.container) {
|
260
|
+
this.$element.css('width',this.options.width);
|
261
|
+
}
|
262
|
+
}
|
263
|
+
},
|
264
|
+
|
265
|
+
selectPosition:function() {
|
266
|
+
var selectElementTop = this.$element.offset().top;
|
267
|
+
var selectElementLeft = this.$element.offset().left;
|
268
|
+
this.$newElement.appendTo(this.options.container);
|
269
|
+
this.$newElement.css({'position':'absolute', 'top':selectElementTop+'px', 'left':selectElementLeft+'px'});
|
270
|
+
},
|
271
|
+
|
272
|
+
refresh:function() {
|
273
|
+
this.reloadLi();
|
274
|
+
this.render();
|
275
|
+
this.setSize();
|
276
|
+
this.checkDisabled();
|
277
|
+
if (this.options.container) {
|
278
|
+
this.selectPosition();
|
279
|
+
}
|
280
|
+
},
|
281
|
+
|
282
|
+
setSelected:function(index, selected) {
|
283
|
+
if(selected) {
|
284
|
+
this.$newElement.find('li').eq(index).addClass('selected');
|
285
|
+
} else {
|
286
|
+
this.$newElement.find('li').eq(index).removeClass('selected');
|
287
|
+
}
|
288
|
+
},
|
289
|
+
|
290
|
+
setDisabled:function(index, disabled) {
|
291
|
+
if(disabled) {
|
292
|
+
this.$newElement.find('li').eq(index).addClass('disabled');
|
293
|
+
} else {
|
294
|
+
this.$newElement.find('li').eq(index).removeClass('disabled');
|
295
|
+
}
|
296
|
+
},
|
297
|
+
|
298
|
+
checkDisabled: function() {
|
299
|
+
if (this.$element.is(':disabled')) {
|
300
|
+
this.button.addClass('disabled');
|
301
|
+
this.button.click(function(e) {
|
302
|
+
e.preventDefault();
|
303
|
+
});
|
304
|
+
this.button.on('focusin', function() {
|
305
|
+
$(this).blur();
|
306
|
+
});
|
307
|
+
} else if (!this.$element.is(':disabled') && this.button.hasClass('disabled')) {
|
308
|
+
this.button.removeClass('disabled');
|
309
|
+
this.button.click(function() {
|
310
|
+
return true;
|
311
|
+
});
|
312
|
+
}
|
313
|
+
},
|
314
|
+
|
315
|
+
checkTabIndex: function() {
|
316
|
+
if (this.$element.is('[tabindex]')) {
|
317
|
+
var tabindex = this.$element.attr("tabindex");
|
318
|
+
this.button.attr('tabindex', tabindex);
|
319
|
+
}
|
320
|
+
},
|
321
|
+
|
322
|
+
clickListener: function() {
|
323
|
+
var _this = this;
|
324
|
+
|
325
|
+
$('body').on('touchstart.dropdown', '.dropdown-menu', function (e) { e.stopPropagation(); });
|
326
|
+
|
327
|
+
this.$newElement.on('click', 'li a', function(e){
|
328
|
+
var clickedIndex = $(this).parent().index(),
|
329
|
+
$this = $(this).parent(),
|
330
|
+
$select = $this.parents('.bootstrap-select'),
|
331
|
+
prevValue = _this.$element.val();
|
332
|
+
|
333
|
+
//Dont close on multi choice menu
|
334
|
+
if(_this.multiple) {
|
335
|
+
e.stopPropagation();
|
336
|
+
}
|
337
|
+
|
338
|
+
e.preventDefault();
|
339
|
+
|
340
|
+
//Dont run if we have been disabled
|
341
|
+
if (_this.$element.not(':disabled') && !$(this).parent().hasClass('disabled')){
|
342
|
+
//Deselect all others if not multi select box
|
343
|
+
if (!_this.multiple) {
|
344
|
+
_this.$element.find('option').removeAttr('selected');
|
345
|
+
_this.$element.find('option').eq(clickedIndex).prop('selected', true).attr('selected', 'selected');
|
346
|
+
}
|
347
|
+
//Else toggle the one we have chosen if we are multi selet.
|
348
|
+
else {
|
349
|
+
var selected = _this.$element.find('option').eq(clickedIndex).prop('selected');
|
350
|
+
|
351
|
+
if(selected) {
|
352
|
+
_this.$element.find('option').eq(clickedIndex).removeAttr('selected');
|
353
|
+
} else {
|
354
|
+
_this.$element.find('option').eq(clickedIndex).prop('selected', true).attr('selected', 'selected');
|
355
|
+
}
|
356
|
+
}
|
357
|
+
|
358
|
+
|
359
|
+
$select.find('.filter-option').html($this.text());
|
360
|
+
$select.find('button').focus();
|
361
|
+
|
362
|
+
// Trigger select 'change'
|
363
|
+
if (prevValue != _this.$element.val()) {
|
364
|
+
_this.$element.trigger('change');
|
365
|
+
}
|
366
|
+
|
367
|
+
_this.render();
|
368
|
+
}
|
369
|
+
|
370
|
+
});
|
371
|
+
|
372
|
+
this.$newElement.on('click', 'li.disabled a, li dt, li .div-contain', function(e) {
|
373
|
+
e.preventDefault();
|
374
|
+
e.stopPropagation();
|
375
|
+
$select = $(this).parent().parents('.bootstrap-select');
|
376
|
+
$select.find('button').focus();
|
377
|
+
});
|
378
|
+
|
379
|
+
this.$element.on('change', function(e) {
|
380
|
+
_this.render();
|
381
|
+
});
|
382
|
+
},
|
383
|
+
|
384
|
+
val:function(value) {
|
385
|
+
|
386
|
+
if(value!=undefined) {
|
387
|
+
this.$element.val( value );
|
388
|
+
|
389
|
+
this.$element.trigger('change');
|
390
|
+
return this.$element;
|
391
|
+
} else {
|
392
|
+
return this.$element.val();
|
393
|
+
}
|
394
|
+
},
|
395
|
+
|
396
|
+
selectAll:function() {
|
397
|
+
this.$element.find('option').prop('selected', true).attr('selected', 'selected');
|
398
|
+
this.render();
|
399
|
+
},
|
400
|
+
|
401
|
+
deselectAll:function() {
|
402
|
+
this.$element.find('option').prop('selected', false).removeAttr('selected');
|
403
|
+
this.render();
|
404
|
+
},
|
405
|
+
|
406
|
+
};
|
407
|
+
|
408
|
+
$.fn.selectpicker = function(option, event) {
|
409
|
+
//get the args of the outer function..
|
410
|
+
var args = arguments;
|
411
|
+
var value;
|
412
|
+
var chain = this.each(function () {
|
413
|
+
if ($(this).is('select')) {
|
414
|
+
var $this = $(this),
|
415
|
+
data = $this.data('selectpicker'),
|
416
|
+
options = typeof option == 'object' && option;
|
417
|
+
|
418
|
+
if (!data) {
|
419
|
+
$this.data('selectpicker', (data = new Selectpicker(this, options, event)));
|
420
|
+
} else if(options){
|
421
|
+
for(var i in options) {
|
422
|
+
data.options[i]=options[i];
|
423
|
+
}
|
424
|
+
}
|
425
|
+
|
426
|
+
if (typeof option == 'string') {
|
427
|
+
//Copy the value of option, as once we shift the arguments
|
428
|
+
//it also shifts the value of option.
|
429
|
+
property = option;
|
430
|
+
if(data[property] instanceof Function) {
|
431
|
+
[].shift.apply(args);
|
432
|
+
value = data[property].apply(data, args);
|
433
|
+
} else {
|
434
|
+
value = data.options[property];
|
435
|
+
}
|
436
|
+
}
|
437
|
+
}
|
438
|
+
});
|
439
|
+
|
440
|
+
if(value!=undefined) {
|
441
|
+
return value;
|
442
|
+
} else {
|
443
|
+
return chain;
|
444
|
+
}
|
445
|
+
};
|
446
|
+
|
447
|
+
$.fn.selectpicker.defaults = {
|
448
|
+
style: null,
|
449
|
+
size: 'auto',
|
450
|
+
title: null,
|
451
|
+
selectedTextFormat : 'values',
|
452
|
+
noneSelectedText : 'Nothing selected',
|
453
|
+
width: null,
|
454
|
+
container: false
|
455
|
+
}
|
456
|
+
|
457
|
+
}(window.jQuery);
|