2022年12月12日
前回の記事まででメディアライブラリで画像を選択してファイルパスをデータベースに登録するところまではできました。
ここから例えばスライドショーの画像が6枚あったとしたら6つの画像選択フォームを用意したい。欲を言うならメディアライブラリで複数選択したい。
複数選択にすることは比較的簡単でした。前回作ったmedia-uploader-main.jsのファイルのmultipleの部分をtrueにするだけで複数選択できるようにはなりました。
しかし順番を思った通りにできない。jqueryのすばらしい機能を使えば、選択したあとに直感的に画像を移動させて順番を入れ替えることができるかもしれないけど、メディアライブラリがそもそも複数選択できるかどうかがわかりづらい見た目をしているのと、まあスキル的に不可能だろうと思い断念。
作った画像選択画面を複数作る方がわかりやすいと判断しました。
素直に作るのであればhtmlのフォームでidを6つ作って、それぞれに対応するjavascriptをがんばって書いていくのですが、それでは芸がないというかコピペミスすることが目に見えてますのでなんとか動的に作りたい。いろいろ試行錯誤した結果できたので備忘録として残しておこうと思います。
考え方としてはまず、javascript側でidがmedia-uploadとなっているものをクリックしたとき、メディアライブラリが開くように現状なっているので、これをidではなくclassにすることでメディアライブラリが開けるリンク(ボタン)をいくつでも作れるようにします。
次に各ボタンに別にidを付けておき、ボタンをクリックしたときにそのidを取得、そのidをファイルパスを反映させるフォームidに付けることでユニークなidを作り選択した画像が表示されるようにします。
html側はループ処理を使ってひとつのフォームを6回繰り返して表示させ、フォームのidはjavascript側と同じidがつくように細工しておけばうまくいくはず。
順番通りにやてみます。
(function($) {
$(function() {
var custom_uploader = wp.media({
title: 'Choose Image',
library: {
type: 'image'
},
button: {
text: 'Choose Image'
},
multiple: false
});
$("#media-upload").on("click", function(e) {
e.preventDefault();
custom_uploader.open();
});
custom_uploader.on("select", function () {
var images = custom_uploader.state().get('selection');
images.each(function(file) {
$("#iamge-url").val(file.toJSON().url);
$("#iamge-view").attr("src", file.toJSON().url);
});
});
});
})(jQuery);
現状こうなっています。この中の$("#media-upload")
の部分を$(".media-upload")
に変更すると、html側でclass="media-upload"
となっているボタンをクリックするとメディアライブラリが開くようになります。
このクリックしたイベントの関数の中にクリックしたボタンのidを取得する関数を入れます。
var button_id = e.target.id;
ここで取得したidを使って、ファイルパスを表示する要素のidを作成します。
iamge_url = '#image-url' + button_id;
iamge_view = '#image-view' + button_id;
次に選択した画像を反映するidを指定している部分をここで作成したidに変更します。
$("#iamge-url").val(file.toJSON().url);
$("#iamge-view").attr("src", file.toJSON().url);
これを
$(iamge_url).val(file.toJSON().url);
$(iamge_view).attr("src", file.toJSON().url);
こうします。
スポンサーリンク次にhtml側を変更します。
<form method="POST" action="<?php echo str_replace( '%7E', '~', $_SERVER['REQUEST_URI']); ?>">
<div class="uk-margin">
<label class="uk-form-label" for="form-stacked-text">テストテキスト</label>
<div class="uk-form-controls">
<input class="uk-input" id="form-stacked-text" name="slider_image_select_plugin_entry_form" value="<?php echo esc_attr(get_option('slider_image_select_plugin_entry_form')); ?>" type="text" placeholder="なんか入れて">
</div>
</div>
<div class="uk-margin">
<button id="media-upload" class="uk-button uk-button-primary uk-margin-bottom">画像を選択する</button><br>
<img id="image-view" src="<?php echo plugins_url( 'images/no-image.gif', __FILE__); ?>" width="260">
<input id="image-url" type="text" class="large-text">
</div>
<input type="hidden" name="posted" value="slider_save">
<button class="uk-button uk-button-primary" type="submit">登録</button>
</form>
現状こうなっている
<button id="media-upload" class="uk-button uk-button-primary uk-margin-bottom">
この部分をまず
<button id="" class="media-upload uk-button uk-button-primary uk-margin-bottom">
このように変更します。そしてこの画像選択部分に6回分ループ処理をかけます。
<?php for($i=0; $i<6; $i++){ ?>
<div class="uk-margin">
<button id="" class="media-upload uk-button uk-button-primary uk-margin-bottom">画像を選択する</button><br>
<img id="image-view" src="<?php echo plugins_url( 'images/no-image.gif', __FILE__); ?>" width="260">
<input id="image-url" type="text" class="large-text">
</div>
<?php } ?>
こうしてやると、
入りきってないですが、6つフォームができました。ここでループ処理で使った変数$iを利用してidも動的に作成します。今idの部分は空欄になっていますが、この部分に
<button id="<?php echo $i; ?>" class="media-upload uk-button uk-button-primary uk-margin-bottom">
こんな感じで出力してやります。あと、ファイルパスを反映させたいフォームのidの後ろにも変数iを出力してやります。
<img id="image-view<?php echo $i; ?>" src="<?php echo plugins_url( 'images/no-image.gif', __FILE__); ?>" width="260">
<input id="image-url<?php echo $i; ?>" type="text" class="large-text">
こんな感じ。すると各idに番号が出力されてユニークな値になりました。
これで各フォームで画像を選択してやると…
こんな感じでそれぞれ違う画像を選択できるようになりました。あとはフォームが見やすくなるようにスタイルをいじってやれば完了です。
プラグインとしての機能性を考えると、有効化した後にスライドショーの画像数を最初に登録させて、その数だけループ処理をかけるようにしたほうが親切ですね。ただ画像数を減らした際にカスタムフィールドを削除する機能なども付けないといけないことを考えると、自分で使う範囲としてはこんなもんでいいかもしれません。
もしくはカスタムフィールドはひとつにしといて、カンマ区切りでデータベースには登録、スライドショーに出力するときもループ処理で出力するというのが汎用性高そうです。画像名にカンマが入ってしまうと絶望ですが…
外部でjsonデータで保存して配列で処理しちゃうほうがいいかもしれませんね。そうすればカスタムフィールドも画像数だけ保存するだけで済むのでデータベースにもやさしいかも…
と、いろいろ考えられますのでいろいろやってみて汎用性の高いものができたらwordpressに登録してみるのもいいかもしれません。気が向いたら次回はそこまでやってみようかと思います。
お仕事のご依頼やご相談、弊社サービス内容に関してなど、お気軽にご相談ください。