質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

1回答

2140閲覧

【laravel,javascript,fullcalendar】クリックしたイベントのidをlaravel側に渡したい

asahiko123

総合スコア43

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2021/12/11 08:02

前提・実現したいこと

laravelを使って単純なCRUDアプリを作っています。

ただし、今回はDBから取得したレコードをfullcalendar(https://fullcalendar.io/)に反映させ、
さらにイベントをクリックしてデータの更新等も行いたいと思っています。

現状MySQLから取得したレコードをfullcalendarに反映させることはできましたが、
イベントをクリックしてモーダルをつけ、イベントの日付を更新する過程で問題があります。
イメージ説明
例えば2021/12/7のBイベントを2021/12/14に移動させたい場合、
イメージ説明
モーダルから日付を選択するのですが、更新を押すと、
イメージ説明

なぜか12/10にあったAイベントが移動してきます。
これを意図通りに動くように修正したいです。

原因は以下のようなものかなと思うのですが
解決する手段がわかりませんでした。

原因(と思われるもの)

以下は移動するイベントのidを取得しているindex.blade.phpのモーダル部分です。

<!-- Modal --> <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Modal title</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <div class="container-fluid"> <div class="row"> <div class="col-sm-9"> <div class="row"> <div class="col-8 col-sm-12"> @foreach($schedules as $schedule) <!-- 更新 --> <form method="POST" action="{{ route('schedules.update',['id'=>$schedule->id])}}"> @endforeach @csrf <div class="col-md-12"> <label>勤務日</label> <input type="date" class="form-control mb-3" name="workday"required> <button type="submit"class="btn btn-info text-nowrap">更新</button> </div> </form> </div> </div> </div> </div> </div> </div> </div> </div> </div>

Controllerから渡された$schedulesをfor文でまわし、取り出した$scheduleのidを使って日付の更新を行います。

ここで$schedulesにはDBからselectされた条件に合うレコードの値が全て入っています(下参照)。

ということは、先の$schedule->idにはクリックしたイベントのidではなく、
単にDBから取れてきたCollectionの最初のidが入っているということです。

dd($schedules)で確認するとCollectionの最初のidはAイベントのidでした
ここにクリックしたイベントのidを入れることができれば、万事解決する気がします。

<?php namespace App\Http\Controllers; use App\Models\ScheduleForm; use App\Models\User; use Illuminate\Support\Facades\DB; use Illuminate\Http\Request; use Illuminate\Support\Str; use Illuminate\Support\Facades\Auth; class ScheduleController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index(Request $request) { $id =Auth::id(); $forms =User::find($id)->scheduleForms(); $role =User::find($id)->role; //一般アカウント用レコード取得 $schedules =$forms ->select('schedule_forms.id',DB::raw('concat(workday,"T",start_time)as start,concat(workday,"T",end_time)as end'),'user_id','name as title') ->leftjoin('users','users.id','=','schedule_forms.user_id') ->get();      //管理者アカウント用レコード取得 if(0<$role && $role<=5){ $schedules = DB::table('schedule_forms') ->select('schedule_forms.id',DB::raw('concat(workday,"T",start_time)as start,concat(workday,"T",end_time)as end'),'user_id','name as title') ->leftjoin('users','users.id','=','schedule_forms.user_id') ->get(); } file_put_contents("json-events.json" , $schedules); return view('schedules.index',compact('schedules')); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { $users =DB::table('users') ->select('id','name') ->get(); return view('schedules.create',compact('users')); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $schedule = new ScheduleForm; $schedule->description = $request->input('description'); $schedule->workday = $request->input('workday'); $schedule->start_time =$request->input('start_time'); $schedule->end_time = $request->input('end_time'); $schedule->user_id = $request->input('user_id'); $schedule->save(); return redirect('schedule/index'); } * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { $schedule = ScheduleForm::find($id); $schedule->workday = $request->input('workday'); $schedule->save(); return redirect('schedule/index'); } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { $schedule =ScheduleForm::find($id); $schedule->delete(); return redirect('schedule/index'); } }

試したこと

ここまでのことを考えて、js側からクリックされたイベントのidをlaravelに渡せないか、と思い下記のコードを書きました。

calendar.js

document.addEventListener('DOMContentLoaded', function() { var Calendar = FullCalendar.Calendar; var calendarEl = document.getElementById('calendar'); var calendar = new Calendar(calendarEl, {    //中略 events:'../json-events.json', selectable: true, select: function(info){ document.location.href="/schedule/create"; }, eventClick: function(info) { var id = info.event.id;//クリックしたイベントのid console.log(id); $.ajax({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, type:`post`, url:'/schedule/index', data:{ "id":id, }, dataType:"text", success:function(data){ console.log('送信しました'); }, error:function(error){ console.log(error.errorThrown); } }); $('#exampleModalLabel').html('イベントの更新または削除'); // モーダルのタイトルをセット $('#modalBody').html(''); // モーダルの本文をセット $('#exampleModal').modal(); // モーダル着火 }, }); calendar.render(); });

イメージ説明

このコード自体にエラーはでていないので、値を送れている(?)
ようですが、$_post['id']はundefinedになります。

イベントをクリックしないと中身が入らないので、
そのせいかと思いますが、どうやって組み込んだらいいものか..というところで行き詰まっています。

いい方法があれば教えて頂ければと思います。

長文で分かりずらい点があれば申し訳ありません。

補足web.php

<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\ScheduleController; /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home'); Auth::routes(); Route::group(['prefix'=>'schedule','middleware'=>['auth','can:user-higher']],function(){ Route::match(['get','post'],'index',[ScheduleController::class,'index'])->name('schedules.index'); }); Route::group(['prefix'=>'schedule','middleware'=>['auth','can:admin-higher']],function(){ Route::get('create',[ScheduleController::class,'create'])->name('schedules.create'); Route::post('store',[ScheduleController::class,'store'])->name('schedules.store'); Route::post('delete/{id}',[ScheduleController::class,'destroy'])->name('schedules.delete'); Route::post('update/{id}',[ScheduleController::class,'update'])->name('schedules.update'); }); Route::group(['prefix'=>'schedule','middleware'=>['auth','can:system-only']],function(){ // });

補足情報(FW/ツールのバージョンなど)

laravel8
MySQL
fullcalendar4.3.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

skys215

2021/12/11 08:27

@foreach($schedules as $schedule) <!-- 更新 --> <form method="POST" action="{{ route('schedules.update',['id'=>$schedule->id])}}"> @endforeach どうしてform要素をループでいくつかも作る必要があるのですか?</form>も同時にないとダメだと思います。 イベントをクリックした時点で、クリックされたイベントのidをモデルに渡してformのformのactionを更新するべきだと思います。
asahiko123

2021/12/12 06:57

ご指摘ありがとうございます。 formの入れ子はhiddenを用いて解消しました。
guest

回答1

0

ベストアンサー

@foreach($schedules as $schedule) <!-- 更新 --> <form method="POST" action="{{ route('schedules.update',['id'=>$schedule->id])}}"> @endforeach

この時点でHTMLとしておかしいです。

<form>開始タグだけスケジュールの数分だけ作られていることになります。 ```html <form > <form > <form > <form > </form> ```

formタグの入れ子はできませんし、数が合っていません。
いずれにしても何をしても1つしかリクエストを飛ばせないということになります。

幾つイベントがあってもモーダルは1つしか上げないのですから、
たとえばhiddenを用意しておき、モーダルが上がるタイミングで仰るように「クリックしたイベントのID」を取得されるようにしたら良いかと。

ドキュメント見ますと、「クリックした要素」はあるようなので、例えばdata属性などでイベントのIDを設定しておけば取得可能となるのでは。

投稿2021/12/11 08:39

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asahiko123

2021/12/12 06:59 編集

ご指摘ありがとうございます。 空のvalueにgetElementByIdを使ってクリックしたイベントのidを渡すことができました。 これによって@foreachで値をとる必要がなくなったので、formの入れ子も解消しました。 <form method="POST" action="{{ route('schedules.update')}}"> @csrf <div class="col-md-12"> <label>勤務日</label> <input type="date" id="start"class="form-control mb-3" name="workday"required> <input type="hidden" id="id" name="id"value=""> <button type="submit"class="btn btn-info text-nowrap">更新</button> </div> </form>
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問