@@ -2349,60 +2349,84 @@ var minlengthDirective = function() {
2349
2349
* @name ngList
2350
2350
*
2351
2351
* @description
2352
- * Text input that converts between a delimited string and an array of strings. The delimiter
2353
- * can be a fixed string (by default a comma) or a regular expression.
2352
+ * Text input that converts between a delimited string and an array of strings. The default
2353
+ * delimiter is a comma followed by a space - equivalent to `ng-list=", "`. You can specify a custom
2354
+ * delimiter as the value of the `ngList` attribute - for example, `ng-list=" | "`.
2355
+ *
2356
+ * The behaviour of the directive is affected by the use of the `ngTrim` attribute.
2357
+ * * If `ngTrim` is set to `"false"` then whitespace around both the separator and each
2358
+ * list item is respected. This implies that the user of the directive is responsible for
2359
+ * dealing with whitespace but also allows you to use whitespace as a delimiter, such as a
2360
+ * tab or newline character.
2361
+ * * Otherwise whitespace around the delimiter is ignored when splitting (although it is respected
2362
+ * when joining the list items back together) and whitespace around each list item is stripped
2363
+ * before it is added to the model.
2364
+ *
2365
+ * ### Example with Validation
2366
+ *
2367
+ * <example name="ngList-directive" module="listExample">
2368
+ * <file name="app.js">
2369
+ * angular.module('listExample', [])
2370
+ * .controller('ExampleController', ['$scope', function($scope) {
2371
+ * $scope.names = ['morpheus', 'neo', 'trinity'];
2372
+ * }]);
2373
+ * </file>
2374
+ * <file name="index.html">
2375
+ * <form name="myForm" ng-controller="ExampleController">
2376
+ * List: <input name="namesInput" ng-model="names" ng-list required>
2377
+ * <span class="error" ng-show="myForm.namesInput.$error.required">
2378
+ * Required!</span>
2379
+ * <br>
2380
+ * <tt>names = {{names}}</tt><br/>
2381
+ * <tt>myForm.namesInput.$valid = {{myForm.namesInput.$valid}}</tt><br/>
2382
+ * <tt>myForm.namesInput.$error = {{myForm.namesInput.$error}}</tt><br/>
2383
+ * <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
2384
+ * <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
2385
+ * </form>
2386
+ * </file>
2387
+ * <file name="protractor.js" type="protractor">
2388
+ * var listInput = element(by.model('names'));
2389
+ * var names = element(by.binding('{{names}}'));
2390
+ * var valid = element(by.binding('myForm.namesInput.$valid'));
2391
+ * var error = element(by.css('span.error'));
2392
+ *
2393
+ * it('should initialize to model', function() {
2394
+ * expect(names.getText()).toContain('["morpheus","neo","trinity"]');
2395
+ * expect(valid.getText()).toContain('true');
2396
+ * expect(error.getCssValue('display')).toBe('none');
2397
+ * });
2398
+ *
2399
+ * it('should be invalid if empty', function() {
2400
+ * listInput.clear();
2401
+ * listInput.sendKeys('');
2402
+ *
2403
+ * expect(names.getText()).toContain('');
2404
+ * expect(valid.getText()).toContain('false');
2405
+ * expect(error.getCssValue('display')).not.toBe('none');
2406
+ * });
2407
+ * </file>
2408
+ * </example>
2409
+ *
2410
+ * ### Example - splitting on whitespace
2411
+ * <example name="ngList-directive-newlines">
2412
+ * <file name="index.html">
2413
+ * <textarea ng-model="list" ng-list=" " ng-trim="false"></textarea>
2414
+ * <pre>{{ list | json }}</pre>
2415
+ * </file>
2416
+ * </example>
2354
2417
*
2355
2418
* @element input
2356
2419
* @param {string= } ngList optional delimiter that should be used to split the value.
2357
- *
2358
- * @example
2359
- <example name="ngList-directive" module="listExample">
2360
- <file name="index.html">
2361
- <script>
2362
- angular.module('listExample', [])
2363
- .controller('ExampleController', ['$scope', function($scope) {
2364
- $scope.names = ['igor', 'misko', 'vojta'];
2365
- }]);
2366
- </script>
2367
- <form name="myForm" ng-controller="ExampleController">
2368
- List: <input name="namesInput" ng-model="names" ng-list required>
2369
- <span class="error" ng-show="myForm.namesInput.$error.required">
2370
- Required!</span>
2371
- <br>
2372
- <tt>names = {{names}}</tt><br/>
2373
- <tt>myForm.namesInput.$valid = {{myForm.namesInput.$valid}}</tt><br/>
2374
- <tt>myForm.namesInput.$error = {{myForm.namesInput.$error}}</tt><br/>
2375
- <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
2376
- <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
2377
- </form>
2378
- </file>
2379
- <file name="protractor.js" type="protractor">
2380
- var listInput = element(by.model('names'));
2381
- var names = element(by.binding('{{names}}'));
2382
- var valid = element(by.binding('myForm.namesInput.$valid'));
2383
- var error = element(by.css('span.error'));
2384
-
2385
- it('should initialize to model', function() {
2386
- expect(names.getText()).toContain('["igor","misko","vojta"]');
2387
- expect(valid.getText()).toContain('true');
2388
- expect(error.getCssValue('display')).toBe('none');
2389
- });
2390
-
2391
- it('should be invalid if empty', function() {
2392
- listInput.clear();
2393
- listInput.sendKeys('');
2394
-
2395
- expect(names.getText()).toContain('');
2396
- expect(valid.getText()).toContain('false');
2397
- expect(error.getCssValue('display')).not.toBe('none'); });
2398
- </file>
2399
- </example>
2400
2420
*/
2401
2421
var ngListDirective = function ( ) {
2402
2422
return {
2403
2423
require : 'ngModel' ,
2404
2424
link : function ( scope , element , attr , ctrl ) {
2405
- var separator = attr . ngList || ', ' ;
2425
+ // We want to control whitespace trimming so we use this convoluted approach
2426
+ // to access the ngList attribute, which doesn't pre-trim the attribute
2427
+ var ngList = element . attr ( attr . $attr . ngList ) || ', ' ;
2428
+ var trimValues = attr . ngTrim !== 'false' ;
2429
+ var separator = trimValues ? trim ( ngList ) : ngList ;
2406
2430
2407
2431
var parse = function ( viewValue ) {
2408
2432
// If the viewValue is invalid (say required but empty) it will be `undefined`
@@ -2411,8 +2435,8 @@ var ngListDirective = function() {
2411
2435
var list = [ ] ;
2412
2436
2413
2437
if ( viewValue ) {
2414
- forEach ( viewValue . split ( trim ( separator ) ) , function ( value ) {
2415
- if ( value ) list . push ( trim ( value ) ) ;
2438
+ forEach ( viewValue . split ( separator ) , function ( value ) {
2439
+ if ( value ) list . push ( trimValues ? trim ( value ) : value ) ;
2416
2440
} ) ;
2417
2441
}
2418
2442
@@ -2422,7 +2446,7 @@ var ngListDirective = function() {
2422
2446
ctrl . $parsers . push ( parse ) ;
2423
2447
ctrl . $formatters . push ( function ( value ) {
2424
2448
if ( isArray ( value ) ) {
2425
- return value . join ( separator ) ;
2449
+ return value . join ( ngList ) ;
2426
2450
}
2427
2451
2428
2452
return undefined ;
0 commit comments