From ffdc3c8772d96675d298b79717d7b9cf9c76e1d9 Mon Sep 17 00:00:00 2001 From: lordfriend Date: Mon, 15 Dec 2014 21:29:29 +0800 Subject: [PATCH] add a deep-watch function to enable a deep-watch to collection expression of nya-bs-option. This may make the #32 issue possible to solve --- examples/app2.js | 3 + examples/index2.html | 518 +++++++++++++++++++++++++++++++++++ src/nya-bs-config.js | 12 + src/nya-bs-option.js | 11 +- test/spec/dynamic-feature.js | 36 ++- 5 files changed, 576 insertions(+), 4 deletions(-) create mode 100644 examples/app2.js create mode 100644 examples/index2.html create mode 100644 src/nya-bs-config.js diff --git a/examples/app2.js b/examples/app2.js new file mode 100644 index 0000000..f54aae1 --- /dev/null +++ b/examples/app2.js @@ -0,0 +1,3 @@ +/** + * Created by bob on 12/8/14. + */ diff --git a/examples/index2.html b/examples/index2.html new file mode 100644 index 0000000..15fed97 --- /dev/null +++ b/examples/index2.html @@ -0,0 +1,518 @@ + + + + + nya-bootstrap-select demo + + + + + + + +
+
+

nya-bootstrap-select

+ +

An angular wrapper for Bootstrap-select with dynamic loading options support

+ View on Github +
+
+
+
+

Overview

+ +

This is an angular directive wrapping for popular custom select Bootstrap-select. + Unlike other directives. This directive support ng-repeat in option. +

+ +

All of the Bootstrap-select's + function is supported. + The select result is bound to a model, so you don't need to use + Bootstrap-select's api to get + value. + just write your select in the angular way +

+ +
+
+

Dynamic Examples

+ +

Track by

+ +

Track by is nothing different with ng-repeat

+ +
+

You have select {{dynModel2}}

+

options4 is {{options4}}

+ + +
    +
  1. + + {{option.name}} + + +
  2. +
+
+ +

Group Options

+ +

If you want show grouped options. we assume you have an property which being used to group by. add group by property after the + collection in your nya-bs-option statement

+

add <span class="dropdown-header">{{$group}}</span> before the <a> element

+ +
+

You have select {{dynModel3}}

+

options4 is {{options4}}

+ + + + +
    +
  1. + {{$group}} + + {{option.name}} + + +
  2. +
+
+ +

Object Collection

+

Like ng-repeat, object collection is also supported

+ +
+

You have select {{dynModel4}}

+

options4 is {{options5}}

+ + + + +
    +
  1. + {{$group}} + + {{key}} + + +
  2. +
+
+
+
+

Bootstrap-select Features

+ +

Features borrowed from Bootstrap-select

+ +

Color Class

+ +

set btn-primary, btn-success, btn-info, btn-warning, btn-danger to nya-bs-select

+ +
+
    +
  1. + Alpha + +
  2. +
  3. Bravo
  4. +
  5. Charlie
  6. +
+
    +
  1. Alpha
  2. +
  3. Bravo
  4. +
  5. Charlie
  6. +
+
    +
  1. Alpha
  2. +
  3. Bravo
  4. +
  5. Charlie
  6. +
+
    +
  1. Alpha
  2. +
  3. Bravo
  4. +
  5. Charlie
  6. +
+
    +
  1. Alpha
  2. +
  3. Bravo
  4. +
  5. Charlie
  6. +
+
+ +

Live Search

+ +

Add data-live-search="true" in nya-bs-select directive to add live search support

+ +
+
    +
  1. Alpha
  2. +
  3. Bravo
  4. +
  5. Charlie
  6. +
+
+ +

Alternate selection display

+ +

You can set title attribute on each nya-bs-option as an alternative to display when an option is selected.

+ +
+
    +
  1. Alpha
  2. +
  3. Bravo
  4. +
  5. Charlie
  6. +
+
+ +

default selection display

+ +

+ To display an default information when nothing is selected. just set title attribute in nya-bs-select directive.
+ Note: This only works on multiple nya-bs-select. For single nyab-bs-selectYou should give your model an default value to avoid the default text to display +

+ +
+
    +
  1. Alpha
  2. +
  3. Bravo
  4. +
  5. Charlie
  6. +
+
+ + +

selection display format

+ +

Using the data-selected-text-format attribute on an multiple nya-bs-select you can specify how the selection is displayed.

