2013-06-12 25 views
35

Tôi đang cố gắng thực hiện một vùng văn bản đơn giản với "nhiều ký tự còn lại" cùng với xác thực. khi tôi sử dụng ng-maxlength để xác thực biểu mẫu của tôi, nó sẽ đặt lại số tiền của tôi ngay khi độ dài chạm vào độ dài tối đa. Đây là plunkr Bất kỳ cách giải quyết nào?vít ng-maxlength lên mẫu của tôi

<body ng-controller="MainCtrl"> 
    <div ng-form="noteForm"> 
     <textarea ng-maxlength="15" ng-model="result"></textarea> 
     <p>{{15 - result.length}} chars remaining</p> 
     <button ng-disabled="!noteForm.$valid">Submit</button> 
    </div> 
    </body> 
+0

điều Funny, nhưng đối với tôi (sử dụng góc 1.4.7 + nguyên cảo 1.8.7) sử dụng thuộc tính HTML "maxLength" có cùng tác dụng như đối với đề cập ở đây "ng-maxLength": sau khi thiết lập một số giá trị lớn (lớn hơn giới hạn xác định) trực tiếp thành mô hình, giá trị trong mô hình trở nên không xác định. Theo quan điểm của tôi, đây là lỗi Góc (giống như [user3232182] (http://stackoverflow.com/users/3232182/user3232182) được đề cập ở trên). Có lẽ thậm chí không liên quan đến ng-maxLength directve, nhưng cho toàn bộ cơ chế ràng buộc. – bkg

Trả lời

55

Khi textarea của bạn vượt quá 15 ký tự, result trở thành undefined — đó chỉ là cách các ng-min/maxlength chỉ thị làm việc. Tôi nghĩ bạn sẽ phải viết chỉ thị của riêng bạn. Đây là một chỉ thị rằng sẽ chặn đầu vào sau khi 15 ký tự:

<textarea my-maxlength="15" ng-model="result"></textarea> 
app.directive('myMaxlength', function() { 
    return { 
    require: 'ngModel', 
    link: function (scope, element, attrs, ngModelCtrl) { 
     var maxlength = Number(attrs.myMaxlength); 
     function fromUser(text) { 
      if (text.length > maxlength) { 
      var transformedInput = text.substring(0, maxlength); 
      ngModelCtrl.$setViewValue(transformedInput); 
      ngModelCtrl.$render(); 
      return transformedInput; 
      } 
      return text; 
     } 
     ngModelCtrl.$parsers.push(fromUser); 
    } 
    }; 
}); 

fiddle


Cập nhật: cho phép hơn 15 ký tự, nhưng vô hiệu hóa các nút gửi khi đếm vượt quá 15:

link: function (scope, element, attrs, ngModelCtrl) { 
    var maxlength = Number(attrs.myMaxlength); 
    function fromUser(text) { 
     ngModelCtrl.$setValidity('unique', text.length <= maxlength); 
     return text; 
    } 
    ngModelCtrl.$parsers.push(fromUser); 
} 

fiddle

+1

cảm ơn rất nhiều. Tôi đã thích nó để vượt ra ngoài và hiển thị tiêu cực như twitter, nhưng điều này là đủ tốt :) – Riz

+0

@Riz, xem câu trả lời được cập nhật. –

+0

rực rỡ! điều này sẽ là hành vi ng-maxlength mặc định. Có lẽ bạn có thể đẩy điều này sang góc cạnh;) – Riz

52

Hoặc bạn chỉ có thể thêm tiêu chuẩn html maxlength thuộc tính cùng với ng-maxlength.

<form name="myForm"> 
    <textarea name="myTextarea" ng-maxlength="15" maxlength="15" ng-model="result"></textarea> 
    <span class="error" ng-show="myForm.myTextarea.$error.maxlength"> 
     Reached limit! 
    </span> 
</form> 

này sẽ cắt tại ký tự "15", như maxlength đã luôn thực hiện và bổ sung các ng-maxlength phép bạn hiển thị thông báo tùy chỉnh khi đạt đến giới hạn.

Click for Plunker Example

+0

Tôi nghĩ rằng đây là cách tiếp cận tốt nhất. –

+0

Điều này cũng bao gồm dán trong văn bản lớn hơn tối đa, cảm ơn bạn. –

+0

Vâng, đây là cách tôi nhận được nó hoạt động, mặc dù nó không phải là hiệu quả vì tôi sẽ cần phải lặp lại cùng một giá trị trong cả hai thuộc tính ... –

3

