2013-03-06 65 views

Trả lời

96

Có, bạn cần để xác định chỉ thị và xác định chức năng của trình phân tích cú pháp của riêng bạn:

myApp.directive('capitalizeFirst', function($parse) { 
    return { 
    require: 'ngModel', 
    link: function(scope, element, attrs, modelCtrl) { 
     var capitalize = function(inputValue) { 
      if (inputValue === undefined) { inputValue = ''; } 
      var capitalized = inputValue.charAt(0).toUpperCase() + 
          inputValue.substring(1); 
      if(capitalized !== inputValue) { 
       modelCtrl.$setViewValue(capitalized); 
       modelCtrl.$render(); 
      }   
      return capitalized; 
     } 
     modelCtrl.$parsers.push(capitalize); 
     capitalize($parse(attrs.ngModel)(scope)); // capitalize initial value 
    } 
    }; 
}); 

HTML:

<input type="text" ng-model="obj.name" capitalize-first> 

Fiddle

+1

bạn có thể giải thích thêm một chút về cách thức hoạt động hoặc cung cấp liên kết tới tài liệu không? Ngoài ra, nếu bạn nhập một chữ cái thường ở đầu và hộp không trống thì con trỏ sẽ di chuyển đến cuối, nhưng nếu bạn nhập ký tự viết hoa thì không ... –

+0

@JasonGoemaat, http://docs.angularjs.org/guide/forms # customvalidation Tôi không có bất kỳ ý tưởng nào về cách sửa chuyển động của con trỏ. –

+2

