bootstrap-multiselect-rails 0.0.5 → 0.0.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.
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