jekyll-theme-ici3d 0.1.0
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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +50 -0
- data/_data/publications/pulliam2012.yml +12 -0
- data/_data/team/ackley.yml +25 -0
- data/_data/team/are.yml +22 -0
- data/_data/team/beauclair.yml +14 -0
- data/_data/team/bekele.yml +14 -0
- data/_data/team/bellan.yml +46 -0
- data/_data/team/bolton.yml +33 -0
- data/_data/team/borchering.yml +65 -0
- data/_data/team/brook.yml +15 -0
- data/_data/team/brown.yml +18 -0
- data/_data/team/bruce.yml +26 -0
- data/_data/team/brucePA.yml +9 -0
- data/_data/team/deleo.yml +49 -0
- data/_data/team/delva.yml +15 -0
- data/_data/team/dushoff.yml +52 -0
- data/_data/team/ervin.yml +10 -0
- data/_data/team/faikah.yml +26 -0
- data/_data/team/grebe.yml +36 -0
- data/_data/team/hargrove.yml +36 -0
- data/_data/team/hitchcock.yml +10 -0
- data/_data/team/hladish.yml +45 -0
- data/_data/team/january.yml +9 -0
- data/_data/team/kassanjee.yml +20 -0
- data/_data/team/li.yml +45 -0
- data/_data/team/lord.yml +20 -0
- data/_data/team/marx.yml +14 -0
- data/_data/team/mcintosh.yml +20 -0
- data/_data/team/mhlanga.yml +22 -0
- data/_data/team/mthombothi.yml +23 -0
- data/_data/team/mugwagwa.yml +18 -0
- data/_data/team/mwangi.yml +24 -0
- data/_data/team/mwebaze.yml +20 -0
- data/_data/team/ndifon.yml +18 -0
- data/_data/team/ngonghala.yml +30 -0
- data/_data/team/nondi.yml +14 -0
- data/_data/team/nyamai.yml +18 -0
- data/_data/team/october.yml +9 -0
- data/_data/team/paradza.yml +19 -0
- data/_data/team/pearson.yml +58 -0
- data/_data/team/porco.yml +14 -0
- data/_data/team/pulliam.yml +51 -0
- data/_data/team/reiner.yml +18 -0
- data/_data/team/scheepers.yml +9 -0
- data/_data/team/scott.yml +51 -0
- data/_data/team/sempa.yml +32 -0
- data/_data/team/sikhondze.yml +14 -0
- data/_data/team/template.yml +18 -0
- data/_data/team/ujeneza.yml +38 -0
- data/_data/team/vanschalkwyk.yml +32 -0
- data/_data/team/welte.yml +18 -0
- data/_data/team/williams.yml +28 -0
- data/_data/team/ying.yml +21 -0
- data/_includes/MedPH/.DS_Store +0 -0
- data/_includes/MedPH/assignments.md +42 -0
- data/_includes/MedPH/assignmentsStandard.md +74 -0
- data/_includes/MedPH/computerlabs.md +38 -0
- data/_includes/MedPH/computerlabsStandard.md +38 -0
- data/_includes/MedPH/lectures.md +12 -0
- data/_includes/MedPH/references.md +71 -0
- data/_includes/MedPH/schedule.md +85 -0
- data/_includes/MedPH/scheduleStandard.md +93 -0
- data/_includes/bottomTable.html +5 -0
- data/_includes/centerTable.html +5 -0
- data/_includes/clinicNavbar.html +46 -0
- data/_includes/contact.html +12 -0
- data/_includes/directors.html +47 -0
- data/_includes/footer.html +23 -0
- data/_includes/head.html +28 -0
- data/_includes/header.html +31 -0
- data/_includes/hero.html +14 -0
- data/_includes/index.md +9 -0
- data/_includes/mission.html +13 -0
- data/_includes/navStructure.html +70 -0
- data/_includes/navbar.html +65 -0
- data/_includes/outputs.html +74 -0
- data/_includes/partners.html +75 -0
- data/_includes/profile.html +67 -0
- data/_includes/publications/faculty.md +13 -0
- data/_includes/publications/instructional.md +5 -0
- data/_includes/publications/participant.md +33 -0
- data/_includes/talk.html +12 -0
- data/_includes/topTable.html +6 -0
- data/_includes/upcoming.html +43 -0
- data/_layouts/clinic.liquid +43 -0
- data/_layouts/example.liquid +601 -0
- data/_layouts/main.liquid +34 -0
- data/_layouts/medph.page.liquid +60 -0
- data/_layouts/page.liquid +41 -0
- data/_layouts/people.page.liquid +27 -0
- data/_layouts/profile.liquid +44 -0
- data/_layouts/redirect.liquid +15 -0
- data/_layouts/talk.liquid +42 -0
- data/assets/css/academicons.css +249 -0
- data/assets/css/academicons.min.css +1 -0
- data/assets/css/bootstrap.css +6760 -0
- data/assets/css/bootstrap.css.map +1 -0
- data/assets/css/bootstrap.min.css +6 -0
- data/assets/css/font-awesome.css +2086 -0
- data/assets/css/font-awesome.min.css +4 -0
- data/assets/css/ie.css +5 -0
- data/assets/css/main-one-page.css +6433 -0
- data/assets/css/main.css +7160 -0
- data/assets/css/my-custom-styles.css +14 -0
- data/assets/css/shop-main.css +3117 -0
- data/assets/css/skins/brown.css +299 -0
- data/assets/css/skins/deepskyblue.css +299 -0
- data/assets/css/skins/goldenrod.css +299 -0
- data/assets/css/skins/ici3dBlue.css +229 -0
- data/assets/css/skins/ici3dBlue.css.map +7 -0
- data/assets/css/skins/ici3dIndigo.css +229 -0
- data/assets/css/skins/ici3dIndigo.css.map +7 -0
- data/assets/css/skins/indianred.css +299 -0
- data/assets/css/skins/lightgreen.css +299 -0
- data/assets/css/skins/orange.css +299 -0
- data/assets/css/skins/seagreen.css +299 -0
- data/assets/css/skins/slategray.css +299 -0
- data/assets/fonts/academicons.eot +0 -0
- data/assets/fonts/academicons.svg +66 -0
- data/assets/fonts/academicons.ttf +0 -0
- data/assets/fonts/academicons.woff +0 -0
- data/assets/fonts/fontawesome-webfont.eot +0 -0
- data/assets/fonts/fontawesome-webfont.svg +655 -0
- data/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/assets/fonts/fontawesome-webfont.woff +0 -0
- data/assets/fonts/fontawesome-webfont.woff2 +0 -0
- data/assets/fonts/glyphicons-halflings-regular.eot +0 -0
- data/assets/fonts/glyphicons-halflings-regular.svg +288 -0
- data/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/assets/fonts/glyphicons-halflings-regular.woff +0 -0
- data/assets/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/assets/ico/favicon.ico +0 -0
- data/assets/ico/favicon.png +0 -0
- data/assets/ico/ici3d114x114.png +0 -0
- data/assets/ico/ici3d144x144.png +0 -0
- data/assets/ico/ici3d57x57.png +0 -0
- data/assets/ico/ici3d72x72.png +0 -0
- data/assets/img/8hearts.png +0 -0
- data/assets/img/MMED2015_tutorials.jpg +0 -0
- data/assets/img/badge.png +0 -0
- data/assets/img/blog/balloon-med.jpg +0 -0
- data/assets/img/blog/balloon.jpg +0 -0
- data/assets/img/blog/buildings-med.jpg +0 -0
- data/assets/img/blog/buildings.jpg +0 -0
- data/assets/img/blog/people-med.jpg +0 -0
- data/assets/img/blog/people.jpg +0 -0
- data/assets/img/bx_loader.gif +0 -0
- data/assets/img/clients/logo1.png +0 -0
- data/assets/img/clients/logo2.png +0 -0
- data/assets/img/clients/logo3.png +0 -0
- data/assets/img/clients/logo4.png +0 -0
- data/assets/img/clients/logo5.png +0 -0
- data/assets/img/flags/China.png +0 -0
- data/assets/img/flags/Germany.png +0 -0
- data/assets/img/flags/Japan.png +0 -0
- data/assets/img/flags/South-Africa.png +0 -0
- data/assets/img/flags/United-Kingdom.png +0 -0
- data/assets/img/flags/United-States.png +0 -0
- data/assets/img/free.png +0 -0
- data/assets/img/fullscreen-bg.jpg +0 -0
- data/assets/img/gray_jean.png +0 -0
- data/assets/img/hero-unit-bg.png +0 -0
- data/assets/img/hero-unit-obj.png +0 -0
- data/assets/img/hero-unit-obj2.png +0 -0
- data/assets/img/hero-unit-obj3.png +0 -0
- data/assets/img/intro-img.png +0 -0
- data/assets/img/location-pin.png +0 -0
- data/assets/img/logo/ici3d-logo-light.png +0 -0
- data/assets/img/logo/ici3d-logo-nav.png +0 -0
- data/assets/img/logo/ici3d-logo-white.png +0 -0
- data/assets/img/logo/ici3d-logo-white_v2.png +0 -0
- data/assets/img/logo/ici3d-logo-white_v3.png +0 -0
- data/assets/img/logo/repute-logo-light-brown.png +0 -0
- data/assets/img/logo/repute-logo-light-deepskyblue.png +0 -0
- data/assets/img/logo/repute-logo-light-goldenrod.png +0 -0
- data/assets/img/logo/repute-logo-light-indianred.png +0 -0
- data/assets/img/logo/repute-logo-light-lightgreen.png +0 -0
- data/assets/img/logo/repute-logo-light-orange.png +0 -0
- data/assets/img/logo/repute-logo-light-seagreen.png +0 -0
- data/assets/img/logo/repute-logo-light-slategray.png +0 -0
- data/assets/img/logo/repute-logo-light.png +0 -0
- data/assets/img/logo/repute-logo-nav-brown.png +0 -0
- data/assets/img/logo/repute-logo-nav-deepskyblue.png +0 -0
- data/assets/img/logo/repute-logo-nav-goldenrod.png +0 -0
- data/assets/img/logo/repute-logo-nav-indianred.png +0 -0
- data/assets/img/logo/repute-logo-nav-light.png +0 -0
- data/assets/img/logo/repute-logo-nav-lightgreen.png +0 -0
- data/assets/img/logo/repute-logo-nav-orange.png +0 -0
- data/assets/img/logo/repute-logo-nav-seagreen.png +0 -0
- data/assets/img/logo/repute-logo-nav-slategray.png +0 -0
- data/assets/img/logo/repute-logo-nav.png +0 -0
- data/assets/img/mentors/are.jpg +0 -0
- data/assets/img/mentors/bolton.jpg +0 -0
- data/assets/img/mentors/brown.jpg +0 -0
- data/assets/img/mentors/kassanjee.jpg +0 -0
- data/assets/img/mentors/mhlanga.jpg +0 -0
- data/assets/img/mentors/nyamai.png +0 -0
- data/assets/img/news/featured-news.png +0 -0
- data/assets/img/news/news1.png +0 -0
- data/assets/img/news/news2.png +0 -0
- data/assets/img/news/news3.png +0 -0
- data/assets/img/news/news4.png +0 -0
- data/assets/img/news/news5.png +0 -0
- data/assets/img/other/snoep.jpg +0 -0
- data/assets/img/page-header-bg.png +0 -0
- data/assets/img/participants/SempaJB.jpg +0 -0
- data/assets/img/partners/AIMS-SA.jpg +0 -0
- data/assets/img/partners/CEMA_UN.pdf +0 -0
- data/assets/img/partners/CEMA_UN.png +0 -0
- data/assets/img/partners/CIDID.png +0 -0
- data/assets/img/partners/CIDID_long.png +0 -0
- data/assets/img/partners/Colby.png +0 -0
- data/assets/img/partners/MIDAS.png +0 -0
- data/assets/img/partners/McMaster.jpg +0 -0
- data/assets/img/partners/PSU.png +0 -0
- data/assets/img/partners/Proctor.png +0 -0
- data/assets/img/partners/SACEMA_228.png +0 -0
- data/assets/img/partners/UCSF.png +0 -0
- data/assets/img/partners/UF.png +0 -0
- data/assets/img/partners/UGA_228.png +0 -0
- data/assets/img/pattern-geometry.png +0 -0
- data/assets/img/portfolio/800x500/work1.png +0 -0
- data/assets/img/portfolio/800x500/work2.png +0 -0
- data/assets/img/portfolio/800x500/work3.png +0 -0
- data/assets/img/portfolio/800x500/work4.png +0 -0
- data/assets/img/portfolio/800x500/work5.png +0 -0
- data/assets/img/portfolio/800x500/work6.png +0 -0
- data/assets/img/portfolio/800x500/work7.png +0 -0
- data/assets/img/portfolio/800x500/work8.png +0 -0
- data/assets/img/portfolio/800x800/work1.png +0 -0
- data/assets/img/portfolio/800x800/work2.png +0 -0
- data/assets/img/portfolio/800x800/work3.png +0 -0
- data/assets/img/portfolio/800x800/work4.png +0 -0
- data/assets/img/portfolio/800x800/work5.png +0 -0
- data/assets/img/portfolio/800x800/work6.png +0 -0
- data/assets/img/portfolio/800x800/work7.png +0 -0
- data/assets/img/portfolio/800x800/work8.png +0 -0
- data/assets/img/portfolio/single/bicycle.jpg +0 -0
- data/assets/img/portfolio/single/blurred_lines.jpg +0 -0
- data/assets/img/portfolio/single/edge.jpg +0 -0
- data/assets/img/scholars/ackley.jpg +0 -0
- data/assets/img/scholars/beauclair.jpg +0 -0
- data/assets/img/scholars/beauclair.png +0 -0
- data/assets/img/scholars/bekele.jpg +0 -0
- data/assets/img/scholars/lord.jpg +0 -0
- data/assets/img/scholars/marx.jpg +0 -0
- data/assets/img/scholars/mcintosh.jpg +0 -0
- data/assets/img/scholars/mwebaze.jpg +0 -0
- data/assets/img/scholars/nondi.jpg +0 -0
- data/assets/img/scholars/sempa.jpg +0 -0
- data/assets/img/scholars/ying.jpg +0 -0
- data/assets/img/sliders/full-slide-color.jpg +0 -0
- data/assets/img/sliders/full-slide-color2.jpg +0 -0
- data/assets/img/sliders/full-slide-color3.jpg +0 -0
- data/assets/img/sliders/full-slide.jpg +0 -0
- data/assets/img/sliders/full-slide2.jpg +0 -0
- data/assets/img/sliders/full-slide3.jpg +0 -0
- data/assets/img/sliders/slider1-h500.png +0 -0
- data/assets/img/sliders/slider2-h500.png +0 -0
- data/assets/img/sliders/slider3-h500.png +0 -0
- data/assets/img/team/bellan.jpg +0 -0
- data/assets/img/team/borchering.jpg +0 -0
- data/assets/img/team/brook.jpg +0 -0
- data/assets/img/team/bruce.jpg +0 -0
- data/assets/img/team/deleo.jpg +0 -0
- data/assets/img/team/delva.jpg +0 -0
- data/assets/img/team/dushoff.jpg +0 -0
- data/assets/img/team/ervin.jpg +0 -0
- data/assets/img/team/grebe.jpg +0 -0
- data/assets/img/team/hargrove.jpg +0 -0
- data/assets/img/team/hitchcock.jpg +0 -0
- data/assets/img/team/hladish.jpg +0 -0
- data/assets/img/team/january.jpg +0 -0
- data/assets/img/team/li.jpg +0 -0
- data/assets/img/team/mthombothi.jpg +0 -0
- data/assets/img/team/mugwagwa.jpg +0 -0
- data/assets/img/team/mwangi.png +0 -0
- data/assets/img/team/ndifon.jpg +0 -0
- data/assets/img/team/ngonghala.jpg +0 -0
- data/assets/img/team/october.jpg +0 -0
- data/assets/img/team/paradza.jpg +0 -0
- data/assets/img/team/pearson.jpg +0 -0
- data/assets/img/team/porco.jpg +0 -0
- data/assets/img/team/pulliam.jpg +0 -0
- data/assets/img/team/reiner.jpg +0 -0
- data/assets/img/team/scheepers.jpg +0 -0
- data/assets/img/team/scott.jpg +0 -0
- data/assets/img/team/ujeneza.jpg +0 -0
- data/assets/img/team/vanschalkwyk.jpg +0 -0
- data/assets/img/team/welte.jpg +0 -0
- data/assets/img/team/williams.jpg +0 -0
- data/assets/img/testimonial-bg.png +0 -0
- data/assets/img/transmission.png +0 -0
- data/assets/js/bootstrap.js +2363 -0
- data/assets/js/bootstrap.min.js +7 -0
- data/assets/js/jquery-2.1.1.min.js +4 -0
- data/assets/js/plugins/autohidingnavbar/jquery.bootstrap-autohidingnavbar.js +213 -0
- data/assets/js/plugins/autohidingnavbar/jquery.bootstrap-autohidingnavbar.min.js +9 -0
- data/assets/js/plugins/bootstrap-datepicker/bootstrap-datepicker.js +474 -0
- data/assets/js/plugins/bootstrap-multiselect/bootstrap-multiselect.js +994 -0
- data/assets/js/plugins/daterangepicker/daterangepicker.js +868 -0
- data/assets/js/plugins/easing/jquery.easing.js +205 -0
- data/assets/js/plugins/easing/jquery.easing.min.js +71 -0
- data/assets/js/plugins/fitvids/jquery.fitvids.js +83 -0
- data/assets/js/plugins/google-map/google-map.js +160 -0
- data/assets/js/plugins/isotope/isotope.pkgd.js +4049 -0
- data/assets/js/plugins/isotope/isotope.pkgd.min.js +8 -0
- data/assets/js/plugins/jquery-cycle/jquery.cycle.all.js +1543 -0
- data/assets/js/plugins/jquery-easypiechart/jquery.easypiechart.js +359 -0
- data/assets/js/plugins/jquery-easypiechart/jquery.easypiechart.min.js +9 -0
- data/assets/js/plugins/jquery-maskedinput/jquery.masked-input.js +338 -0
- data/assets/js/plugins/jquery-maskedinput/jquery.masked-input.min.js +7 -0
- data/assets/js/plugins/maximage/jquery.maximage.js +697 -0
- data/assets/js/plugins/maximage/jquery.maximage.min.js +4 -0
- data/assets/js/plugins/moment/moment.js +1662 -0
- data/assets/js/plugins/moment/moment.min.js +6 -0
- data/assets/js/plugins/parsley-validation/parsley.js +2074 -0
- data/assets/js/plugins/parsley-validation/parsley.min.js +9 -0
- data/assets/js/plugins/scrollto/jquery.localscroll-1.2.7-min.js +9 -0
- data/assets/js/plugins/scrollto/jquery.localscroll-1.2.7.js +133 -0
- data/assets/js/plugins/scrollto/jquery.scrollTo-1.4.3.1-min.js +7 -0
- data/assets/js/plugins/scrollto/jquery.scrollTo-1.4.3.1.js +218 -0
- data/assets/js/plugins/slick/slick.js +2643 -0
- data/assets/js/plugins/slick/slick.min.js +18 -0
- data/assets/js/plugins/stellar/jquery.stellar.js +660 -0
- data/assets/js/plugins/stellar/jquery.stellar.min.js +2 -0
- data/assets/js/repute-scripts.js +539 -0
- metadata +385 -0
@@ -0,0 +1,994 @@
|
|
1
|
+
/**
|
2
|
+
* bootstrap-multiselect.js
|
3
|
+
* https://github.com/davidstutz/bootstrap-multiselect
|
4
|
+
*
|
5
|
+
* Copyright 2012 - 2014 David Stutz
|
6
|
+
*
|
7
|
+
* Dual licensed under the BSD-3-Clause and the Apache License, Version 2.0.
|
8
|
+
*/
|
9
|
+
!function($) {
|
10
|
+
|
11
|
+
"use strict";// jshint ;_;
|
12
|
+
|
13
|
+
if (typeof ko !== 'undefined' && ko.bindingHandlers && !ko.bindingHandlers.multiselect) {
|
14
|
+
ko.bindingHandlers.multiselect = {
|
15
|
+
|
16
|
+
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
|
17
|
+
|
18
|
+
var listOfSelectedItems = allBindingsAccessor().selectedOptions,
|
19
|
+
config = ko.utils.unwrapObservable(valueAccessor());
|
20
|
+
|
21
|
+
$(element).multiselect(config);
|
22
|
+
|
23
|
+
if (isObservableArray(listOfSelectedItems)) {
|
24
|
+
// Subscribe to the selectedOptions: ko.observableArray
|
25
|
+
listOfSelectedItems.subscribe(function (changes) {
|
26
|
+
var addedArray = [], deletedArray = [];
|
27
|
+
changes.forEach(function (change) {
|
28
|
+
switch (change.status) {
|
29
|
+
case 'added':
|
30
|
+
addedArray.push(change.value);
|
31
|
+
break;
|
32
|
+
case 'deleted':
|
33
|
+
deletedArray.push(change.value);
|
34
|
+
break;
|
35
|
+
}
|
36
|
+
});
|
37
|
+
if (addedArray.length > 0) {
|
38
|
+
$(element).multiselect('select', addedArray);
|
39
|
+
};
|
40
|
+
if (deletedArray.length > 0) {
|
41
|
+
$(element).multiselect('deselect', deletedArray);
|
42
|
+
};
|
43
|
+
}, null, "arrayChange");
|
44
|
+
}
|
45
|
+
},
|
46
|
+
|
47
|
+
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
|
48
|
+
|
49
|
+
var listOfItems = allBindingsAccessor().options,
|
50
|
+
ms = $(element).data('multiselect'),
|
51
|
+
config = ko.utils.unwrapObservable(valueAccessor());
|
52
|
+
|
53
|
+
if (isObservableArray(listOfItems)) {
|
54
|
+
// Subscribe to the options: ko.observableArray incase it changes later
|
55
|
+
listOfItems.subscribe(function (theArray) {
|
56
|
+
$(element).multiselect('rebuild');
|
57
|
+
});
|
58
|
+
}
|
59
|
+
|
60
|
+
if (!ms) {
|
61
|
+
$(element).multiselect(config);
|
62
|
+
}
|
63
|
+
else {
|
64
|
+
ms.updateOriginalOptions();
|
65
|
+
}
|
66
|
+
}
|
67
|
+
};
|
68
|
+
}
|
69
|
+
|
70
|
+
function isObservableArray(obj) {
|
71
|
+
return ko.isObservable(obj) && !(obj.destroyAll === undefined);
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* Constructor to create a new multiselect using the given select.
|
76
|
+
*
|
77
|
+
* @param {jQuery} select
|
78
|
+
* @param {Object} options
|
79
|
+
* @returns {Multiselect}
|
80
|
+
*/
|
81
|
+
function Multiselect(select, options) {
|
82
|
+
|
83
|
+
this.options = this.mergeOptions(options);
|
84
|
+
this.$select = $(select);
|
85
|
+
|
86
|
+
// Initialization.
|
87
|
+
// We have to clone to create a new reference.
|
88
|
+
this.originalOptions = this.$select.clone()[0].options;
|
89
|
+
this.query = '';
|
90
|
+
this.searchTimeout = null;
|
91
|
+
|
92
|
+
this.options.multiple = this.$select.attr('multiple') === "multiple";
|
93
|
+
this.options.onChange = $.proxy(this.options.onChange, this);
|
94
|
+
this.options.onDropdownShow = $.proxy(this.options.onDropdownShow, this);
|
95
|
+
this.options.onDropdownHide = $.proxy(this.options.onDropdownHide, this);
|
96
|
+
|
97
|
+
// Build select all if enabled.
|
98
|
+
this.buildContainer();
|
99
|
+
this.buildButton();
|
100
|
+
this.buildSelectAll();
|
101
|
+
this.buildDropdown();
|
102
|
+
this.buildDropdownOptions();
|
103
|
+
this.buildFilter();
|
104
|
+
|
105
|
+
this.updateButtonText();
|
106
|
+
this.updateSelectAll();
|
107
|
+
|
108
|
+
this.$select.hide().after(this.$container);
|
109
|
+
};
|
110
|
+
|
111
|
+
Multiselect.prototype = {
|
112
|
+
|
113
|
+
defaults: {
|
114
|
+
/**
|
115
|
+
* Default text function will either print 'None selected' in case no
|
116
|
+
* option is selected or a list of the selected options up to a length of 3 selected options.
|
117
|
+
*
|
118
|
+
* @param {jQuery} options
|
119
|
+
* @param {jQuery} select
|
120
|
+
* @returns {String}
|
121
|
+
*/
|
122
|
+
buttonText: function(options, select) {
|
123
|
+
if (options.length === 0) {
|
124
|
+
return this.nonSelectedText + ' <b class="caret"></b>';
|
125
|
+
}
|
126
|
+
else {
|
127
|
+
if (options.length > this.numberDisplayed) {
|
128
|
+
return options.length + ' ' + this.nSelectedText + ' <b class="caret"></b>';
|
129
|
+
}
|
130
|
+
else {
|
131
|
+
var selected = '';
|
132
|
+
options.each(function() {
|
133
|
+
var label = ($(this).attr('label') !== undefined) ? $(this).attr('label') : $(this).html();
|
134
|
+
|
135
|
+
selected += label + ', ';
|
136
|
+
});
|
137
|
+
return selected.substr(0, selected.length - 2) + ' <b class="caret"></b>';
|
138
|
+
}
|
139
|
+
}
|
140
|
+
},
|
141
|
+
/**
|
142
|
+
* Updates the title of the button similar to the buttonText function.
|
143
|
+
* @param {jQuery} options
|
144
|
+
* @param {jQuery} select
|
145
|
+
* @returns {@exp;selected@call;substr}
|
146
|
+
*/
|
147
|
+
buttonTitle: function(options, select) {
|
148
|
+
if (options.length === 0) {
|
149
|
+
return this.nonSelectedText;
|
150
|
+
}
|
151
|
+
else {
|
152
|
+
var selected = '';
|
153
|
+
options.each(function () {
|
154
|
+
selected += $(this).text() + ', ';
|
155
|
+
});
|
156
|
+
return selected.substr(0, selected.length - 2);
|
157
|
+
}
|
158
|
+
},
|
159
|
+
/**
|
160
|
+
* Create a label.
|
161
|
+
*
|
162
|
+
* @param {jQuery} element
|
163
|
+
* @returns {String}
|
164
|
+
*/
|
165
|
+
label: function(element){
|
166
|
+
return $(element).attr('label') || $(element).html();
|
167
|
+
},
|
168
|
+
/**
|
169
|
+
* Triggered on change of the multiselect.
|
170
|
+
* Not triggered when selecting/deselecting options manually.
|
171
|
+
*
|
172
|
+
* @param {jQuery} option
|
173
|
+
* @param {Boolean} checked
|
174
|
+
*/
|
175
|
+
onChange : function(option, checked) {
|
176
|
+
|
177
|
+
},
|
178
|
+
/**
|
179
|
+
* Triggered when the dropdown is shown.
|
180
|
+
*
|
181
|
+
* @param {jQuery} event
|
182
|
+
*/
|
183
|
+
onDropdownShow: function(event) {
|
184
|
+
|
185
|
+
},
|
186
|
+
/**
|
187
|
+
* Triggered when the dropdown is hidden.
|
188
|
+
*
|
189
|
+
* @param {jQuery} event
|
190
|
+
*/
|
191
|
+
onDropdownHide: function(event) {
|
192
|
+
|
193
|
+
},
|
194
|
+
buttonClass: 'btn btn-default',
|
195
|
+
dropRight: false,
|
196
|
+
selectedClass: 'active',
|
197
|
+
buttonWidth: 'auto',
|
198
|
+
buttonContainer: '<div class="btn-group" />',
|
199
|
+
// Maximum height of the dropdown menu.
|
200
|
+
// If maximum height is exceeded a scrollbar will be displayed.
|
201
|
+
maxHeight: false,
|
202
|
+
checkboxName: 'multiselect',
|
203
|
+
includeSelectAllOption: false,
|
204
|
+
includeSelectAllIfMoreThan: 0,
|
205
|
+
selectAllText: ' Select all',
|
206
|
+
selectAllValue: 'multiselect-all',
|
207
|
+
enableFiltering: false,
|
208
|
+
enableCaseInsensitiveFiltering: false,
|
209
|
+
filterPlaceholder: 'Search',
|
210
|
+
// possible options: 'text', 'value', 'both'
|
211
|
+
filterBehavior: 'text',
|
212
|
+
preventInputChangeEvent: false,
|
213
|
+
nonSelectedText: 'None selected',
|
214
|
+
nSelectedText: 'selected',
|
215
|
+
numberDisplayed: 3,
|
216
|
+
templates: {
|
217
|
+
button: '<button type="button" class="multiselect dropdown-toggle" data-toggle="dropdown"></button>',
|
218
|
+
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>',
|
220
|
+
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>'
|
223
|
+
}
|
224
|
+
},
|
225
|
+
|
226
|
+
constructor: Multiselect,
|
227
|
+
|
228
|
+
/**
|
229
|
+
* Builds the container of the multiselect.
|
230
|
+
*/
|
231
|
+
buildContainer: function() {
|
232
|
+
this.$container = $(this.options.buttonContainer);
|
233
|
+
this.$container.on('show.bs.dropdown', this.options.onDropdownShow);
|
234
|
+
this.$container.on('hide.bs.dropdown', this.options.onDropdownHide);
|
235
|
+
},
|
236
|
+
|
237
|
+
/**
|
238
|
+
* Builds the button of the multiselect.
|
239
|
+
*/
|
240
|
+
buildButton: function() {
|
241
|
+
this.$button = $(this.options.templates.button).addClass(this.options.buttonClass);
|
242
|
+
|
243
|
+
// Adopt active state.
|
244
|
+
if (this.$select.prop('disabled')) {
|
245
|
+
this.disable();
|
246
|
+
}
|
247
|
+
else {
|
248
|
+
this.enable();
|
249
|
+
}
|
250
|
+
|
251
|
+
// Manually add button width if set.
|
252
|
+
if (this.options.buttonWidth && this.options.buttonWidth !== 'auto') {
|
253
|
+
this.$button.css({
|
254
|
+
'width' : this.options.buttonWidth
|
255
|
+
});
|
256
|
+
}
|
257
|
+
|
258
|
+
// Keep the tab index from the select.
|
259
|
+
var tabindex = this.$select.attr('tabindex');
|
260
|
+
if (tabindex) {
|
261
|
+
this.$button.attr('tabindex', tabindex);
|
262
|
+
}
|
263
|
+
|
264
|
+
this.$container.prepend(this.$button);
|
265
|
+
},
|
266
|
+
|
267
|
+
/**
|
268
|
+
* Builds the ul representing the dropdown menu.
|
269
|
+
*/
|
270
|
+
buildDropdown: function() {
|
271
|
+
|
272
|
+
// Build ul.
|
273
|
+
this.$ul = $(this.options.templates.ul);
|
274
|
+
|
275
|
+
if (this.options.dropRight) {
|
276
|
+
this.$ul.addClass('pull-right');
|
277
|
+
}
|
278
|
+
|
279
|
+
// Set max height of dropdown menu to activate auto scrollbar.
|
280
|
+
if (this.options.maxHeight) {
|
281
|
+
// TODO: Add a class for this option to move the css declarations.
|
282
|
+
this.$ul.css({
|
283
|
+
'max-height': this.options.maxHeight + 'px',
|
284
|
+
'overflow-y': 'auto',
|
285
|
+
'overflow-x': 'hidden'
|
286
|
+
});
|
287
|
+
}
|
288
|
+
|
289
|
+
this.$container.append(this.$ul);
|
290
|
+
},
|
291
|
+
|
292
|
+
/**
|
293
|
+
* Build the dropdown options and binds all nessecary events.
|
294
|
+
* Uses createDivider and createOptionValue to create the necessary options.
|
295
|
+
*/
|
296
|
+
buildDropdownOptions: function() {
|
297
|
+
|
298
|
+
this.$select.children().each($.proxy(function(index, element) {
|
299
|
+
|
300
|
+
// Support optgroups and options without a group simultaneously.
|
301
|
+
var tag = $(element).prop('tagName')
|
302
|
+
.toLowerCase();
|
303
|
+
|
304
|
+
if (tag === 'optgroup') {
|
305
|
+
this.createOptgroup(element);
|
306
|
+
}
|
307
|
+
else if (tag === 'option') {
|
308
|
+
|
309
|
+
if ($(element).data('role') === 'divider') {
|
310
|
+
this.createDivider();
|
311
|
+
}
|
312
|
+
else {
|
313
|
+
this.createOptionValue(element);
|
314
|
+
}
|
315
|
+
|
316
|
+
}
|
317
|
+
|
318
|
+
// Other illegal tags will be ignored.
|
319
|
+
}, this));
|
320
|
+
|
321
|
+
// Bind the change event on the dropdown elements.
|
322
|
+
$('li input', this.$ul).on('change', $.proxy(function(event) {
|
323
|
+
var $target = $(event.target);
|
324
|
+
|
325
|
+
var checked = $target.prop('checked') || false;
|
326
|
+
var isSelectAllOption = $target.val() === this.options.selectAllValue;
|
327
|
+
|
328
|
+
// Apply or unapply the configured selected class.
|
329
|
+
if (this.options.selectedClass) {
|
330
|
+
if (checked) {
|
331
|
+
$target.parents('li')
|
332
|
+
.addClass(this.options.selectedClass);
|
333
|
+
}
|
334
|
+
else {
|
335
|
+
$target.parents('li')
|
336
|
+
.removeClass(this.options.selectedClass);
|
337
|
+
}
|
338
|
+
}
|
339
|
+
|
340
|
+
// Get the corresponding option.
|
341
|
+
var value = $target.val();
|
342
|
+
var $option = this.getOptionByValue(value);
|
343
|
+
|
344
|
+
var $optionsNotThis = $('option', this.$select).not($option);
|
345
|
+
var $checkboxesNotThis = $('input', this.$container).not($target);
|
346
|
+
|
347
|
+
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
|
+
if (checked) {
|
357
|
+
this.select(values);
|
358
|
+
}
|
359
|
+
else {
|
360
|
+
this.deselect(values);
|
361
|
+
}
|
362
|
+
}
|
363
|
+
|
364
|
+
if (checked) {
|
365
|
+
$option.prop('selected', true);
|
366
|
+
|
367
|
+
if (this.options.multiple) {
|
368
|
+
// Simply select additional option.
|
369
|
+
$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);
|
375
|
+
}
|
376
|
+
|
377
|
+
$($checkboxesNotThis).prop('checked', false);
|
378
|
+
$optionsNotThis.prop('selected', false);
|
379
|
+
|
380
|
+
// It's a single selection, so close.
|
381
|
+
this.$button.click();
|
382
|
+
}
|
383
|
+
|
384
|
+
if (this.options.selectedClass === "active") {
|
385
|
+
$optionsNotThis.parents("a").css("outline", "");
|
386
|
+
}
|
387
|
+
}
|
388
|
+
else {
|
389
|
+
// Unselect option.
|
390
|
+
$option.prop('selected', false);
|
391
|
+
}
|
392
|
+
|
393
|
+
this.$select.change();
|
394
|
+
this.options.onChange($option, checked);
|
395
|
+
|
396
|
+
this.updateButtonText();
|
397
|
+
this.updateSelectAll();
|
398
|
+
|
399
|
+
if(this.options.preventInputChangeEvent) {
|
400
|
+
return false;
|
401
|
+
}
|
402
|
+
}, this));
|
403
|
+
|
404
|
+
$('li a', this.$ul).on('touchstart click', function(event) {
|
405
|
+
event.stopPropagation();
|
406
|
+
|
407
|
+
var $target = $(event.target);
|
408
|
+
|
409
|
+
if (event.shiftKey) {
|
410
|
+
var checked = $target.prop('checked') || false;
|
411
|
+
|
412
|
+
if (checked) {
|
413
|
+
var prev = $target.parents('li:last')
|
414
|
+
.siblings('li[class="active"]:first');
|
415
|
+
|
416
|
+
var currentIdx = $target.parents('li')
|
417
|
+
.index();
|
418
|
+
var prevIdx = prev.index();
|
419
|
+
|
420
|
+
if (currentIdx > prevIdx) {
|
421
|
+
$target.parents("li:last").prevUntil(prev).each(
|
422
|
+
function() {
|
423
|
+
$(this).find("input:first").prop("checked", true)
|
424
|
+
.trigger("change");
|
425
|
+
}
|
426
|
+
);
|
427
|
+
}
|
428
|
+
else {
|
429
|
+
$target.parents("li:last").nextUntil(prev).each(
|
430
|
+
function() {
|
431
|
+
$(this).find("input:first").prop("checked", true)
|
432
|
+
.trigger("change");
|
433
|
+
}
|
434
|
+
);
|
435
|
+
}
|
436
|
+
}
|
437
|
+
}
|
438
|
+
|
439
|
+
$target.blur();
|
440
|
+
});
|
441
|
+
|
442
|
+
// Keyboard support.
|
443
|
+
this.$container.on('keydown', $.proxy(function(event) {
|
444
|
+
if ($('input[type="text"]', this.$container).is(':focus')) {
|
445
|
+
return;
|
446
|
+
}
|
447
|
+
if ((event.keyCode === 9 || event.keyCode === 27)
|
448
|
+
&& this.$container.hasClass('open')) {
|
449
|
+
|
450
|
+
// Close on tab or escape.
|
451
|
+
this.$button.click();
|
452
|
+
}
|
453
|
+
else {
|
454
|
+
var $items = $(this.$container).find("li:not(.divider):visible a");
|
455
|
+
|
456
|
+
if (!$items.length) {
|
457
|
+
return;
|
458
|
+
}
|
459
|
+
|
460
|
+
var index = $items.index($items.filter(':focus'));
|
461
|
+
|
462
|
+
// Navigation up.
|
463
|
+
if (event.keyCode === 38 && index > 0) {
|
464
|
+
index--;
|
465
|
+
}
|
466
|
+
// Navigate down.
|
467
|
+
else if (event.keyCode === 40 && index < $items.length - 1) {
|
468
|
+
index++;
|
469
|
+
}
|
470
|
+
else if (!~index) {
|
471
|
+
index = 0;
|
472
|
+
}
|
473
|
+
|
474
|
+
var $current = $items.eq(index);
|
475
|
+
$current.focus();
|
476
|
+
|
477
|
+
if (event.keyCode === 32 || event.keyCode === 13) {
|
478
|
+
var $checkbox = $current.find('input');
|
479
|
+
|
480
|
+
$checkbox.prop("checked", !$checkbox.prop("checked"));
|
481
|
+
$checkbox.change();
|
482
|
+
}
|
483
|
+
|
484
|
+
event.stopPropagation();
|
485
|
+
event.preventDefault();
|
486
|
+
}
|
487
|
+
}, this));
|
488
|
+
},
|
489
|
+
|
490
|
+
/**
|
491
|
+
* Create an option using the given select option.
|
492
|
+
*
|
493
|
+
* @param {jQuery} element
|
494
|
+
*/
|
495
|
+
createOptionValue: function(element) {
|
496
|
+
if ($(element).is(':selected')) {
|
497
|
+
$(element).prop('selected', true);
|
498
|
+
}
|
499
|
+
|
500
|
+
// Support the label attribute on options.
|
501
|
+
var label = this.options.label(element);
|
502
|
+
var value = $(element).val();
|
503
|
+
var inputType = this.options.multiple ? "checkbox" : "radio";
|
504
|
+
|
505
|
+
var $li = $(this.options.templates.li);
|
506
|
+
$('label', $li).addClass(inputType);
|
507
|
+
$('label', $li).append('<input type="' + inputType + '" name="' + this.options.checkboxName + '" />');
|
508
|
+
|
509
|
+
var selected = $(element).prop('selected') || false;
|
510
|
+
var $checkbox = $('input', $li);
|
511
|
+
$checkbox.val(value);
|
512
|
+
|
513
|
+
if (value === this.options.selectAllValue) {
|
514
|
+
$checkbox.parent().parent()
|
515
|
+
.addClass('multiselect-all');
|
516
|
+
}
|
517
|
+
|
518
|
+
$('label', $li).append(" " + label);
|
519
|
+
|
520
|
+
this.$ul.append($li);
|
521
|
+
|
522
|
+
if ($(element).is(':disabled')) {
|
523
|
+
$checkbox.attr('disabled', 'disabled')
|
524
|
+
.prop('disabled', true)
|
525
|
+
.parents('li')
|
526
|
+
.addClass('disabled');
|
527
|
+
}
|
528
|
+
|
529
|
+
$checkbox.prop('checked', selected);
|
530
|
+
|
531
|
+
if (selected && this.options.selectedClass) {
|
532
|
+
$checkbox.parents('li')
|
533
|
+
.addClass(this.options.selectedClass);
|
534
|
+
}
|
535
|
+
},
|
536
|
+
|
537
|
+
/**
|
538
|
+
* Creates a divider using the given select option.
|
539
|
+
*
|
540
|
+
* @param {jQuery} element
|
541
|
+
*/
|
542
|
+
createDivider: function(element) {
|
543
|
+
var $divider = $(this.options.templates.divider);
|
544
|
+
this.$ul.append($divider);
|
545
|
+
},
|
546
|
+
|
547
|
+
/**
|
548
|
+
* Creates an optgroup.
|
549
|
+
*
|
550
|
+
* @param {jQuery} group
|
551
|
+
*/
|
552
|
+
createOptgroup: function(group) {
|
553
|
+
var groupName = $(group).prop('label');
|
554
|
+
|
555
|
+
// Add a header for the group.
|
556
|
+
var $li = $(this.options.templates.liGroup);
|
557
|
+
$('label', $li).text(groupName);
|
558
|
+
|
559
|
+
this.$ul.append($li);
|
560
|
+
|
561
|
+
if ($(group).is(':disabled')) {
|
562
|
+
$li.addClass('disabled');
|
563
|
+
}
|
564
|
+
|
565
|
+
// Add the options of the group.
|
566
|
+
$('option', group).each($.proxy(function(index, element) {
|
567
|
+
this.createOptionValue(element);
|
568
|
+
}, this));
|
569
|
+
},
|
570
|
+
|
571
|
+
/**
|
572
|
+
* Build the selct all.
|
573
|
+
* Checks if a select all ahs already been created.
|
574
|
+
*/
|
575
|
+
buildSelectAll: function() {
|
576
|
+
var alreadyHasSelectAll = this.hasSelectAll();
|
577
|
+
|
578
|
+
if (!alreadyHasSelectAll && this.options.includeSelectAllOption && this.options.multiple
|
579
|
+
&& $('option[data-role!="divider"]', this.$select).length > this.options.includeSelectAllIfMoreThan) {
|
580
|
+
|
581
|
+
// Check whether to add a divider after the select all.
|
582
|
+
if (this.options.includeSelectAllDivider) {
|
583
|
+
this.$select.prepend('<option value="" disabled="disabled" data-role="divider">');
|
584
|
+
}
|
585
|
+
|
586
|
+
this.$select.prepend('<option value="' + this.options.selectAllValue + '">' + this.options.selectAllText + '</option>');
|
587
|
+
}
|
588
|
+
},
|
589
|
+
|
590
|
+
/**
|
591
|
+
* Builds the filter.
|
592
|
+
*/
|
593
|
+
buildFilter: function() {
|
594
|
+
|
595
|
+
// Build filter if filtering OR case insensitive filtering is enabled and the number of options exceeds (or equals) enableFilterLength.
|
596
|
+
if (this.options.enableFiltering || this.options.enableCaseInsensitiveFiltering) {
|
597
|
+
var enableFilterLength = Math.max(this.options.enableFiltering, this.options.enableCaseInsensitiveFiltering);
|
598
|
+
|
599
|
+
if (this.$select.find('option').length >= enableFilterLength) {
|
600
|
+
|
601
|
+
this.$filter = $(this.options.templates.filter);
|
602
|
+
$('input', this.$filter).attr('placeholder', this.options.filterPlaceholder);
|
603
|
+
this.$ul.prepend(this.$filter);
|
604
|
+
|
605
|
+
this.$filter.val(this.query).on('click', function(event) {
|
606
|
+
event.stopPropagation();
|
607
|
+
}).on('input keydown', $.proxy(function(event) {
|
608
|
+
// This is useful to catch "keydown" events after the browser has updated the control.
|
609
|
+
clearTimeout(this.searchTimeout);
|
610
|
+
|
611
|
+
this.searchTimeout = this.asyncFunction($.proxy(function() {
|
612
|
+
|
613
|
+
if (this.query !== event.target.value) {
|
614
|
+
this.query = event.target.value;
|
615
|
+
|
616
|
+
$.each($('li', this.$ul), $.proxy(function(index, element) {
|
617
|
+
var value = $('input', element).val();
|
618
|
+
var text = $('label', element).text();
|
619
|
+
|
620
|
+
var filterCandidate = '';
|
621
|
+
if ((this.options.filterBehavior === 'text')) {
|
622
|
+
filterCandidate = text;
|
623
|
+
}
|
624
|
+
else if ((this.options.filterBehavior === 'value')) {
|
625
|
+
filterCandidate = value;
|
626
|
+
}
|
627
|
+
else if (this.options.filterBehavior === 'both') {
|
628
|
+
filterCandidate = text + '\n' + value;
|
629
|
+
}
|
630
|
+
|
631
|
+
if (value !== this.options.selectAllValue && text) {
|
632
|
+
// by default lets assume that element is not
|
633
|
+
// interesting for this search
|
634
|
+
var showElement = false;
|
635
|
+
|
636
|
+
if (this.options.enableCaseInsensitiveFiltering && filterCandidate.toLowerCase().indexOf(this.query.toLowerCase()) > -1) {
|
637
|
+
showElement = true;
|
638
|
+
}
|
639
|
+
else if (filterCandidate.indexOf(this.query) > -1) {
|
640
|
+
showElement = true;
|
641
|
+
}
|
642
|
+
|
643
|
+
if (showElement) {
|
644
|
+
$(element).show();
|
645
|
+
}
|
646
|
+
else {
|
647
|
+
$(element).hide();
|
648
|
+
}
|
649
|
+
}
|
650
|
+
}, this));
|
651
|
+
}
|
652
|
+
|
653
|
+
// TODO: check whether select all option needs to be updated.
|
654
|
+
}, this), 300, this);
|
655
|
+
}, this));
|
656
|
+
}
|
657
|
+
}
|
658
|
+
},
|
659
|
+
|
660
|
+
/**
|
661
|
+
* Unbinds the whole plugin.
|
662
|
+
*/
|
663
|
+
destroy: function() {
|
664
|
+
this.$container.remove();
|
665
|
+
this.$select.show();
|
666
|
+
this.$select.data('multiselect', null);
|
667
|
+
},
|
668
|
+
|
669
|
+
/**
|
670
|
+
* Refreshs the multiselect based on the selected options of the select.
|
671
|
+
*/
|
672
|
+
refresh: function() {
|
673
|
+
$('option', this.$select).each($.proxy(function(index, element) {
|
674
|
+
var $input = $('li input', this.$ul).filter(function() {
|
675
|
+
return $(this).val() === $(element).val();
|
676
|
+
});
|
677
|
+
|
678
|
+
if ($(element).is(':selected')) {
|
679
|
+
$input.prop('checked', true);
|
680
|
+
|
681
|
+
if (this.options.selectedClass) {
|
682
|
+
$input.parents('li')
|
683
|
+
.addClass(this.options.selectedClass);
|
684
|
+
}
|
685
|
+
}
|
686
|
+
else {
|
687
|
+
$input.prop('checked', false);
|
688
|
+
|
689
|
+
if (this.options.selectedClass) {
|
690
|
+
$input.parents('li')
|
691
|
+
.removeClass(this.options.selectedClass);
|
692
|
+
}
|
693
|
+
}
|
694
|
+
|
695
|
+
if ($(element).is(":disabled")) {
|
696
|
+
$input.attr('disabled', 'disabled')
|
697
|
+
.prop('disabled', true)
|
698
|
+
.parents('li')
|
699
|
+
.addClass('disabled');
|
700
|
+
}
|
701
|
+
else {
|
702
|
+
$input.prop('disabled', false)
|
703
|
+
.parents('li')
|
704
|
+
.removeClass('disabled');
|
705
|
+
}
|
706
|
+
}, this));
|
707
|
+
|
708
|
+
this.updateButtonText();
|
709
|
+
this.updateSelectAll();
|
710
|
+
},
|
711
|
+
|
712
|
+
/**
|
713
|
+
* Select all options of the given values.
|
714
|
+
*
|
715
|
+
* @param {Array} selectValues
|
716
|
+
*/
|
717
|
+
select: function(selectValues) {
|
718
|
+
if(!$.isArray(selectValues)) {
|
719
|
+
selectValues = [selectValues];
|
720
|
+
}
|
721
|
+
|
722
|
+
for (var i = 0; i < selectValues.length; i++) {
|
723
|
+
var value = selectValues[i];
|
724
|
+
|
725
|
+
var $option = this.getOptionByValue(value);
|
726
|
+
var $checkbox = this.getInputByValue(value);
|
727
|
+
|
728
|
+
if (this.options.selectedClass) {
|
729
|
+
$checkbox.parents('li')
|
730
|
+
.addClass(this.options.selectedClass);
|
731
|
+
}
|
732
|
+
|
733
|
+
$checkbox.prop('checked', true);
|
734
|
+
$option.prop('selected', true);
|
735
|
+
}
|
736
|
+
|
737
|
+
this.updateButtonText();
|
738
|
+
},
|
739
|
+
|
740
|
+
/**
|
741
|
+
* Clears all selected items
|
742
|
+
*
|
743
|
+
*/
|
744
|
+
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
|
+
}
|
759
|
+
},
|
760
|
+
|
761
|
+
/**
|
762
|
+
* Deselects all options of the given values.
|
763
|
+
*
|
764
|
+
* @param {Array} deselectValues
|
765
|
+
*/
|
766
|
+
deselect: function(deselectValues) {
|
767
|
+
if(!$.isArray(deselectValues)) {
|
768
|
+
deselectValues = [deselectValues];
|
769
|
+
}
|
770
|
+
|
771
|
+
for (var i = 0; i < deselectValues.length; i++) {
|
772
|
+
|
773
|
+
var value = deselectValues[i];
|
774
|
+
|
775
|
+
var $option = this.getOptionByValue(value);
|
776
|
+
var $checkbox = this.getInputByValue(value);
|
777
|
+
|
778
|
+
if (this.options.selectedClass) {
|
779
|
+
$checkbox.parents('li')
|
780
|
+
.removeClass(this.options.selectedClass);
|
781
|
+
}
|
782
|
+
|
783
|
+
$checkbox.prop('checked', false);
|
784
|
+
$option.prop('selected', false);
|
785
|
+
}
|
786
|
+
|
787
|
+
this.updateButtonText();
|
788
|
+
},
|
789
|
+
|
790
|
+
/**
|
791
|
+
* Rebuild the plugin.
|
792
|
+
* Rebuilds the dropdown, the filter and the select all option.
|
793
|
+
*/
|
794
|
+
rebuild: function() {
|
795
|
+
this.$ul.html('');
|
796
|
+
|
797
|
+
// Remove select all option in select.
|
798
|
+
$('option[value="' + this.options.selectAllValue + '"]', this.$select).remove();
|
799
|
+
|
800
|
+
// Important to distinguish between radios and checkboxes.
|
801
|
+
this.options.multiple = this.$select.attr('multiple') === "multiple";
|
802
|
+
|
803
|
+
this.buildSelectAll();
|
804
|
+
this.buildDropdownOptions();
|
805
|
+
this.buildFilter();
|
806
|
+
|
807
|
+
this.updateButtonText();
|
808
|
+
this.updateSelectAll();
|
809
|
+
},
|
810
|
+
|
811
|
+
/**
|
812
|
+
* The provided data will be used to build the dropdown.
|
813
|
+
*
|
814
|
+
* @param {Array} dataprovider
|
815
|
+
*/
|
816
|
+
dataprovider: function(dataprovider) {
|
817
|
+
var optionDOM = "";
|
818
|
+
dataprovider.forEach(function (option) {
|
819
|
+
optionDOM += '<option value="' + option.value + '">' + option.label + '</option>';
|
820
|
+
});
|
821
|
+
|
822
|
+
this.$select.html(optionDOM);
|
823
|
+
this.rebuild();
|
824
|
+
},
|
825
|
+
|
826
|
+
/**
|
827
|
+
* Enable the multiselect.
|
828
|
+
*/
|
829
|
+
enable: function() {
|
830
|
+
this.$select.prop('disabled', false);
|
831
|
+
this.$button.prop('disabled', false)
|
832
|
+
.removeClass('disabled');
|
833
|
+
},
|
834
|
+
|
835
|
+
/**
|
836
|
+
* Disable the multiselect.
|
837
|
+
*/
|
838
|
+
disable: function() {
|
839
|
+
this.$select.prop('disabled', true);
|
840
|
+
this.$button.prop('disabled', true)
|
841
|
+
.addClass('disabled');
|
842
|
+
},
|
843
|
+
|
844
|
+
/**
|
845
|
+
* Set the options.
|
846
|
+
*
|
847
|
+
* @param {Array} options
|
848
|
+
*/
|
849
|
+
setOptions: function(options) {
|
850
|
+
this.options = this.mergeOptions(options);
|
851
|
+
},
|
852
|
+
|
853
|
+
/**
|
854
|
+
* Merges the given options with the default options.
|
855
|
+
*
|
856
|
+
* @param {Array} options
|
857
|
+
* @returns {Array}
|
858
|
+
*/
|
859
|
+
mergeOptions: function(options) {
|
860
|
+
return $.extend(true, {}, this.defaults, options);
|
861
|
+
},
|
862
|
+
|
863
|
+
/**
|
864
|
+
* Checks whether a select all option is present.
|
865
|
+
*
|
866
|
+
* @returns {Boolean}
|
867
|
+
*/
|
868
|
+
hasSelectAll: function() {
|
869
|
+
return $('option[value="' + this.options.selectAllValue + '"]', this.$select).length > 0;
|
870
|
+
},
|
871
|
+
|
872
|
+
/**
|
873
|
+
* Updates the select all option based on the currently selected options.
|
874
|
+
*/
|
875
|
+
updateSelectAll: function() {
|
876
|
+
if (this.hasSelectAll()) {
|
877
|
+
var selected = this.getSelected();
|
878
|
+
|
879
|
+
if (selected.length === $('option:not([data-role=divider])', this.$select).length - 1) {
|
880
|
+
this.select(this.options.selectAllValue);
|
881
|
+
}
|
882
|
+
else {
|
883
|
+
this.deselect(this.options.selectAllValue);
|
884
|
+
}
|
885
|
+
}
|
886
|
+
},
|
887
|
+
|
888
|
+
/**
|
889
|
+
* Update the button text and its title based on the currently selected options.
|
890
|
+
*/
|
891
|
+
updateButtonText: function() {
|
892
|
+
var options = this.getSelected();
|
893
|
+
|
894
|
+
// First update the displayed button text.
|
895
|
+
$('button', this.$container).html(this.options.buttonText(options, this.$select));
|
896
|
+
|
897
|
+
// Now update the title attribute of the button.
|
898
|
+
$('button', this.$container).attr('title', this.options.buttonTitle(options, this.$select));
|
899
|
+
|
900
|
+
},
|
901
|
+
|
902
|
+
/**
|
903
|
+
* Get all selected options.
|
904
|
+
*
|
905
|
+
* @returns {jQUery}
|
906
|
+
*/
|
907
|
+
getSelected: function() {
|
908
|
+
return $('option[value!="' + this.options.selectAllValue + '"]:selected', this.$select).filter(function() {
|
909
|
+
return $(this).prop('selected');
|
910
|
+
});
|
911
|
+
},
|
912
|
+
|
913
|
+
/**
|
914
|
+
* Gets a select option by its value.
|
915
|
+
*
|
916
|
+
* @param {String} value
|
917
|
+
* @returns {jQuery}
|
918
|
+
*/
|
919
|
+
getOptionByValue: function (value) {
|
920
|
+
|
921
|
+
var options = $('option', this.$select);
|
922
|
+
var valueToCompare = value.toString();
|
923
|
+
|
924
|
+
for (var i = 0; i < options.length; i = i + 1) {
|
925
|
+
var option = options[i];
|
926
|
+
if (option.value === valueToCompare) {
|
927
|
+
return $(option);
|
928
|
+
}
|
929
|
+
}
|
930
|
+
},
|
931
|
+
|
932
|
+
/**
|
933
|
+
* Get the input (radio/checkbox) by its value.
|
934
|
+
*
|
935
|
+
* @param {String} value
|
936
|
+
* @returns {jQuery}
|
937
|
+
*/
|
938
|
+
getInputByValue: function (value) {
|
939
|
+
|
940
|
+
var checkboxes = $('li input', this.$ul);
|
941
|
+
var valueToCompare = value.toString();
|
942
|
+
|
943
|
+
for (var i = 0; i < checkboxes.length; i = i + 1) {
|
944
|
+
var checkbox = checkboxes[i];
|
945
|
+
if (checkbox.value === valueToCompare) {
|
946
|
+
return $(checkbox);
|
947
|
+
}
|
948
|
+
}
|
949
|
+
},
|
950
|
+
|
951
|
+
/**
|
952
|
+
* Used for knockout integration.
|
953
|
+
*/
|
954
|
+
updateOriginalOptions: function() {
|
955
|
+
this.originalOptions = this.$select.clone()[0].options;
|
956
|
+
},
|
957
|
+
|
958
|
+
asyncFunction: function(callback, timeout, self) {
|
959
|
+
var args = Array.prototype.slice.call(arguments, 3);
|
960
|
+
return setTimeout(function() {
|
961
|
+
callback.apply(self || window, args);
|
962
|
+
}, timeout);
|
963
|
+
}
|
964
|
+
};
|
965
|
+
|
966
|
+
$.fn.multiselect = function(option, parameter) {
|
967
|
+
return this.each(function() {
|
968
|
+
var data = $(this).data('multiselect');
|
969
|
+
var options = typeof option === 'object' && option;
|
970
|
+
|
971
|
+
// Initialize the multiselect.
|
972
|
+
if (!data) {
|
973
|
+
data = new Multiselect(this, options);
|
974
|
+
$(this).data('multiselect', data);
|
975
|
+
}
|
976
|
+
|
977
|
+
// Call multiselect method.
|
978
|
+
if (typeof option === 'string') {
|
979
|
+
data[option](parameter);
|
980
|
+
|
981
|
+
if (option === 'destroy') {
|
982
|
+
$(this).data('multiselect', false);
|
983
|
+
}
|
984
|
+
}
|
985
|
+
});
|
986
|
+
};
|
987
|
+
|
988
|
+
$.fn.multiselect.Constructor = Multiselect;
|
989
|
+
|
990
|
+
$(function() {
|
991
|
+
$("select[data-role=multiselect]").multiselect();
|
992
|
+
});
|
993
|
+
|
994
|
+
}(window.jQuery);
|