bootstrap-multiselect-rails 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3b61fad2e4a7ae7fd6ea103d630cc1541403e69c
4
- data.tar.gz: 82986b14141417ee6ec1fe9db45cd7d9179bf41c
3
+ metadata.gz: 4dc53b8cfa8b951d7216b82c1d49ff02a6ebd051
4
+ data.tar.gz: 14a6ecf99e4d4daba47e6d45a8f29ca6c996871a
5
5
  SHA512:
6
- metadata.gz: 54d6abfd1c2140f5bc5ce0b54fa7558ba8fdae414fa8947feccc558b77d14304032abddb530b68070b23b715a762e959f33613ab2cffe5790d51cdd76169f88d
7
- data.tar.gz: 55d9e736173711f2a00c812d41f99ed32d86d6d034f48611868ad024fa1e5d2ca7f8cd5ef674800dd8d82802b8e449d6b0091b39b8644adffc7a6775d3256164
6
+ metadata.gz: c1d991c834143b9a50bfcdaf8f9d8d0cd93a80a18b335db78e0c46d2d90978409e16baa72682b6237d7b0cf5b2f95ac7ff69b830e77bb62aa6f698b5598365f6
7
+ data.tar.gz: be8e2965951159e1600c85b6c16ea0bdee6db3bd2b278c1747da175d1cad8990a0744e16e7ed3aa85274f45656f16b3525b5cea2faddbeb87a8ae6195cdd3216
@@ -1,5 +1,5 @@
1
1
  module BootstrapMultiselect
2
2
  module Rails
3
- VERSION = "0.0.5"
3
+ VERSION = "0.0.6"
4
4
  end
5
5
  end
@@ -1,4 +1,4 @@
1
- require "bootstrap-multiselect/version"
1
+ require "bootstrap-multiselect/rails/version"
2
2
 
3
3
  module BootstrapMultiselect
4
4
  module Rails
@@ -7,8 +7,17 @@
7
7
  * Dual licensed under the BSD-3-Clause and the Apache License, Version 2.0.
8
8
  */
