0

I'm new to cakephp, I have followed a tutorial to implement search box with autocomplete and all went well, the search box at the View/Pages/home.ctp works as expected, but I really need to put that search box at my View/Terms/index.ctp, and I can not find the way to make it work, here I paste all the code I've generated, I hope somebody can help me, and thanks in advance:

file: Controller/TermsController.php

<?php
App::uses('AppController', 'Controller');
class TermsController extends AppController {
    public $helpers = array('Js'=>'Jquery', 'Form', 'Html');
    public $components = array('Paginator', 'RequestHandler', 'Session');
    public function getdata($id = null){
            $this->Term->id = $id;
            if(!$this->Term->exists()):
                    throw new NotFoundException("El terme no existeix");
            endif;
            $this->set('term', $this->Term->read(null, $id));
            $this->layout = 'ajax';
    }

    public function autocomplete(){
            $this->set('terms', $this->Term->find('all', 
            array('conditions' => array(
            'Term.entry LIKE' => $this->request->query['term'].'%'),
            'fields' => array('id', 'entry')
            )
    ));
    $this->layout = 'ajax';
    }

    public function index() {
            $this->Term->recursive = 0;
            $this->set('terms', $this->Paginator->paginate());
    }
}

file: View/Pages/home.ctp (the one that works)

<?php $this->layout = 'default';?>
<?php   echo $this->Form->create(null,array());
    echo $this->Form->input('word', array('label' => 'Cerca entrada'));
    $this->Form->end('Cerca'); ?>
<div id="results"></div>
   <script type="text/javascript">
    var js = jQuery.noConflict();
    (function($){
            js(document).ready(function(){
            js("#results").hide();
//Autocomplete
            js( "#word" ).autocomplete({
                    source: "terms/autocomplete",
                    minLength: 3,
                    focus: function(event, ui){
                    js("#word").val(ui.item.Term.entry); return false;
                    },
                    select: function( event, ui ) {
                    js( "#word" ).val(ui.item.Term.entry);
                    var id = ui.item.Term.id;
                    $.ajax({
                            url: 'terms/getdata/'+id,
                            dataType: 'json',
                            success: function(data){
                            var html = '<div class="lemma_tag">';
                                    html += '<h2>Lemes i etiquetes</h2>';
                                    html += '<p>'+data.Term.lemma_tag+'</p>';
                                    html += '<p><a href="terms/view/'+id+'">Més accions</a></p>';
                                    html += '</div>';
                            js("#results").html(html);
                            js("#results").show('blind');
                    }
                    });
                    return false;
}
//select
            }).data( "ui-autocomplete" )._renderItem = function(ul, item){
                    return $("<li></li>")
                            .data("ui-autocomplete-item", item)
                            .append("<a>" + item.Term.entry + "</a>")
                            .appendTo(ul)
            };
//Autocomplete.end
            });
    })(jQuery);
    </script>

file: View/Terms/autocomplete.ctp

<?php echo $this->Js->object($terms);?>

file: View/Terms/getdata.ctp

<?php echo $this->Js->object($term); ?>

file: View/Terms/index.ctp (here is where it doesn't work, I paste the entire file for you to have an idea of what I'm trying to achieve)

<div class="terms index">
    <h2><?php echo __('Terms'); ?></h2>
    <table cellpadding="0" cellspacing="0">
    <tr>
                    <th><?php echo $this->Paginator->sort('id'); ?></th>
                    <th><?php echo $this->Paginator->sort('entry', 'Entrada'); ?></th>
                    <th><?php echo $this->Paginator->sort('lemma_tag', 'Lemes i etiquetes'); ?></th>
                    <th><?php echo $this->Paginator->sort('status', 'Estat'); ?></th>
                    <th class="actions"><?php echo __('Actions'); ?></th>
    </tr>
    <?php foreach ($terms as $term): ?>
    <tr>
            <td><?php echo h($term['Term']['id']); ?>&nbsp;</td>
            <td><?php echo h($term['Term']['entry']); ?>&nbsp;</td>
            <td><?php echo h($term['Term']['lemma_tag']); ?>&nbsp;</td>
            <td><?php echo h($term['Term']['status']); ?>&nbsp;</td>
            <td class="actions">
                    <?php echo $this->Html->link(__('View'), array('action' => 'view', $term['Term']['id'])); ?>
                    <?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $term['Term']['id'])); ?>
                    <?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $term['Term']['id']), array(), __('Are you sure you want to delete # %s?', $term['Term']['id'])); ?>
            </td>
    </tr>
