20210129のHTMLに関する記事は17件です。

【初心者でもわかる】要素をピラミッド構造で並べる方法

どうも7noteです。レイアウト案、ピラミッド編です。

3カラムで並べたり、均等幅で並べたり、行送りにしたり等様々な配置方法がありますが、ちょっとマニアックにピラミッド型に並べる方法を考えてみました。
誰かの参考になれば幸いです。

ソース

index.html
<p>
  <span>コンテンツ</span><br>
  <span>コンテンツ</span><span>コンテンツ</span><br>
  <span>コンテンツ</span><span>コンテンツ</span><span>コンテンツ</span>
</p>
style.css
p {
  text-align: center;     /* 中央揃えにする */
}
p span {
  width: 160px;           /* 1要素の幅を指定 */
  border: 1px solid #000; /* 見やすいように線を入れる */
  text-align: center;     /* 文字を真ん中寄せにする */
  background: #CCC;       /* 背景色をグレーにする */
  display: inline-block;  /* インラインブロック要素にする */
  margin: 5px;            /* 余白を取る */
}

結果

sample.png

解説

インラインブロック要素を中央揃えで並べて配置し、改行で1個、2個、3個と行を分けているだけですね。均等に綺麗になるように余白は全方向に同一に取っています。
説明する必要もないくらい簡単な作りです。

まとめ

シンプルに作っていますので実用的に使うには親要素に最低幅を指定したり少し工夫がいるかもしれません。高さも揃いませんしね。
レベルアップしたものをまた考えて掲載できればと思います。

作ったはいいものの使い道がまだ思いついていないので、ぜひコメント等でいい使い道を一緒に考えていただきたいです。コメントお待ちしております!

おそまつ!

~ Qiitaで毎日投稿中!! ~
【初心者向け】WEB制作のちょいテク詰め合わせ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GitHubのWikiに画像が表示されないときに確認すること

GitHubのWiki機能、便利ですよね。でも、画像が上手く表示されないこともあります。

画像が表示されないときには以下の点を確認しましょう。

  • パスが正しいか
  • 画像が破損していないか
  • 画像のファイル名に日本語が含まれていないか
  • imgタグではなくMarkdown記法を使っているか
  • 画像をGitHubにPushしているか

特に、2つ目の「画像のファイル名に日本語が含まれていないか」は重要です。画像が表示されなくて困っていて、ネットで調べて出てきたものを色々試しても効果がなかったとき、これが原因でした。画像のファイル名に日本語が含まれていると表示されません。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【JavaScript】スマホ判定する方法

プログラミング勉強日記

2021年1月29日
JavaScriptでデバイスがスマホかどうか判定する方法について簡単にまとめる。

UserAgentから判定する

 UserAgentがiPhoneまたはAndroidとMobileを含む場合はスマホと判定できる。接続してきたユーザー情報を知るためにnavigatorオブジェクトのUserAgentを使用する。navigatorオブジェクトはいくつもの端末やブラウザの情報が格納されていて、プロパティとして情報を取得できる。

userAgentに含まれている情報の例
Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/577.01 
(KHTML, like Gecko) Version/6.8 Mobile/11A111 Safari/9788.91
function isSmartPhone() {
  // UserAgentからのスマホ判定
  if (navigator.userAgent.match(/iPhone|Android.+Mobile/)) {
    return true;
  } else {
    return false;
  }
}

デバイスの画面幅から判定する

 window.matchMedia()関数を使うことで、デバイス画面幅を判定できる。この方法はスマホを判断するのではなく、画面幅によってUIを変更したいときに使うのが望ましい。

function isSmartPhone() {
  // デバイス幅が640px以下の場合にスマホと判定する
  if (window.matchMedia && window.matchMedia('(max-device-width: 640px)').matches) {
    return true;
  } else {
    return false;
  }
}

サンプルプログラム

<html>
<head>
<title>スマホ判定</title>
</head>
<body>

<p>使用中の端末:</p>
<p id="Terminal"></p>

<script type="text/javascript">
    let tarminal = document.getElementById('Terminal')
    let msg = ""
    let ut = navigator.userAgent;

    if(ut.indexOf('iPhone') > 0 || ut.indexOf('iPod') > 0 || ut.indexOf('Android') > 0 && ut.indexOf('Mobile') > 0){
        msg = "SmartPhon";
    }else if(ut.indexOf('iPad') > 0 || ut.indexOf('Android') > 0){
        msg ="Tablet";
    }else{
        msg = "Personal Computer";
    }

    tarminal.textContent = msg
</script>

</body>
</html>

実行結果
image.png

参考文献

JavaScriptでスマホ判定する2つの方法
JavaScriptでアクセス元の端末がスマホかどうか判定する方法を現役エンジニアが解説【初心者向け】

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【HTML】俺流リファレンス:<style>

<style>

<style>は、HTML文書内にスタイルシート(CSS)を埋め込むものである。
CSSを使用するためには、<link>でcssファイルを読み込むか、<style>で指定する必要がある。(基本的には<link>が推奨)
<style>タグを用いてCSSを記載する場合は、全体を<!-- -->でコメントアウトする。これは、CSSに対応していないブラウザで、CSSがそのままテキストとして表示されることを避けるためである。

属性

  • 必須属性
    • なし
  • 任意属性
    • type:CSSのMIMEタイプを指定
      • デフォルト値はtext/css
    • media:対象のメディアクエリを指定
      • デフォルト値はall
    • nonce:コンテンツセキュリティーポリシーで使用する暗号を指定
      • コンテンツセキュリティポリシー(CPS: Content Security Policy) に従い、Web ページ上に悪意を持って埋め込まれたスクリプトの実行を抑制するために用いる

使用例