9
9
  !function($) {
10
-
10
+
11
11
  "use strict";// jshint ;_;
12
+
13
+ if (Array.prototype.forEach === null || Array.prototype.forEach === undefined) {
14
+ Array.prototype.forEach = function (func) {
15
+ var index;
16
+ for (index = 0; index < this.length; ++index) {
17
+ func(this[index]);
18
+ }
19
+ };
20
+ }
12
21
 
13
22
  if (typeof ko !== 'undefined' && ko.bindingHandlers && !ko.bindingHandlers.multiselect) {
14
23
  ko.bindingHandlers.multiselect = {
@@ -97,8 +106,8 @@
97
106
  // Build select all if enabled.
98
107
  this.buildContainer();
99
108
  this.buildButton();
100
- this.buildSelectAll();
101
109
  this.buildDropdown();
110
+ this.buildSelectAll();
102
111
  this.buildDropdownOptions();
103
112
  this.buildFilter();
104
113
 
@@ -216,10 +225,10 @@
216
225
  templates: {
217
226
  button: '<button type="button" class="multiselect dropdown-toggle" data-toggle="dropdown"></button>',
218
227
  ul: '<ul class="multiselect-container dropdown-menu"></ul>',
219
- filter: '<div class="input-group"><span class="input-group-addon"><i class="glyphicon glyphicon-search"></i></span><input class="form-control multiselect-search" type="text"></div>',
228
+ filter: '<li class="multiselect-item filter"><div class="input-group"><span class="input-group-addon"><i class="glyphicon glyphicon-search"></i></span><input class="form-control multiselect-search" type="text"></div></li>',
220
229
  li: '<li><a href="javascript:void(0);"><label></label></a></li>',
221
- divider: '<li class="divider"></li>',
222
- liGroup: '<li><label class="multiselect-group"></label></li>'
230
+ divider: '<li class="multiselect-item divider"></li>',
231
+ liGroup: '<li class="multiselect-item group"><label class="multiselect-group"></label></li>'
223
232
  }
224
233
  },
225
234
 
@@ -300,6 +309,10 @@
300
309
  // Support optgroups and options without a group simultaneously.
301
310
  var tag = $(element).prop('tagName')
302
311
  .toLowerCase();
312
+
313
+ if ($(element).prop('value') == this.options.selectAllValue) {
314
+ return;
315
+ }
303
316
 
304
317
  if (tag === 'optgroup') {
305
318
  this.createOptgroup(element);
@@ -345,56 +358,51 @@
345
358
  var $checkboxesNotThis = $('input', this.$container).not($target);
346
359
 
347
360
  if (isSelectAllOption) {
348
- var values = [];
349
-
350
- // Select the visible checkboxes except the "select-all" and possible divider.
351
- var availableInputs = $('li input[value!="' + this.options.selectAllValue + '"][data-role!="divider"]', this.$ul).filter(':visible');
352
- for (var i = 0, j = availableInputs.length; i < j; i++) {
353
- values.push(availableInputs[i].value);
354
- }
355
-
356
361
  if (checked) {
357
- this.select(values);
362
+ this.selectall();
358
363
  }
359
364
  else {
360
- this.deselect(values);
365
+ this.deselectall();
361
366
  }
362
367
  }
363
368
 
364
- if (checked) {
365
- $option.prop('selected', true);
366
-
367
- if (this.options.multiple) {
368
- // Simply select additional option.
369
+ if(!isSelectAllOption){
370
+ if (checked) {
369
371
  $option.prop('selected', true);
370
- }
371
- else {
372
- // Unselect all other options and corresponding checkboxes.
373
- if (this.options.selectedClass) {
374
- $($checkboxesNotThis).parents('li').removeClass(this.options.selectedClass);
372
+
373
+ if (this.options.multiple) {
374
+ // Simply select additional option.
375
+ $option.prop('selected', true);
375
376
  }
377
+ else {
378
+ // Unselect all other options and corresponding checkboxes.
379
+ if (this.options.selectedClass) {
380
+ $($checkboxesNotThis).parents('li').removeClass(this.options.selectedClass);
381
+ }
376
382
 
377
- $($checkboxesNotThis).prop('checked', false);
378
- $optionsNotThis.prop('selected', false);
383
+ $($checkboxesNotThis).prop('checked', false);
384
+ $optionsNotThis.prop('selected', false);
379
385
 
380
- // It's a single selection, so close.
381
- this.$button.click();
382
- }
386
+ // It's a single selection, so close.
387
+ this.$button.click();
388
+ }
383
389
 
384
- if (this.options.selectedClass === "active") {
385
- $optionsNotThis.parents("a").css("outline", "");
390
+ if (this.options.selectedClass === "active") {
391
+ $optionsNotThis.parents("a").css("outline", "");
392
+ }
393
+ }
394
+ else {
395
+ // Unselect option.
396
+ $option.prop('selected', false);
386
397
  }
387
- }
388
- else {
389
- // Unselect option.
390
- $option.prop('selected', false);
391
398
  }
392
399
 
393
400
  this.$select.change();
394
- this.options.onChange($option, checked);
395
-
401
+
396
402
  this.updateButtonText();
397
403
  this.updateSelectAll();
404
+
405
+ this.options.onChange($option, checked);
398
406
 
399
407
  if(this.options.preventInputChangeEvent) {
400
408
  return false;
@@ -440,7 +448,7 @@
440
448
  });
441
449
 
442
450
  // Keyboard support.
443
- this.$container.on('keydown', $.proxy(function(event) {
451
+ this.$container.off('keydown.multiselect').on('keydown.multiselect', $.proxy(function(event) {
444
452
  if ($('input[type="text"]', this.$container).is(':focus')) {
445
453
  return;
446
454
  }
@@ -451,7 +459,7 @@
451
459
  this.$button.click();
452
460
  }
453
461
  else {
454
- var $items = $(this.$container).find("li:not(.divider):visible a");
462
+ var $items = $(this.$container).find("li:not(.divider):not(.disabled) a").filter(":visible");
455
463
 
456
464
  if (!$items.length) {
457
465
  return;
@@ -511,6 +519,7 @@
511
519
  $checkbox.val(value);
512
520
 
513
521
  if (value === this.options.selectAllValue) {
522
+ $li.addClass("multiselect-item multiselect-all");
514
523
  $checkbox.parent().parent()
515
524
  .addClass('multiselect-all');
516
525
  }
@@ -522,6 +531,8 @@
522
531
  if ($(element).is(':disabled')) {
523
532
  $checkbox.attr('disabled', 'disabled')
524
533
  .prop('disabled', true)
534
+ .parents('a')
535
+ .attr("tabindex", "-1")
525
536
  .parents('li')
526
537
  .addClass('disabled');
527
538
  }
@@ -570,20 +581,35 @@
570
581
 
571
582
  /**
572
583
  * Build the selct all.
573
- * Checks if a select all ahs already been created.
584
+ * Checks if a select all has already been created.
574
585
  */
575
586
  buildSelectAll: function() {
576
587
  var alreadyHasSelectAll = this.hasSelectAll();
577
588
 
578
589
  if (!alreadyHasSelectAll && this.options.includeSelectAllOption && this.options.multiple
579
- && $('option[data-role!="divider"]', this.$select).length > this.options.includeSelectAllIfMoreThan) {
590
+ && $('option', this.$select).length > this.options.includeSelectAllIfMoreThan) {
580
591
 
581
592
  // Check whether to add a divider after the select all.
582
593
  if (this.options.includeSelectAllDivider) {
583
- this.$select.prepend('<option value="" disabled="disabled" data-role="divider">');
594
+ this.$ul.prepend($(this.options.templates.divider));
584
595
  }
585
-
586
- this.$select.prepend('<option value="' + this.options.selectAllValue + '">' + this.options.selectAllText + '</option>');
596
+
597
+ var $li = $(this.options.templates.li);
598
+ $('label', $li).addClass("checkbox");
599
+ $('label', $li).append('<input type="checkbox" name="' + this.options.checkboxName + '" />');
600
+
601
+ var $checkbox = $('input', $li);
602
+ $checkbox.val(this.options.selectAllValue);
603
+
604
+ $li.addClass("multiselect-item multiselect-all");
605
+ $checkbox.parent().parent()
606
+ .addClass('multiselect-all');
607
+
608
+ $('label', $li).append(" " + this.options.selectAllText);
609
+
610
+ this.$ul.prepend($li);
611
+
612
+ $checkbox.prop('checked', false);
587
613
  }
588
614
  },
589
615
 
@@ -641,16 +667,16 @@
641
667
  }
642
668
 
643
669
  if (showElement) {
644
- $(element).show();
670
+ $(element).show().removeClass("filter-hidden");
645
671
  }
646
672
  else {
647
- $(element).hide();
673
+ $(element).hide().addClass("filter-hidden");
648
674
  }
649
675
  }
650
676
  }, this));
651
677
  }
652
678
 
653
- // TODO: check whether select all option needs to be updated.
679
+ this.updateSelectAll();
654
680
  }, this), 300, this);
655
681
  }, this));
