今回はLaravelでjQueryを使ってモーダルを作成してみました。
その際にモーダルの中身は別のbladeファイルから呼び出したかった。だけど、なかなか方法が見つからなかったのでまとめます。
Table of Contents
モーダルウインドウを作成。
モーダルの作成は以下を参考にさせていただきました。
【Laravel】モーダルウィンドウを表示するコンポーネント(blade)ファイルを作成しました。
resources/views/modal_window.blade.php
@section('modal_window')
<div id="modal-content">
@parent
</div>
<script>
$(function(){
//モーダルウィンドウを出現させるクリックイベント
$("#modal-open").click( function(){
//キーボード操作などにより、オーバーレイが多重起動するのを防止する
$( this ).blur() ; //ボタンからフォーカスを外す
if( $( "#modal-overlay" )[0] ) return false ; //新しくモーダルウィンドウを起動しない (防止策1)
//if($("#modal-overlay")[0]) $("#modal-overlay").remove() ; //現在のモーダルウィンドウを削除して新しく起動する (防止策2)
//オーバーレイを出現させる
$( "body" ).append( '<div id="modal-overlay"></div>' ) ;
$( "#modal-overlay" ).fadeIn( "slow" ) ;
//コンテンツをセンタリングする
centeringModalSyncer() ;
//コンテンツをフェードインする
$( "#modal-content" ).fadeIn( "slow" ) ;
//[#modal-overlay]、または[#modal-close]をクリックしたら…
$( "#modal-overlay,#modal-close" ).unbind().click( function(){
//[#modal-content]と[#modal-overlay]をフェードアウトした後に…
$( "#modal-content,#modal-overlay" ).fadeOut( "slow" , function(){
//[#modal-overlay]を削除する
$('#modal-overlay').remove() ;
} ) ;
} ) ;
} ) ;
//リサイズされたら、センタリングをする関数[centeringModalSyncer()]を実行する
$( window ).resize( centeringModalSyncer ) ;
//センタリングを実行する関数
function centeringModalSyncer() {
//画面(ウィンドウ)の幅、高さを取得
var w = $( window ).width() ;
var h = $( window ).height() ;
// コンテンツ(#modal-content)の幅、高さを取得
var cw = $( "#modal-content" ).outerWidth();
var ch = $( "#modal-content" ).outerHeight();
//センタリングを実行する
$( "#modal-content" ).css( {"left": ((w - cw)/2) + "px","top": ((h - ch)/2) + "px"} ) ;
}
});
</script>
<style>
#modal-content {
width: 50% ;
margin: 0 ;
padding: 10px 20px ;
border: 2px solid #aaa ;
background: #fff ;
position: fixed ;
display: none ;
z-index: 2 ;
}
#modal-overlay {
z-index: 1 ;
display: none ;
position: fixed ;
top: 0 ;
left: 0 ;
width: 100% ;
height: 120% ;
background-color: rgba( 0,0,0, 0.75 ) ;
}
.button-link {
color: #00f ;
text-decoration: underline ;
}
.button-link:hover {
cursor: pointer ;
color: #f00 ;
}
</style>
@endsection
Code language: HTML, XML (xml)
作成したモーダルウィンドウを読み込むページを作成します。
resources/views/○○○
<div id="faq_csv_modal_window">
{{-- モーダルウィンドウ --}}
@include('components.modal_window')
@section('modal_window')
<div id="modal_open">
<header id="modal_header">
モーダルヘッダーです。
</header>
<main id="modal_main">
</main>
<footer id="modal_footer">
<p><a id="modal-close" class="button-link">閉じる</a></p>
</footer>
</div>
@endsection
@yield('modal_window')
</div>
Code language: HTML, XML (xml)
これでモーダルが完成します。(参考サイトのままです…)
別bladeファイルをモーダルの中身に表示する。
なぜ、別ファイルにするかというと、動的にファイルの中身が変わるからです。
選択したコンテンツによってファイルの中身を変えたい。ということで、、、
コンテンツがクリックされるとajaxでデータを取得してみます。
var userId = $(this).data('id'); //クリックされた要素を取得
var hostUrl= '/download/' + userId; //post送信先のURLを定義
$.ajax({
url: hostUrl,
type: 'GET',
})
Code language: JavaScript (javascript)
getでurlを投げます。すると、controllerから表示したいviewを返すように書きます。
function showData($id)
{
//取得したユーザーの情報を$userに入れてuser/download.blade.phpに返す
$user = userPost::find($id);
return view('user.download', compact('user')); //bladeの中身にしたいbladeファイルを返す
}
Code language: PHP (php)
こうすると、bladeファイルと必要な要素が送られてきます。
ということで、それを表示するためにjQueryに以下を追記してみましょう。
//通信が成功したとき
.done((data)=>{
//通信が成功した時にDownloadControllerからformが記載されているviewが返されるのでそれを表示する。
$('main').empty();
$('main').append(data);
})
Code language: JavaScript (javascript)
これで送られてきたdataが<main></main>タグの間にbladeファイルが表示されるようになります!
まとめ
最初は直接別bladeファイルの中身を書き込んでいたんですが、そこでは変数が必要で、contrpllerから送られてくる特定の要素が必要だったんで一覧表示の際には取得できないからエラーが出ていたんですね。
だからajaxを使って通信を行って必要な要素とファイルを必要なタイミングで取得できるようにしました。
結構つまった箇所になるので何とかやりたいことできて良かったです…