+
    +
  • +

    values A comma delimited list of selected values.(default)

    + +
    +
      +
    1. + + {{option}} + + +
    2. +
    +
    +
  • +
  • +

    count If one item is selected, then the value is shown, if more than one is selected then the number of selected items is displayed.

    +
    +
      +
    1. + + {{option}} + + +
    2. +
    +
    +
  • +
  • +

    count > x Where X is the number of items selected when the display format changes from values to + count

    +
    +
      +
    1. + + {{option}} + + +
    2. +
    +
    +
  • +
+ +

Show Option Tick

+ +

This feature is implemented by yourself. You don't need add show-tick class to nya-bs-select. you just need to add the tick to each nya-bs-option

+

For example, if you want use Bootstrap Glyph. You need to add <span class="glyphicon glyphicon-ok check-mark"></span> following the text content of a + nya-bs-option as a child of <a></a>

+

If you want to use glyph in font-awesome, you can replace the glyphicon with font-awesome class, but keep the check-mark.

+
+      <ol class="nya-bs-select" ng-model="model2">
+        <li nya-bs-option="option in option1">
+          <a>
+            {{option}}
+            <span class="glyphicon glyphicon-ok check-mark"></span>
+          </a>
+        </li>
+      </ol>
+    
+ +

Show Menu Arrow

+

Just add show-menu-arrow class to nya-bs-select

+ +
+
    +
  1. + + {{option}} + + +
  2. +
+
+ +

Other styles feature

+

Thanks to the structure of nya-bs-select. you can easy control the look of an option or the width of the directive

+ +

Change any option styles as you like

+
+
    +
  1. + + {{option}} + + +
  2. +
+
+ +

Add col-lg-*, col-md-* or other grid column class to control the width of the directive

+ +
+
    +
  1. + + {{option}} + + +
  2. +
+
    +
  1. + + {{option}} + + +
  2. +
+
    +
  1. + + {{option}} + + +
  2. +
+
+ +

Disable dropdown

+

set size to an number, which will limit the dropdown menu size to limit number of element. the default value is 'auto'

+ +
+
    +
  1. Alpha
  2. +
  3. Bravo
  4. +
  5. Charlie
  6. +
+
+ +

Disable An Option

+

Add disabled class to any nya-bs-option you want disabled

+ +
+
    +
  1. Alpha
  2. +
  3. Bravo
  4. +
  5. Charlie
  6. +
+
+ +

Addition Note: Unlike Bootstrap-select, setting disabled attribute on optgroup to disable entire group options is not supported because we don't have + optgroup

+ +

Divider

+

Add an <li> element without nya-bs-option attribute and class but with divider class in your option list

+ +
+
    +
  1. Alpha
  2. +
  3. Bravo
  4. +
  5. +
  6. Charlie
  7. +
  8. Delta
  9. +
+
+ +

Subtext

+

Add a subtext on an nya-bs-option is very straightforward because you have full control what you want to display

+
+
    +
  1. + + + {{option}} + option {{$index}} + + + +
  2. +
+
    +
  1. + + + {{option}} + + option {{$index}} + + +
  2. +
+
+
+      
+      <!-- You can put your subtext with any style inside the first child element of <a> -->
+      
+      <ol class="nya-bs-select" ng-model="model2">
+        <li nya-bs-option="option in option1">
+          <a>
+            
+              <span>
+                {{option}}
+                <small>option {{$index}}</small>
+              </span>
+            
+            <span class="glyphicon glyphicon-ok check-mark"></span>
+          </a>
+        </li>
+      </ol>
+
+      
+      <!-- You can also put your subtext with any style aside the first child element of <a>. This format will
+        lead the subtext not shown in button. Note: you still need to wrap your option text with <span> or other inline tag
+      -->
+      
+      <ol class="nya-bs-select" ng-model="model2">
+        <li nya-bs-option="option in option1">
+          <a>
+            
+              <span>
+              {{option}}
+              </span>
+              <small>option {{$index}}</small>
+            
+            <span class="glyphicon glyphicon-ok check-mark"></span>
+          </a>
+        </li>
+      </ol>
+    
+ +

Custom option content

+

Custom option content is nothing different with subtext.

+
+
    +
  1. + + Alpha + + +
  2. +
  3. + + Bravo + + +
  4. +
  5. + + Charlie + + +
  6. +