656
682
  }
@@ -725,6 +751,11 @@
725
751
  var $option = this.getOptionByValue(value);
726
752
  var $checkbox = this.getInputByValue(value);
727
753
 
754
+ if($option === void(0) || $checkbox === void(0))
755
+ {
756
+ continue;
757
+ }
758
+
728
759
  if (this.options.selectedClass) {
729
760
  $checkbox.parents('li')
730
761
  .addClass(this.options.selectedClass);
@@ -742,20 +773,9 @@
742
773
  *
743
774
  */
744
775
  clearSelection: function () {
745
-
746
- var selected = this.getSelected();
747
-
748
- if (selected.length) {
749
-
750
- var arry = [];
751
-
752
- for (var i = 0; i < selected.length; i = i + 1) {
753
- arry.push(selected[i].value);
754
- }
755
-
756
- this.deselect(arry);
757
- this.$select.change();
758
- }
776
+ this.deselectall(false);
777
+ this.updateButtonText();
778
+ this.updateSelectAll();
759
779
  },
760
780
 
761
781
  /**
@@ -775,6 +795,11 @@
775
795
  var $option = this.getOptionByValue(value);
776
796
  var $checkbox = this.getInputByValue(value);
777
797
 
798
+ if($option === void(0) || $checkbox === void(0))
799
+ {
800
+ continue;
801
+ }
802
+
778
803
  if (this.options.selectedClass) {
779
804
  $checkbox.parents('li')
780
805
  .removeClass(this.options.selectedClass);
@@ -786,6 +811,57 @@
786
811
 
787
812
  this.updateButtonText();
788
813
  },
814
+
815
+ /**
816
+ * Selects all enabled & visible options.
817
+ *
818
+ */
819
+ selectall: function () {
820
+ var allCheckboxes = $("li input[type='checkbox']:enabled", this.$ul),
821
+ visibleCheckboxes = allCheckboxes.filter(":visible"),
822
+ allCheckboxesCount = allCheckboxes.length,
823
+ visibleCheckboxesCount = visibleCheckboxes.length;
824
+
825
+ visibleCheckboxes.prop('checked', true);
826
+ $("li:not(.divider):not(.disabled)", this.$ul).filter(":visible").addClass(this.options.selectedClass);
827
+
828
+ if (allCheckboxesCount === visibleCheckboxesCount) {
829
+ $("option:enabled", this.$select).prop('selected', true);
830
+ }
831
+ else {
832
+ var values = visibleCheckboxes.map(function() { return $(this).val() }).get();
833
+ $("option:enabled", this.$select).filter(function(index){ return $.inArray($(this).val(), values) !== -1; }).prop('selected', true);
834
+ }
835
+ },
836
+
837
+ /**
838
+ * Deselects all options.
839
+ * If justVisible is true or not specified, only visible options are deselected.
840
+ *
841
+ * @param {Boolean} justVisible
842
+ */
843
+ deselectall: function (justVisible) {
844
+ var allCheckboxes = $("li input[type='checkbox']:enabled", this.$ul),
845
+ justVisible = typeof justVisible === 'undefined' ? true : justVisible,
846
+ visibleCheckboxes = void(0);
847
+
848
+ if(justVisible) {
849
+ var values = void(0);
850
+ visibleCheckboxes = allCheckboxes.filter(":visible");
851
+ visibleCheckboxes.prop('checked', false);
852
+
853
+ values = visibleCheckboxes.map(function() { return $(this).val() }).get();
854
+
855
+ $("option:enabled", this.$select).filter(function(index){ return $.inArray($(this).val(), values) !== -1; }).prop('selected', false);
856
+
857
+ $("li:not(.divider):not(.disabled)", this.$ul).filter(":visible").removeClass(this.options.selectedClass);
858
+
859
+ }else {
860
+ allCheckboxes.prop('checked', false);
861
+ $("option:enabled", this.$select).prop('selected', false);
862
+ $("li:not(.divider):not(.disabled)", this.$ul).removeClass(this.options.selectedClass);
863
+ }
864
+ },
789
865
 
790
866
  /**
791
867
  * Rebuild the plugin.
@@ -794,9 +870,6 @@
794
870
  rebuild: function() {
795
871
  this.$ul.html('');
796
872
 
797
- // Remove select all option in select.
798
- $('option[value="' + this.options.selectAllValue + '"]', this.$select).remove();
799
-
800
873
  // Important to distinguish between radios and checkboxes.
801
874
  this.options.multiple = this.$select.attr('multiple') === "multiple";
802
875
 
@@ -806,6 +879,10 @@
806
879
 
807
880
  this.updateButtonText();
808
881
  this.updateSelectAll();
882
+
883
+ if (this.options.dropRight) {
884
+ this.$ul.addClass('pull-right');
885
+ }
809
886
  },
810
887
 
811
888
  /**
@@ -815,10 +892,24 @@
815
892
  */
816
893
  dataprovider: function(dataprovider) {
817
894
  var optionDOM = "";
818
- dataprovider.forEach(function (option) {
819
- optionDOM += '<option value="' + option.value + '">' + option.label + '</option>';
820
- });
895
+ var groupCounter = 0;
896
+
897
+ $.each(dataprovider, function (option) {
898
+ if ($.isArray(option.children)) {
899
+ groupCounter++;
900
+ optionDOM += '<optgroup label="' + (option.title || 'Group ' + groupCounter) + '">';
821
901
 
902
+ option.children.forEach(function(subOption) {
903
+ optionDOM += '<option value="' + subOption.value + '">' + (subOption.label || subOption.value) + '</option>';
904
+ });
905
+
906
+ optionDOM += '</optgroup>';
907
+ }
908
+ else {
909
+ optionDOM += '<option value="' + option.value + '">' + (option.label || option.value) + '</option>';
910
+ }
911
+ });
912
+
822
913
  this.$select.html(optionDOM);
823
914
  this.rebuild();
824
915
  },
@@ -861,26 +952,32 @@
861
952
  },