sample.html
<!DOCTYPE html>
<html>
  <head>
    <title>styleサンプル</title>
    <style>
    <!--
      h1 { color: red; }
      p { height: 100px; }
     -->
    </style>
  </head>
  <body>
    <h1>Hello World!</h1>
    <p>hello world!!</p>
  </body>
</html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【HTML】俺流リファレンス:<link>

<link>

<link>は、その文書に関連する外部の文書を取り入れる。
例として、CSSファイルやJavaScriptファイルなどを取り込む。また、自前でないネット上にある外部のファイルも取り込むことが可能。

属性

  • 必須属性
  • 任意属性
    • hreflang:リンク先の記述言語("ja", "en"など)
    • type:リンク先のMIMEタイプ
    • media:対象のメディアクエリ
    • sizes:アイコンのサイズ (rel="icon"の場合、指定可能)
      • 可変サイズ
      • 「横幅x高さ」をピクセル数で指定し、半角スペース区切りで複数指定可能
    • crossorigin:別ドメインにあるリソースの扱いを指定
      • anonymous:認証を利用しない
      • use-credentials:認証を利用する
    • rev:別の文書からみたこの文書との関係をリンクタイプで指定

使用例

以下はstyle.cssを読み込む例である。

sample.html
<!DOCTYPE html>
<html>
  <head>
    <title>文書のタイトル</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
  </body>
</html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【HTML】俺流リファレンス:<meta>

【HTML】俺流リファレンス:

<meta>は、その文書に関する情報(メタ情報)を<head>に指定する。
<meta>は以下のようなメタ情報を指定できる。

  • 文字コードの指定
  • 文書の説明・キーワードの指定
  • 文書の作者を表記
  • 文書を作成したエディタを表記
  • キャッシュの制御と有効期限の指定
  • 別ページへの自動ジャンプと画読み込み
  • 基準スタイルシート言語と基準スクリプト言語の指定
  • 検索ロボットの制御

属性

  • 必須属性
    • なし
  • 任意属性
    • charset:文書の文字エンコーディングを指定(UTF-8、Shift_JIS、EUC-JPなど)
    • http-equiv:指示の種類
      • content-type:文書の文字エンコーディング
      • refresh:再読み込み・リダイレクト
    • name:文書情報の種類
      • description:文書の説明
      • keywords:文書のキーワード
      • robots:検索ロボットに対して登録されないよう、また文書内のリンクをたどらないように指定
      • author:文書の著者名
      • generator:文書の生成に使用したソフト名
    • content:http-equiv、nameを指定したときの内容(左記の属性を指定した場合は、必ず指定する)
      • content-typeの例:text/htmlなど
      • refreshの例:リダイレクトの秒数を指定し、urlでリダイレクト先を指定
      • descriptionの例:HTMLの勉強
      • keywordsの例:HTML,CSS
      • robotsの例:noindex、nofollow
      • authorの例:soseki-natsume
      • generatorの例:notepad

使用例

sample.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="refresh" content="30">
    <meta name="author" content="soseki-natsume">
  </head>
  <body>
  </body>
</html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【HTML】俺流リファレンス:<base>

<base>

<base>は、基準となる相対的なURIを絶対パスとして指定する。(<head>内で1つのみ記載できる)
文書内では、<base>で指定したパスを基準に、リンクや画像などのパスを使用する。
<base>によるURIの指定をしない場合は、その文書の位置が基準のURIとなる。

属性

  • 必須属性
    • なし
  • 任意属性
    • href:基準となるURI(絶対パス)
      • URI:http:// から始まるURIを絶対パスで指定する
    • target:リンク先の表示方法
      • _blank:新規のウィンドウに表示
      • _self:現在のウィンドウに表示
      • _parent:親ウィンドウに表示
      • _top:フレームを解除してウィンドウ全体に表示

属性href、targetは任意属性と記載しているが、どちらか1つは必ず指定しなければならない。

使用例

<base>でhttp://test/を指定すると、<a>のindex.htmlhttp://test/index.htmlが参照される。

sampl.html
<html>
 <head>
  <title>baseの使い方</title>
  <base href="http://test/">
 </head>
 <body>
  <a href="index.html"></a>
 </body>
</html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【HTML】俺流リファレンス:<title>

<title>

<title>は、文書のタイトルを表し、以下に使用される。

  • ブラウザのタブに表示される
  • ブラウザでお気に入りに登録した場合に表示される
  • 検索エンジンの検索結果で表示される

属性

なし

使用例

sample.html
<!DOCTYPE html>
<html>
  <head>
    <title>タイトルサンプル</title>
  </head>
</html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【HTML】俺流リファレンス:<head>

<head>

<head>は、文書のヘッダ情報(メタデータという文書に関する様々な情報)を記載するためのタグである。メタデータには以下のようなものがある。(=headタグに記載できるもの)

属性

なし

使用例

sample.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <base href="http://www.htmq.com/">
    <title>HTML文書のサンプル</title>
    <link rel="stylesheet" href="default.css">
  </head>
  <body>
  </body>
</html>

- 以上 -

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【備忘録】同じタグ内で複数のclass名を並べる理由とCSS記述について

初めに

HtmlのdivタグやspanタグにCSSを適用するためには、id名もしくはclass名を付けます。特にcalssセレクタは頻繁に使われていますが、その中でも複数のクラス名を一つの要素に並べるケースについてその理由とcssの記述について纏めてみました。

目次

  • idとclassの違い
  • 同じタグ内に複数のclass名を付ける理由
  • 同じタグ内に複数のclass名が並んだ場合のCSS記述
  • 複数のクラス名が入れ子構造(ネスト)の場合
  • 複数のclassに同じcssを適用する場合
  • まとめ

idとclassの違い

