20211014のlaravelに関する記事は8件です。

【フォーム】追加ボタンを押して関連した入力欄2つを同時に増やしていく方法

はじめに 今回以下のようなフォームは作ったので、備忘録として残しておきます。 HTML部分 create.brade.php <label>{{ __('材料') }} <a onclick=add() class="btn btn-sm btn-light">+追加</a> <div id="input_plural"> <div class="d-flex"> <input type="text" class="form-control mb-1" name="ing-name-1"> <input type="text" class="form-control mb-1" name="ing-size-1"> <input type="button" value="削除" onclick="del(this)"> </div> </div> </label> javaScript部分 main.js let inputPlural = document.getElementById('input_plural'); var count = 2; function add() { let div = document.createElement('DIV'); div.classList.add('d-flex'); var input = document.createElement('INPUT'); input.classList.add('form-control'); input.setAttribute('name', 'ing-name-'+count); div.appendChild(input); var input = document.createElement('INPUT'); input.classList.add('form-control'); input.setAttribute('name', 'ing-size-'+count); div.appendChild(input); var input = document.createElement('INPUT'); input.setAttribute('type', 'button'); input.setAttribute('value', '削除'); input.setAttribute('onclick', 'del(this)'); div.appendChild(input); inputPlural.appendChild(div); count++; } function del(o) { o.parentNode.remove(); } おわりに bootstrapを使ってちょっぴり整えているので、その点はご了承ください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】ルートパラメータの渡し方

はじめに  URLにパラメータを渡して、それをコントローラーで受け取る方法をメモしておきます。 Webページを作るのにとても便利です。 view まずはリンクを設定します。 bladeテンプレートにこのように書いていきます。 view.blade.php <a href="{{ route('index',['id' => 1]) }}">テスト</a> route関数の第二引数にこのように指定していきます。 ここでは直接数字を入れていますが、データベースから取得してきたデータのIDなどを入れるパターンが多いと思います。 ルーティング web.phpにはルーティングを書いていきます。 web.php Route::get('/index/{id}', [HomeController::class, 'index'])->name('index'); URLには先ほど bladeテンプレートのaタグで指定したidが入ります。 ルーティングのURlが指定されてリクエストが送られると、コントローラーのメソッドが呼び出されます。 controller コントローラーのメソッドはこのように記述します。 controller.php public function index($id) { $post = Post::where('id',$id)->first(); return view('index',compact('post')); } あくまで一例ですが、こんな感じで取得してきたidをEloquentのwhere句に使ったりすることで、特定のデータを取得することができます。 あとはview側でテンプレートを使って煮るなり焼くなりするだけです! テンプレートの書き方は省略します。 終わりに 書き方いつも迷うので備忘録として書きました。 Webページの詳細をアイテムごとに表示したりするのに便利なので、使い方を覚えておいて損はないと思います!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel8】マイグレーションで既存のテーブルにカラムとデータを追加する