@JasonGoemaat Chuyển động của con trỏ xảy ra vì nội dung đang được thay thế bằng văn bản đã thay đổi (chỉ thay đổi khi chữ cái đầu tiên được nhập là không phải vốn). Để khắc phục điều này, bạn có thể nắm bắt phạm vi lựa chọn và đặt lại phạm vi lựa chọn mới trong văn bản mới khi nó được đặt. Có một thư viện ngọt ngào gọi là Rangy (https://code.google.com/p/rangy/) sẽ giúp bạn với điều này nếu bạn đủ nghiêm túc về nó để sửa chữa nó. – James

22

Bạn có thể tạo một bộ lọc tùy chỉnh 'hoa' và áp dụng nó vào bất kỳ chuỗi bạn muốn:

<div ng-controller="MyCtrl"> 
    {{aString | capitalize}} ! 
</div> 

mã JavaScript cho bộ lọc:

var app = angular.module('myApp',[]); 

myApp.filter('capitalize', function() { 
    return function(input, scope) { 
     return input.substring(0,1).toUpperCase()+input.substring(1); 
    } 
}); 
+5

Cách này hoạt động với trường nhập liệu như thế nào? –

+5

Tôi không nghĩ rằng bộ lọc có thể được áp dụng trên trường nhập. – tamakisquare

+1

Không phải là một sự xấu hổ như vậy, @tamakisquare; Tôi đến đây googling cho chính xác điều đó. –

51

Hãy nhớ rằng không phải mọi thứ cần một giải pháp góc. Bạn thấy điều này rất nhiều với đám đông jQuery; họ thích sử dụng các hàm jQuery đắt tiền để làm những việc đơn giản hoặc dễ dàng hơn với javascript thuần túy.

Vì vậy, trong khi bạn rất tốt có thể cần một chức năng tận dụng và các câu trả lời trên quy định rằng, nó sẽ có rất nhiều hiệu quả hơn để chỉ cần sử dụng quy tắc css "text-transform: viết hoa"

<tr ng-repeat="(key, value) in item"> 
    <td style="text-transform: capitalize">{{key}}</td> 
    <td>{{item}}</td> 
</tr> 
+12

OP chỉ muốn viết hoa chữ cái đầu tiên trong đầu vào. Giải pháp này viết hoa mỗi từ –

+2

suy nghĩ tốt, nhưng điều này sẽ không nhất thiết phải làm việc cho các trường nhập liệu, nếu nó được gửi (nhập vào, bấm lưu, ví dụ), tôi chỉ bị cắn bởi điều đó. – oma

+2

Trong trường hợp của tôi, tôi đã đáp xuống câu hỏi này tìm kiếm một giải pháp "lực thấp". Cảm ơn bạn đã đăng bài này mặc dù đây không phải là giải pháp hoàn hảo cho OP. – adamdport

-3

Bạn có thể sử dụng css tinh khiết:

input { text-transform: capitalize; }

+3

OP chỉ muốn viết hoa chữ cái đầu tiên trong đầu vào. Giải pháp này viết hoa mỗi từ –

2

Để khắc phục vấn đề con trỏ (từ nơi Mark Rajcok của giải pháp), bạn có thể lưu trữ element [0] .selectionStart vào đầu của phương pháp của bạn, và sau đó đảm bảo đặt lại phần tử [0] .selectionStart và phần tử [0] .selectionEnd thành giá trị được lưu trước khi trả về. Điều này sẽ nắm bắt phạm vi lựa chọn của bạn trong góc

+1

Điều này đã giúp ích rất nhiều! – Illiax

4

Sử dụng CSS: chữ cái giả dạng chữ cái đầu tiên.

Bạn cần phải đặt tất cả mọi thứ chữ thường và sau khi áp dụng các chữ hoa chỉ để chữ cái đầu tiên

p{ 
    text-transform: lowercase; 
} 
p:first-letter{ 
    text-transform: uppercase; 
} 

Dưới đây là một ví dụ: http://jsfiddle.net/AlexCode/xu24h/

+2

Thao tác này sẽ không hoạt động trên đầu vào? –

+1

Không, tôi không sợ. Điều này áp dụng cho nội dung, không áp dụng cho các thuộc tính cụ thể của một phần tử. Trên đầu vào tôi sợ bạn phải sử dụng javascript. – AlexCode

4

Modified mã của mình để tận dụng tất cả các ký tự đầu tiên của từ.Nếu bạn cung cấp cho 'john doe', đầu ra là 'John Doe'

myApp.directive('capitalizeFirst', function() { 
    return { 
    require: 'ngModel', 
    link: function(scope, element, attrs, modelCtrl) { 
     var capitalize = function(inputValue) { 
      var capitalized = inputValue.split(' ').reduce(function(prevValue, word){ 
      return prevValue + word.substring(0, 1).toUpperCase() + word.substring(1) + ' '; 
     }, ''); 
      if(capitalized !== inputValue) { 
       modelCtrl.$setViewValue(capitalized); 
       modelCtrl.$render(); 
      }   
      return capitalized; 
     } 
     modelCtrl.$parsers.push(capitalize); 
     capitalize(scope[attrs.ngModel]); // capitalize initial value 
    } 
    }; 
}); 
1

Dưới đây là một codepen cho một bộ lọc mà tận dụng các chữ cái đầu tiên: http://codepen.io/WinterJoey/pen/sfFaK

angular.module('CustomFilter', []). 
    filter('capitalize', function() { 
    return function(input, all) { 
     return (!!input) ? input.replace(/([^\W_]+[^\s-]*) */g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}) : ''; 
    } 
    }); 
4

Tôi muốn một bộ lọc và chỉ thị. Điều này sẽ làm việc với phong trào con trỏ:

app.filter('capitalizeFirst', function() { 
    return function (input, scope) { 
     var text = input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase(); 
     return text; 
    } 
}); 

app.directive('capitalizeFirst', ['$filter', function ($filter) { 
    return { 
     require: 'ngModel', 
     link: function (scope, element, attrs, controller) { 
      controller.$parsers.push(function (value) { 
       var transformedInput = $filter('capitalizeFirst')(value); 
       if (transformedInput !== value) { 
        var el = element[0]; 
        el.setSelectionRange(el.selectionStart, el.selectionEnd); 
        controller.$setViewValue(transformedInput); 
        controller.$render(); 
       } 
       return transformedInput; 
      }); 
     } 
    }; 
}]); 

Đây là một fiddle

2

Comment để giải pháp Đánh dấu Rajcok: khi sử dụng $ setViewValue, bạn kích hoạt các phân tích cú pháp và xác nhận một lần nữa. Nếu bạn thêm câu lệnh console.log ở đầu hàm viết hoa, bạn sẽ thấy nó được in hai lần.

