以前、その場編集をプラグインで実装するという記事を書きましたが
結局うまく動かすことが出来ませんでした(下記参照)
【CakePHP】その場編集(edit in place)をプラグインでやってみる - kento0824jp’s diary
色々と先輩にアドバイスを伺った所、自分で作るのもそんなに難しくなさそうだったので、やってみました。
たぶんちゃんと動いたはずなので、コードや注意点その他をまとめておきます。
さっそくですがソースコードです
$(function(){
'use strict';
var currrentTd;
var selectedTd;
var recordId;
var columnName;
var formId
var currentText;
var isFirstClick = true;
$('#table td.record').dblclick(function(){
if (!isFirstClick){
currentText = $('#' + formId).val()
postToEdit(selectedTd, recordId, columnName, currentText);
}
currrentTd = '#' + $(this).attr('id');
if(currrentTd == selectedTd){
selectedTd = ''
isFirstClick = true;
return;
}
selectedTd = '#' + $(this).attr('id');
recordId = $(this).attr('id').split('-')[0]
columnName = $(this).attr('id').split('-')[1]
formId = $(this).attr('id') + '_form'
var form = "<textarea rows= '3' " + "id ='" + formId + "'>" + initialText + "</textarea>"
$(selectedTd).html(form);
isFirstClick = false;
});
function postToEdit(selectedTd, id, columnName, currentText){
if(currentText.length == 0){
content = '*EMPTY*'
}
var editUrl = '/my_app/items/edit/' + id + '/' + columnName + '/' + currentText
$.ajax({
url: editUrl,
type: "POST",
data: { id : id, columnName: columnName, content: currentText },
dataType: "text",
success : function(response){
var textEdited = response.split('<!DOCTYPE html>')[0];
if(textEdited == '*EMPTY*'){
textEdited = '';
}
$(selectedTd).html(textEdited);
},
error: function(){
alert('通信失敗');
}
});
};
});
ざっくり概要
今回作ったのは「その場編集できるテーブル要素」です。
テーブルはデータベースの内容を表示するものです。
以前「ダブルクリックすると色が変わることで『今このセルを選択中です!』ということを示すテーブル」を作りました。
【jquery】表のセルを選択可能にする - kento0824jp’s diary
これを応用して、
「セルAをダブルクリックすると選択状態にする」
「Aの中にテキストボックスを表示」
「セルBをダブルクリックするとAのテキストボックスの入力内容をPOST」
「Bを選択状態にして、Aの選択を解除する」
というものを作りました。
POSTはajaxを使ってコントローラのメソッドに飛ばしています。
細かい解説
$('#table td.record').dblclick(function(){
if (!isFirstClick){
currentText = $('#' + formId).val()
postToEdit(selectedTd, recordId, columnName, currentText);
}
まだどのセルもダブルクリックしていない
=どのセルも選択していない
=何も編集していない
=POSTするものが何もない
なので、一番最初のダブルクリックでない場合のみPOSTします。
currrentTd = '#' + $(this).attr('id');
if(currrentTd == selectedTd){
selectedTd = ''
isFirstClick = true;
return;
}
編集中のセルをもう一度ダブルクリックした場合は
内容をPOSTした上で、どのセルも選択していない状態に戻るようにしています。
selectedTd = '#' + $(this).attr('id');
recordId = $(this).attr('id').split('-')[0]
columnName = $(this).attr('id').split('-')[1]
こちらがPOSTするまえの諸々の準備です。
今回は各セルに #レコードid-カラム名 という形式のid属性を付けていますので、そこからレコードidとカラム名を取得します。
続きましてPOSTする関数です。
大体はajaxでPOSTするときの一般的な描き方通りだと思いますが、1点だけ解説しておきます。
if(currentText.length == 0){ content = '*EMPTY*'
}
CakePHPではコントローラのメソッドに与える引き数をアドレスの後ろにスラッシュ区切りで記述します。
このとき、スラッシュ区切りの中身が空だとメソッド上では未定義変数として扱われてしまうみたいです。
これを防ぐために、空文字列を*EMPTY*という文字列で一時的に置き換えるようにしています。