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

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

ただいまの
回答率

90.12%

SELECTボックスの値取得して、jQueryで利用

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 4
  • VIEW 587

kirin311

score 51

不明点があり、再度お世話になります。

前提・実現したいこと

・PHPによってあらかじめHTMLの<option>が生成されており、Fullcalendarの「fc-next-button」というクラス名が付いたボタンを押したときに、JavaScriptによって現在のURLの値を用いて<option>のvalueの値を変更したい。

・現状の問題解決

 現状の問題

・現状では、ボタンを押す度にvalueの後ろが長くなる。

 分かりづらいかと思いますので・・・

◆PHPによってあらかじめHTML<option>の生成した内容

<option class="query" value="./index.php?no=1">名前1</option>
<option class="query" value="./index.php?no=2">名前2</option>
・
・
(以後繰り返し)
・
・
<option class="query" value="./index.php?no=60">名前60</option>

があります。

ここまでは問題ないのですが、ここから

●fc-next-button」というクラス名が付いたボタンを2回押したとき

<option class="query" value="./index.php?no=1&year=2018&month=10&day=01&view=month&year=2018&month=11&day=01&view=month">名前1</option>
・
・
(以後繰り返し)
・
・
<option class="query" value="./index.php?no=60&year=2018&month=10&day=01&view=month&year=2018&month=11&day=01&view=month">名前60</option>

●fc-next-button」というクラス名が付いたボタンを3回押したとき

<option class="query" value="./index.php?no=1&year=2018&month=10&day=01&view=month&year=2018&month=11&day=01&view=month&year=2018&month=12&day=01&view=month">名前1</option>
・
・
(以後繰り返し)
・
・
<option class="query" value="./index.php?no=60&year=2018&month=10&day=01&view=month&year=2018&month=11&day=01&view=month&year=2018&month=12&day=01&view=month">名前60</option>

となります。
つまり余計なクエリーが増えてしまう状態です。

最終的に例えば3回目ボタンを押したら

<option class="query" value="./index.php?no=1&year=2018&month=12&day=01&view=month">名前1</option>
・
・
(以後繰り返し)
・
・
<option class="query" value="./index.php?no=60&year=2018&month=12&day=01&view=month">名前60</option>

にしたいです。

※一応念のため
当月が9月だった場合3回押したときは12月なので取得するのは、
month=12の方です。

 該当のソースコード

$('.fc-next-button').click(function(){
    select_query();
});

function select_query(){
var arg = param();
var year = arg.year;
var month = arg.month;
var day = arg.day;
var view = arg.view;

var getValue = [];
  for (var i = 0; i<60;i++) {
    getValue[i] = $('#ge'+i).val();
    if(getValue[i]!=undefined){
     var path = getValue[i]+"&year="+year+"&month="+month+"&day="+day+"&view="+view;
    }
  }
  $('.query').val(path);
}
});

function param(){
// URLパラメータ取得
  var arg  = new Object;
  url = location.search.substring(1).split('&');
  for(i=0; url[i]; i++) {
    var k = url[i].split('=');
    arg[k[0]] = k[1];
  }
  return arg;
}

 試したこと

takey様の
getValue[i] = getValue[i].split("&")[0];

追加を試しましたがnoまで変わってしまうので解決にはなっていませんでした・・
◆追加後
<option class="query" value="./index.php?no=1">名前1</option>
<option class="query" value="./index.php?no=1">名前2</option>




<option class="query" value="./index.php?no=1">名前60</option>

 コメントへの返信

コメント欄には入力しづらいため、こちらに記述します。

crsh様
コメントありがとうございます。
申し訳ありませんが長いので引用させていただきます。

ページを初めて表示した状態のURLは「http://○○○/index.php」で、ユーザーを選択するなんらかの処理を行うとURLが「http://○○○/index.php?no=3(noパラメータは2桁頭0付きのno=03でしょうか)」

・すみません、加筆修正では、2桁になっておりましたがnoパラメータは0から9までは一桁ですね。
noパラメータ自体は、1~60まで存在します。