+
    +
  1. + + Euro Dollar + + +
  2. +
  3. + + US Dollar + + +
  4. +
  5. + + Great Britain Pound + + +
  6. +
+
+ +

Dropdown Size

+

set size to an number, which will limit the dropdown menu size to limit number of element. the default value is 'auto'

+ +
+
    +
  1. Alpha
  2. +
  3. Bravo
  4. +
  5. Charlie
  6. +
  7. Delta
  8. +
  9. Echo
  10. +
  11. Fox
  12. +
  13. Golf
  14. +
  15. Hotel
  16. +
  17. India
  18. +
  19. Juliet
  20. +
+
+

ngSwitch

+

for test

+ +
+

+ +

+
+
+
    +
  1. + + {{option}} + + +
  2. +
+
+
+

condition2

+
+
+ +
+
+
+ + + + + + + + + + + + diff --git a/src/nya-bs-config.js b/src/nya-bs-config.js new file mode 100644 index 0000000..8868f85 --- /dev/null +++ b/src/nya-bs-config.js @@ -0,0 +1,12 @@ +/** + * A service for configuration. the configuration is shared globally. + */ +nyaBsSelect.service('nyaBsConfig', function() { + var interfaceText = { + 'en-US': { + defaultNoneSelection: 'Nothing selected', + noSearchResult: 'NO SEARCH RESULT', + numberItemSelected: '%d item selected' + } + }; +}); diff --git a/src/nya-bs-option.js b/src/nya-bs-option.js index 6f053c7..fec3cba 100644 --- a/src/nya-bs-option.js +++ b/src/nya-bs-option.js @@ -106,7 +106,14 @@ nyaBsSelect.directive('nyaBsOption', ['$parse', function($parse){ // hasOwnProperty. var lastBlockMap = createMap(); - $scope.$watchCollection(collectionExp, function nyaBsOptionAction(collection) { + // deepWatch will impact performance. use with caution. + if($attr.deepWatch === 'true') { + $scope.$watch(collectionExp, nyaBsOptionAction, true); + } else { + $scope.$watchCollection(collectionExp, nyaBsOptionAction); + } + + function nyaBsOptionAction(collection) { var index, previousNode = $element[0], // node that cloned nodes should be inserted after @@ -289,7 +296,7 @@ nyaBsSelect.directive('nyaBsOption', ['$parse', function($parse){ lastBlockMap = nextBlockMap; nyaBsSelectCtrl.onCollectionChange(values); - }); + } }; } } diff --git a/test/spec/dynamic-feature.js b/test/spec/dynamic-feature.js index 2f3cebb..b96f2c7 100644 --- a/test/spec/dynamic-feature.js +++ b/test/spec/dynamic-feature.js @@ -5,7 +5,8 @@ describe('Features contains ngModel, option auto generate, etc;', function() { var $scope, - $compile; + $compile, + $timeout; var options = ['Alpha', 'Bravo', 'Charlie', 'Delta', @@ -16,9 +17,10 @@ describe('Features contains ngModel, option auto generate, etc;', function() { beforeEach(module('nya.bootstrap.select')); - beforeEach(inject(function(_$rootScope_, _$compile_){ + beforeEach(inject(function(_$rootScope_, _$compile_, _$timeout_){ $scope = _$rootScope_.$new(); $compile = _$compile_; + $timeout = _$timeout_; })); it('should generate corresponding options with array and populate some meta property in each sub-scope of nya-bs-option', function() { @@ -343,4 +345,34 @@ describe('Features contains ngModel, option auto generate, etc;', function() { expect(selectElement).toHaveClass('ng-valid-required'); expect(selectElement).not.toHaveClass('ng-invalid-required'); }); + + it('should update button label with deepWatch options when collection changed.', function() { + + $scope.options = [ + {name: 'Alpha', value: 'a'}, + {name: 'Bravo', value: 'b'} + ]; + + $scope.model = 'b'; + $scope.$digest(); + + var selectElement = angular.element('
    ' + + '
  1. ' + + '{{option.name}}' + + '
  2. ' + + '
'); + $compile(selectElement)($scope); + + $scope.$digest(); + $timeout.flush(); + expect(selectElement.find('button').children().eq(0).text()).toBe('Bravo'); + + // now change property of options. + + $scope.options[1].name = 'Beta'; + + $scope.$digest(); + $timeout.flush(); + expect(selectElement.find('button').children().eq(0).text()).toBe('Beta'); + }); });