概要 既に作成済みのテーブルへカラムを追加し、データまで入れる機会があったのでまとめます。 データの投入といえばシーダーが一般的かと思いますが、追加するカラムへどのようなデータが投入されるのかをマイグレーションファイルのみで確認できるため、今回はこの方法を採用しました。 想定 リリース済みのサービスへの改修依頼 並び順カラム(sort_id)を追加し、1,2,3・・・とデータを挿入する 環境 Laravel 8.24.0 マイグレーションファイル <?php use App\Models\Post; use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; class Modifyposts20211013 extends Migration { /** * Run the migrations. * * @return void */ public function up() { // sort_idカラムの追加 Schema::table('posts', function (Blueprint $table) { $table->unsignedInteger('sort_id'); }); // カテゴリなしのsort_idを指定 // Postレコードの追加 $postRecord = [ 'name' => '投稿1', 'sort_id' => 0, ]; DB::table('posts')->insert($postRecord); // 既存のカテゴリレコードを取得 $posts = Post::oldest('id')->get(); $counter = 1; // 既存のカテゴリレコードへsort_idの追加 foreach ($posts as $post) { if($post->name === '投稿1') { continue; } $post->sort_id = $counter; $post->save(); $counter++; } } /** * Reverse the migrations. * * @return void */ public function down() { // Postレコードの削除 DB::table('posts')->where('name', '投稿1')->delete(); // sort_idカラムの削除 Schema::table('posts', function (Blueprint $table) { $table->dropColumn('sort_id'); }); } } 解説 use App\Models\Post;について use Illuminate\Support\Facades\DB; $users = DB::table('users')->get(); foreach ($users as $user) { echo $user->name; } 上記はマニュアルの日本語訳サイトにあるものです。DBファサードを使用して既存のレコードを取得することはできるのですが、$userはstdClassオブジェクトのインスタンスとなるため、saveメソッドやupdateメソッドが使用できずエラーが発生します。そのためuse App\Models\Post; を使用し既存レコードをコレクションとして取得してデータを保存しています。 投稿1の追加など、レコードを1件挿入する際はDBファサードを使用して簡単に行うことができます。 down()メソッドについて // Postレコードの削除 DB::table('posts')->where('name', '投稿1')->delete(); downメソッドには追加したレコードの削除も書いておきます。 この記述がないとロールバックした際に追加したレコードが削除されないため注意です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

転職活動管理アプリを作ろう⑥(laravel-admin 役割ごとのメニュー切り替え)

前回の記事は コチラ やりたいこと なんでも見れるし触れる Administrator、一般利用者を想定した users の 2 つのアカウント種別を作成したい これこそ JetStream を使った一般権限を作成 しろとか言わないでください UI イチから作るのめんどくさいので やったこと概略 権限の作成 laravel-admin では URI の部分一致で設定する 役割の作成 laravel-admin ではホワイトリスト方式 アカウントの作成 ログイン後 HOME 画面の作成、リダイレクト設定 各メニューのサイドバー表示設定 1. 権限の作成 転職活動のメインコンテンツ部分を触れる権限を作成する http://localhost/admin/auth/permissions 以下画像のように作成する 2. 役割の作成 一般利用者を想定しているので、以下のような内容を想定 閲覧不可 ダッシュボード 管理者による設定系メニュー 閲覧可能 転職活動メインコンテンツ部分 アカウント設定 (新規作成)ホーム画面 http://localhost/admin/auth/roles 以下画像のように作成する 3. アカウントの作成 http://localhost/admin/auth/users 役割の値を [2.] で作成した users にしておく 4. ログイン後 HOME 画面の作成、リダイレクト設定 $ php artisan make:controller UserHomeController ひとまず HomeController からパクって以下のようにする namespace App\Admin\Controllers; use App\Http\Controllers\Controller; use Encore\Admin\Controllers\Dashboard; use Encore\Admin\Layout\Column; use Encore\Admin\Layout\Content; use Encore\Admin\Layout\Row; class UserHomeController extends Controller { public function index(Content $content) { return $content ->title('User Home') ->description('ここはホーム画面です') ->row( view('admin::dashboard.title') ) ->row(function (Row $row) { $row->column(12, function (Column $column) { $column->append(Dashboard::environment()); }); }); } } Admin/routes.php を以下のように修正 Route::group([ 'prefix' => config('admin.route.prefix'), 'namespace' => config('admin.route.namespace'), 'middleware' => config('admin.route.middleware'), 'as' => config('admin.route.prefix') . '.', ], function (Router $router) { $router->get('/', 'HomeController@index')->name('home'); $router->resource('agents', AgentController::class); // 以下を追記 Route::group(['prefix' => 'jobhunting', 'as' => 'jobhunting.'], function() { Route::get('/home', 'UserHomeController@index')->name('home'); }); }); 作成したページへのメニューを laravel-admin にて以下のように追加 http://localhost/admin/auth/menu 役割によってログイン後のトップ画面を制御するため、Admin/Controllers/AuthController に以下メソッドを追加 /** * Get the post login redirect path. * * @return string */ protected function redirectTo() { if( Admin::user()->isRole('users') ) { // ここで制御 return config('admin.route.prefix') . '/jobhunting/home'; } // 以下は Encore\Admin\Controllers\AuthController の redirectPath() からコピペ return property_exists($this, 'redirectTo') ? $this->redirectTo : config('admin.route.prefix'); } 各役割のアカウントでログインして、動作確認 5. 各メニューのサイドバー表示設定 laravel-admin では、サイドバーのメニューごとに「どの役割に対して表示するか?」を設定できる めんどくさいが、各メニューの編集画面を開いて以下赤四角部分に表示 したい 役割を追加していく おまけ このアプリでは laravel-admin の画面しか稼働しないため、URI の /admin/ 部分を消す .env ファイルに ADMIN_ROUTE_PREFIX= を追記 プレフィックスに何も設定しない意思表示 routes/web.php の Route::get('/', function () {〜 の部分をコメントアウト laravel デフォルトのトップ画面への遷移を削除 所感 laravel-admin ではメニューの制御を UI で出来るためとても楽でした Controller を作ってルーティングまではコーディングが必要 laravel-admin のドキュメンテーションが中文しか見当たらなかったため少し苦労した ついでにドキュメンテーションをかいつまんで読んでみたけど、やりたいことが直感的にできそうでこのライブラリの素晴らしさを認識しました
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

転職活動管理アプリを作ろう⑤(laravel-admin 拡張〜テーブル作成)

前回は コチラ laravel-admin 拡張 Extension をインストール redis-manager redis の中身を閲覧できる simplemde markdown editor config https://github.com/sparksuite/simplemde-markdown-editor#configuration セッション管理を redis に変更 $ composer require predis/predis .env ファイルを以下のように修正 SESSION_DRIVER=redis : REDIS_HOST=redis REDIS_PASSWORD=null REDIS_PORT=6379 REDIS_CLIENT=predis サーバー再起動 発生したエラー Class "Redis" not found REDIS_CLIENT の値が phpredis のままだったため発生。predis に修正して対応した。 redis のまま対応しようとすると、Redis 拡張モジュールをインストールする必要がある?(未確認) 詳細は この方の記事 にあるっぽい テーブル作成 テーブル定義については コチラの記事 を参照 作り方 (例:Agents テーブル) $ php artisan make:migration create_agents_table --create=agents 作成されたマイグレーションファイルにて、定義したテーブルの構成を記載 /** * Run the migrations. * * @return void */ public function up() { Schema::create('agents', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('top_url'); $table->string('login_url'); $table->boolean('active'); $table->timestamps(); }); } $ php artisan migrate $ php artisan make:model Agent モデルを作成 $ php artisan admin:make AgentController --model=App\\Models\\Agent コントローラを作成 grid() を カスタマイズ すると、一覧画面の見せ方を変更できる form() を カスタマイズ すると、新規登録/更新画面の見せ方を変更できる app/Admin/routes.php に以下ルーティングを追記 $router->resource('agents', AgentController::class); http://localhost/admin/agents にアクセスし表示されれば OK メニュー追加 親メニュー admin 内メニューの「Menu」へ移動 以下内容を入力し submit 再ログインするとサイドバーに反映される 子メニュー admin 内メニューの「Menu」へ移動 以下内容を入力し submit 再ログインするとサイドバーに反映される
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravel, chart.js で n件ごとのグラフを表示する(備忘録

概要 laravelの練習を兼ねて、下記のような体調管理webアプリを作成した。 10件、30件、全件表示のボタンを押下することでグラフの切り替えが可能。 Controller $userid = Auth::id(); // ページネーションのため10件ずつ取得 if(History::where('user_id', $userid)->count() >= 10){ $histories = History::where('user_id', $userid)->latest()->paginate(10); }else{ $histories = History::where('user_id', $userid)->latest()->paginate(History::where('user_id', $userid)->count()); } // チャートでの表示のため30件を取得 if(History::where('user_id', $userid)->count() >= 30){ $histories_thirty = History::where('user_id', $userid)->latest()->paginate(30); }else{ $histories_thirty = History::where('user_id', $userid)->latest()->paginate(History::where('user_id', $userid)->count()); } // チャートでの表示のため全件を取得 $histories_all = History::where('user_id', $userid)->latest()->get(); return view('index', ['histories' => $histories, 'histories_thirty' => $histories_thirty, 'histories_all' => $histories_all, 'userid' => $userid,]); paginateを利用して、それぞれの件数を変数に格納する。 それらをViewに渡す。 View (グラフ部分のみ) <div style="width:1000px; margin: 0 auto 30px auto;"> <div class="text-right"> <button id="display_tenchart" class="btn btn-dark" disabled>10件</button> <button id="display_thirtychart" class="btn btn-dark">30件</button> <button id="display_allchart" class="btn btn-dark">全部</button> </div> <canvas id="Chart_default" style="width:1000px; height:300px;"></canvas> </div> <script> var ctx = document.getElementById('Chart_default').getContext('2d'); var score = []; var labels = []; var histories_json = @json($histories); var histories_thirty_json = @json($histories_thirty); var histories_all_json = @json($histories_all); get_scores_ten(); display_chart(); //10件のスコアを取得 function get_scores_ten(){ $("#display_tenchart").prop("disabled", true); $("#display_thirtychart").prop("disabled", false); $("#display_allchart").prop("disabled", false); score = []; labels = []; for(var i=0; i < histories_json['data'].length; i++){ score.unshift(histories_json['data'][i]['score']); labels.unshift(histories_json['data'][i]['created_at'].split(" ")[0].split("-")[1] + "/" + histories_json['data'][i]['created_at'].split(" ")[0].split("-")[2]); } } //30件のスコアを取得 function get_scores_thirty(){ $("#display_tenchart").prop("disabled", false); $("#display_thirtychart").prop("disabled", true); $("#display_allchart").prop("disabled", false); score = []; labels = []; for(var i=0; i < histories_thirty_json['data'].length; i++){ score.unshift(histories_thirty_json['data'][i]['score']); labels.unshift(histories_thirty_json['data'][i]['created_at'].split(" ")[0].split("-")[1] + "/" + histories_thirty_json['data'][i]['created_at'].split(" ")[0].split("-")[2]); } } //全件のスコアを取得 function get_scores_all(){ $("#display_tenchart").prop("disabled", false); $("#display_thirtychart").prop("disabled", false); $("#display_allchart").prop("disabled", true); score = []; labels = []; for(var i=0; i < histories_all_json.length; i++){ score.unshift(histories_all_json[i]['score']); labels.unshift(histories_all_json[i]['created_at'].split(" ")[0].split("-")[1] + "/" + histories_all_json[i]['created_at'].split(" ")[0].split("-")[2]); } } //10件表示 $('#display_tenchart').on('click', function() { myChart.destroy(); get_scores_ten() display_chart(); }); //30件表示 $('#display_thirtychart').on('click', function() { myChart.destroy(); get_scores_thirty() display_chart(); }); //全件表示 $('#display_allchart').on('click', function() { myChart.destroy(); get_scores_all() display_chart(); }); // チャートを表示 function display_chart(){ myChart = new Chart(ctx, { type: 'line', data: { labels: labels, datasets: [{ label: '体調スコアの推移', data: score } ] }, options:{ scales:{ xAxes:[], yAxes:[ { ticks:{ min: 0, max: 100, } } ] } }, }); }; // インスタンス破棄をするために、グローバル変数で定義 var myChart = new Chart(ctx, { type: 'line', data: { labels: labels, datasets: [{ label: '体調スコアの推移', data: score } ] }, options:{ scales:{ xAxes:[], yAxes:[ { ticks:{ min: 0, max: 100, } } ] } }, }); </script>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Carbonで次の特定曜日の日付を取得する方法

最近Carbonのnext/previousを見つけてテストコードや曜日に関連した処理を作るときにに便利そうだったのでメモです! 特定の日付から次の〇曜日を取得する $today = Carbon::parse('2021/10/14'); // 2021/10/18(Mon) dump($today->copy()->next(Carbon::MONDAY)->format('Y/m/d(D)')); // 2021/10/19(Tue) dump($today->copy()->next(Carbon::TUESDAY)->format('Y/m/d(D)')); // 2021/10/20(Wed) dump($today->copy()->next(Carbon::WEDNESDAY)->format('Y/m/d(D)')); // 2021/10/21(Thu) dump($today->copy()->next(Carbon::THURSDAY)->format('Y/m/d(D)')); // 2021/10/15(Fri) dump($today->copy()->next(Carbon::FRIDAY)->format('Y/m/d(D)')); // 2021/10/16(Sat) dump($today->copy()->next(Carbon::SATURDAY)->format('Y/m/d(D)')); // 2021/10/17(Sun) dd($today->copy()->next(Carbon::SUNDAY)->format('Y/m/d(D)')); 特定の日付から前の〇曜日を取得する $today = Carbon::parse('2021/10/14'); // 2021/10/11(Mon) dump($today->copy()->previous(Carbon::MONDAY)->format('Y/m/d(D)')); // 2021/10/12(Tue) dump($today->copy()->previous(Carbon::TUESDAY)->format('Y/m/d(D)')); // 2021/10/13(Wed) dump($today->copy()->previous(Carbon::WEDNESDAY)->format('Y/m/d(D)')); // 2021/10/07(Thu) dump($today->copy()->previous(Carbon::THURSDAY)->format('Y/m/d(D)')); // 2021/10/08(Fri) dump($today->copy()->previous(Carbon::FRIDAY)->format('Y/m/d(D)')); // 2021/10/09(Sat) dump($today->copy()->previous(Carbon::SATURDAY)->format('Y/m/d(D)')); // 2021/10/10(Sun) dd($today->copy()->previous(Carbon::SUNDAY)->format('Y/m/d(D)')); Carbon便利ですね?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】bladeファイルでReact側に変数を渡す

はじめに Laravelで一部分をReactでSPA化した際、APIを使うまでもなさそうな変数をグローバル変数として渡していました。 一応、備忘録として残します。 実装 script内でconst access_token = "{{ $access_token }}"のように値を渡します。 @section('main') <link href="{{ asset('/css/app.css') }}" rel="stylesheet" type="text/css"> <script> const access_token = "{{ $access_token }}" const api_url = "{{ url('/graphql') }}"; const app_store_url = "{{ env('APP_STORE_URL') }}" const pet_age = @json(config('define.pet.age')); </script> <div id="app"></div> <script src="{{asset('/js/app.js')}}"></script> @stop 以下のような連想配列(および配列)を渡す際には、@jsonでJSONに変換して渡します。 pet.php <?php return [ 'age' => [ 'dog' => 5, 'cat' => 10, 'bird' => 8, ] ]; React側で変数を呼び出す際、TypeScriptを使っているとWarningCan't find name ~がでるので、新しく変数を用意して// @ts-ignoreをつけてあげます。 index.ts const Component = () => { // @ts-ignore const petAge = pet_age ... } 参考資料
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む