(ユーザー3を選択した場合)に変わり、日付に関するなんらかの処理を行うとURLが「http://○○○/index.php?no=3&year=2018&month=10&day=07&view=month」」(「月」表示の時に「2018年10月7日」を選択した場合。jQueryのFullCalenderプラグインを使ったことが無いのですが、日付選択時などの処理でしょうか)に変わるとうことでしょうか。 

・今回、あくまでもFullcalendarの「fc-next-button」というクラス名が付いたボタンを押したときの処理の部分のことなので該当ソースには載せていませんが

1.『「fc-next-button」というクラス名が付いたボタンを押した後』にオプション値変更。
※今回の目的

2.変更後、オプション選択し検索ボタンを押すとページに飛ぶ。
といった処理になっています。

検索ボタンを押した際のページに飛ぶ動作内容としては、
単純に『ユーザー3の2018年10月7日(monthページ)』
です。

飛ぶための条件として、URLパラメーターから取得している形です。
→条件に必要なのは、
no(どのユーザーに飛ぶか)
year(どの年に飛ぶか)
month(どの月に飛ぶか)
day(どの日に飛ぶか)
view(月、週、日のどのページに飛ぶか)

以上の全てになります。

イメージ説明

ID重複の指摘によって <option> の id="ge2"の記述を削除していただいているようですが、それに伴い提示していただいたソースコードを実行しても現象が再現しなくなっています(「select_query」関数の「$('#ge'+i).val();」の部分が必ず undefined になるため、現状提示いただいているコードだとボタンを押すたびにパラメータが追加されるという現象は発生しません。もちろんそれによって、他の不具合は発生しています)。 また、ボタンを2回押したとき・3回押したときについても再現しません(再現しないというより別の不具合が発生しています。

すみません、個人的になりますが休みのため手元にコードがないためこちらテラテイルのコード内容をテスト確認せず修正しておりました。
休み明け(9日火曜日)になりますが、IDで別の名前つけられるように修正する予定です。(名前というかge2,ge3,ge4・・・といった連番ですかね)

「$('.query').val(path);」がforループの外側で実行されているので、「query」クラスが付いた<option>すべてのvalue値が同じ値に変更されてしまうため)。 あとforループの処理について、「getValue[i] = $('#ge'+i).val();」は元々<option>に指定していたidを元にvalueを使おうとしているのですがこれは何のための処理でしょうか。

optionの値がそれぞれ違いますのでそれぞれの内容を取得しようとidを元に取得しておりました。
他により良い方法があれば、そちらを選びます。

optionの内容としては、
『◆PHPによってあらかじめHTML<option>の生成した内容
でnoの値が違います。

<option>のvalueの「no=3」部分を取得したいがための処理でしょうか。(<option>のvalueの値を元にgetValueの配列に格納して、配列から値を取り出して使うのには何か意味があるのでしょうか。現状のコードだけを見るとループカウンタのiを使って「no=3」部分を生成すれば良いような気がするのですが、それだと何か問題があるのでしょうか)

valueの「no=3」部分を取得したいがための処理で合っています。
私としては、こうした方がコード短くなるのかなと思ってやっておりました。

一応、意味としては、
元のデータ『◆PHPによってあらかじめHTML<option>の生成した内容』のnoの内容を残しておきたかったのです。
このnoは、名前1~60と連動しており、さらに抜けが存在することがあります。

例えば、
オプションのno1、no2、no3と続いて いきなりno30で割り振られたりします。

この場合forですと
no1 名前1
no2 名前2
no30 名前3

になってしまいます。

以上ですが、↑についてfor文でもif文の追加でやれば出来ると思いますのでfor文でも構いません。
あくまでも結果が重視なので過程はあまり考えていません。

取得したい情報としては、
no
year
month
day
view

です。

crsh様へ開発ツール該当のシンタックスエラー

イメージ説明

↑ご覧通り、$optionsが消えてしまっています。
黄色になっているところ以外にも消えている個所があります・・

