teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

4

解決方法を追記

2015/10/29 08:23

投稿

seagal18
seagal18

スコア32

title CHANGED
File without changes
body CHANGED
@@ -181,4 +181,90 @@
181
181
 
182
182
  そしてたった今、Chromeのブラウザコンソールに**500 (Internal Server Error)**が表示されていることに気付きました。
183
183
  (途中でeripongさん、tozjpさんが言っていたのはこういう所を見ろということだったんですね・・・)
184
- 少し前進した気がしますので、もう少し調べてみたいと思います。
184
+ 少し前進した気がしますので、もう少し調べてみたいと思います。
185
+
186
+
187
+ ---
188
+ 解決しました!
189
+
190
+
191
+ 根本的な原因は、tozjpさんのご指摘の通り、autocompleteメソッドからのレスポンスが純粋なJSONではなかったことでした。
192
+ CakePHPがビューなどを自動で付与したデータを返していたため、javascript側で正常に処理できなかったのだと思われます。
193
+
194
+ [http://digape.com/201210/cakephp2-json%E5%BD%A2%E5%BC%8F%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E6%89%8B%E8%BB%BD%E3%81%AB%E5%87%BA%E5%8A%9B%E3%81%99%E3%82%8B/](http://digape.com/201210/cakephp2-json%E5%BD%A2%E5%BC%8F%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E6%89%8B%E8%BB%BD%E3%81%AB%E5%87%BA%E5%8A%9B%E3%81%99%E3%82%8B/)
195
+ [http://www.sssg.org/blogs/hiro345/archives/14793.html](http://www.sssg.org/blogs/hiro345/archives/14793.html)
196
+ 上記のリンクを参考に、JSONのみを返すアクションに修正しました。
197
+ まずは予め用意した配列を返せるか検証。
198
+ **TableAController.php**
199
+ ```php
200
+ public function autocomplete(){
201
+ $result = array(
202
+ ['id' => '1', 'value' => 'item1'],
203
+ ['id' => '2', 'value' => 'item2'],
204
+ ['id' => '3', 'value' => 'item3'],
205
+ );
206
+ $this->viewClass = 'Json';
207
+ $this->set(compact('result'));
208
+ $this->set('_serialize', 'result');
209
+ }
210
+ ```
211
+ autocompleteアクションを単体で実行し、JSONのみが表示されることを確認しました。
212
+ テキストボックスに入力してみると、item1~3の候補がドロップダウンされることも確認。
213
+
214
+ 続いて元々やりたかった別テーブルからのデータを取得するように修正。
215
+ **TableAController.php**
216
+ ```php
217
+ public function autocomplete(){
218
+ $this->loadModel('TableB');
219
+ $field = 'name';
220
+ $term = $this->params['url']['term'];
221
+
222
+ // 入力値 無:全てのデータの中から10件返す。
223
+ // 入力値 有:入力値を含むデータを10件返す
224
+ $condition = array();
225
+ if(!empty($term)){
226
+ $condition = array('TableB.'.$field.' like' => "%".$term."%");
227
+ }
228
+
229
+ $query = array(
230
+ 'fields' => array($field),
231
+ 'conditions' => $condition,
232
+ 'limit' => 10,
233
+ 'order' => array('TableB.'.$field => 'ASC'),
234
+ 'group' => $field,
235
+ );
236
+
237
+ $data = array();
238
+ $items = $this->TableB->find('all', $query);
239
+
240
+ foreach ($items as $item) {
241
+ $cnt = array_push($data, $item['TableB'][$field]);
242
+ }
243
+
244
+ // JSONデータのみを返す
245
+ $this->viewClass = 'Json';
246
+ $this->set(compact('data'));
247
+ $this->set('_serialize', 'data');
248
+ }
249
+ ```
250
+ ビュー側はこうです。
251
+ **TableA/index.ctp**
252
+ ```php
253
+ <script type="text/javascript">
254
+ $(function(){
255
+ $('#autocomplete').autocomplete({
256
+ source: '<?php echo $this->Html->url(array('controller' => 'TableA', 'action' => 'autocomplete')); ?>',
257
+ autoFocus: true,
258
+ delay: 500,
259
+ minLength: 2
260
+ });
261
+ })
262
+ </script>
263
+
264
+ <?php echo $this->Form->input('name', array(
265
+ 'type' => 'text',
266
+ 'id' => 'autocomplete',
267
+ )); ?>
268
+ ```
269
+
270
+ これにより、ちゃんとテーブルBのデータがオートコンプリート表示されるようになりました。

3

追加検証について記載

2015/10/29 08:23

投稿

seagal18
seagal18

スコア32

title CHANGED
File without changes
body CHANGED
@@ -82,4 +82,103 @@
82
82
  これでテキストボックスが作成されますが、入力してもオートコンプリートが動作しません。
83
83
  2.の時点でautocomplete()メソッド自体は正常に動作している(と思われる)ので、怪しいのはjavascriptかと思っています。
84
84
  特にsource: '/TableA/autocomplete',の部分が、ちゃんとしたURLを参照できているのかが疑わしいです。
85
- しかし実際のところどういう動作をしているのか確認する方法が分からず、詰まっています。
85
+ しかし実際のところどういう動作をしているのか確認する方法が分からず、詰まっています。
86
+
87
+ ---
88
+ 2015/10/29追記
89
+
90
+ ipadcaronさんのアドバイスを元にシンプルな構成で検証してみました。
91
+ CakePHPでの動作は一旦忘れて、htmlとphpだけで構成してみました。
92
+
93
+ **json_echo.php**
94
+ ```php
95
+ <?php
96
+ echo '[{"id":"1","value":"item1"},{"id":"2","value":"item2"},{"id":"3","value":"item3"}]';
97
+ ?>
98
+ ```
99
+ **index.html**
100
+ ```html
101
+ <!doctype html>
102
+ <html lang="en">
103
+ <head>
104
+ <meta charset="utf-8">
105
+ <title>jQuery UI Autocomplete - Remote datasource</title>
106
+ <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
107
+ <script src="//code.jquery.com/jquery-1.10.2.js"></script>
108
+ <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
109
+ <script>
110
+ $(function() {
111
+ function log( message ) {
112
+ $( "<div>" ).text( message ).prependTo( "#log" );
113
+ $( "#log" ).scrollTop( 0 );
114
+ }
115
+
116
+ $( "#birds" ).autocomplete({
117
+ source: "json_echo.php",
118
+ minLength: 2,
119
+ select: function( event, ui ) {
120
+ log( ui.item ?
121
+ "Selected: " + ui.item.value + " aka " + ui.item.id :
122
+ "Nothing selected, input was " + this.value );
123
+ }
124
+ });
125
+ });
126
+ </script>
127
+ </head>
128
+ <body>
129
+
130
+ <div class="ui-widget">
131
+ <label for="birds">Birds: </label>
132
+ <input id="birds">
133
+ </div>
134
+
135
+ <div class="ui-widget" style="margin-top:2em; font-family:Arial">
136
+ Result:
137
+ <div id="log" style="height: 200px; width: 300px; overflow: auto;" class="ui-widget-content"></div>
138
+ </div>
139
+
140
+
141
+ </body>
142
+ </html>
143
+ ```
144
+
145
+ index.htmlを開きテキストボックスに入力してみたところ、item1~3が候補として表示されることを確認しました。
146
+ この場合はどんな文字列を入力しても、echoで返されるJSONデータは決まっているので常にitem1~3が表示されるということで、正しい動作だと思います。
147
+
148
+ この結果を受けてCakePHPで以下のように実装しました。
149
+ **TableAController.php**
150
+ ```php
151
+ public function autocomplete(){
152
+ echo '[{"id":"1","value":"item1"},{"id":"2","value":"item2"},{"id":"3","value":"item3"}]';
153
+ }
154
+
155
+ ```
156
+ **TableA/index.ctp**
157
+ ```html
158
+ <script>
159
+ $(function() {
160
+ function log( message ) {
161
+ $( "<div>" ).text( message ).prependTo( "#log" );
162
+ $( "#log" ).scrollTop( 0 );
163
+ }
164
+
165
+ $( "#birds" ).autocomplete({
166
+ source: '<?php echo $this->Html->url(array('controller' => 'OrderLedgers', 'action' => 'autocomplete')); ?>',
167
+ minLength: 2,
168
+ select: function( event, ui ) {
169
+ log( ui.item ?
170
+ "Selected: " + ui.item.value + " aka " + ui.item.id :
171
+ "Nothing selected, input was " + this.value );
172
+ }
173
+ });
174
+ });
175
+ </script>
176
+
177
+ HTML部分は同一
178
+ ```
179
+
180
+ これを実行してみましたが、動作せず。。。
181
+
182
+ そしてたった今、Chromeのブラウザコンソールに**500 (Internal Server Error)**が表示されていることに気付きました。
183
+ (途中でeripongさん、tozjpさんが言っていたのはこういう所を見ろということだったんですね・・・)
184
+ 少し前進した気がしますので、もう少し調べてみたいと思います。

2

ファイル名修正

2015/10/29 06:12

投稿

seagal18
seagal18

スコア32

title CHANGED
File without changes
body CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  2. テーブルAのコントローラに、オートコンプリートのデータを取得するメソッドを追加。
20
20
 
21
- **TableA.php**
21
+ **TableAController.php**
22
22
  ```php
23
23
  public function autocomplete(){
24
24
  $this->loadModel('TableB');

1

参考URLをリンク化

2015/10/28 05:09

投稿

seagal18
seagal18

スコア32

title CHANGED
File without changes
body CHANGED
@@ -9,9 +9,9 @@
9
9
  jQuery UI 1.11.4
10
10
 
11
11
  ■参考にしたサイト
12
- http://junichi11.com/?p=423
13
- http://www.buildinsider.net/web/jqueryuiref/0019
14
- http://js.studio-kingdom.com/jqueryui/widgets/autocomplete
12
+ [http://junichi11.com/?p=423](http://junichi11.com/?p=423)
13
+ [http://www.buildinsider.net/web/jqueryuiref/0019](http://www.buildinsider.net/web/jqueryuiref/0019)
14
+ [http://js.studio-kingdom.com/jqueryui/widgets/autocomplete](http://js.studio-kingdom.com/jqueryui/widgets/autocomplete)
15
15
 
16
16
  ■実装手順
17
17
  1. jqueryとjquery UIをレイアウトファイルで指定。