質問編集履歴

4

解決方法を追記

2015/10/29 08:23

投稿

seagal18
seagal18

スコア32

test CHANGED
File without changes
test CHANGED
@@ -365,3 +365,175 @@
365
365
  (途中でeripongさん、tozjpさんが言っていたのはこういう所を見ろということだったんですね・・・)
366
366
 
367
367
  少し前進した気がしますので、もう少し調べてみたいと思います。
368
+
369
+
370
+
371
+
372
+
373
+ ---
374
+
375
+ 解決しました!
376
+
377
+
378
+
379
+
380
+
381
+ 根本的な原因は、tozjpさんのご指摘の通り、autocompleteメソッドからのレスポンスが純粋なJSONではなかったことでした。
382
+
383
+ CakePHPがビューなどを自動で付与したデータを返していたため、javascript側で正常に処理できなかったのだと思われます。
384
+
385
+
386
+
387
+ [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/)
388
+
389
+ [http://www.sssg.org/blogs/hiro345/archives/14793.html](http://www.sssg.org/blogs/hiro345/archives/14793.html)
390
+
391
+ 上記のリンクを参考に、JSONのみを返すアクションに修正しました。
392
+
393
+ まずは予め用意した配列を返せるか検証。
394
+
395
+ **TableAController.php**
396
+
397
+ ```php
398
+
399
+ public function autocomplete(){
400
+
401
+ $result = array(
402
+
403
+ ['id' => '1', 'value' => 'item1'],
404
+
405
+ ['id' => '2', 'value' => 'item2'],
406
+
407
+ ['id' => '3', 'value' => 'item3'],
408
+
409
+ );
410
+
411
+ $this->viewClass = 'Json';
412
+
413
+ $this->set(compact('result'));
414
+
415
+ $this->set('_serialize', 'result');
416
+
417
+ }
418
+
419
+ ```
420
+
421
+ autocompleteアクションを単体で実行し、JSONのみが表示されることを確認しました。
422
+
423
+ テキストボックスに入力してみると、item1~3の候補がドロップダウンされることも確認。
424
+
425
+
426
+
427
+ 続いて元々やりたかった別テーブルからのデータを取得するように修正。
428
+
429
+ **TableAController.php**
430
+
431
+ ```php
432
+
433
+ public function autocomplete(){
434
+
435
+ $this->loadModel('TableB');
436
+
437
+ $field = 'name';
438
+
439
+ $term = $this->params['url']['term'];
440
+
441
+
442
+
443
+ // 入力値 無:全てのデータの中から10件返す。
444
+
445
+ // 入力値 有:入力値を含むデータを10件返す
446
+
447
+ $condition = array();
448
+
449
+ if(!empty($term)){
450
+
451
+ $condition = array('TableB.'.$field.' like' => "%".$term."%");
452
+
453
+ }
454
+
455
+
456
+
457
+ $query = array(
458
+
459
+ 'fields' => array($field),
460
+
461
+ 'conditions' => $condition,
462
+
463
+ 'limit' => 10,
464
+
465
+ 'order' => array('TableB.'.$field => 'ASC'),
466
+
467
+ 'group' => $field,
468
+
469
+ );
470
+
471
+
472
+
473
+ $data = array();
474
+
475
+ $items = $this->TableB->find('all', $query);
476
+
477
+
478
+
479
+ foreach ($items as $item) {
480
+
481
+ $cnt = array_push($data, $item['TableB'][$field]);
482
+
483
+ }
484
+
485
+
486
+
487
+ // JSONデータのみを返す
488
+
489
+ $this->viewClass = 'Json';
490
+
491
+ $this->set(compact('data'));
492
+
493
+ $this->set('_serialize', 'data');
494
+
495
+ }
496
+
497
+ ```
498
+
499
+ ビュー側はこうです。
500
+
501
+ **TableA/index.ctp**
502
+
503
+ ```php
504
+
505
+ <script type="text/javascript">
506
+
507
+ $(function(){
508
+
509
+ $('#autocomplete').autocomplete({
510
+
511
+ source: '<?php echo $this->Html->url(array('controller' => 'TableA', 'action' => 'autocomplete')); ?>',
512
+
513
+ autoFocus: true,
514
+
515
+ delay: 500,
516
+
517
+ minLength: 2
518
+
519
+ });
520
+
521
+ })
522
+
523
+ </script>
524
+
525
+
526
+
527
+ <?php echo $this->Form->input('name', array(
528
+
529
+ 'type' => 'text',
530
+
531
+ 'id' => 'autocomplete',
532
+
533
+ )); ?>
534
+
535
+ ```
536
+
537
+
538
+
539
+ これにより、ちゃんとテーブルBのデータがオートコンプリート表示されるようになりました。

3

追加検証について記載

2015/10/29 08:23

投稿

seagal18
seagal18

スコア32

test CHANGED
File without changes
test CHANGED
@@ -167,3 +167,201 @@
167
167
  特にsource: '/TableA/autocomplete',の部分が、ちゃんとしたURLを参照できているのかが疑わしいです。
168
168
 
169
169
  しかし実際のところどういう動作をしているのか確認する方法が分からず、詰まっています。
170
+
171
+
172
+
173
+ ---
174
+
175
+ 2015/10/29追記
176
+
177
+
178
+
179
+ ipadcaronさんのアドバイスを元にシンプルな構成で検証してみました。
180
+
181
+ CakePHPでの動作は一旦忘れて、htmlとphpだけで構成してみました。
182
+
183
+
184
+
185
+ **json_echo.php**
186
+
187
+ ```php
188
+
189
+ <?php
190
+
191
+ echo '[{"id":"1","value":"item1"},{"id":"2","value":"item2"},{"id":"3","value":"item3"}]';
192
+
193
+ ?>
194
+
195
+ ```
196
+
197
+ **index.html**
198
+
199
+ ```html
200
+
201
+ <!doctype html>
202
+
203
+ <html lang="en">
204
+
205
+ <head>
206
+
207
+ <meta charset="utf-8">
208
+
209
+ <title>jQuery UI Autocomplete - Remote datasource</title>
210
+
211
+ <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
212
+
213
+ <script src="//code.jquery.com/jquery-1.10.2.js"></script>
214
+
215
+ <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
216
+
217
+ <script>
218
+
219
+ $(function() {
220
+
221
+ function log( message ) {
222
+
223
+ $( "<div>" ).text( message ).prependTo( "#log" );
224
+
225
+ $( "#log" ).scrollTop( 0 );
226
+
227
+ }
228
+
229
+
230
+
231
+ $( "#birds" ).autocomplete({
232
+
233
+ source: "json_echo.php",
234
+
235
+ minLength: 2,
236
+
237
+ select: function( event, ui ) {
238
+
239
+ log( ui.item ?
240
+
241
+ "Selected: " + ui.item.value + " aka " + ui.item.id :
242
+
243
+ "Nothing selected, input was " + this.value );
244
+
245
+ }
246
+
247
+ });
248
+
249
+ });
250
+
251
+ </script>
252
+
253
+ </head>
254
+
255
+ <body>
256
+
257
+
258
+
259
+ <div class="ui-widget">
260
+
261
+ <label for="birds">Birds: </label>
262
+
263
+ <input id="birds">
264
+
265
+ </div>
266
+
267
+
268
+
269
+ <div class="ui-widget" style="margin-top:2em; font-family:Arial">
270
+
271
+ Result:
272
+
273
+ <div id="log" style="height: 200px; width: 300px; overflow: auto;" class="ui-widget-content"></div>
274
+
275
+ </div>
276
+
277
+
278
+
279
+
280
+
281
+ </body>
282
+
283
+ </html>
284
+
285
+ ```
286
+
287
+
288
+
289
+ index.htmlを開きテキストボックスに入力してみたところ、item1~3が候補として表示されることを確認しました。
290
+
291
+ この場合はどんな文字列を入力しても、echoで返されるJSONデータは決まっているので常にitem1~3が表示されるということで、正しい動作だと思います。
292
+
293
+
294
+
295
+ この結果を受けてCakePHPで以下のように実装しました。
296
+
297
+ **TableAController.php**
298
+
299
+ ```php
300
+
301
+ public function autocomplete(){
302
+
303
+ echo '[{"id":"1","value":"item1"},{"id":"2","value":"item2"},{"id":"3","value":"item3"}]';
304
+
305
+ }
306
+
307
+
308
+
309
+ ```
310
+
311
+ **TableA/index.ctp**
312
+
313
+ ```html
314
+
315
+ <script>
316
+
317
+ $(function() {
318
+
319
+ function log( message ) {
320
+
321
+ $( "<div>" ).text( message ).prependTo( "#log" );
322
+
323
+ $( "#log" ).scrollTop( 0 );
324
+
325
+ }
326
+
327
+
328
+
329
+ $( "#birds" ).autocomplete({
330
+
331
+ source: '<?php echo $this->Html->url(array('controller' => 'OrderLedgers', 'action' => 'autocomplete')); ?>',
332
+
333
+ minLength: 2,
334
+
335
+ select: function( event, ui ) {
336
+
337
+ log( ui.item ?
338
+
339
+ "Selected: " + ui.item.value + " aka " + ui.item.id :
340
+
341
+ "Nothing selected, input was " + this.value );
342
+
343
+ }
344
+
345
+ });
346
+
347
+ });
348
+
349
+ </script>
350
+
351
+
352
+
353
+ HTML部分は同一
354
+
355
+ ```
356
+
357
+
358
+
359
+ これを実行してみましたが、動作せず。。。
360
+
361
+
362
+
363
+ そしてたった今、Chromeのブラウザコンソールに**500 (Internal Server Error)**が表示されていることに気付きました。
364
+
365
+ (途中でeripongさん、tozjpさんが言っていたのはこういう所を見ろということだったんですね・・・)
366
+
367
+ 少し前進した気がしますので、もう少し調べてみたいと思います。

2

ファイル名修正

2015/10/29 06:12

投稿

seagal18
seagal18

スコア32

test CHANGED
File without changes
test CHANGED
@@ -38,7 +38,7 @@
38
38
 
39
39
 
40
40
 
41
- **TableA.php**
41
+ **TableAController.php**
42
42
 
43
43
  ```php
44
44
 

1

参考URLをリンク化

2015/10/28 05:09

投稿

seagal18
seagal18

スコア32

test CHANGED
File without changes
test CHANGED
@@ -20,11 +20,11 @@
20
20
 
21
21
  ■参考にしたサイト
22
22
 
23
- http://junichi11.com/?p=423
23
+ [http://junichi11.com/?p=423](http://junichi11.com/?p=423)
24
24
 
25
- http://www.buildinsider.net/web/jqueryuiref/0019
25
+ [http://www.buildinsider.net/web/jqueryuiref/0019](http://www.buildinsider.net/web/jqueryuiref/0019)
26
26
 
27
- http://js.studio-kingdom.com/jqueryui/widgets/autocomplete
27
+ [http://js.studio-kingdom.com/jqueryui/widgets/autocomplete](http://js.studio-kingdom.com/jqueryui/widgets/autocomplete)
28
28
 
29
29
 
30
30