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

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

新規登録して質問してみよう
ただいま回答率
85.50%
CoffeeScript

CoffeeScriptはプログラミング言語です。シンタックスシュガーの導入により、JavaScriptのコードに変換された後動作します。JavaScriptに比べ、可読性と簡潔性が向上しています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

5回答

6991閲覧

CoffeeScriptでchangeイベントが動作しません

sorachi77

総合スコア13

CoffeeScript

CoffeeScriptはプログラミング言語です。シンタックスシュガーの導入により、JavaScriptのコードに変換された後動作します。JavaScriptに比べ、可読性と簡潔性が向上しています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

1グッド

0クリップ

投稿2016/05/01 08:59

編集2016/05/01 13:06

###前提・実現したいこと
Ruby on Railsで記述しているselectタグの変更を検知するイベントを、CoffeeScriptで記述したい。

###発生している問題・エラーメッセージ
ページ読み込み時に一度実行されるが、ブラウザからselectの選択を変えても、JSコンソールには何の反応もない。

###該当のソースコード

lang

1<%= select_tag('pay_category', options_from_collection_for_select(@categories, :category, :category)) %><br>

lang

1do -> 2 console.log('test') 3 4 $('.pay_category').on 5 'change': console.log('change')

###chromeのJSコンソール出力結果
①ページ読み込み時
test
change

②select要素変更時
①と変化なし

###試したこと
CoffeeScript公式サイトのTRY機能でコンパイルしたところ、以下のようにコンパイルされました。

lang

1(function() { 2 console.log('test'); 3 return $('.pay_category').on({ 4 'change': console.log('change') 5 }); 6})();

最後の処理にreturnが付くのがCoffeeScriptの仕様と勉強したのですが、それによって即時関数が終了してしまっている(?)ことが原因かと考え、色々検索してみたのですが解決することができず、ご質問させていただきました。

初歩的な質問となってしまい、大変申し訳ございません。
もし解決方法をご存知でしたら、お手数をおかけいたしますがよろしくお願い致します。

###2016/5/1 21:30追記
皆様ご回答いただきましてありがとうございました。

お恥ずかしながら、classとidの指定方法を混合しておりました。
いただいたご回答をもとに、以下のとおり修正致しました。

lang

1 $('#pay_category').on 'change', -> 2 console.log 'change'

しかし、これでselectの選択を変更してもJSコンソールに変化がなく、もっと根本的なところに原因があるのかと、次の実験を行いました。

【実験①:シンプルに要素の取得だけ試す】

以下のコードを追記し、要素の取得ができているかどうかの実験を行いました。

Viewにただのテキストボックスを追加。

lang

1<%= select_tag('pay_category', options_from_collection_for_select(@categories, :category, :category)) %><br> 2<input type="text" id="textone" value="textone初期値">

CoffeeScriptに以下を追加。

lang

1do -> 2 console.log('test') 3 4 #追加 5 test = $('#textone').val() 6 console.log(test) 7 8 $('#pay_category').on 'change', -> 9 console.log 'change'

しかし、textoneのログ結果はundifinedでした。
ですので、根本的にフォームの要素を取得できていないことがわかりました。

【実験②:Viewにscriptを書いて実験】

Viewファイルの1番下に以下を追加。

lang

1<script> 2 var test; 3 test = $('#textone').val(); 4 console.log(test); 5</script>

そうすると、JSコンソールには以下の通り表示されました。

textone初期値

よって、やはりCoffeeScriptとViewの接続がうまくいっていないように思えます。

【実験③:applicasion.jsに書いて実験】

本来は推奨されないと読んだのですが、AssetPipelineに問題があるのかと思い、application.jsに実験①と同様のコードを書いた実験も行いました。
しかし、結果はundifinedとなりました。
ですので、原因はView←→CoffeeScriptにありそうです。

せっかくご回答いただきましたのに、別の所に原因がありまして大変申し訳ございませんでした。
ご回答をいただきましてから本原因の調査もしてみたのですが、解決する情報を見つけることが出来ませんでした。
もしまだお付き合いいただけましたら、本原因もご存知でしたら、ご教授いただけると幸いです。

環境はmacにvagrantで作ったcentos環境を使用しており、今回が初railsですのでgemなどは足りないものが出てきたらググッて追加しているところであります。

raccy👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

$('.pay_category')....

は class="pay_category" となっている要素について処理を設定しています。

画面の html ソース上で selectタグの部分を確認してみてください。
おそらく id="pay_category" となっているのではと思います。
そうなっていたなら、 $('#pay_category')... と書く必要があります。

select タグの部分に id や適切なクラスが設定されていなければ、 select_tag の使い方をしらべて
class を指定するように書いて、そのクラスに対して、coffeescript で処理を設定するようにすれば良いと思います。

投稿2016/05/01 10:05

編集2016/05/01 10:06
katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sorachi77

2016/05/01 13:11

>katoy様 ご回答ありがとうございます。 コードの修正を行ったのですが、私の調査不足で他に原因がありそうなことが判明致しました。 大変お手数をおかけして恐縮ですが、もしお時間がありましたら本文に追記いたしましたので、ご覧いただけると幸いでございます。
sorachi77

2016/05/02 11:26

>katoy様 無事解決することが出来ました。 ご回答いただきましてどうもありがとうございました。
guest

0

