Cakephp 2.1和Jquery UI自动完成

时间:2012-04-10 07:01:46

标签: ajax jquery-ui cakephp jquery

使命:

在名为department的员工表单字段中实现部门的自动完成(保存在departments表中)。 用户输入一些部门名称的拼写 这会显示匹配部门的名称列表 用户选择一个就是它。

平台

  1. CakePhp 2.1
  2. Jquery UI Autocomplete(Jquery UI库版本1.8.18的一部分)
  3. 数据库模型

    Emplyee(id,first_name,last_name,department_id) 部门(ID,姓名)

    所以在我的add.ctp文件中,ajax调用类似于

          $( "#auto_complete" ).autocomplete({
            source: function( request, response ) {
                $.ajax({
                    url:  "/employees/showDepartment",
                    dataType: "json",
                    data: {
                        featureClass: "P",
                        style: "full",
                        maxRows: 12,
                        name_startsWith: request.term
                    },
                    success: function( data ) {
                        alert("success--");
                        response( $.map( data, function( item ) {
                        //alert(item);
                            return {
                                label: item.name,
                                value: item.id
                            }
                        }));
                    }
                });
            },
            minLength: 2,
            select: function( event, ui ) {
                log( ui.item ?
                    "Selected: " + ui.item.label :
                    "Nothing selected, input was " + this.value);
            },
            open: function() {
                $( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
            },
            close: function() {
                $( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
            }
        });
    

    我的EmployeeController中有一个名为show_depatment()

    的动作
        public function getAddress() {
            $this->autoRender = false;// I do not want to make view against this  action. 
            $this->log($this->params->query['name_startsWith'] , 'debug');
            $str = $this->params->query['name_startsWith'];
            $this->log($str, 'debug');
            $this->layout = 'ajax';
            $departments = $this->Employee->Department->find('all', array( 'recursive' => -1,
                'conditions'=>array('Department.name LIKE'=>$str.'%'),
       'fields'=>array('name', 'id')));
            //$this->set('departments',$departments);
            $this->log($departments, 'debug');
            echo json_encode($departments);
    }
    

    我不希望show_department操作有任何视图,所以我做了 $ this-> autoRender = false;

    但它没有按预期工作。

    当我使用firebug响应和HTLM部分调试响应时显示

               [{"Department":{"name":"Accounting","id":"4"}}] // when i type "acc" in input field
    

    问题

    1. 如何使其在表单字段中显示。
    2. echo json_encode($ departments);是以json格式发送响应的正确方法吗?
    3. 当我在ajax呼叫的成功部分发出警报时(警报(项目);)它将错误视为“未定义”

1 个答案:

答案 0 :(得分:2)

我是胖模型和瘦控制器的朋友所以我的控制器动作看起来像这样

public function getAddress()
{
    if($this->RequestHandler->isAjax()) {
        Configure::write('debug', 0);
        $this->layout = 'ajax';
        $this->autoRender = false;
        echo json_encode($this->Employee->Department->getAddress($this->params['url']['term']));
        exit;
    }
}

和我的部门模型方法:

public function getAddress($str)
{

    $rs = array();
    $search =  $this->find('all', array( 
        'recursive' => -1,
        'conditions'=>array('Department.name LIKE'=>$str.'%'),
        'fields'=>array('name', 'id')
    ));


    if (!empty($search))
    {
        //the jquery ui autocomplete requires object with label/value  so we need to traverse the query results and create required array 

        foreach ($search as $key => $val)
        {
            $rs[] = array('label' => $val['Department']['name'], 
              'value' => $val['Department']['id']);
        }
    }
    return $rs;
}

最后我的观点是这样的:

$( "#auto_complete" ).autocomplete({
    minLength: 2,
    source: function( request, response ) {
        var term = request.term;
        if ( term in cache ) {
            response( cache[ term ] );
            return;
        }

        lastXhr = $.getJSON( "/employees/showDepartment", request, function( data, status, xhr ) {
            cache[ term ] = data;
            if ( xhr === lastXhr ) {
                response( data );
            }
        });
    }
});

希望这会有所帮助。