862
953
 
863
954
  /**
864
- * Checks whether a select all option is present.
955
+ * Checks whether a select all checkbox is present.
865
956
  *
866
957
  * @returns {Boolean}
867
958
  */
868
959
  hasSelectAll: function() {
869
- return $('option[value="' + this.options.selectAllValue + '"]', this.$select).length > 0;
960
+ return $('li.' + this.options.selectAllValue, this.$ul).length > 0;
870
961
  },
871
962
 
872
963
  /**
873
- * Updates the select all option based on the currently selected options.
964
+ * Updates the select all checkbox based on the currently displayed and selected checkboxes.
874
965
  */
875
966
  updateSelectAll: function() {
876
967
  if (this.hasSelectAll()) {
877
- var selected = this.getSelected();
968
+ var allBoxes = $("li:not(.multiselect-item):not(.filter-hidden) input:enabled", this.$ul),
969
+ allBoxesLength = allBoxes.length,
970
+ checkedBoxesLength = allBoxes.filter(":checked").length,
971
+ selectAllLi = $("li." + this.options.selectAllValue, this.$ul),
972
+ selectAllInput = selectAllLi.find("input");
878
973
 
879
- if (selected.length === $('option:not([data-role=divider])', this.$select).length - 1) {
880
- this.select(this.options.selectAllValue);
974
+ if (checkedBoxesLength > 0 && checkedBoxesLength === allBoxesLength) {
975
+ selectAllInput.prop("checked", true);
976
+ selectAllLi.addClass(this.options.selectedClass);
881
977
  }
882
978
  else {
883
- this.deselect(this.options.selectAllValue);
979
+ selectAllInput.prop("checked", false);
980
+ selectAllLi.removeClass(this.options.selectedClass);
884
981
  }
885
982
  }
886
983
  },
@@ -905,9 +1002,7 @@
905
1002
  * @returns {jQUery}
906
1003
  */
907
1004
  getSelected: function() {
908
- return $('option[value!="' + this.options.selectAllValue + '"]:selected', this.$select).filter(function() {
909
- return $(this).prop('selected');
910
- });
1005
+ return $('option', this.$select).filter(":selected");
911
1006
  },
912
1007
 
913
1008
  /**
@@ -1 +1 @@
1
- .multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li>label.multiselect-group{margin:0;padding:3px 20px;height:100%;font-weight:700}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400}.multiselect-container>li>a>label.radio,.multiselect-container>li>a>label.checkbox{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}
1
+ .multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li>label.multiselect-group{margin:0;padding:3px 20px;height:100%;font-weight:700}.multiselect-container>li>a{padding:0}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container>li>a>label.radio,.multiselect-container>li>a>label.checkbox{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootstrap-multiselect-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Canac
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-26 00:00:00.000000000 Z
11
+ date: 2014-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails