Fun with highlighting- plus occurrence count
https://groups.google.com/d/topic/knockoutjs/iO_rMnwES8Y/discussion
http://www.knockmeout.net/2011/06/fun-with-highlighting-in-knockoutjs.html?showComment=1307370451742#c3222361922660848046
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 />
<p data-bind="text:'Found '+counter()">3</p>
<div data-bind="highlightedText: { text: text, highlight: match, css: style, count:counter}, 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
}
if (!search || search.length < 3) {
element.innerHTML = value
return;
}
const matches = value.match(new RegExp(search, "gi"));
let temp = value;
if (matches != null) {
const myarray = matches.reduce((prev, curr) => {
console.log(prev, curr);
if (prev.length === 0 || prev.every(p => p !== curr)) {
prev.push(curr);
}
return prev;
}, []);
console.log(myarray);
myarray.forEach(m => {
const replacement = "<span class=" + css + ">" + m + "</span>";
temp = temp.replace(new RegExp(m, "g"), replacement);
});
}
element.innerHTML = temp;
}
};
//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)...