※標準APIの方はシンタックスエラーがありませんでした。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • kirin311

    2018/10/06 20:20

    ご指摘ありがとうございます。ID削除いたしました。

    キャンセル

  • crsh

    2018/10/07 08:23 編集

    質問内容の加筆修正いただきありがとうございます。 実際のURLが提示できないのであれば、公開できない箇所は ○○○ などで表示していただければ問題ありません。 ページを初めて表示した状態のURLは「http://○○○/index.php」で、ユーザーを選択するなんらかの処理を行うとURLが「http://○○○/index.php?no=3(noパラメータは2桁頭0付きのno=03でしょうか)」(ユーザー3を選択した場合)に変わり、日付に関するなんらかの処理を行うとURLが「http://○○○/index.php?no=3&year=2018&month=10&day=07&view=month」」(「月」表示の時に「2018年10月7日」を選択した場合。jQueryのFullCalenderプラグインを使ったことが無いのですが、日付選択時などの処理でしょうか)に変わるとうことでしょうか。 ID重複の指摘によって <option> の id="ge2"の記述を削除していただいているようですが、それに伴い提示していただいたソースコードを実行しても現象が再現しなくなっています(「select_query」関数の「$('#ge'+i).val();」の部分が必ず undefined になるため、現状提示いただいているコードだとボタンを押すたびにパラメータが追加されるという現象は発生しません。もちろんそれによって、他の不具合は発生しています)。 また、ボタンを2回押したとき・3回押したときについても再現しません(再現しないというより別の不具合が発生しています。「$('.query').val(path);」がforループの外側で実行されているので、「query」クラスが付いた<option>すべてのvalue値が同じ値に変更されてしまうため)。 あとforループの処理について、「getValue[i] = $('#ge'+i).val();」は元々<option>に指定していたidを元にvalueを使おうとしているのですがこれは何のための処理でしょうか。<option>のvalueの「no=3」部分を取得したいがための処理でしょうか。(<option>のvalueの値を元にgetValueの配列に格納して、配列から値を取り出して使うのには何か意味があるのでしょうか。現状のコードだけを見るとループカウンタのiを使って「no=3」部分を生成すれば良いような気がするのですが、それだと何か問題があるのでしょうか。<option>のvalueから何か他にも取得したい情報があるということでしょうか)

    キャンセル

  • kirin311

    2018/10/07 09:47

    コメントありがとうございます、長くなりますので加筆修正の方で返信させていただきました。

    キャンセル

回答 3

checkベストアンサー

+2

質問内容の加筆修正および質問に回答していただきありがとうございました。
以下の通り回答いたします。

 前提となるHTML

オプションのno1、no2、no3と続いて いきなりno30で割り振られたりします。

IDで別の名前つけられるように修正する予定です。(名前というかge2,ge3,ge4・・・といった連番ですかね)

とのことなので、PHPによって以下のようなHTMLが出力されていると仮定します。

<select id="user">
    <option id="ge1" class="query" value="./index.php?no=1">名前1</option>
    <option id="ge2" class="query" value="./index.php?no=2">名前2</option>
    <option id="ge3" class="query" value="./index.php?no=3">名前3</option>
    <option id="ge30" class="query" value="./index.php?no=30">名前30</option>
</select>

 なぜ余計なパラメータが重複してしまうか

他の方の回答と重複する内容となりますが、$('#ge'+i).val()で得られる値は
1回目の呼び出しでは
"./index.php?no=1"
なので
"./index.php?no=1"の後ろに"&year=2018&month=10&day=01&view=month"
が連結されて
"index.php?no=1&year=2018&month=10&day=01&view=month"
となるため、うまくいってるように見えるのですが

ここで注意しなければならないのは、その際にoptionvalueの値は
index.php?no=1&year=2018&month=10&day=01&view=month
に書き換わってしまってしまっているということです。

したがって、2回目の呼び出しで$('#ge'+i).val()で得られる値は
"./index.php?no=1"
ではなく
"index.php?no=1&year=2018&month=10&day=01&view=month"
に書き換わってしまっているため
"index.php?no=1&year=2018&month=10&day=01&view=month"
の後ろに
"&year=2018&month=10&day=01&view=month"
が連結されて
"no=1&year=2018&month=10&day=01&view=month&year=2018&month=11&day=01&view=month"
になってしまうということです。

3回目以降は上記の繰り返しとなり、パラメータがどんどん重複してしまうということです。