Tôi đề nghị các giải pháp chỉ thị sau (nơi ngModel là không bắt buộc):

.directive('capitalize', function() { 
    return { 
    restrict: 'A', 
    require: '?ngModel', 
    link: function(scope, element, attrs, ngModel) { 
     var capitalize = function (inputValue) { 
      return (inputValue || '').toUpperCase(); 
     } 
     if(ngModel) { 
      ngModel.$formatters.push(capitalize); 
      ngModel._$setViewValue = ngModel.$setViewValue; 
      ngModel.$setViewValue = function(val){ 
       ngModel._$setViewValue(capitalize(val)); 
       ngModel.$render(); 
      }; 
     }else { 
      element.val(capitalize(element.val())); 
      element.on("keypress keyup", function(){ 
       scope.$evalAsync(function(){ 
        element.val(capitalize(element.val())); 
       }); 
      }); 
     } 
    } 
    }; 
}); 
0

Xây dựng ra giải pháp Đánh dấu Rajcok của; Điều quan trọng cần xem xét là chỉ thị chỉ đánh giá khi trường đầu vào được tham gia, nếu không bạn sẽ nhận được thông báo lỗi bị tắt cho đến khi trường nhập có ký tự thứ nhất. Dễ dàng sửa chữa với một vài điều kiện: Một jsfiddle đi với rằng: https://jsfiddle.net/Ely_Liberov/Lze14z4g/2/

 .directive('capitalizeFirst', function(uppercaseFilter, $parse) { 
     return { 
     require: 'ngModel', 
     link: function(scope, element, attrs, modelCtrl) { 
      var capitalize = function(inputValue) { 
       if (inputValue != null) { 
       var capitalized = inputValue.charAt(0).toUpperCase() + 
       inputValue.substring(1); 
       if (capitalized !== inputValue) { 
       modelCtrl.$setViewValue(capitalized); 
       modelCtrl.$render(); 
       } 
       return capitalized; 
      } 
      }; 
      var model = $parse(attrs.ngModel); 
      modelCtrl.$parsers.push(capitalize); 
      capitalize(model(scope)); 
     } 
     }; 
    }); 
1

Tiếp tục với câu trả lời CSS-chỉ, bạn luôn có thể sử dụng Twitter Bootstrap:

<td class="text-capitalize"> 
0

Vấn đề với css- câu trả lời ony là mô hình góc không được cập nhật với chế độ xem. Điều này là do css chỉ áp dụng kiểu dáng sau khi kết xuất.

Chỉ thị sau cập nhật các mô hình và nhớ con trỏ vị trí

app.module.directive('myCapitalize', [ function() { 
     'use strict'; 

    return { 
     require: 'ngModel', 
     restrict: "A", 
     link: function (scope, elem, attrs, modelCtrl) { 

      /* Watch the model value using a function */ 
      scope.$watch(function() { 
       return modelCtrl.$modelValue; 
      }, function (value) { 

       /** 
       * Skip capitalize when: 
       * - the value is not defined. 
       * - the value is already capitalized. 
       */ 
       if (!isDefined(value) || isUpperCase(value)) { 
        return; 
       } 

       /* Save selection position */ 
       var start = elem[0].selectionStart; 
       var end = elem[0].selectionEnd; 

       /* uppercase the value */ 
       value = value.toUpperCase(); 

       /* set the new value in the modelControl */ 
       modelCtrl.$setViewValue(value); 

       /* update the view */ 
       modelCtrl.$render(); 

       /* Reset the position of the cursor */ 
       elem[0].setSelectionRange(start, end); 
      }); 

      /** 
      * Check if the string is defined, not null (in case of java object usage) and has a length. 
      * @param str {string} The string to check 
      * @return {boolean} <code>true</code> when the string is defined 
      */ 
      function isDefined(str) { 
       return angular.isDefined(str) && str !== null && str.length > 0; 
      } 

      /** 
      * Check if a string is upper case 
      * @param str {string} The string to check 
      * @return {boolean} <code>true</code> when the string is upper case 
      */ 
      function isUpperCase(str) { 
       return str === str.toUpperCase(); 
      } 
     } 
    }; 
}]); 
Các vấn đề liên quan