id属性はhtml文書内でたった一つしかない要素に対してスタイルを適用する時に使います。なので同じ文書内に同じid名が複数存在することはあり得ません。これに対してclass属性の場合、複数のタグに同じclass名を付けてそれぞれ同じスタイルを適用することができます。「この部分は絶対このスタイルにしたい、他の要素タグとスタイルが被りたくない」と言う場合を除いて、class属性を使った方が無難です。

同じタグ内に複数のclass名を付ける理由

色んなケースがあると思いますが代表的な例としては、cssを利用したアニメーションを作る場合が挙げられます。z-indexを指定し、layer構造にしてそれぞれ違うスタイルを適用する場合に複数のclass名を並べます。cssアニメーションについては下記のサイトをご利用ください。
- https://techacademy.jp/magazine/9409

同じタグ内に複数のclass名が並んだ場合のCSS記述

divタグ内にapplicationとexampleと言う2つのクラス名が並んだケースを見てみると
①HTML

<div class="application example">application <br>
</div>

②CSS

.application.example {
                       color: #3f32d3;
                       }

ここでポイントになるのが、「.application」と「.example」の間を半角スペースなどで空けてはいけません。理由は同じタグ内にクラス名が並んでいるからです。これと似たような記述で間違えやすいのが次の様なケースです。

複数のクラス名が入れ子構造(ネスト)の場合

次のように適用したいクラスの要素がexampleで、example要素がapplication要素に対して親子関係にある場合は次のように
CSSを記述します。
①HTML

<div class="application"> <br>
     <section class="example">example
    </section>
</div>

②CSS

.application .example {
                       color: #3f32d3;
}

この場合、「.application」と「.example」の間は半角スペース1個分を空けなければなりません。その理由はapplicationクラスとexampleクラスがネスト構造で離れているからです。

複数のclassに同じcssを適用する場合

最後に次の様に複数の異なるクラスに同じスタイルを適用する場合には以下の様に記述します。
①HTML

<div class="kind-1">kind-1</div>
<div class="kind-2">kind-2</div>

②CSS

.kind-1,.kind-2 {
                 color: pink;
}

ポイントは「.kind-1」クラスと「.kind-2」クラスの間に「,」を入れつことです。

まとめ

以上をまとめて表示すると次のようになります。
①HTML

<body>
    <div class="application example">application<br>
        <section class="example">example
        </section>
    </div>
    <div class="trip" id="helper">trip</div>

    <div class="kind-1">kind-1</div>
    <div class="kind-2">kind-2</div>
</body>

②CSS

.application .example {
    color: #3f32d3;
}

.application.example {
    color: #f324df;
}

.trip#helper {
    color: #aafef6;
}

.kind-1,
.kind-2 {
    color: pink;
}

③画像
スクリーンショット 2021-01-29 20.41.35.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

テスト(初投稿&備忘録)

プログラミング初学者です。

body {
  height: 1000px;
  width: 1000px;
  background-image: url("../images/cafe_2.jpeg");
  background-size: cover;
  background-attachment: fixed;
}

とコードを書いたら

スクリーンショット 2021-01-29 16.50.09.png

何故か左寄りになったので

body {
  height: 1000px;
  width: 1000px;
  background-image: url("../images/cafe_2.jpeg");
  background-size: cover;
  background-attachment: fixed;
  margin-right: auto;←追加
  margin-left: auto;←追加
}

としたら

スクリーンショット 2021-01-29 16.54.52.png

中央揃えになりましたw(何故かは理解しておりませんw誰かお暇な方よろしくお願いしますw)

自分はプログラミング歴1年半ですが今までほぼほぼインプットでしか学習して来ませんでした。
なので今後は9:1でアウトプットで学習していくつもりです。

よろしくです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Bootstrapの基礎②

デイトラWeb制作コース初級編DAY11の学び

【この記事に書いてあること】

 【学習時間】

1時間45分

 【学び】

1 width/heightの調整
・横幅を変更:w-50→width 50%という意味

・縦幅の変更:h-50→hight 50%という意味

*パーセントの変更は25,50,75,100,autoのみ!

スクリーンショット 2021-01-28 6.33.04.png

2 padding/marginの調整

・paddingの変更:pt(padding-top) pr(padding-right) pb(padding-bottom) pl(padding-light)+数字

・paddingの横幅のみ変更;px 0 --;

・paddingの縦幅のみ変更:py -- 0;

*paddign,marginは段階的に1~5までの幅が決まっている

*Bootstrapの大きなルールとして、制御したいプロパティの頭文字+数字で記述する

スクリーンショット 2021-01-28 6.33.29.png

3 Gridレイアウト

ルール:①class="container"の中に作る
    ②改行はclass="row"で囲うとそこまでが一行
    ③一つ一つのブロックはclass="col"をつける

参考サイト: Bootstrapのグリッドシステムの使い方を初心者に向けておさらいする

特徴1:Gridレイアウトを使うことで、横幅を整えつつレイアウトを決めることができる!

index.html
    <div class="container">
        <div class="row">
            <div class="col bg-primary">
                1 of 2
            </div>
            <div class="col bg-warning">
                2 of 2
            </div>
        </div>
        <div class="row">
            <div class="col bg-success">
                1 of 3
            </div>
            <div class="col bg-danger">
                2 of 3
            </div>
            <div class="col bg-info">
                3 of 3
            </div>
        </div>
    </div>

スクリーンショット 2021-01-28 6.53.40.png

特徴2:1行を12分割して横幅を自在に変えることができる

index.html
   <div class="container">
        <div class="row">
            <div class="col-7 bg-primary">
                1 of 2
            </div>
            <div class="col-5 bg-warning">
                2 of 2
            </div>
        </div>
        <div class="row">
            <div class="col-6 bg-success">
                1 of 3
            </div>
            <div class="col-4 bg-danger">
                2 of 3
            </div>
            <div class="col-1 bg-info">
                3 of 3
            </div>
        </div>
    </div>

