JSFiddle - React, Tailwind, and code Playground
HTML
<div ng-app="textarea-pattern">
<label>Filtered using [^\n\r]*</label>
<textarea ng-model="text" ta-pattern="[^\n\r]*" ta-pattern-block-invalid></textarea>
<label>Unfiltered textarea with same model</label>
<textarea ng-model="text"></textarea>
<label>Input with same model</label>
<input ng-model="text"></input>
<label>Preformatted model</label>
<pre>{{text}}</pre>
</div>
CSS
label, textarea, input {
display:block;
}
textarea, input {
margin-bottom: 5px;
}
.ng-invalid {
border: #a00;
background-color:#fcc;
}
JavaScript
angular
.module('textarea-pattern', [])
.directive('taPattern', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attributes, ngModelController) {
var pattern = attributes.taPattern;
var flag = attributes.taPatternIgnoreCase === true ? 'i' : undefined;
var blockInvalidInput = attributes.hasOwnProperty('taPatternBlockInvalid');
var model = attributes.ngModel;
if(!pattern) return;
if(pattern[0] != '^')
pattern = '^' + pattern;
if(pattern[pattern.length - 1] != '$')
pattern += '$';
var regex = new RegExp(pattern, flag);
// $parsers handle input from the element where the
// ng-model directive is set
ngModelController.$parsers.unshift(function(value) {
if(!value) return value;
var modelValue = ngModelController.$modelValue;
var isValid = regex.test(value);
ngModelController.$setValidity('Does not match pattern', isValid);
return value;
});
// $formatters handle when the model is changed and
// the element needs to be updated
ngModelController.$formatters.unshift(function(value) {
if(!value) return value;
var isValid = regex.test(value);
ngModelController.$setValidity('Does not match pattern', isValid);
return value;
});
if(blockInvalidInput){
element.on('keypress', function(e) {
var char = String.fromCharCode(e.which);
var text =...