私は現在、内容が変更時にセッション変数に保存されるいくつかのテキスト入力を使用して、隕石keyup
でユーザーインターフェイスを設計しています(イベント)。パッケージによりpreserve-inputs
、これらの入力ボックスは、フォーカスされている間は再レンダリングされません。
これらの入力ボックスをデフォルトで無効にし、ダブルクリックで編集できるようにしました (これは悪い選択かもしれませんが、目前の問題には最も簡単で、最初のドラフトには十分です - 多分私は尋ねます.後でUXで)。ただし、最初に無効にすると、入力ボックスは保持されず、1 文字の入力時に再レンダリングされ、再び無効になります。
通常、編集不可能な要素が再レンダリングされないようにすることは意味がありませんが、disabled
状態を区別するようなコードは見つかりませんでした。では、それはどこにあり、どうすればこれを回避できますか? (もちろん、disabled
ダブルクリック/ぼかしにセッション変数を設定し、有効な状態で入力ボックスを再レンダリングすることもできますが、これは私には複雑すぎるようです)。
次のコード (純粋にクライアント側の JavaScript であることに注意してください) は、この問題を再現します。また、無効になることはありませんが、ダブルクリックした後にのみアクセスできる 2 番目の入力ボックスもレンダリングします。これは、再レンダリングなしで意図したとおりに機能します。ライブ デモがhttp://preserve-disabled-inputs.meteor.com/にデプロイされます。
disabled.html
:
<head>
<title>disabled</title>
</head>
<body>
{{> body}}
</body>
<template name="body">
<p>Double-click to enter text</p>
{{> input f}}
{{> input t}}
</template>
<template name="input">
<div style="position: relative; width: 400px;">
<input id="{{id}}" class="input" type="text" value="{{value}}" style="width: 100%;" {{disabled}}/>
<!-- events on disabled inputs are not triggered -->
<!-- overlay with transparent div to catch clicks -->
<div class="catch" style="position: absolute; left: 0; top: 0; right: 0; bottom: 0;" />
</div>
</template>
disabled.js
:
if (Meteor.isClient) {
// Setup for the example
Session.setDefault('valuefalse', 'This one is preserved and can be edited without problems');
Session.setDefault('valuetrue', 'This one is not preserved and loses focus on edit');
Template.body.t = function() {
return { disabled: true };
}
Template.body.f = function() {
return { disabled: false };
}
Template.input.disabled = function() {
return this.disabled ? 'disabled="disabled" ' : '';
}
Template.input.id = function() {
return this.disabled ? 'd' : 'e';
}
Template.input.value = function() {
return Session.get('value' + this.disabled);
}
// Here goes ...
Template.input.events({
'dblclick div.catch': function (evt) {
var input = $('input.input', evt.target.parentNode);
// Enable text box
input.removeAttr('disabled');
input.focus();
// Don't render the div so the input box becomes accessible
evt.target.style.display = 'none';
},
'keyup input.input': function (evt) {
Session.set('value' + this.disabled, evt.target.value);
},
'blur input.input': function(evt) {
// Re-render the catcher div
$('div.catch', evt.target.parentNode).css('display', '');
// Disable text box, if appliccable
if (this.disabled) evt.target.disabled = 'disabled';
}
});
}