【CakePHP jquery】その場編集(edit in place)を実装してみた

 

以前、その場編集をプラグインで実装するという記事を書きましたが
結局うまく動かすことが出来ませんでした(下記参照)

【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){// 一番最初にダブルクリックしたときはpostしない
            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
  // editはcontorollerのfunction edit

        $.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){// 一番最初にダブルクリックしたときはpostしない
            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*という文字列で一時的に置き換えるようにしています。