前回までで登録・一覧・削除ができたので今回は編集機能を作ります。
Actionsのペンアイコンをクリックしたときに該当データの編集画面を表示しデータの変更ができるようにします。すでに登録用のコンポーネントにフォームがあるので共有化しましょう。
目次
開発環境
Laradock v10
Laravel 7
Vue 2.6
Laravel:コントローラーにメソッド実装
showメソッドで指定されたIDのデータを返します。
updateメソッドで指定されたIDのデータを更新します。
public function show($id)
{
$status = 200;
$message = null;
$data = null;
$item = Item::find($id);
if ($item) {
$data = $item;
$data['checkbox'] = explode(',', $data['checkbox']);
} else {
$status = 404;
$message = 'Not Found.';
}
return response()->json(['item' => $data, 'status' => $status, 'message' => $message]);
}
public function update(ItemRequest $request, $id)
{
$status = 200;
$message = null;
$result = false;
$data = $request->all();
$data['checkbox'] = implode(',', $data['checkbox']);
$item = Item::find($id);
if ($item) {
$result = $item->fill($data)->save();
} else {
$status = 404;
$message = 'Not Found.';
}
return response()->json(['result' => $result, 'status' => $status, 'message' => $message]);
}
※updateメソッドのリクエストは登録で使用したItemRequestを利用してバリデーションに対応します。
※Laravel側でエラーを出すとJavascriptが止まってしまうのでエラーとして返してJavascript側で処理することにします。
コンポーネント名を変更
フォームのコンポーネントはItemAddComponent.vueになっていましたが、共有化するためにitemEditComponet.vueに変更しましょう。
resources/js/components/User/ItemAddComponent.vue
↓
resources/js/components/User/ItemEditComponent.vue
Vue-Routerの変更
フォームの共有化のため、Vue-Routerの設定を変更します。
// import UserItemAdd from './components/User/ItemAddComponent'
import UserItemEdit from './components/User/ItemEditComponent' // 変更
・・・
// {
// path: '/user/item/add',
// name: 'user-item-add',
// component: UserItemAdd,
// },
// 上記コードを以下に変更
{
path: '/user/item/edit/:id(\\d+)?',
name: 'user-item-edit',
component: UserItemEdit,
},
※id付きでアクセスされたときはそのidでデータを呼び出して編集フォームに、idが無かったときは登録フォームにしたいと思います。
ItemComponentのリンク先変更
新規登録ボタンのリンク先変更
idを指定しない形で/user/item/editへ!
<router-link to="/user/item/add">
<v-btn>新規登録</v-btn>
</router-link>
↓
<router-link to="/user/item/edit">
<v-btn>新規登録</v-btn>
</router-link>
ペンアイコンを編集画面へのリンクに
上記、router.jsの設定により、router-linkでnameをuser-item-edit、paramにidを与えることで/user/item/edit/{id}にリンクしてくれます。
<v-icon
class="mr-2"
@click="editItem(item)"
>
mdi-pencil
</v-icon>
↓
<router-link :to="{ name: 'user-item-edit', params: { id: item.id } }">
<v-icon
class="mr-2"
>
mdi-pencil
</v-icon>
</router-link>
ItemEditComponentの修正
ItemAddComponent.vueから名前を変更してItemEditComponent.vueにしたので内容を修正します。
resources/js/components/User/ItemEditComponent.vueの変更です。
タイトルの変更
v-ifを使ってforms.idの有無でタイトルの切り替え
<h1>UserItemAdd</h1>
↓
<h1 v-if="forms.id == ''">UserItemAdd</h1>
<h1 v-else>UserItemEdit</h1>
formsにid追加
dataオブジェクトformsにidを追加します。
<script>
export default {
data() {
return {
・・・
forms: {
id: '', // 追加
textbox: '',
textarea: '',
radiobtn: '1',
select: '',
checkbox: [],
},
・・・
created()でItemデータ取得
ItemComponent.vueのリンクでparamを設定しましたが this.$route.params.id で取得することができます。これを利用してidが存在するときだけAxiosでItemデータを取得してformsに設定します。
created() {
・・・
// 以下追加
if (this.$route.params.id) {
this.forms.id = this.$route.params.id;
axios.get('/ajax/user/item/' + this.$route.params.id).then((res) => {
if (res.data.status == 200) {
const item = res.data.item;
item.radiobtn = item.radiobtn.toString()
item.select = item.select.toString()
this.forms = item;
} else {
// エラー処理
}
})
.catch(function(error) {
console.log(error)
// エラー処理
})
}
※ここまでで編集フォームに変更するItemデータを設定するところまでできました。
methodsのsubmit()での送信先切り替え
送信ボタンを押したときの送信先もAxiosのメソッドの切り替えが必要です。
forms.idが空でなければ更新なので
putメソッドで送信先は/ajax/user/item/[変更するデータのID]
空なら登録で
postメソッドで送信先は/ajax/user/item
ですね。
// 送信処理
let ajax;
if (this.forms.id) {
// 更新
ajax = axios.put('/ajax/user/item/' + this.forms.id, this.forms);
} else {
// 新規登録
ajax = axios.post('/ajax/user/item', this.forms);
}
ajax.then((res) => {
・・・
後記
当初、編集機能まで書くつもりがなかったのですが、一応完結するために追加しました。
最初から登録と編集のフォームを共有化しておけばよかったですね。
編集完了時の戻り先(ページ)とかエラー時の対応とか実装できてないところがありますが、またいずれ・・・