Text Counter & Limiter
by Jason Butz
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<textarea data-bind="textInput: v, charCount: 2048, charLimiter: 2048"></textarea>
SCSS
textarea {
width: 100%;
height: 32px;
}
span.text-counter {
display: block;
float: right;
font-size: 0.8em;
}
JavaScript
function App() {
var self = this;
self.v = ko.observable('Hello World');
}
ko.bindingHandlers.charCount = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext){
// Get the character limit to display
var charLimit = valueAccessor();
// Get input value
var inputText = allBindings().value || allBindings().textInput;
// Create the computed to setup our text
var counterText = ko.pureComputed(() => {
return inputText().length + ' / ' + charLimit;
});
// Create DOM elements
var $counter = $('<span class="text-counter"></span>');
// Add element after the element this is bound to
$(element).after($counter);
// Apply binding to new element
ko.applyBindingsToNode($counter.get(0), {
text: counterText
});
}
};
ko.bindingHandlers.charLimit = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext){
// Get the character limit to display
var charLimit = valueAccessor();
// Get input value
var inputText = allBindings().value || allBindings().textInput;
// Subscribe to text observable
inputText.subscribe((newValue) => {
// If we have more than the allotted number of characters
if(newValue.length > charLimit) {
// hack off the extra
inputText(newValue.substr(0, charLimit));
}
})
}
};
ko.applyBindings(new App());