したがって、もしoptionvalueを元に新たな値を生成したいのであれば
上記の通り1回目と2回目でvalueの値が変わっていることも考慮したコードに
する必要があるのですが、今回の場合、

valueの「no=3」部分を取得したいがための処理で合っています。

とのことなので、noのパラメータを取得するために、あえてoptionvalueの値を
使用する必要はないかと思います。
他の実装方法で、何をやりたいのか分かりやすいコードにすべきかと思います。
(実際のJavaScriptのコードは後述します)

 ループ処理について

optionvalueの値を変更したいということであれば、select_query関数の

 for (var i = 0; i<60;i++) {

このforループは、ユーザーの上限が60人ということでi<60としていると推測しますが

実現したい内容は

<option>のvalueの値を変更したい

であるわけで、また

オプションのno1、no2、no3と続いて いきなりno30で割り振られたりします。

なので、60回ループさせる必要は無く、optionタグの要素を取得してループさせるべきです。

そうすることでループ内の判定if(getValue[i]!=undefined){も必要もなくなり、
コードが短くなり、何をやりたいのか分かりやすいコードになるかと思います。

また、ユーザーの上限が60人固定ではないのであれば、なおさらこのような実装にすべきではありません。

 JavaScriptの処理について

以上を踏まえて、提示していただいているコードを元に以下のように書き換えることで実現できるかと思います。

なお、$('.fc-next-button')のクリックイベントに直接記述してしまっていますが、
関数に切り出す必要があれば切り出して実装してください。

以下のコードでは、パラメータnooptionidを元に取得するようにした例です。
下記のようにすることで、valueの値にパラメータが含まれているかどうかを考慮する必要がなくなります。

$('.fc-next-button').on('click',() => {
    const arg = param();
    const $options = $('#user option');
    $options.each((i, option) => {
        const $option = $(option);
        const id = $option.attr('id');
        const no = id.match(/^ge(\d+)$/)[1];
        const path = `./index.php?no=${no}&year=${arg.year}&month=${arg.month}&day=${arg.day}&view=${arg.view}`;
        $option.val(path);
    });
});

また、この程度の処理であればjQueryを使わずとも標準APIで可能です。

$('.fc-next-button').on('click',() => {
    const arg = param();
    const options = document.querySelectorAll('#user option');
    options.forEach(option => {
        const id = option.id;
        const no = id.match(/^ge(\d+)$/)[1];
        const path = `./index.php?no=${no}&year=${arg.year}&month=${arg.month}&day=${arg.day}&view=${arg.view}`;
        option.value = path;
    });
});

なお、上記はパラメータnoを取得する際に、質問内容のコードを元にした実装にしたため
optionidを元に正規表現を使って取得していますが、意味の無いidの指定は
好ましくないため、カスタムデータ属性(data-*)を使って

<option data-no="3" class="query" value="./index.php?no=3">名前3</option>


のようにしておき、以下のいずれか

// jQuery
const no = $option.data('no');

// 標準API
const no = option.dataset.no;

// もしくは (標準API)
const no = option.getAttribute('data-no');


で値を取得するのが、より良い方法かと思います。

 対象ブラウザについて

ここまで記述した後に質問内容などを見直していたのですが

すみません、個人的になりますが休みのため手元にコードがないため

であったり

主旨違いますが「mysql_query」を使っているようですが、いまやありえない関数なので自己解決できないなら使うべきではありません

コメント、ありがとうございます。私自身もPDOを使えば良いとは思ってはいるんですが、そこまで変更となると、今回の内容だけでなく他のファイル群まで手を出さねばならなくなるので・・・

ということや、JavaScriptの変数の宣言にvarを使用していることから推測すると、
かなり古い業務システムの保守対応案件などでしょうか。

(それとも単純に、参考にしたコードが過去の本や過去のホームページなどというだけでしょうか)

何を気にしてるかと言いますと、対象ブラウザがレガシーなIE8やIE11などが含まれていますでしょうか。

それらのブラウザ(特にIE8)はJavaScriptのバージョンが古いため、上記で記したコードは一部動作しない箇所が
あるため、それらのブラウザでも動作するように古い記法に置き換えて実装していただく必要があります。

もし、レガシーなブラウザが対象であるが、古い記法への置き換え方が分からないようであれば
古い記法でのコードを追記しますのでその旨返信ください。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/10/10 09:12

    返信ありがとうございます。
    使用ブラウザですが、まずはChromeで実行いたしました。

    「記述先がPHPファイルのせい」と判断した理由としては開発ツールにてソースを確認しましたところ
    const = $('#sel option');
    となっており、$optionsが消えております。
    (そして動作しません。)

    これは、変数がPHPだから消えてしまっているのでは?と判断した次第です。
    私自身の予想であり、はっきりと確証を持ってるわけではないです。

    該当の開発ツール内容のSSを撮りましたので質問内容の加筆修正いたします。

    キャンセル

  • 2018/10/10 23:46

    シンタックスエラーのスクリーンショットの提示ありがとうございます。

    JavaScriptを<?php ~ ?>で囲った中に記述してしまっているということですね。

    PHPは先頭が $ が先頭のものは、PHPの変数として識別されてしまうため、<?php ~ ?>
    で囲った中に JavaScript を記述した $options がPHPの変数として認識されてしまい、
    変数が展開されて消えてしまっているのが原因かと思います。

    PHPが必要な箇所だけ<?php ~?>で囲った実装にすべきですが、それをやろうとすると
    保守対象の元々のコードの都合で全体のコードの改修になってしまうので難しい等あれば、
    とりあえずPHPの変数として認識されないように、$options や $option の変数名の先頭を
    $ではない物に変更すれば動作はするかと思います。

    JavaScriptでは、$には特別な意味は無いので$を付けなくても問題ありません。
    ・jQueryオブジェクト の変数
    ・HTMLElementやNodeListなどのオブジェクトの変数
    を視覚的に区別するために、先頭に $ を付けているだけです。

    キャンセル

  • 2018/10/11 09:13

    そういうことでしたか。
    確かに<?php ~ ?>で囲った中にJavascriptを記述しております。

    Javascriptに$がなくても問題ないのですね。
    必要かと思って残しておりましたが$ が先頭を削除したところ、動作しませんでしたがconst全てをvarに変えたところ動作できるようになりました。


    ありがとうございました、無事解決しましたのでベストアンサーとつけさせていただきます。

    キャンセル

0

今の書き方が、
① valueの値を取得する
② 値の後ろに日付を足す
③ 値をoption valueにセットする
になっているので、もちろんボタンを押す度にvalueの後ろが長くなります。

なので、値に「?」がついている場合はそこで区切ってみて一度index.phpだけのものにしてやる必要があります。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/09/28 19:53

    回答ありがとうございます。

    浅学で申し訳ありませんが、区切るというのは、JSのsplitを使っていくということでしょうか?

    キャンセル

0

getValue[i] = $('#ge'+i).val();
// 1回目の呼び出しでは、$('#ge'+i).val() ==> "./index.php?no=01"
// 2回目の呼び出しでは、$('#ge'+i).val() ==> "./index.php?no=01&year=2018&month=10&day=01&view=month"
// 3回目の呼び出しでは、$('#ge'+i).val() ==> "./index.php?no=01&year=2018&month=10&day=01&view=month&year=2018&month=11&day=01&view=month"
// ...
// なので、素朴な方法としては、次のコードを直後に追加すると解決するかもしれません。
getValue[i] = getValue[i].split("&")[0];

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/10/05 13:57

    すみません返事が遅くなりました、
    getValue[i] = getValue[i].split("&")[0];を追加させていただいたところ


    ◆元が
    <option id="ge2" class="query" value="./index.php?no=1">名前1</option>



    <option id="ge2" class="query" value="./index.php?no=60">名前60</option>



    ◆変更後
    <option id="ge2" class="query" value="./index.php?no=1">名前1</option>
    <option id="ge2" class="query" value="./index.php?no=1">名前2</option>




    <option id="ge2" class="query" value="./index.php?no=1">名前60</option>


    となります。
    説明不足ですいません、valueの後ろが長くならないようにあくまでクエリ―追加という形で行いたいので。。

    キャンセル

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

  • ただいまの回答率 90.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる