8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

KnockoutJSAdvent Calendar 2014

Day 18

キャレット位置をバインド&キャレット位置に文字列を挿入「caret binding」

Last updated at Posted at 2014-12-17

TinyMCE ほど高機能な WYSIWYG エディタでなくても、カーソル位置に文字列を挿入する機能くらいつけたいなぁなんてことありませんか :question:
そこで今回ご紹介するのが「caret binding」です :snowman:

caret binding

DEMO:JSFIDDLE

caret-binding

ko.bindingHandlers.caret = {
	init: function(element, valueAccessor, allBindings) {
		var $elm = $(element),
			suspend = true,
			value_writer = allBindings()._ko_property_writers.value;

		function updateModel() {
			var pos = $elm.caret();
			var modelValue = valueAccessor();
			suspend = true;
			if (ko.isObservable(modelValue)) modelValue(pos);
			else valueAccessor(pos);
		}

		$elm.bind('keydown click focus', updateModel);

		ko.computed(function() {
			var modelValue = ko.unwrap(valueAccessor());
			if (suspend) {
				suspend = false;
				if (typeof modelValue == 'number') return;
			}
			var st = element.scrollTop;
			$elm.caret(modelValue);
			element.scrollTop = st;
			if (typeof modelValue == 'string') {
				updateModel();
				if (value_writer) {
					value_writer($elm.val());
				}
			}
		});
	}
};

依存: jQuery, jquery.caret

使い方

<input type="text"><textarea> にバインドして使います。

<textarea data-bind="value: body, caret: bodyCaret"></textarea>
function ViewModel() {
	var self = this;
	self.body = ko.observable("");
	self.bodyCaret = ko.observable();
	
	self.insertFoo = function() {
		self.bodyCaret('Foo');
	};
}

バインドした bodyCaret には常に文字のキャレット位置が格納されますが、ViewModel 側から文字列を書きこむことでキャレット位置に挿入することができます。

またそのままだとなぜかスクロール位置が末尾に飛んでしまうため、その補正もかけています。

謝罪

元々は別のタイトルを考えていましたが、どうにも考えがまとまらずに諦めてかなりミニマムな記事になってしましました。
申し訳ございません。

ですが、個人的にはこういった「こんなカスタムバインディング書いたよ!」というミニマムな記事が増えてほしいと思っています。リユーザブルな知見を共有しましょう!

8
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?