Tôi nghĩ điều này nên được ghi lại dưới dạng lỗi trên góc. Nó không phải là nghĩa vụ phải xóa model.I của bạn có một chỉ thị liên kết một dropdown chọn vào một hộp văn bản và ngay sau khi bạn chèn một từ mà làm cho nó đi qua chiều dài tối đa sau đó nó xóa mô hình của tôi và textbox.It là vụ phải là người xác thực không xóa mô hình của bạn khi mô hình cho rằng mô hình không hợp lệ.

3

Một giải pháp thay thế mà tôi đang sử dụng là giữ nguyên hành vi tương tự như trình xác nhận độ dài ng-maxlength nhưng để nạp lại độ dài thông qua thuộc tính bổ sung 'chiều dài thực tế'.

app.directive('newMaxlength', function() { 
     return { 
      require: 'ngModel', 
      scope: { 
       maxlength: '=newMaxlength', 
       actualLength: '=' 
      }, 
      link: function (scope, elem, attr, ngModelCtrl) { 

       function validate(ctrl, validatorName, validity, value) { 
        ctrl.$setValidity(validatorName, validity); 
        return validity ? value : undefined; 
       } 

       var maxlength = parseInt(scope.maxlength, 10); 
       var maxLengthValidator = function (value) { 
        scope.actualLength = value ? value.length : 0; 
        return validate(ngModelCtrl, 'maxlength', ngModelCtrl.$isEmpty(value) || value.length <= maxlength, value); 
       }; 

       ngModelCtrl.$parsers.push(maxLengthValidator); 
       ngModelCtrl.$formatters.push(maxLengthValidator); 
      } 
     }; 
    }); 

Dưới đây là yếu tố với các thuộc tính bổ sung:

<textarea name="myTextarea" new-maxlength="100" actual-length="actualLength" ng-model="text"></textarea> 
0

Tôi có một giải pháp tốt hơn tôi nghĩ: để thiết lập các maxlength nếu ng-maxlength có mặt.

Bằng cách này bạn sẽ có được cả hai tính năng cùng một lúc: kiểm chứng thực góc + văn bản cắt đứt

.directive("textarea", function() { 
    return { 
     restrict: "E", 
     link: function (scope, elem, attrs) { 
      if (angular.isDefined(attrs["ngMaxlength"])) { 
       attrs.$set("maxlength", attrs["ngMaxlength"]); 
      } 
     } 
    }; 
}) 
+1

Điều này sẽ không hoạt động trong ví dụ 9 như độ dài attr chỉ hoạt động trong HTML5 – alecellis1985

+0

. nhưng bạn có thể sử dụng polyfills cho trường hợp đó tôi đoán. Ví dụ: http://stackoverflow.com/questions/1125482/how-to-impose-maxlength-on-textarea-in-html-using-javascript/1125521#1125521, mặc dù tôi chưa cố gắng làm cho nó hoạt động bên trong chỉ thị, nhưng tôi đoán nó không phải là khó. CẢM ƠN VÌ TIỀN HỖ TRỢ! –

16

Nếu bạn thêm một thuộc tính tên cho textarea sau đó một tài sản mới có giá trị được tạo ra trong phạm vi biểu mẫu mà bạn có thể sử dụng để lấy độ dài cho bộ đếm ký tự của mình.

<body ng-controller="MainCtrl"> 
    <div ng-form="noteForm"> 
    <textarea ng-maxlength="15" name="noteItem" ng-model="result"></textarea> 
    <p>{{15 - noteForm.noteItem.$viewValue.length}} chars remaining</p> 
    <button ng-disabled="!noteForm.$valid">Submit</button> 
    </div> 
</body> 

cập nhật của bạn plnkr

+1

Cái này đẹp và không cần thêm mã. Cảm ơn! – yarl

+1

Tại sao câu trả lời này không có nhiều phiếu bầu. Vì vậy, nhanh chóng dễ dàng và cho điểm. : D Cảm ơn bạn và có xin vui lòng – BrettS

13

Khi doc nói, $ validate chức năng thiết lập mô hình để undefined khi thay đổi giá trị không hợp lệ.

Tuy nhiên, chúng tôi vẫn có thể ngăn chặn hành vi này chỉ bằng cách thêm allowInvalid: true vào tùy chọn ng-model-options.

Vì vậy, chỉ cần sửa đổi mã của bạn như:

<body ng-controller="MainCtrl"> 
    <div ng-form="noteForm"> 
     <textarea ng-maxlength="15" ng-model="result" 
      ng-model-options="{ allowInvalid: true }"></textarea> 
     <p>{{15 - result.length}} chars remaining</p> 
     <button ng-disabled="!noteForm.$valid">Submit</button> 
    </div> 
</body> 
+2

Đây phải là câu trả lời đúng –

+0

Cảm ơn bạn người đàn ông của tôi! – Wax

Các vấn đề liên quan