Skip to content

Instantly share code, notes, and snippets.

@josephcooney
Last active August 3, 2016 12:05
Show Gist options
  • Save josephcooney/f52ac562aa41ae88bdf15bd57e2a41b3 to your computer and use it in GitHub Desktop.
Save josephcooney/f52ac562aa41ae88bdf15bd57e2a41b3 to your computer and use it in GitHub Desktop.
ko.bindingHandlers.tagValue = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var replaceTags = function(taggedString, targetUrl, linkClass) {
if (!taggedString) {
return null;
}
var exp = /(^#|\W#)[\w-_]+/g;
var match = taggedString.match(exp);
if (match && match.length > 0) {
for (var i = 0; i < match.length; i++) {
var tag = match[i].trim();
if (tag != "#") {
var uri = " <span class='atwho-inserted' data-atwho-at-query='" + tag + "'><a href='" + targetUrl + tag.replace("#", "") + "' class='" + linkClass + "'>" + tag + "</a></span>";
taggedString = taggedString.replace(match[i], uri);
}
}
}
return taggedString;
};
var tags = allBindings.get('tags');
var tagUri = allBindings.get('tagUri');
// set current value
var value = valueAccessor();
var valueUnwrapped = ko.unwrap(value);
element.innerHTML = replaceTags(valueUnwrapped, tagUri + "?tag=", "tag");
$(element).atwho({
at: "#",
data: tags(),
insertTpl: '<a class="tag" href="' + tagUri + '?tag=${name}">#${name}</a>'
});
$(element).on('paste', function (e) {
e.preventDefault();
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
document.execCommand('insertText', false, text);
});
$(element).on('keydown', function (e) {
if (e.ctrlKey && (String.fromCharCode(e.which).toLowerCase() === 'b' || String.fromCharCode(e.which).toLowerCase() === 'i' || String.fromCharCode(e.which).toLowerCase() === 'u')) {
e.preventDefault();
}
if (e.which == 13) {
e.preventDefault(); // suppress enter key
}
});
$(element).blur(function () {
var value = valueAccessor();
value(element.textContent);
});
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).atwho('destroy');
});
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called once when the binding is first applied to an element,
// and again whenever any observables/computeds that are accessed change
// Update the DOM element based on the supplied values here.
var tags = allBindings.get('tags');
$(element).atwho('load', '#', tags());
var tagUri = allBindings.get('tagUri');
var value = valueAccessor();
var valueUnwrapped = ko.unwrap(value);
element.innerHTML = util.replaceTags(valueUnwrapped, tagUri + "?tag=", "tag");
}
};
@josephcooney
Copy link
Author

josephcooney commented Aug 3, 2016

Usage:
<div contenteditable="true" data-bind="tagValue: Description, tags: $root.tags, tagUri:'/your-url-to-tags-page/'"></div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment