summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoristeven <isteven@server.fake>2014-03-28 17:53:21 +0800
committeristeven <isteven@server.fake>2014-03-28 17:53:21 +0800
commit2f283f174c1d8b521f74b7eff4b67dbe171b18e7 (patch)
tree3c2bd217bf11f043e85d8596b282630e96f704a1
parent9ded8a2d388383deff8f056d979de974061f04d1 (diff)
downloadangular-multi-select-2f283f174c1d8b521f74b7eff4b67dbe171b18e7.zip
angular-multi-select-2f283f174c1d8b521f74b7eff4b67dbe171b18e7.tar.gz
angular-multi-select-2f283f174c1d8b521f74b7eff4b67dbe171b18e7.tar.bz2
Removed divs inside button tag
Changed button into div and make it responsive Removed no-wrap from CSS Used 9662 HTML char as the caret. Caret class is still available.
-rw-r--r--README.md19
-rw-r--r--angular-multi-select.css15
-rw-r--r--angular-multi-select.js156
-rw-r--r--multiselect.htm19
-rw-r--r--screenshot.jpgbin20586 -> 20551 bytes
5 files changed, 109 insertions, 100 deletions
diff --git a/README.md b/README.md
index 4f354a4..7fc00f1 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,6 @@ Features
- Set orientation of checkboxes
- Enable / disable checkboxes
- Set maximum number of items to be displayed on the button label
- - Maximum height of checkbox layer in pixels (will show scrollbar on overflow)
- Utilizes AngularJS filter
- Responsive to some extent
@@ -27,7 +26,6 @@ Usage
output-model="output_list"
orientation="vertical"
max-labels="4"
- max-height="500"
is-disabled="multi_select_state" >
</div>
@@ -35,7 +33,7 @@ Usage
<multi-select
...
- ...
+ ... >
</multi-select>
Attributes / Options
@@ -59,7 +57,7 @@ input-model property that you want to display on the button & checkboxes. Separa
<br />Example:
item-label="firstName lastName"
-##### tick-property (REQUIRED):
+##### tick-property (REQUIRED)
input-model property with a boolean value that represent the state of a checkbox.
<br />For example:
- item-ticker is "selected"
@@ -69,7 +67,7 @@ input-model property with a boolean value that represent the state of a checkbox
- if isOn === true, checkbox will be ticked.
- If isOn === false, checkbox will not be ticked.
-##### output-model:
+##### output-model
A $scope variable. If specified, will list all the selected checkboxes model.
##### orientation ( "vertical" | "horizontal" )
@@ -78,11 +76,7 @@ Orientation of the list of checkboxes. If not specified, the default will be "ve
##### max-labels
Maximum number of items that will be displayed in the dropdown button. If not specified, will display all selected items.
<br />Example: "1"
-<br />- Using the input-model above, then button will display: "Bruce Wayne, ... [ Selected: 2 ]"
-
-##### max-height
-Maximum height of the list of checkboxes in pixels. Will show scrollbar on overflow.
-<br />Example: "100".
+<br />- Using the input-model above, then button will display: "Bruce Wayne, ... [ Total: 2 ]"
##### is-disabled
Expression to be evaluated. Will disable or enable the checkboxes.
@@ -93,7 +87,10 @@ Example
--
Download all the files into a same folder and open multiselect.htm.
<br />Or, if you prefer JSfiddle: http://jsfiddle.net/s47RE/
-<br />_I don't know why but JSfiddle requires you to click on the caret icon (the small triangle button) to toggle the dropdown. However, the multiselect.htm sample works OK in all browsers I tested._
+
+Note
+--
+I use HTML entity 9662 for the caret (downward pointing arrow). If you want a better looking arrow, you can use the .caret class in the CSS file. Just create a span using that .caret. Do note that this span won't toggle the dropdown. You need to click outside the span.
Requirements
--
diff --git a/angular-multi-select.css b/angular-multi-select.css
index 8031a0c..6a48c6b 100644
--- a/angular-multi-select.css
+++ b/angular-multi-select.css
@@ -1,4 +1,8 @@
-.multiSelect {
+body {
+ font-family: "Verdana";
+ font-size: 14px;
+}
+.multiSelect {
}
.multiSelect.inlineBlock {
@@ -7,14 +11,14 @@
.multiSelect .button {
display: block;
- margin-bottom: 0;
+ position: relative;
+ margin:0 auto;
font-weight: normal;
text-align: center;
vertical-align: middle;
cursor: pointer;
- background-image: none;
+ background-image: none;
border: 1px solid transparent;
- white-space: nowrap;
padding: 6px 12px;
font-size: 14px;
line-height: 1.428571429;
@@ -26,7 +30,7 @@
user-select: none;
background-color: #5CB85C;
border-color: #4CAE4C;
- color: #fff;
+ color: #fff;
}
.multiSelect .helperButton {
@@ -38,7 +42,6 @@
cursor: pointer;
background-image: none;
border: 1px solid #ccc;
- white-space: nowrap;
padding: 2px 2px;
font-size: 14px;
line-height: 1;
diff --git a/angular-multi-select.js b/angular-multi-select.js
index 29fa87c..72dae75 100644
--- a/angular-multi-select.js
+++ b/angular-multi-select.js
@@ -1,11 +1,10 @@
/*
- * Ignatius Steven
* Created: Tue, 14 Jan 2014 - 5:18:02 PM
- * Last update: Wed, 26 Mar 2014 - 11:12:29 AM
*
* Angular JS Multi Select
* Creates a dropdown-like button with checkboxes.
*
+ * Released under MIT License
* --------------------------------------------------------------------------------
* MIT License
*
@@ -47,19 +46,15 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$timeout'
tickProperty : '@',
orientation : '@',
maxLabels : '@',
- maxHeight : '@',
isDisabled : '='
},
template:
'<span class="multiSelect inlineBlock">' +
- '<button type="button" class="multiSelect button multiSelectButton" ng-click="toggleCheckboxes( $event ); refreshSelectedItems();">' +
- '<div ng-if="selectedItems.length <= 0">None selected</div>' +
- '<div ng-if="selectedItems.length > 0" ng-repeat="item in selectedItems | limitTo: varMaxLabels">' +
- '<span ng-if="$index > 0">, </span>{{writeLabel( item )}}' +
- '</div>' +
- '<div ng-if="more">, ... [ Selected: {{selectedItems.length}} ]</div><span class="caret"></span>' +
- '</button>' +
+ '<div class="multiSelect button multiSelectButton" ng-click="toggleCheckboxes( $event ); refreshSelectedItems();">' +
+ '{{buttonLabel}}' +
+ ' &nbsp;&#9662;' +
+ '</div>' +
'<div class="multiSelect checkboxLayer hide" style="{{layerStyle}}">' +
'<div class="multiSelect line">' +
'<span ng-if="!isDisabled">Select: &nbsp;&nbsp;</span>' +
@@ -85,7 +80,7 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$timeout'
$scope.selectedItems = [];
$scope.backUp = [];
$scope.layerStyle = '';
- $scope.varMaxLabels = 0;
+ $scope.buttonLabel = '';
// Checkbox is ticked
$scope.syncItems = function( item ) {
@@ -97,39 +92,71 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$timeout'
// Refresh the button to display the selected items and push into output model if specified
$scope.refreshSelectedItems = function() {
- $scope.selectedItems = [];
+ $scope.buttonLabel = '';
+ $scope.selectedItems = [];
+ ctr = 0;
+
angular.forEach( $scope.inputModel, function( value, key ) {
if ( typeof value !== 'undefined' ) {
if ( value[ $scope.tickProperty ] === true || value[ $scope.tickProperty ] === 'true' ) {
- $scope.selectedItems.push( value );
+ $scope.selectedItems.push( value );
}
}
});
-
+
// Push into output model
if ( typeof attrs.outputModel !== 'undefined' ) {
$scope.outputModel = angular.copy( $scope.selectedItems );
}
+ var tempMaxLabels = $scope.selectedItems.length;
+ if ( typeof $scope.maxLabels !== 'undefined' && $scope.maxLabels !== '' && $scope.maxLabels !== "0" ) {
+ tempMaxLabels = $scope.maxLabels;
+ }
+
// If max amount of labels displayed..
- if ( $scope.selectedItems.length > $scope.maxLabels ) {
+ if ( $scope.selectedItems.length > tempMaxLabels ) {
$scope.more = true;
}
else {
$scope.more = false;
}
- if ( typeof $scope.maxLabels === 'undefined' ) {
- $scope.varMaxLabels = $scope.selectedItems.length;
+
+ // Write label...
+ angular.forEach( $scope.selectedItems, function( value, key ) {
+ if ( typeof value !== 'undefined' ) {
+ if ( ctr < tempMaxLabels ) {
+ $scope.buttonLabel += ( $scope.buttonLabel.length > 0 ? ', ' : '') + $scope.writeLabel( value );
+ }
+ ctr++;
+ }
+ });
+
+ if ( $scope.more === true ) {
+ $scope.buttonLabel += ', ... (Total: ' + $scope.selectedItems.length + ')';
}
- else {
- $scope.varMaxLabels = $scope.maxLabels;
- }
+ }
+
+ // A simple function to parse the item label settings
+ $scope.writeLabel = function( item ) {
+ var label = '';
+ var temp = $scope.itemLabel.split( ' ' );
+ angular.forEach( temp, function( value2, key2 ) {
+ if ( typeof value2 !== 'undefined' ) {
+ angular.forEach( item, function( value1, key1 ) {
+ if ( key1 == value2 ) {
+ label += ' ' + value1;
+ }
+ });
+ }
+ });
+ return label;
}
// UI operations to show/hide checkboxes
$scope.toggleCheckboxes = function( e ) {
- $scope.labelFilter = '';
+ $scope.labelFilter = '';
// We search them based on the class names
var multiSelectIndex = -1;
@@ -137,24 +164,26 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$timeout'
var multiSelectButtons = document.querySelectorAll( '.multiSelectButton' );
for( i=0; i < multiSelectButtons.length; i++ ) {
- if ( e.target == multiSelectButtons[ i ] ) {
+ if ( e.target === multiSelectButtons[ i ] ) {
multiSelectIndex = i;
break;
}
- }
+ }
- for( i=0; i < checkboxes.length; i++ ) {
- if ( i != multiSelectIndex ) {
- checkboxes[i].className = 'multiSelect checkboxLayer hide';
- }
- }
+ if ( multiSelectIndex > -1 ) {
+ for( i=0; i < checkboxes.length; i++ ) {
+ if ( i != multiSelectIndex ) {
+ checkboxes[i].className = 'multiSelect checkboxLayer hide';
+ }
+ }
- if ( checkboxes[ multiSelectIndex ].className == 'multiSelect checkboxLayer hide' ) {
- checkboxes[ multiSelectIndex ].className = 'multiSelect checkboxLayer show';
+ if ( checkboxes[ multiSelectIndex ].className == 'multiSelect checkboxLayer hide' ) {
+ checkboxes[ multiSelectIndex ].className = 'multiSelect checkboxLayer show';
+ }
+ else if ( checkboxes[ multiSelectIndex ].className == 'multiSelect checkboxLayer show' ) {
+ checkboxes[ multiSelectIndex ].className = 'multiSelect checkboxLayer hide';
+ }
}
- else if ( checkboxes[ multiSelectIndex ].className == 'multiSelect checkboxLayer show' ) {
- checkboxes[ multiSelectIndex ].className = 'multiSelect checkboxLayer hide';
- }
}
// Select All / None / Reset
@@ -180,24 +209,28 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$timeout'
default:
}
$scope.refreshSelectedItems();
- }
+ }
- // What's written on the button
- $scope.writeLabel = function( item ) {
- var label = '';
- var temp = $scope.itemLabel.split( ' ' );
- angular.forEach( temp, function( value2, key2 ) {
- if ( typeof value2 !== 'undefined' ) {
- angular.forEach( item, function( value1, key1 ) {
- if ( key1 == value2 ) {
- label += ' ' + value1;
- }
- });
- }
- });
- return label;
+
+ // Generic validation for required attributes
+ validate = function() {
+ if ( typeof $scope.inputModel === 'undefined' ) {
+ alert( 'multi-select ERROR - input model is not defined!' );
+ }
+
+ if ( typeof $scope.itemLabel === 'undefined' ) {
+ alert( 'multi-select ERROR - item label is not defined!' );
+ }
+
+ if ( typeof $scope.tickProperty === 'undefined' ) {
+ alert( 'multi-select ERROR - tick property is not defined!' );
+ }
+
+ validateProperties( $scope.itemLabel.split( ' ' ), $scope.inputModel );
+ validateProperties( new Array( $scope.tickProperty ), $scope.inputModel );
}
+ // Validate whether the properties specified in the directive attributes are present in the input model
validateProperties = function( arrProperties, arrObject ) {
var notThere = false;
var missingProperty = '';
@@ -224,26 +257,7 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$timeout'
/////////////////////
// Logic starts here
/////////////////////
-
-
- // Validations..
- validate = function() {
- if ( typeof $scope.inputModel === 'undefined' ) {
- alert( 'multi-select ERROR - input model is not defined!' );
- }
-
- if ( typeof $scope.itemLabel === 'undefined' ) {
- alert( 'multi-select ERROR - item label is not defined!' );
- }
-
- if ( typeof $scope.tickProperty === 'undefined' ) {
- alert( 'multi-select ERROR - tick property is not defined!' );
- }
-
- validateProperties( $scope.itemLabel.split( ' ' ), $scope.inputModel );
- validateProperties( new Array( $scope.tickProperty ), $scope.inputModel );
- }
-
+
validate();
$scope.refreshSelectedItems();
@@ -260,11 +274,6 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$timeout'
$scope.isDisabled = newVal;
});
- // Checkbox height
- if ( typeof $scope.maxHeight !== 'undefined' ) {
- $scope.layerStyle = 'max-height:' + $scope.maxHeight + 'px; overflow: auto; min-width: auto';
- }
-
// Monitor for clicks outside the button element to hide the checkboxes
angular.element( document ).bind( 'click' , function( e ) {
var checkboxes = document.querySelectorAll( '.checkboxLayer' );
@@ -277,6 +286,7 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$timeout'
}
});
+ // For IE8, perhaps. Not sure if this is really executed.
if ( !Array.prototype.indexOf ) {
Array.prototype.indexOf = function(what, i) {
i = i || 0;
diff --git a/multiselect.htm b/multiselect.htm
index a05f684..6495f9e 100644
--- a/multiselect.htm
+++ b/multiselect.htm
@@ -15,7 +15,7 @@
Minimal:
<br />
- <div
+ <div
multi-select
input-model="minData"
item-label="firstName"
@@ -33,33 +33,32 @@
output-model="resultData"
item-label="firstName lastName"
tick-property="checked"
- orientation="vertical"
+ orientation="horizontal"
max-labels="3"
>
</div>
<br /><br />
- Dynamic input model and checkbox state
+ Use element instead of attribute, update input model on the fly, and toggle checkbox state
<br />
- <div
- multi-select
+ <multi-select
input-model="dynamicData"
item-label="car"
tick-property="ticked"
is-disabled="dinDisabled"
>
- </div>
+ </multi-select>
<br /><br />
- <button type="button" ng-click="dinDisabled = !dinDisabled" >Enable / Disable</button>
- Is disabled: {{dinDisabled}}
-
- <br /><br />
<button type="button" ng-click="switchSource( 'data1' )" >Load data 1</button>
<button type="button" ng-click="switchSource( 'data2' )" >Load data 2</button>
<button type="button" ng-click="switchSource( 'data3' )" >Load data 3</button>
+ <br /><br />
+ <button type="button" ng-click="dinDisabled = !dinDisabled" >Enable / Disable</button>
+ Is disabled: {{dinDisabled}}
+
</body>
<script>
diff --git a/screenshot.jpg b/screenshot.jpg
index dff59b0..9c229d7 100644
--- a/screenshot.jpg
+++ b/screenshot.jpg
Binary files differ