スクリーンショット 2021-01-28 6.57.25.png*12に満たない部分は空白になる

特徴3:各ブラウザサイズでレイアウトを操作できる
スクリーンショット 2021-01-28 7.03.33.png

4 Bootstrapでボタン作成する

① Bootstrapはボタンのレイアウトがすでに決められている

☆共通クラスclass="btn"を忘れずに記入する!

index.html
<button type="button" class="btn btn-primary">Primary</button>

スクリーンショット 2021-01-29 15.53.54.png

② ボタンのデザインも決めることができる
class="btn-outline-色を記入

index.html
<button type="button" class="btn btn-outline-success">Success</button><button type="button" class="btn btn-outline-danger">Danger</button>

スクリーンショット 2021-01-29 16.02.05.png

③ ボタンのサイズも決めることができる

大きくするならclass="btn-lg
小さくするならclass="btn-smを記入

index.html
<button type="button" class="btn btn-secondary btn-lg">Large button</button>

<button type="button" class="btn btn-primary btn-sm">Small button</button>

スクリーンショット 2021-01-29 16.18.28.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelでほんの少しハイレベルな検索機能を作ってみた。(初心者向け)

こんにちは、しろうです。

現在、Laravelで小説サイトを作成しています。

そんな中で、(自分的には)ちょっとだけハイレベルな検索機能を作ってみたので、忘れないようにメモとして残しておきます。

検索機能を実装したい人はぜひ、参考にしてください。

もしミスとかあればコメントして頂けると大変有り難いですm(_ _)m

前置き

・クラス名とかひどいのあるかと思いますが、気にしないで頂けると幸いです。
・Formファサードを使ったり、素のformを使ったり混在していますが、許してくださいm(_ _)m
・cssは貼り付けていないので、皆さん側で好きなように変更してください。

今回作る検索機能

・複数条件での絞り込み検索ができる。(例:キーワードとジャンルで絞り込む。)
・現在の検索条件がタグとして表示される。
・タグを削除すれば、検索条件から削除される。

検索機能のイメージ動画

ちなみにイメージ動作は下記の通りです。

ezgif.com-gif-maker.gif

下記のように、他のページからジャンルとかをクリックしたら、そのジャンル名で検索してくれる機能もつけてます。

ezgif.com-gif-maker (1).gif

さて、じゃあどんどん作っていきます。

とりあえず検索機能を作る

viewファイルの作成(検索項目の部分)

スクリーンショット 2021-01-29 13.53.31.jpg

とりあえず検索項目を作成していきます。

今回は「キーワード検索」と「ジャンル検索」のみを作成しています。
また、CSSは貼り付けないので、皆さんの方で好きなように変更よろしくお願いしますm(_ _)m

search.blade.php
{{ Form::open(['route'=>'search','method'=>'GET','id'=>'side_search_form','autocomplete'=>"off"]) }}
<div class="search_keyword">
    <div class="search">
        <input name="keyword" value="{{request('keyword')}}" type="search" class="searchTerm" placeholder="キーワード検索">
        <button type="submit" class="searchButton" form="side_search_form">
            <i class="fa fa-search fa-xs"></i>
        </button>
    </div>
</div>

<div class="search_genre search_side_item_border">
    <h4>ジャンル</h4>
    <div class="ripples_radio">
        {{ Form::radio('genre','', isset(request()->genre) ? false :true, ['id'=>'search_genre_none'])
        }}
        {{ Form::label('search_genre_none', '指定なし', []) }}
    </div>
    @foreach ($genres as $index => $genre)
    <div class="ripples_radio">
        {{ Form::radio('genre',$genre, $genre == request()->genre ? true :false,
        ['id'=>'search_genre'.$index]) }}
        {{ Form::label('search_genre'.$index, $genre, []) }}
    </div>
    @endforeach
</div>

{{ Form::close() }}

解説していきます。

'autocomplete'=>"off"・・・これをつけると検索履歴が表示されなくなります。お好みでどうぞ。
value="{{request('keyword')}}"・・・このようにするとvalue値が「keywordというパラメーター(クエリ文字列)の値」になります。
requestメソッド・・・リクエストデータを取得できるやつです。

@foreach ($genres as $index => $genre)・・・この$genresはコントローラーから検索できるジャンル名を返しています。単純にジャンル名を1つずつ処理しているだけです。

下記少しわかりにくいかと思います。

{{ Form::radio('genre',$genre, $genre == request()->genre ? true :false,
        ['id'=>'search_genre'.$index]) }}

Form::radioは第三引数がtrueならcheckedをつけるので、ジャンル名とパラメーターのジャンル名(現在検索しているジャンル名)が一致するなら、checkedをつけるようにしています。

例えば、http://127.0.0.1:8000/search?genre=恋愛(現世)とかなら、request()->genreによって、恋愛(現世)という文字列を取得できます。

なので、$genre == request()->genreとすることで、現在検索しているジャンルボタンにのみcheckedをつけることができます。

指定なしというラジオボタンもほしいので、下記コードで作成しています。

{{ Form::radio('genre','', isset(request()->genre) ? false :true, ['id'=>'search_genre_none'])}}
{{ Form::label('search_genre_none', '指定なし', []) }}

value属性''(空文字)にしておけば、コントローラー側の処理でいい感じにできます。(解説は後ほど。)

web.phpにルーティングを追加

とりあえず、なんでもいいのでルーティングを追加します。

web.php
Route::get('search', 'UsersController@search')->name('search');

ジャンル用のファイルを作成

今回はconfig/getValue/radio.phpにジャンル用の配列を作成しました。

config/getValue/radio.php
<?php
return [
    'genre' =>[
        '1' =>'恋愛(異世界)',
        '2'=>'恋愛(現世)',
        '3'=>'ラブコメ',
        '4'=>'ホラー',
        '5'=>'推理(ミステリー小説)',
        '6'=>'異世界ファンタジー',
        '7'=>'現代ファンタジー',
        '8'=>'コメディ',
        '9'=>'SF',
        '10'=>'詩・エッセイ・童話',
        '11'=>'歴史・戦国',
        '12'=>'その他',
    ],
];

このようにすることでconfig('getValue.radio.genre')とすれば、ジャンル名の配列を取得することができます。

コントローラー内でこのジャンル名の配列を取得します。

コントローラーに処理を追加

次にコントローラー側に検索処理を記述していきます。

UsersController.php
public function search(Request $request)
    {
       //SQL文を書くためにqueryメソッドを使う。
        $query = Novel::query();

       //ジャンル名を取得。(viewファイルに返すだけ。)
        $genres = config('getValue.radio.genre');

      //keywordがあるかどうか。
        if ($request->filled('keyword')) {
            //検索キーワードとタイトルが一致するレコードを絞り込む
            $query->where('title', 'like', '%'.$request->get('keyword').'%');
        }

      //genreがあるかどうか。
        if ($request->filled('genre')) {
            //検索ジャンルとジャンル名が一致するレコードのidをgenresテーブルから取得
            $genre_id = Genre::where('name', $request->genre)->first()->id;
            //genre_idが一致するレコードをnovelsテーブルから絞り込む
            $query->where('genre_id', $genre_id);
        }

       //条件に一致するレコードを作成日で降順に並び替えて取得
        $novels = $query->latest('novels.created_at')->paginate(50);

        //viewファイルは好きなファイルにしてください。
        return view("search", compact('novels', 'genres'));
    }

たぶん、ほとんど読めばわかるんじゃないかと思います。

$request->filled('genre')を使えば、リクエストに値が存在して、かつ、空でない場合にtrueを返してくれます。

似たものに$request->has('genre')というのがありますが、これだと空であってもtrueになります。

それだと、下記のような指定なし(value値が空文字列)の場合でも実行されてしまうので、今回はfilledメソッドを使用しています。

{{ Form::radio('genre','', isset(request()->genre) ? false :true, ['id'=>'search_genre_none'])}}
{{ Form::label('search_genre_none', '指定なし', []) }}

ちなみにlatest()を使えば、降順に並び替えてくれます。(下記の通り)

$query->latest('novels.created_at')->paginate(50);

あとは、好きなようにviewファイル側でデザインしてあげれOK。

試しにsearch.blade.phpとかで{{dd($novels)}}とかで中身を確認してみてください。

現在の検索条件を表示する機能の作成

スクリーンショット 2021-01-29 14.04.43.jpg

なんて説明すればいいかわかりませんが、ここからは上記の画像のやつを作っていきます。笑

方法としては、そこまで難しくありませんので、ご安心ください!!!

まずはview側に処理を追加

とりあえず、viewファイルに処理を追加していきます。

下記のようにすれば現在の検索条件を表示することができます。

search.blade.php
<div class="search_condition">
    <ul>
        @if(!empty(request()->keyword))
        <li class="search_condition_item">
            {{request()->keyword }}<a href="keyword" class="search_condition_a"><i class="fas fa-times search_condition_delete"></i></a>
        </li>
        @endif

        @if(!empty(request()->genre))
        <li class="search_condition_item">
            {{request()->genre }}<a href="genre" class="search_condition_a"><i class="fas fa-times search_condition_delete"></i></a>
        </li>
        @endif
    </ul>
</div>

見て大体わかると思いますので、ざっくり説明していきます。

まずempty()は引数が空ならtrueを返すので、!(エクスクラメーション)をつけて、中身が空ではない時にif文内のhtmlが表示されるようにします。

そしてif文の条件を「!empty(request()->keyword)」みたいな感じにすることで、現在keywordで検索をしているのかどうか、がわかります。(このkeywordというのはinputのname属性のことです。)

例えば、http://127.0.0.1:8000/search?keyword=&genre=みたいな感じで、keywordが空になっているなら、処理は実行されません。

逆にhttp://127.0.0.1:8000/search?keyword=人生楽しいね&genre=とかだと、「人生楽しいね」というキーワードで検索されていることになるので、if文内の処理が実行されます。

そして、if文内の処理は下記のようにします。

<li class="search_condition_item">
      {{request()->keyword }}<a href="keyword" class="search_condition_a"><i class="fas fa-times search_condition_delete"></i></a>
</li>

まず{{request()->keyword }}とすることで「人生楽しいね」が表示されます。
でもって、aタグのhref属性keywordと記述して、JavaScriptでこいつを操作していきます。

JavaScriptを記述

ここからはJavaScript(今回はjQuery)の出番です。

なんでもいいので、JavaScritのファイルを作って、下記のように記述してください。

search.js
$(function () {
    $('.search_condition_a').each(function () {
       //href属性を取得
        attr = $(this).attr('href');
       //初期化
        var url = new URL(window.location);
       //パラメーター削除
        url.searchParams.delete(attr);
        if (url.search) {
            $(this).attr('href', 'search' +url.search);
        } else {
            $(this).attr('href', 'search');
        }
    });
});

まず、$('.search_condition_a').each(function () {}とすることで、search_condition_aクラスの要素(aタグの部分)をループさせています。

attr = $(this).attr('href');とすることで、ループされたaタグのhref属性を取得しています。

例えば、下記の場合はkeywordという文字列が取得できます。

<a href="keyword" class="search_condition_a">

次にURLオブジェクトを作成し、searchParamsメソッドdeleteメソッドを使用して、先ほど取得した、href属性の初期値と一致するパラメーターを削除します。

//初期化(URLオブジェクトの作成)
var url = new URL(window.location);
//パラメーター削除
 url.searchParams.delete(attr);

もう少し詳しく解説していきます。

URLオブジェクトとは、URLを作成したり、編集したりするときに使えるメソッドが沢山入っている、JavaScriptが用意してくれている便利なやつです。()

参考:URL()

そして、引数にはwindow.location として、現在開いているURLを与えます。

次にsearchParamsで、URLのパラメーター(URLの?以降の部分)を取得、deleteメソッドで引数に与えたものと一致するパラメーターを削除します。

例えば、attrkeywordという文字列が入っている場合は、url.searchParams.delete(attr);によって、

http://127.0.0.1:8000/search?keyword=人生楽しいね&genre=恋愛(異世界)
からkeywordの部分が削除されるので、
http://127.0.0.1:8000/search?genre=恋愛(異世界)
こんな感じになります。

最後にパラメーターがあるかないかで条件分岐させています。
こうしないと、他のページから単一条件で検索ページに飛んだときに、1つのパラメーターを削除すると、全てのパラメーターがなくなり、期待通りの動作をしてくれなかったからです。(もっと良い方法もあるかもです...)

if (url.search) {
            $(this).attr('href', 'search' +url.search);
        } else {
            $(this).attr('href', 'search');
        }

url.searchとすることで、URLのパラメーターを取得できます。

あとはattrメソッドを使って、href属性の値を変更してあげればOK。

これでタグの部分は完成です。

別ページから条件検索をしたい時

別ページから検索したい時は下記のように、直接href属性にパラメーターを仕込んでおけばOK。

test.blade.php
<a href="{{route('search')}}?genre={{$novel->genre->name}}">{{$novel->genre->name}}</a>

並び替え機能も実装

スクリーンショット 2021-01-29 16.15.34.jpg

ついでに並び替え機能の紹介もしておきます。(「新着順」と「更新順」だけ)

viewファイルに追加

下記のような感じで実装しました。

search.blade.php
<div class="search_sort">
    <button
        class="sort_btn {{strpos(request()->fullUrl(), 'new') !== false  || strpos(request()->fullUrl(), 'sort') === false ? 'sort_active' : ''}}"
        name="sort" value="new" form="side_search_form" type="submit">
        <span class="spot"></span>新着順
    </button>

    <button class="sort_btn {{strpos(request()->fullUrl(), 'update') !== false ? 'sort_active' : ''}}"
        name="sort" value="update" form="side_search_form" type="submit">
        <span class="spot"></span>更新順
    </button>
</div>

順に解説していきます。

まずformタグの外側でボタンを作る時はform属性formタグのid属性を指定します。

下記の2つの部分は現在のURLによってsort_activeクラスを付与するかどうか三項演算子を利用して、決定しています。

{{strpos(request()->fullUrl(), 'new') !== false  || strpos(request()->fullUrl(), 'sort') === false ? 'sort_active' : ''}}

//省略

{{strpos(request()->fullUrl(), 'update') !== false ? 'sort_active' : ''}}

strpos()は文字列の中に指定した文字列があるかどうかを判定するメソッドです。
request()->fullUrl()で現在のURLが取得できます。

コントローラーに処理を追加

最後に下記のように処理を追加・変更します。

SearchController.php
public function search(Request $request){

//省略

  if ($request->filled('sort') && $request->sort === 'new') {
      $query->latest('novels.created_at');
  }elseif ($request->filled('sort') && $request->sort === 'update') {
      $query->latest('novels.updated_at');
  } else {
      $query->latest('novels.created_at');
  }

  //こっちのlatestは消す。
  $novels = $query->paginate(50);

  return view("search", compact('novels', 'genres'));

}

これで並び替え機能も完成です。

簡単簡単。

最後に

これで一応、イメージ動画みたいな感じの検索機能が実装できたかと思います。

昔から検索機能を作るのは苦手なので、少し苦労しました...なんか条件分岐が多いですし疲れますね。(コードのせいかも。)

駆け足だったので、わかりにくい部分があるかも・・・その時はコメントしてくださいませm(_ _)m

たぶん、もう少し仕様変更とかしますが、ひとまずこれにて終了です!お疲れ様でした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[未経験エンジニア]のオリジナルアプリ制作の反省1.「ビューは先にしっかり作っとけ」

誰なのか

某短期集中エンジニア養成プログラムでエンジニア転職を目指している者です。
エンジニアとして学習を始めて、現在2ヶ月になります。

何を書くのか

  • オリジナルアプリを制作した過程で「もっとこうしておけばよかった...」と後悔した部分
  • 「ここは、実装難しかったな...」と、思った部分

について,1日1つ取り上げ、ネタがなくなるまで投稿します。

基本的には、自分の備忘録としての記録となりますので、至らない点も多々あるかと思います。
それでも、もし僕みたいに「未経験からエンジニアになろう!」と思っている人の参考になれば幸いです。

環境

ruby: 2.6.5
Rails: 6.0.3.4

今回の結論

タイトルの通りです。ビューをあらかじめ作っておくことの重要性をひしひしと感じました。
ソースコードも交えてお話しします。

こうしとけばよかった!

具体的には、開発を始める前の企画段階で
- リセットcssについての知識が足りておらず、とりあえずcssの設定を機能実装の都度ちょこちょこしていたこと
- レスポンシブデザインを考慮しない設計構造になっていたこと

の2つを課題として考えています。

なぜそうなってしまったのか

要件定義の段階で、実装したい機能は決まりました。しかし、それを支えてくれるページレイアウトに関しては、当初、フロントエンドに対して苦手意識もあり、「機能を開発する度に」html, cssを作成するやり方で進めていたのが、失敗の原因だと思います。一般的な開発ではどうなのか分かりませんが、これは自分にとって最終的に悪い形で帰ってきました。

今後に向けて考えたこと

個人開発、ポートフォリオ向けの開発には、webフレームワーク(有名なのはboostrap)などを用いて大体のレイアウトを整えるのも一つの手段だと思います。
しかし、今回あげた課題に共通するのは、そもそもwebアプリケーション全体としてのゴールを見通せてなかったことにあると思います。

ゴールは、最初に決めておいた方がいいですよね。すなわち、要件定義の際に、ページレイアウト、画面遷移図などを、メモの時点でほとんど完成系に近づけるべきだということです。

このように提案する理由は、サーバーサイドとフロントエンドがお互いに影響を及ぼす可能性を排除できないことにあります。一つ例を挙げます。form_with, link_toのようなヘルパーメソッドのブラウザ上の表示は、html, cssの言語に変換されて表示されます。

例えば、form_withは、フォームを作成することができるヘルパーメソッドです。

<%= form_with url: "/posts", method: :post, local: true do |f| %>
  <%= f.text_field :title %>
  <%= f.submit '投稿する' %>
<% end %>

このように記述された場合、ブラウザ上では

<form action="/main" method="post">
  <input type="text" name="title">
  <input type="submit" value="投稿する">
</form>

と表示されます。

以上から、サーバーサイドとフロントエンドは密接に関わり合っていることがわかってもらえたと思います。

アクションプラン

  • ページレイアウト(ビュー)は、サーバーサイドやJavaScriptなど、レイアウトに影響を及ぼす要素を踏まえて完成度60~70%くらいまで企画で決めておき、先に実装を進めておく。
  • リセットcssは、レイアウト全体(物によっては字体まで!)に影響を及ぼすので、一番最初に導入し、読み込ませる。
  • レスポンシブなサイトになるように、企画の時点で、少なくとも「その箱の中でどのくらいの存在感を持たせるのかという割合(%」)」を決めておく。できるなら、もっと細かくpx単位で考えぬく。
  • もしサーバーサイドとして活躍したいなら、時にはboostarpなどのフレームワークも用いる。

最後に

最後まで読んでいただいた皆様、ありがとうございます。
ソースコード、記事の書き方について「もっとこうしたほうがいいよ!」というご意見「そこどうなっているの?」というご質問など、お待ちしております。

参考文献

・【Rails】form_withの使い方を徹底解説!
https://pikawaka.com/rails/form_with

・【個人開発・ポートフォリオに】簡単にいい感じのデザインにできるサービスまとめ
https://qiita.com/aiandrox/items/4196c8f5b564d29fdce7

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「 :~ 」と「 .~ 」の使い分け

はじめに

Rubyの学習中よく「 :~ 」と「 .~ 」の使い方の違いで混乱していたので、

今回 「 :id 」と「 .id 」を例にまとめていきたいと思います。

「 :~ 」

「 :~ 」はparamsのキーを指しており、
そのキーの値(バリュー)を格納するために記述する。

また、「 :~ 」はDBのカラムと「一致させる」ハッシュのキー(一致するとDBに保存可)で、
これはビューファイルでハッシュのキーを指定する

例1)コントローラーで「 :~ 」を記述する場合

def show
    @post = Post.find(params[:id])
end


[ :id ]params = { :id => “バリュー”}の:id(キー)の部分を指している。

params[:id]「id」というキーの、値を格納するための記述!

例2)ビューファイルで「 :~ 」を記述する場合

html.erb
<%= f.text_area :first_name_kana, class: "input-name", id: "first-name-kana", placeholder: "例)サトウ " %>


「:first_name_kana」はハッシュのキーを指しており、ここに「 f.text_area」によって入力されたデータ(バリュー)が入る!

params = { :first_name_kana => 入力されたデータ}
        キー       バリュー

例3)レコード{text : ”こんにちは”}があると仮定

params[:text]

DBカラム textカラムがある場合  保存可能
      messageカラムがない場合  保存できない

※viewファイルからparams(キー: バリュー)は送られてくる。

「.~ 」

「 . 」はほぼ全てメソッド

例)

user.id

user.idは「userオブジェクトのidメソッドの呼び出し」です。

スクエアブラケット

[ ]のこと

おわりに

ちなみに「 :id 」と「 .id 」と混合しやすい「 _id 」は外部キーだそうです。

今後はparamsについての理解をもっと深めていきたいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

wordpress編集時に絶対に気をつけるべきだが気づきにくい重大なポイント

wordpressは、phpや記事を直接編集できるという点でも非常に便利なCMSですが、
エディタではなくwordpress上で編集してしまうからこそ気づきにくい・陥りやすい、重大なポイントがあります。

スペースに気をつけろ!

はい。超初歩的ですが、スペースです。全角スペース/半角スペース/タブ。VSCodeやAtomなどのエディタではプラグインで視覚的にわかるようにしている方も多いかと思います。
しかし、wordpress上ではただの空白。半角スペースで打ったつもりが、全角になってしまっている、ということも。

タグのミスマッチに気をつけろ!

これも超初歩的ですが、開始divタグは消したのに終了divタグを消していなかったり。セットでコピペしたと思いきや、どちらかがミスマッチになってしまっていたり。
いやそんなミスしないよ、というミスほど、行き詰まっているときに陥りやすく、しかも見直しにくいものだと思います。(筆者だけ…?)

不具合になりそうなとこ全部直したはずなのに。直らない。そんなときこそ。

目に見える不具合箇所は全部修正した、なのに動作がおかしい。
そんなときは一回、直近の動作OKだった時点以降にwordpress上で修正した箇所のコードを見直してみましょう。
あなたの愛用のエディタに貼って、Ctrl+Sで保存。
それだけで、どこがおかしいのかひと目でわかるように整形してくれるはずです。

詰まっているときこそ、足元を見直す。これ大切ですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

フロントエンジニアのための入門~上達までのオススメ本(随時更新)

SE/エンジニアとしての基礎

①システム発注から導入までを成功させる90の鉄則