<?php endforeach; ?>
    </table>
    <p>
    <?php
    echo $this->Paginator->counter(array(
    'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
    ));
    ?>      </p>
    <div class="paging">
    <?php
            echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
            echo $this->Paginator->numbers(array('separator' => ''));
            echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
    ?>
    </div>
</div>
<div class="actions">
    <h3><?php echo __('Actions'); ?></h3>
    <ul>
            <li>
            </li>
            <li>&nbsp;</li>
            <li><?php echo $this->Html->link(__('New Term'), array('action' => 'add')); ?></li>
            <li>&nbsp;</li>
            <li>
<?php $this->layout = 'default';?>
<?php   echo $this->Form->create(null,array());
    echo $this->Form->input('word', array('label' => 'Cerca entrada'));
    $this->Form->end('Cerca'); ?>
<div id="results"></div>
   <script type="text/javascript">
    var js = jQuery.noConflict();
    (function($){
            js(document).ready(function(){
            js("#results").hide();
//Autocomplete
            js( "#word" ).autocomplete({
                    source: "terms/autocomplete",
                    minLength: 3,
                    focus: function(event, ui){
                    js("#word").val(ui.item.Term.entry); return false;
                    },
                    select: function( event, ui ) {
                    js( "#word" ).val(ui.item.Term.entry);
                    var id = ui.item.Term.id;
                    $.ajax({
                            url: 'terms/getdata/'+id,
                            dataType: 'json',
                            success: function(data){
                            var html = '<div class="lemma_tag">';
                                    html += '<h2>Lemes i etiquetes</h2>';
                                    html += '<p>'+data.Term.lemma_tag+'</p>';
                                    html += '<p><a href="terms/view/'+id+'">Més accions</a></p>';
                                    html += '</div>';
                            js("#results").html(html);
                            js("#results").show('blind');
                    }
                    });
                    return false;
}
//select
            }).data( "ui-autocomplete" )._renderItem = function(ul, item){
                    return $("<li></li>")
                            .data("ui-autocomplete-item", item)
                            .append("<a>" + item.Term.entry + "</a>")
                            .appendTo(ul)
            };
//Autocomplete.end
            });
    })(jQuery);
    </script>
    </li>
    <li>&nbsp;</li>
    <li>
            <?php echo $this->Upload->view('Term', $term['Term']['id']); ?>
    </li>
    </ul>
</div>

Solution:

For those who face this same problem, the second part of the great answer of @Salines is the one that make it work: echo $this->Form->input('word', array('id'=>'word','label' => 'Cerca entrada')); the first changes suggested are not necessary.

Andrés Chandía
  • 999
  • 1
  • 16
  • 32

1 Answers1

1

Try to replace this line of code :

source: "terms/autocomplete",
...
url: 'terms/getdata/'+id,

in this:

source: "<?php echo $this->Html->url(array('controller' => 'terms','action' => 'autocomplete'),true);?>",
url: "<?php echo $this->Html->url(array('controller' => 'terms','action' => 'getdata'),true) .'/';?>" +id,

To understand the difference, if you put a static path "terms/autocomplete"in your javascript code, then from your home page javascript has the correct post / get url, but when you're on the terms page, javascript generated url eg /terms/terms/autocomplete.

Update: add id="word" to your input field

echo $this->Form->input('word', array('id'=>'word','label' => 'Cerca entrada'));
Salines
  • 5,674
  • 3
  • 25
  • 50
  • Sorry, I didn't comment the things I've tried, and that was one of those, any way I tried again, but no success – Andrés Chandía Jun 02 '14 at 12:15
  • I update code. look at firebug or chrome developer tools, is a valid path when you typing – Salines Jun 02 '14 at 12:19
  • at firebug it says this: TypeError: js(...).autocomplete(...).data(...) is null }).data( "ui-autocomplete" )._renderItem = function(ul, item){ - only when I press enter, during the typing (for autocomplete) it says nothing – Andrés Chandía Jun 02 '14 at 12:48
  • Actually, on loading the page appears the same error message – Andrés Chandía Jun 02 '14 at 13:05
  • I've seen that the error message I get is related to the syntax of autocomplete: autocomplete or ui.autocomplete, mine should be right,a nyway I've tried eith the wrong one, but nothing, any way can it be related to this sort of things but in some other place or way? – Andrés Chandía Jun 02 '14 at 18:31
  • Or something related to this: http://stackoverflow.com/questions/5590776/why-am-i-getting-this-js-error if it is that, sorry I'm not experienced enough to modify my code accordingly, would you mind giving me a hand, please. – Andrés Chandía Jun 02 '14 at 18:36