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

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

ただいまの
回答率

89.52%

Javascriptでhtmlのselectタグを生成したいが、状況によって動かなくなってしまいます(CSSフレームワークはMaterializeを使用)

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 428

osakana1990

score 11

現在Webページの入力フォームを作成しており、その中で「入社年月日」をHTMLのセレクトタグで選択する箇所があります。
常に現時点の年月を選択範囲に含めたいため、Javascriptで現在の日付を取得し、HTMLのselectタグを生成するコードを書いているのですが、思った通りにselectタグが生成されず悩んでおります。

スーパーリロードをした時だけ、正常にselectタグが生成されるので、原因はキャッシュ関連なのかなと思っていますが、それ以上の原因がどうしてもわからないため、どなたかお分かりになる方にアドバイスをいただけますと幸いです。。

※CSSフレームワークはMaterialize1.0.0を利用しています

<div class="input-field">
  <select id='id_year' required>
    <option value="" disabled selected>選択してください</option>
  </select>
  <label>入社した年</label>
</div>
// 年月の入力フォームで、常に現在時点を反映する機能

$(window).on('load', function(){

    // 現在のページのパスを変数に取得する
    var path = location.pathname

    // パスの中に「review3」の文字列が含まれていた場合、以下を実行する
    if(path.match('review3')){

        (function(){
            'use strict';

            // 現在時刻を変数化
            var optionLoop, this_year, today;
            today = new Date();
            this_year = today.getFullYear();

            // selectのoption生成のループ処理
            optionLoop = function(start, end, id){
                var i, opt;

                opt = null;
                for (i = start; i >= end; i--){
                    if (i === this_year + 1){
                        opt += "<option value='' disabled selected>選択してください</option>"
                    } else {
                        opt += "<option value='" + i + "'>" + i + "</ooption>";
                    }
                }
            return document.getElementById(id).innerHTML = opt;
            };
            optionLoop(this_year + 1, 1950, 'id_year');    
        })();

    } else {
    // パスの中に「review3」の文字列が含まれていなかった場合、何もしない
        ;
    }
});

通常のページ読み込み時(selectタグが生成されない画面)
イメージ説明

スーパーリロードした時(selectタグが生成される)
イメージ説明

お手数おかけしますが、アドバイスなどいただけますと幸いです。
何卒よろしくお願い致します。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • moredeep

    2019/03/19 09:52

    提示のコードのみを使ってみても特に再現しないようです。(IE, Edge, Chrome, FireFox)

    提示されているコードだけを使っても再現しますか?
    現象が発生するHTMLはこれ以外の処理を持っていますか?
    現象が発生する際にデバッグしたらどうなりますか?
    (onload自体実行されない、location.pathnameがうまくとれていない、innerHTMLへの代入まで出来ている等々)

    質問とは関係ありませんが・・・
    optをnullで初期化し、その後+=で文字列を足しています。
    nullが入っている変数に+=で文字列を足すと、"null"という文字列が頭についてしまいます。
    nullではなく空文字で初期化するか、最初の1回は+=ではなく=を使うようにしなければいけません。

    キャンセル

  • m.ts10806

    2019/03/19 10:00

    タグについては「レスポンシブWebデザイン」とか「Material Design」とか
    「CSS」はつけておいたほうが良いように思います。

    キャンセル

  • osakana1990

    2019/03/20 15:24

    >moredeepさん
    アドバイスありがとうございます!
    提示したコードだけで検証したら動きました。
    mts10806さんがご指摘いただいたように、原因はMaterializeのJSによるHTMLの書き換えのようでした!
    また、optの初期化のご指摘もありがとうございます!ご提示いただいた方法で修正してみようと思います。

    キャンセル

回答 2

checkベストアンサー

+2

動的に要素を作っているようですし、要素をHTML上にinnerHTMLで入れた後に
Initializationの宣言が必要に思います。

私もよくAjaxで動的に生成するときはありますが、Initializationをしておかないと
そもそも要素が生成されなかったりします。
実際はselectタグを装飾しているわけではなくてinput type=textとulを組み合わせているため、
materializeのjsによりHTMLの書き換えが発生しています。
イメージ説明

あと細かいところですが</ooption>じゃなくて</option>ですね。

ただ、innerHTMLよりもcreateElementでoption作ってappend(teratail過去質問の回答)の方が確実かなと。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/20 15:11 編集

    丁寧にご回答くださり誠にありがとうございます!
    おっしゃる通り、innerHTMLの後にinitializationをすることで解決できました!

    もしご存知であれば伺いたいのですが、
    ご提示いただいた画像のように自分でも検証ツールで見てみたら確かにselectタグは消えていました。
    JSの関数の引数に指定しているid(id_year)もseletタグと一緒に消えていたので、JSで生成したoptionタグが表示されないのも理解できました。
    ただ、initializationしたあともselectタグが消えているのは同じだったので、逆になぜ動いているのかがよく理解できず。。笑
    大変恐れ入りますが、もしよろしければinitializationの宣言により動いた理由をご教授いただけますと幸いです・・・!
    (初心者のため理解不足で申し訳ございません)

    キャンセル

  • 2019/03/20 15:20

    消えているわけではなく、tabindexに-1が指定されて、display:noneで非表示にされているだけです。もう少しElementsの下のほうを見てください。
    ▼アイコンがsvgで、その下あたり。

    あとは動かしながらElementsの変化を見てみてください。
    細かいところはMaterializeの仕様なのでコードみていったほうがいいかもしれませんが、(私もしっかり見たわけではないですが)
    liのクリックイベントで何を選択しているかも分かるので、そこと実際のselectのoptionのvalueと連動しているのではないかなと。

    キャンセル

  • 2019/03/20 15:41

    ご回答ありがとうございます!
    おっしゃる通り、selectタグは消えておりませんでした。
    initializeした場合としていない場合でselectタグに関しては違いが見られなかったので、li要素とselectの関連性の部分をもう少し見てみようかと思います。
    とても勉強になりました、ありがとうございます。

    キャンセル

  • 2019/03/20 15:42

    理解に繋がったようで何よりです

    キャンセル

+1

違うような気もしますが

<script>
$(function(){
  $('#id_year option:eq(0)').prop('disabled',true);
  var y=new Date().getFullYear();
  for(var i=y;i>=1950;i--){
    $('#id_year').append($('<option>').val(i).text(i));
  }
});
</script>
<div class="input-field">
  <select id='id_year' required>
    <option value="" selected>選択してください</option>
  </select>
  <label>入社した年</label>
</div>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/20 15:19

    ご回答くださりありがとうございます!
    いただいたコードで処理して見たのですが、Materializeを使っていない状態だとうまく動いたのですが、使っている状態だと動きませんでした。。。
    やはりMaterializeのJSとぶつかってしまうのが原因のようです
    ただ、こちらのコードの方が短く、こういう書き方ができるのだと勉強になりました!

    キャンセル

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

  • ただいまの回答率 89.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • JavaScriptに関する質問
  • Javascriptでhtmlのselectタグを生成したいが、状況によって動かなくなってしまいます(CSSフレームワークはMaterializeを使用)