2点あります。

  1. select_tagに引数で渡した名前はidになります。今回ですと<select id="pay_category" ...となっているはずです。idですのでjQueryからセレクタ指定で取得するとは$(#pay_category')とする必要があります。
  2. jQueryのon()の使い方が間違っているようです。引数は、on(イベント名, コールバック関数)またはon({イベント名: コールバック関数)という形です。なので、->で無名関数を作って渡さないと動かないと思います。(miyabi-sunさん、サンクス)

上記を踏まえて、下記のように修正すれば動くようになるかと思います。お試しください。

CoffeeScript

1do -> 2 console.log('test') 3 4 $('#pay_category').on 'change', -> 5 console.log('change')

なお、うまくいかないときは、ブラウザ上で変換されたHTMLやJavaScriptが想定通りなのかを確認すると良いと思います。

投稿2016/05/01 10:17

編集2016/05/01 10:52
raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyabi-sun

2016/05/01 10:24 編集

raccyさんの回答を見てドキッとなったので調べてみました。 http://js.studio-kingdom.com/jquery/events/on このページの1.7バージョンで追加の箇所でこんな記述を見かけたので試してみました。 > .on( events-map [, selector] [, data] ) 1.7追加 下記のコードを打ち込んで試したら確かに動いたので、単純に関数を指定していない事が原因となりそうです。 $($0).on({'click': function(){console.log(123);}})
raccy

2016/05/01 10:48

> miyabi-sunさん まじっすか。って公式APIのドキュメントをよくよんだら二つ目にありますね。例文でも見たこと無かったので、勘違いしてました。関数じゃ無いからが原因の一つですね。
miyabi-sun

2016/05/01 10:57

私もjQueryはオブジェクトが引数になるケースが多いので、 きっとonも同様の動作するんじゃねーのくらいの認識なのでびっくりしました(笑 引数が文字列なら〜、配列なら〜…って動きはあんまり良くない気もしますね。
sorachi77

2016/05/01 13:12

>raccy様 ご回答ありがとうございます。 コードの修正を行ったのですが、私の調査不足で他に原因がありそうなことが判明致しました。 大変お手数をおかけして恐縮ですが、もしお時間がありましたら本文に追記いたしましたので、ご覧いただけると幸いでございます。
sorachi77

2016/05/02 11:26

>raccy様 無事解決することが出来ました。 ご回答いただきましてどうもありがとうございました。
guest

0

ベストアンサー

jQueryのonメソッドのチェンジとして指定されているのが、
質問文のままではundefinedという値になってしまっています。
(changeに入る時に実行後の戻り値を使う→console.logの戻り値は常にundefined)

なのでこうすれば通るんじゃないですかね?

CoffeeScript

1do -> 2 console.log('test') 3 4 $('.pay_category').on 5 'change': -> console.log 'change'

追記部分

そもそもCoffeeスクリプトで書いたconsole.logが出力されている時点でつなぎ込みは正常に行われています。

根本のブラウザ+JavaScriptの仕様として、
JavaScriptはscript要素で読み込まれた瞬間実行されます。
script要素が書かれている内容のJavaScriptの動作が全て終わらない限り、以降の要素は基本的に1行も解析されません。

上記仕様により、
例えばCoffeeScriptで生成されたJavaScriptのファイルがhead要素の配下にある場合、
まだレンダリングされる前の存在しないbodyの中身を必死に探して何もないという結果が帰ってきます。

ブラウザはbodyの中身を全て解析し終わった後、loadイベントを発行します。

body要素のonLoad属性に発火して欲しい処理を記載したり、
jQueryのready機能を使うことでDOM構造の構築が終わってから処理を始める事ができます。
(body要素のonLoad属性は上書きされて古い設定が用意に消えるので、jQueryのready機能を使うことです)

ファイルを下記のように変更すれば動くと思いますので試してみてください。

CoffeeScript

1$ -> 2 console.log('test') 3 4 #追加 5 test = $('#textone').val() 6 console.log(test) 7 8 $('#pay_category').on 'change', -> 9 console.log 'change'

投稿2016/05/01 10:04

編集2016/05/02 03:39
miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sorachi77

2016/05/01 13:11

>miyabi-sun様 ご回答ありがとうございます。 コードの修正を行ったのですが、私の調査不足で他に原因がありそうなことが判明致しました。 大変お手数をおかけして恐縮ですが、もしお時間がありましたら本文に追記いたしましたので、ご覧いただけると幸いでございます。
sorachi77

2016/05/02 11:25

>miyabi-sun様 教えていただいた方法で解決することが出来ました! お忙しい中何度も教えていただき、深く感謝申し上げます。 これからもrailsの勉強に励みたいと思います。 どうもありがとうございました。
guest

0

select要素のクラスはきちんとpay_categoryになっていますでしょうか。別途でクラスやIDを振ったほうが確実かもしれません。

投稿2016/05/01 09:18

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sorachi77

2016/05/01 13:09

>maisumakun様 ご回答ありがとうございます。 お恥ずかしながらidとclassの指定方法を混合しておりました。 コードの修正を行ったのですが、私の調査不足で他に原因がありそうなことが判明致しました。 大変お手数をおかけして恐縮ですが、もしお時間がありましたら本文に追記いたしましたので、ご覧いただけると幸いでございます。
sorachi77

2016/05/02 11:25

>maisumakun様 無事解決することが出来ました。 ご回答いただきましてどうもありがとうございました。
guest

0

coffeeScriptは関数を書いた場合、関数内の最後に定義されたものを自動的にreturnする仕様になっており、イベント処理時にそのまま書くと、関数式が返ってきます。それを避けるには、最後に明示的にreturnを書かないと動作しなかった気がします。
すいません、最初の質問のみ読んで回答しています。

投稿2016/05/01 13:35

DaisukeSakai

総合スコア50

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sorachi77

2016/05/02 11:26

>DaisukeSakai様 無事解決することが出来ました。 ご回答いただきましてどうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問