情シス・IT担当者[必携] システム発注から導入までを成功させる90の鉄則

higurit的おすすめポイント

システム開発に関わる全ての人が読んだ方がいいのでは?という素晴らしい一冊!

ベンダー側からの目線ではなく、システムを発注するユーザー企業側からの目線で、
システム開発の一連の流れが項目ごとに整理されています。
しかも具体例付きなので、自分のプロジェクトに置き換えて考えやすい。
エンジニアになろう!と思った後にまずプログラミングスキルを上げるのももちろん大切ですが、
川上から川下までの流れを一通り知っているのといないのとでは、
仕事のモチベーションも将来設計も大きく変わるはずです。

ほんとに、全員に、おすすめしたい。
以下、本文から引用

以下に複数該当すれば、お役に立てると思います。
・ITプロジェクトの主導権を自社で握りたい
・ITプロジェクトの進め方を網羅的に教えてほしい
・すぐに使えるノウハウとサンプルを入手したい
・ベンダーとWin-Winのアプローチを知りたい
・自社で情報システム部門を立ち上げたい
・システムの導入効果を最大限に引き出したい

②SE力


SE力 自ら成長し最高の成果を上げる方法

higurit的おすすめポイント

SEとしての思考を学びたい人、忙しすぎて思考の整理をする暇もない人、これまでの自分を振り返りたい人にピッタリ!

忙しい日々を過ごしていると目の前のtodoにばかり目がいってしまいがち(僕はそうでした)ですが、
SEとして大切な心構えを思い出させてくれます。
特に、顧客が何を求めているか、最高のエンジニアを目指す、というワードが、刺さりました。
C2DPやPDCA(本書の中ではfollowも含めてPDCAFと呼んでいます)を
著者の実体験に基づいて実例を交えながら解説してくれるので、非常にわかりやすいです。

以下、本文から引用

精神的心構えを身につける
今まで出版されているSEに関する本の多くは、システム構築やプロジェクト
管理の方法、基盤技術やプログラム開発技術の内容が中心だったように思います。
しかし本書は、システム構築のプロジェクトや運用保守工程で重要となるSEの
精神的内面を中心に述べています。それを『SE力』という概念として表現し、
4つの基本となる能力(「リテラシー能力」、「コミュニケーション能力」、
「リーダーシップ能力」、「ソリューション能力」)を高める内容にしました。
『SE力』という定義は個々によりさまざまではあるとは思いますが、本書が
皆さん独自の『SE力』を確立し高められる一助になれば幸いです。 (本文より)

すべてのSEとSEを目指す人に読んでほしい一冊。
特定非営利活動法人 ITコーディネータ協会 会長 播磨 崇氏からも
コメントが寄せられています。
┃ SEには夢がある!
┃ その夢を追いかけるためには、SEとして必要な能力である
┃ SE力と志が必要だ。
┃ すべてのSEとSEを目指す人に読んでほしい1冊。

④ホームページ担当者が知らないと困るWebサイト構築・運営の常識


ホームページ担当者が知らないと困るWebサイト構築・運営の常識

higurit的おすすめポイント

2005年出版のため内容は古いものも含まれますが、webサイト制作~運営までを浅く広く押さえておきたい方にピッタリ!
本書の内容をもとに各内容を深堀りしていけば自然と最新の情報も得られると思いますので、古さも気にならない。
むしろ、設計~運営、定点観測の基本、SEOの基本、個人情報の扱いについてといった
時代が変わっても変わらない大切なポイントを理解できると思います。

以下、本文から抜粋

・第一部では、ウェブサイトの構築コストと立ち上げ前に覚えておくべき基本知識を解説しました。
・第二部ではウェブマーケティングのお話をしました。
・最終章の個人情報関連の知識もウェブサイト管理には必須事項です。

HTML/CSS

①わかばちゃんと学ぶ Webサイト制作の基本〈HTML5・CSS3〉


わかばちゃんと学ぶ Webサイト制作の基本〈HTML5・CSS3〉

higurit的おすすめポイント

挫折しちゃいそうな人、挫折しちゃった人、楽しく学びたい人、浅くていいから広く理解したい人、にはピッタリ!

「webサイト自体はあくまで手段で、まずは目的を決めるところから」
「このwebサイトは、誰に・何を提供するのか?6W1Hで考えてみよう」
というワードが、刺さりました。作ることだけに目がいってしまいがちですからね。
何のために作っているのか?という意識、とても大切。

以下、本文から抜粋

せっかく学ぶなら、楽しい方がいい
・個性的なキャラクターたちが登場する4コマ
・感覚的にわかる図解
・適度な量のコーディングの実践
上記3つの特長で、Webサイト制作の基本を無理なく学べます。

こんな方にオススメ
・将来Webデザイナーになりたい
・個人でWebページを作って集客したい
・いきなりWeb担当に任命されてしまったから、勉強する必要がある
・制作会社の営業担当だから、制作側のことも知っておきたい

Webサイト制作の基本、全部入り!
○企画
○制作
○運用
の3つの概念を一通り学べます。

コンテンツ
・プロローグ/キャラクター紹介/キャラクターの関係図/はじめに
●CHAPTER 1 企画~どんなサイトになるかは企画で決まる!~
●CHAPTER 2 デザイン~企画に合ったデザインをしよう!~
●CHAPTER 3 HTML~文章や画像を貼り付けて、Webサイトの中身を作ろう!~
●CHAPTER 4 CSS~その見た目、華やかにしてあげる!~
●CHAPTER 5 JavaScript~まるで魔法? 動きを付けるのじゃ~
●CHAPTER 6 PHP~できることの幅がグーンと広がる言語~
●CHAPTER 7 公開~ついにWeb上に公開だ!~
●CHAPTER 8 運用~Webサイトは公開してからが本番~
・エピローグ/おわり

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む