Fun with highlighting
https://groups.google.com/d/topic/knockoutjs/iO_rMnwES8Y/discussion
by gurkavcu
HTML
<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/jquery.tmpl.js"></script>
<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/knockout-latest.debug.js"></script>
Highlight: <input data-bind="value: match, valueUpdate: 'afterkeydown'" /> <select data-bind="options: styleChoices, value: style"></select>
<p>Enter a new search term or try selecting text below with your mouse</p>
<hr />
<div data-bind="highlightedText: { text: text, highlight: match, css: style }, selectedText: match"></div>
CSS
.yellow { background-color: yellow; }
.red { background-color: red; color: #ccc; }
.black { background-color: #000; color: #fff; }
.big { font-size: 1.5em; font-weight: bold; }
input { margin: 5px; width: 150px; }
p { color: #666; }
JavaScript
ko.bindingHandlers.highlightedText = {
update: function(element, valueAccessor) {
var options = valueAccessor();
var value = ko.utils.unwrapObservable(options.text);
var search = ko.utils.unwrapObservable(options.highlight);
var css = ko.utils.unwrapObservable(options.css); //could be an observable
if (options.sanitize) {
value = $('<div/>').text(value).html(); //could do this or something similar to escape HTML before replacement, if there is a risk of HTML injection in this value
}
var replacement = '<span class="' + css + '">' + search + '</span>';
element.innerHTML = value.replace(new RegExp(search, 'g'), replacement);
}
};
//set a value based on the text that a user selects
ko.bindingHandlers.selectedText = {
init: function(element, valueAccessor, allBindingsAccessor) {
var value = valueAccessor();
ko.utils.registerEventHandler(element, 'mouseup', function() {
var modelValue = valueAccessor();
//get the selected text
var selectedText = '';
if (window.getSelection) {
selectedText = window.getSelection();
} else if (document.getSelection) {
selectedText = document.getSelection();
} else if (document.selection) {
selectedText = document.selection.createRange().text;
}
//only change if something was selected
if (selectedText.toString()) {
if (ko.isWriteableObservable(modelValue)) {
modelValue(selectedText.toString());
}
else { //handle non-observables
var allBindings = allBindingsAccessor();
if (allBindings['_ko_property_writers'] && allBindings['_ko_property_writers']['selectedText']) allBindings['_ko_property_writers']['selectedText'](selectedText);
}
}
});
...