TO DO リスト 追加機能 (Vue.js + Ajax + Laravel)

2019/06/20

Vue.js + Ajax + Laravel による TO DO リストの作成の続きです。

前回は表示のみ(データベースのレコード抽出 → Vue.jsでループして表示)までのところを作成しました。

今回は入力したテキストを非同期で表示させるところまで作成します。

 
手順

0.前提知識

Laravel 以外にも Vue.js と Ajax の知識も必須になります。

 

1.モデルの作成

入力したデータは Eloquent で todos テーブルに入れる作業が発生するので、モデルを作成しておきます。


php artisan make:model Models/Todo

ブラックリスト方式でカラムを定義


:
protected $table = 'todos'; // ここは設定しなくてもOK
protected $guarded = ['id'];
:

この辺りは基本的なところなので説明を省きます。

よくわからない方は以下のエントリーをご参照ください。

 

2.JavaScript(Vue.js)

ソースコード

var todo = new Vue({
    el: '#app',
    data: {
        list: [],      // 入力テキストを入れる配列
        last: null,    // 入力テキストの最終更新日
        inputText: "", // テキストフォームで入力したデータの変数
    },
    methods: {
        // 送信機能
        send: function () {

            // 最終更新日がNULLのとき
            if(!todo.last){
                todo.last = { created_at: "1970-01-01 00:00:00" }
            }

            sendMessage(this.inputText, todo.last.created_at); // 送信メッセージ関数
            this.inputText = ""; // 初期化
        },
    }
});

 

解説

入力フォームで入力されたデータを inputTextデータバインディングします。

送信機能の関数 sendMessage を起動し inputText と created_at を引数に入れます。

ポイント

データバインディングとは?
データと描画を同期する仕組みです。HTML側のテンプレートに記述されたフォームのinputの部分の文字を変更すると、出力される文字がリアルタイムで変わります。

 

3.JavaScript(Ajax)

ソースコード

// メッセージ送信関数
function sendMessage(message) {
    $.ajaxSetup({
        headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }
    });
    $.ajax({
        type: "POST",
        url: baseURL + '/send_message_api',
        dataType: "json",
        data: { "message": message, "created_at": created_at }
    }).done(function(results) {
        console.log("メッセージ追加成功!");
        console.log('results=',results);
        addMessage(results); // 通信に成功したらAPIからの返り値を addMessage() に入れる
    }).fail(function(jqXHR, textStatus, errorThrown) {
        alert('メッセージを送信に失敗しました。');
        console.log("ajax通信に失敗しました");
        console.log("jqXHR          : " + jqXHR.status);     // HTTPステータスが取得
        console.log("textStatus     : " + textStatus);       // タイムアウト、パースエラー
    });
};

 

解説

メッセージ送信関数( sendMessage ) は Vue.js のインスタンスの外に記述します。

この Ajax は Laravel で作成する WebAPI に通信します。

通信が成功すれば addMessage() メソッドにAPIから取得したデータを引数に入れます。

 

4.Laravel(API)

ソースコード
ルーティング

Route::post('vue/messages_list_api', 'PracticeVueApiController@getAllMessage'); // メッセージ取得API
Route::post('vue/send_message_api',  'PracticeVueApiController@sendMessage');   // メッセージ送信API

 

コントローラ

public function sendMessage(Request $request) {

     $messages = DB::transaction(function() use($request)
     {
         $create = new Todo();
         $create->task = $request['message'];
         $create->save();

         // 前回の最終更新日以上のメッセージを抽出 → 送ったメッセージを抽出
         $updateList = $create->select(
             [
                 'task',
                 'created_at',
             ]
         )
             ->where('created_at', '>', $request['created_at'])
             ->orderBy('created_at', 'asc')
             ->get();
         return $updateList;
     });

    return response()->json(['tasks'=> $messages]);
}

 

解説

Ajax 通信で vue/send_message_api の URI に通信します。

このURIにアクセスすると PracticeVueApiControllersendMessage() が起動します。

sendMessage() では Ajax でセットされた入力データをテーブルに挿入する処理を書きます。

また、前回の最終更新日を条件式に入れて、今回追加分のレコードを抽出します。

これらの処理はトランザクション処理で記述します。

抽出したデータは json 形式に変換して Ajax に返します。

 

5.JavaScript addMesage関数

ソースコード

function addMessage(results) {

    $.each(results.tasks, function() {
        todo.list.push(this); // 配列の末尾に追加分のレコードを追加
        todo.last = this;     // 最終更新日入れる→todo.last.created_atでアクセス
    });

    todo.$forceUpdate();
}

 

解説

追加したデータはここで配列( list[] )に入れます。

後述する Blade で v-for によってループ処理をして表示させます。

Vue.js の data の値を更新させるために $forceUpdate()メソッドを使います。

$forceUpdate()メソッドはDOMの再評価させ表示させるメソッドです。

 

6.Blade

ソースコード

<!-- 入力フォーム -->
<form>
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" v-model="inputText">
<span class="input-group-btn"><button id="send" v-on:click="send" class="btn btn-primary" type="button">送信</button></span>
</div>
</div>
</form>

<hr>

<!--ループ処理-->
<ul class="list-group">
    <li class="list-group-item" v-for="todo in list">@{{ todo.task }}</li>
</ul>

 

解説

テキストフィールドに v-model を使ってデータバインディングします。

送信ボタンを押したら v-on:clicksend メソッドを起動します。

このメソッドでは sendMessage() を呼び出す処理を記述しました。

sendMessage() は入力したテキストをAjax通信でテーブルにインサートするメソッドです。

ここの通信が上手くいけば addMessage() が呼び出され、追加したデータを list[] に入れます。

list[] 配列は Blade の v-for でループ処理をして表示させます。

ポイント

送信ボタンは type="button" で作成します。
type="submit" にするとページ遷移してしまいます。

 
入力機能についての解説は以上になります。

次回は削除機能についての作成&解説をしようと思います。

 

確かな力が身につくJavaScript「超」入門 (確かな力が身につく「超」入門シリーズ)

Stack Overflow によると、よく使われているプログラミング言語はJavaScriptが7年連続で第1位だそうです。(2019年現在)わからない箇所だけネットで調べるやり方は知識が断片化するので、いつか、本を読んでJavaScriptの知識を体系的に整理したいと思っていました。この本はAmazonでも評価が高く、以前から気になっていた本です。図解と実行結果、短めのサンプルプログラムと見やすく解りやすかったのでおススメですね。「超」入門と書いてありますが、後半になると jQueryAjax の内容が出てきます。Ajaxの情報はネットでもあまりなかったので僕にとってはよかったです。

Amazonで詳細を見る

オススメ

 

本庄マサノリ

仕事でLaravelを使っています。気づいたことや新しい発見など情報を発信していきます。メールはこちら

 

-チュートリアル, 中級