生活の跡

個人的な備忘録

FuelPHPで処理の異なる2つのボタンをもつフォームを作る

概要

FuelPHPでWebアプリを作っています。ある商品のデータを編集する画面にて、更新と削除のボタンを用意する方法がわかったので記事に残します。画面のイメージは次の通りです(カクカクしててすみません)。

f:id:ishii-akihiro:20191025010630g:plain

どちらのボタンも同じフォームの要素にしていますが、更新ボタンは type="submit"、削除ボタンは type="button" を指定しています。

環境

FuelPHP 1.8.2

処理の流れ

更新ボタンが押された時は、そのままコントローラを呼び出します。
一方、削除ボタンが押された時は、javaScript でイベントを感知して、確認メッセージを表示してからコントローラを呼び出します。

削除するデータの id は、コントローラ(編集画面表示) → ビュー → javaScript → コントローラ(削除処理) の流れで渡されます。

ソースコード

おもな部分を抜粋します。

商品一覧表示

DBから商品情報を取得して表示するだけです。

  • コントローラ
<?php

class Controller_List extends Controller
{ 
  public function action_index()
  {
    //DBからデータを取得
    $products = Model_Product::select_products();
    
    //ビューを作成
    $view = View::forge('list');
    $view->set_global('products', $products);
    
    return $view;
  }
}
  • ビュー
〜省略〜
    <tbody>
      <?php foreach($products as $key => $value): ?>
        <tr>
          <td><?php echo Html::anchor('detail/index/'.$value['id'], '編集'); ?></td>
          <td><?php echo $value['id']; ?></td>
          <td><?php echo $value['name']; ?></td>
          <td><?php echo $value['price']; ?></td>
        </tr>
      <?php endforeach; ?>
    </tbody>
〜省略〜

編集画面表示

下記コードの(※1)にある通り、削除ボタンに独自の属性を付与し、削除処理を行うコントローラのURIを指定しておきます。ここでは next-uri という属性を定義しています。値に指定したURIは、後述するjavaScriptから呼ばれることになります。

  • コントローラ
<?php

class Controller_Detail extends Controller
{ 
  public function action_index($id = null)
  {
    //フォームを作成
    $form = Fieldset::forge();
    
    //フィールドを追加
    $form->add('name', '商品名', array('type'=>'text'));
    $form->add('price', '価格', array('type'=>'number'));
    $form->add('id', '', array('type'=>'hidden'));
    $form->add('submit', '', array('type'=>'submit', 'value'=>'更新', 'class'=>'btn-edit'));
    
    //(※1)レコードを削除するボタンを追加
    $form->add('button_delete', '', array(
      'type'=>'button',
      'value'=>'削除',
      'id'=>'btn-delete',
      'next_uri'=>Uri::base().'delete/index/'.$id
      )
    );

    //POST送信されていない場合(一覧から遷移した時)
    if(Input::method() !== 'POST')
    {
  〜省略〜
    }
    //POST送信された場合
    else
    {
  〜省略〜
        //更新処理
        Model_Product::update_product($data);
        
        //一覧画面に遷移
        Response::redirect('list');          
  〜省略〜
    }

    //ビューを作成
    $view = View::forge('detail');
    $view->set_global('editform', $form->build(''), false);
    
    return $view;
  }
}

編集画面のビューでは、削除ボタン押下時に呼ばれる jsファイルを読み込みます。本記事ではjQueryを使って jsファイルを書いたので、jQueryのcdnを先に読み込ませています。

  • ビュー
〜省略〜
<body>
  <?php echo $editform; ?>
  
  <!-- jQuery cdn -->
  <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
  <?php echo Asset::js('detail.js'); ?>
</body>
</html>

削除ボタン押下後の処理

jsファイルでイベントが探知され、confirm で確認メッセージを表示します。「OK」が押された場合、以下(※2)にて削除処理のコントローラが呼び出されます。ここで、(※1)で削除ボタンに設定しておいた next_uri 属性の値(削除処理のコントローラのURL)が参照されます

  • javaScript
//jQueryで記述しています
$(function(){
  //削除ボタン押下処理
  $('#btn-delete').on('click', function(){
    //確認メッセージ
    if(confirm('このデータを削除しますか?'))
    {
      //(※2)「OK」なら削除処理のコントローラへ
      location.href = $(this).attr('next_uri');
    }
  });
})

コントローラには削除する商品データのidが渡されます。データ削除後は、一覧画面に遷移させています。

  • コントローラ
<?php

class Controller_Delete extends Controller
{
  public function action_index($id = null)
  {
〜省略〜
      Model_Product::delete_product($id);
      
      Response::redirect('list');
〜省略〜
  }
}

おわりに

一覧画面から商品データのidを渡して、更新と削除を行うことができました。データの id をコントローラ(編集画面表示) → ビュー → javaScript → コントローラ(削除処理) の流れで渡す方法がわかってよかったです。

なお、バリデーションや例外処理などは端折らせていただきました。