Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bootstrap-multiselect
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
bootstrap-multiselect
Commits
3c219fcc
Commit
3c219fcc
authored
Apr 17, 2016
by
David Stutz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Should fix #699, #679, #680 and #655.
parent
13ccb920
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
147 additions
and
121 deletions
+147
-121
bootstrap-multiselect.js
dist/js/bootstrap-multiselect.js
+103
-119
index.html
index.html
+42
-0
bootstrap-multiselect.js
tests/spec/bootstrap-multiselect.js
+2
-2
No files found.
dist/js/bootstrap-multiselect.js
View file @
3c219fcc
...
...
@@ -387,7 +387,7 @@
enableCaseInsensitiveFiltering
:
false
,
enableFullValueFiltering
:
false
,
enableClickableOptGroups
:
false
,
enableCollapsib
el
OptGroups
:
false
,
enableCollapsib
le
OptGroups
:
false
,
filterPlaceholder
:
'
Search
'
,
// possible options: 'text', 'value', 'both'
filterBehavior
:
'
text
'
,
...
...
@@ -535,7 +535,7 @@
},
this
));
// Bind the change event on the dropdown elements.
$
(
'
li input
'
,
this
.
$ul
).
on
(
'
change
'
,
$
.
proxy
(
function
(
event
)
{
$
(
'
li
:not(.multiselect-group)
input
'
,
this
.
$ul
).
on
(
'
change
'
,
$
.
proxy
(
function
(
event
)
{
var
$target
=
$
(
event
.
target
);
var
checked
=
$target
.
prop
(
'
checked
'
)
||
false
;
...
...
@@ -606,7 +606,11 @@
this
.
updateButtonText
();
this
.
updateSelectAll
();
if
(
this
.
options
.
enableClickableOptGroups
&&
this
.
options
.
multiple
)
{
this
.
updateOptGroups
(
$target
,
checked
);
}
if
(
this
.
options
.
preventInputChangeEvent
)
{
return
false
;
}
...
...
@@ -720,107 +724,73 @@
event
.
preventDefault
();
}
},
this
));
if
(
this
.
options
.
enableClickableOptGroups
&&
this
.
options
.
multiple
)
{
$
(
'
li.multiselect-group
'
,
this
.
$ul
).
on
(
'
click
'
,
$
.
proxy
(
function
(
event
)
{
if
(
this
.
options
.
enableClickableOptGroups
&&
this
.
options
.
multiple
)
{
$
(
"
li.multiselect-group input
"
,
this
.
$ul
).
on
(
"
change
"
,
$
.
proxy
(
function
(
event
)
{
console
.
log
(
'
test
'
)
event
.
stopPropagation
();
console
.
log
(
'
test
'
);
var
group
=
$
(
event
.
target
).
parent
();
// Search all option in optgroup
var
$options
=
group
.
nextUntil
(
'
li.multiselect-group
'
);
var
$visibleOptions
=
$options
.
filter
(
"
:visible:not(.disabled)
"
);
// check or uncheck items
var
allChecked
=
true
;
var
optionInputs
=
$visibleOptions
.
find
(
'
input
'
);
var
$target
=
$
(
event
.
target
);
var
checked
=
$target
.
prop
(
'
checked
'
)
||
false
;
var
$li
=
$
(
event
.
target
).
closest
(
'
li
'
);
var
$group
=
$li
.
nextUntil
(
"
li.multiselect-group
"
).
filter
(
"
:visible:not(.disabled)
"
);
var
$inputs
=
$group
.
find
(
"
input
"
);
var
values
=
[];
var
$options
=
[];
optionInputs
.
each
(
function
()
{
allChecked
=
allChecked
&&
$
(
this
).
prop
(
'
checked
'
);
values
.
push
(
$
(
this
).
val
());
});
if
(
!
allChecked
)
{
$
.
each
(
$inputs
,
$
.
proxy
(
function
(
index
,
input
)
{
var
value
=
$
(
input
).
val
();
values
.
push
(
value
);
$options
.
push
(
this
.
getOptionByValue
(
value
));
},
this
))
if
(
checked
)
{
this
.
select
(
values
,
false
);
}
else
{
this
.
deselect
(
values
,
false
);
}
this
.
options
.
onChange
(
optionInputs
,
!
allChecked
);
},
this
));
this
.
options
.
onChange
(
$options
,
checked
);
// $inputs.prop("checked", checked).trigger("change");
},
this
));
}
if
(
this
.
options
.
enableCollapsibleOptGroups
&&
this
.
options
.
multiple
)
{
$
(
"
li.multiselect-group input
"
,
this
.
$ul
).
off
();
$
(
"
li.multiselect-group
"
,
this
.
$ul
).
siblings
().
not
(
"
li.multiselect-group, li.multiselect-all
"
,
this
.
$ul
).
each
(
function
()
{
//
$("li.multiselect-group input", this.$ul).off();
$
(
"
li.multiselect-group
"
,
this
.
$ul
).
siblings
().
not
(
"
li.multiselect-group, li.multiselect-all
"
,
this
.
$ul
).
each
(
function
()
{
$
(
this
).
toggleClass
(
'
hidden
'
,
true
);
});
$
(
"
li.multiselect-group
"
,
this
.
$ul
).
on
(
"
click
"
,
$
.
proxy
(
function
(
group
)
{
group
.
stopPropagation
();
},
this
));
$
(
"
li.multiselect-group > a > b
"
,
this
.
$ul
).
on
(
"
click
"
,
$
.
proxy
(
function
(
t
)
{
t
.
stopPropagation
();
var
n
=
$
(
t
.
target
).
closest
(
'
li
'
);
var
r
=
n
.
nextUntil
(
"
li.multiselect-group
"
);
var
i
=
true
;
r
.
each
(
function
()
{
i
=
i
&&
$
(
this
).
hasClass
(
'
hidden
'
);
});
r
.
toggleClass
(
'
hidden
'
,
!
i
);
},
this
));
$
(
"
li.multiselect-group > a > input
"
,
this
.
$ul
).
on
(
"
change
"
,
$
.
proxy
(
function
(
t
)
{
t
.
stopPropagation
();
var
n
=
$
(
t
.
target
).
closest
(
'
li
'
);
var
r
=
n
.
nextUntil
(
"
li.multiselect-group
"
,
'
:not(.disabled)
'
);
var
s
=
r
.
find
(
"
input
"
);
$
(
"
li.multiselect-group > a > .caret-container
"
,
this
.
$ul
).
on
(
"
click
"
,
$
.
proxy
(
function
(
event
)
{
event
.
stopPropagation
();
var
$li
=
$
(
event
.
target
).
closest
(
'
li
'
);
var
$inputs
=
$li
.
nextUntil
(
"
li.multiselect-group
"
);
var
i
=
true
;
s
.
each
(
function
()
{
i
=
i
&&
$
(
this
).
prop
(
"
checked
"
);
var
selected
=
true
;
$input
s
.
each
(
function
()
{
selected
=
selected
&&
$
(
this
).
hasClass
(
'
hidden
'
);
});
s
.
prop
(
"
checked
"
,
!
i
).
trigger
(
"
change
"
);
$inputs
.
toggleClass
(
'
hidden
'
,
!
selected
);
},
this
));
// Set the initial selection state of the groups.
$
(
'
li.multiselect-group
'
,
this
.
$ul
).
each
(
function
()
{
var
r
=
$
(
this
).
nextUntil
(
"
li.multiselect-group
"
,
'
:not(.disabled)
'
);
var
s
=
r
.
find
(
"
input
"
);
var
$group
=
$
(
this
).
nextUntil
(
"
li.multiselect-group
"
,
'
:not(.disabled)
'
);
var
$inputs
=
$group
.
find
(
"
input
"
);
var
i
=
true
;
s
.
each
(
function
()
{
i
=
i
&&
$
(
this
).
prop
(
"
checked
"
);
var
selected
=
true
;
$input
s
.
each
(
function
()
{
selected
=
selected
&&
$
(
this
).
prop
(
"
checked
"
);
});
$
(
this
).
find
(
'
input
'
).
prop
(
"
checked
"
,
i
);
$
(
this
).
find
(
'
input
'
).
prop
(
"
checked
"
,
selected
);
});
// Update the group checkbox based on new selections among the
// corresponding children.
$
(
"
li:not(.multiselect-group) input
"
,
this
.
$ul
).
on
(
"
change
"
,
$
.
proxy
(
function
(
t
)
{
t
.
stopPropagation
();
var
n
=
$
(
t
.
target
).
closest
(
'
li
'
);
var
r
=
n
.
prev
(
"
li.multiselect-group
"
,
'
:not(.disabled)
'
);
var
q
=
r
.
nextUntil
(
"
li.multiselect-group
"
,
'
:not(.disabled)
'
);
var
s
=
q
.
find
(
"
input
"
);
var
i
=
$
(
t
.
target
).
prop
(
'
checked
'
);
s
.
each
(
function
()
{
i
=
i
&&
$
(
this
).
prop
(
"
checked
"
);
});
n
.
prev
(
'
li.multiselect-group
'
).
find
(
'
input
'
).
prop
(
'
checked
'
,
i
);
},
this
));
$
(
"
li.multiselect-all
"
,
this
.
$ul
).
css
(
'
background
'
,
'
#f3f3f3
'
).
css
(
'
border-bottom
'
,
'
1px solid #eaeaea
'
);
$
(
"
li.multiselect-
group > a, li.multiselect-
all > a > label.checkbox
"
,
this
.
$ul
).
css
(
'
padding
'
,
'
3px 20px 3px 35px
'
);
$
(
"
li.multiselect-all > a > label.checkbox
"
,
this
.
$ul
).
css
(
'
padding
'
,
'
3px 20px 3px 35px
'
);
$
(
"
li.multiselect-group > a > input
"
,
this
.
$ul
).
css
(
'
margin
'
,
'
4px 0px 5px -20px
'
);
}
},
...
...
@@ -907,50 +877,34 @@
* @param {jQuery} group
*/
createOptgroup
:
function
(
group
)
{
if
(
this
.
options
.
enableCollapsibleOptGroups
&&
this
.
options
.
multiple
)
{
var
label
=
$
(
group
).
attr
(
"
label
"
);
var
value
=
$
(
group
).
attr
(
"
value
"
);
var
r
=
$
(
'
<li class="multiselect-item multiselect-group"><a href="javascript:void(0);"><input type="checkbox" value="
'
+
value
+
'
"/><b>
'
+
label
+
'
<b class="caret"></b></b></a></li>
'
);
if
(
this
.
options
.
enableClickableOptGroups
)
{
r
.
addClass
(
"
multiselect-group-clickable
"
)
}
this
.
$ul
.
append
(
r
);
if
(
$
(
group
).
is
(
"
:disabled
"
))
{
r
.
addClass
(
"
disabled
"
)
}
$
(
"
option
"
,
group
).
each
(
$
.
proxy
(
function
(
$
,
group
)
{
this
.
createOptionValue
(
group
)
},
this
))
var
label
=
$
(
group
).
attr
(
"
label
"
);
var
value
=
$
(
group
).
attr
(
"
value
"
);
var
$li
=
$
(
'
<li class="multiselect-item multiselect-group"><a href="javascript:void(0);"><label><b></b></label></a></li>
'
);
if
(
this
.
options
.
enableHTML
)
{
$
(
'
label b
'
,
$li
).
html
(
"
"
+
label
);
}
else
{
var
groupName
=
$
(
group
).
prop
(
'
label
'
);
// Add a header for the group.
var
$li
=
$
(
this
.
options
.
templates
.
liGroup
);
if
(
this
.
options
.
enableHTML
)
{
$
(
'
label
'
,
$li
).
html
(
groupName
);
}
else
{
$
(
'
label
'
,
$li
).
text
(
groupName
);
}
if
(
this
.
options
.
enableClickableOptGroups
)
{
$li
.
addClass
(
'
multiselect-group-clickable
'
);
}
this
.
$ul
.
append
(
$li
);
if
(
$
(
group
).
is
(
'
:disabled
'
))
{
$li
.
addClass
(
'
disabled
'
);
}
// Add the options of the group.
$
(
'
option
'
,
group
).
each
(
$
.
proxy
(
function
(
index
,
element
)
{
this
.
createOptionValue
(
element
);
},
this
));
$
(
'
label b
'
,
$li
).
text
(
"
"
+
label
);
}
if
(
this
.
options
.
enableCollapsibleOptGroups
&&
this
.
options
.
multiple
)
{
$
(
'
a
'
,
$li
).
append
(
'
<span class="caret-container"><b class="caret"></b></span>
'
);
}
if
(
this
.
options
.
enableClickableOptGroups
&&
this
.
options
.
multiple
)
{
$
(
'
a label
'
,
$li
).
prepend
(
'
<input type="checkbox" value="
'
+
value
+
'
"/>
'
);
}
if
(
$
(
group
).
is
(
'
:disabled
'
))
{
$li
.
addClass
(
'
disabled
'
);
}
this
.
$ul
.
append
(
$li
);
$
(
"
option
"
,
group
).
each
(
$
.
proxy
(
function
(
$
,
group
)
{
this
.
createOptionValue
(
group
);
},
this
))
},
/**
...
...
@@ -1495,7 +1449,37 @@
hasSelectAll
:
function
()
{
return
$
(
'
li.multiselect-all
'
,
this
.
$ul
).
length
>
0
;
},
/**
* Update opt groups.
*/
updateOptGroups
:
function
(
$element
,
checked
)
{
var
$prevs
=
$element
.
closest
(
'
li
'
).
prevUntil
(
'
li.multiselect-group
'
).
filter
(
"
:visible:not(.disabled)
"
);
var
$nexts
=
$element
.
closest
(
'
li
'
).
nextUntil
(
'
li.multiselect-group
'
).
filter
(
"
:visible:not(.disabled)
"
);
var
selected
=
checked
;
$prevs
.
each
(
function
()
{
if
(
!
$
(
'
input
'
,
this
).
prop
(
'
checked
'
))
{
selected
=
false
;
}
});
$nexts
.
each
(
function
()
{
if
(
!
$
(
'
input
'
,
this
).
prop
(
'
checked
'
))
{
selected
=
false
;
}
});
var
$group
=
$element
.
closest
(
'
li
'
).
prevAll
(
'
li.multiselect-group
'
);
if
(
selected
)
{
$
(
'
input
'
,
$group
).
prop
(
'
checked
'
,
true
);
}
else
{
$
(
'
input
'
,
$group
).
prop
(
'
checked
'
,
false
);
}
},
/**
* Updates the select all checkbox based on the currently displayed and selected checkboxes.
*/
...
...
index.html
View file @
3c219fcc
...
...
@@ -617,6 +617,48 @@
<
/script
>
</pre>
</div>
<p>
Both options,
<code>
enableCollapsibleOptGroups
</code>
and
<code>
enableCollapsibleOptGroups
</code>
, can also be combined:
</p>
<p
class=
"alert alert-warning"
>
Note, however, that the behavior of combining both options might not be as expected - play around with the below example to get some intuition.
</p>
<div
class=
"example"
>
<script
type=
"text/javascript"
>
$
(
document
).
ready
(
function
()
{
$
(
'
#example-enableCollapsibleOptGroups-enableClickableOptGroups
'
).
multiselect
({
enableClickableOptGroups
:
true
,
enableCollapsibleOptGroups
:
true
});
});
</script>
<select
id=
"example-enableCollapsibleOptGroups-enableClickableOptGroups"
multiple=
"multiple"
>
<optgroup
label=
"Group 1"
>
<option
value=
"1-1"
disabled
>
Option 1.1
</option>
<option
value=
"1-2"
selected=
"selected"
>
Option 1.2
</option>
<option
value=
"1-3"
selected=
"selected"
>
Option 1.3
</option>
</optgroup>
<optgroup
label=
"Group 2"
>
<option
value=
"2-1"
>
Option 2.1
</option>
<option
value=
"2-2"
>
Option 2.2
</option>
<option
value=
"2-3"
>
Option 2.3
</option>
</optgroup>
</select>
</div>
<div
class=
"highlight"
>
<pre
class=
"prettyprint linenums"
>
<
script type=
"
text/javascript
">
$(document).ready(function() {
$('#example-enableCollapsibleOptGroups-enableClickableOptGroups').multiselect({
enableClickableOptGroups: true,
enableCollapsibleOptGroups: true
});
});
<
/script
>
</pre>
</td>
</tr>
<tr>
...
...
tests/spec/bootstrap-multiselect.js
View file @
3c219fcc
...
...
@@ -266,7 +266,7 @@ describe('Bootstrap Multiselect "Single Selection"', function() {
});
});
describe
(
'
Bootstrap Multiselect "Optgroups"
'
,
function
()
{
describe
(
'
Bootstrap Multiselect "
Clickable
Optgroups"
'
,
function
()
{
// Count the number of onChanges fired.
var
fired
=
0
;
...
...
@@ -297,7 +297,7 @@ describe('Bootstrap Multiselect "Optgroups"', function() {
it
(
'
Should correctly create labels for optgroups.
'
,
function
()
{
expect
(
$
(
'
#multiselect-container li.multiselect-group
'
).
length
).
toBe
(
10
);
expect
(
$
(
'
#multiselect-container li.multiselect-group
-clickable
'
).
length
).
toBe
(
10
);
expect
(
$
(
'
#multiselect-container li.multiselect-group
input
'
).
length
).
toBe
(
10
);
$
(
'
#multiselect-container label.multiselect-group
'
).
each
(
function
()
{
expect
(
$
(
'
input
'
,
$
(
this
)).
length
).
toBe
(
10
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment