「その場編集」を実装
前回はツールチップの実装方法をご紹介しました。
今回「Edit In Place」や「その場編集」と呼ばれる,テキストをクリックすると,その場で編集できるようにする仕組みを実装してみます。
今回の仕組みを考える
この「その場編集」の仕組みを考えてみましょう。今回の要件は以下の通りにします。
- 最初はただのテキスト
- クリックをすると,テキストがinput要素に置き換わり編集可能に。
- input要素からフォーカスが外れたら,input要素が編集後の文字に置き換わる。
- フォーカス外れた時,valueの値が空なら最初の値に戻す。
本来であれば,上記の仕組みの4の後に,PHPなどでデータベースに編集後の情報を送信し,保存するという仕組みになるのですが,今回はその前のところまでの実装方法のご紹介とします。
まずは完成サンプルとソースコードを見てみましょう。
完成ソースコード
jQuery(function($){
$('dd').click(function(){
//classでonを持っているかチェック
if(!$(this).hasClass('on')){
//編集可能時はclassでonをつける
$(this).addClass('on');
var txt = $(this).text();
//テキストをinputのvalueに入れてで置き換え
$(this).html('<input type="text" value="'+txt+'" />');
//同時にinputにフォーカスをする
$('dd > input').focus().blur(function(){
var inputVal = $(this).val();
//もし空欄だったら空欄にする前の内容に戻す
if(inputVal===''){
inputVal = this.defaultValue;
};
//編集が終わったらtextで置き換える
$(this).parent().removeClass('on').text(inputVal);
});
};
});
});今回の仕組みでは,どのタイミングで編集を終了するかの仕様は,フォーカスが外れた時にしてみました。今回の紹介した方法のの他にも「保存」などのボタンを作り,そのボタンを押したタイミングで編集が終了するという仕組みにしてみるのもいいと思います。保存前に,アラートを出して確認するというのでもいいと思います。その時々の仕様で仕様を実装してみて下さい。
使用するHTML
今回はdl,dt,ddを利用してマークアップしたものを使用してみます。
HTML
<dl>
<dt>名前:</dt>
<dd>技評太郎</dd>
<dt>会社名:</dt>
<dd>技術評論社</dd>
<dt>役職:</dt>
<dd>WEBディレクター</dd>
<dt>得意:</dt>
<dd>jQuery</dd>
</dl>今回は実装を順をおいながら見ていくことにしましょう。
テキストをクリック後にinput要素へ
まずはテキストをクリックしたら,input要素を表示し,そのinputのvalueに最初のテキストの内容を入れる部分です。
その部分のみを実装したサンプルとソースコードを見てみましょう。
テキストをクリック後にinput要素を表示するソースコード
jQuery(function($){
$('dd').click(function(){
var txt = $(this).text();
$(this).html('<input type="text" value="'+txt+'" />');
});
});DD要素のテキストを変数に入れ,.html()メソッドを利用してテキストとinput要素を置き換えます。.htmlメソッドを使うことで,DD要素の中身が置き換えられるため,最初のテキストを消したりなどの作業は不要になります。
問題点
しかし,このままでは問題があります。このサンプルを実際に試してみて下さい。input要素になるところまではうまくいくと思います。その後,編集をしようとinputをクリックすると,なんと最初に入っていた文字が消えてしまいます。
これはなぜか?
この原因は,DD要素のテキストをinputのvalueに入れている部分にあります。inputが表示されたあとでも,DD要素のテキストを見に行き,それをinput内のvalueに入れ表示させているからです。inputに置き換わった後は,テキストが無いので,変数にはテキストが何も入っていない状態が代入され,それがvalueになって再度inputごと再度置き換わってしまうのです。
これを回避するための策を次に実装してみます。
編集中のDD要素にclassを持たせる
先ほどの問題を回避するために,今回は編集中のDD要素,つまりinput要素に置き換わった後のDD要素に「on」というclassを持たせて,そのclassを持っている間は新たにinputで置き換わらないようにします。
編集中のDD要素にclassを持たせるソースコード
jQuery(function($){
$('dd').click(function(){
if(!$(this).hasClass('on')){
$(this).addClass('on');
var txt = $(this).text();
$(this).html('<input type="text" value="'+txt+'" />');
}
});
});classを持っているかどうかは.hasClassメソッドを使い,もし,それを持っていなかったら実行するようになっています。
//classでonを持っているかチェック
if(!$(this).hasClass('on')){
//classでonを持っていなかったら実行
};$(this).hasClass('on')の前に「!」をつけることで,否定表現にしているため,$(this).hasClass('on')がtrueではなかったら・・・というコードになります。
これで,inputの中身が消えなくなりました。


