C自动完成如何设置回叫功能? YII

时间:2013-10-02 13:09:36

标签: php jquery yii

您好我正在使用SAutoComplete(扩展CAutoComplete),并且需要在从列表中选择值时进行一些工作。

我正在使用它。

this->widget('application.components.SAutoComplete', array('width'=>200,
            'model'=>$cssAtapsClient, 'parseData'=>true, 'matchContains'=>true,
            'attribute'=>'suburb_id', 'data'=>$postCode, 'ddindicator'=>true,
            'max'=>50,
            'multipleSeparator'=>false,
            'options' => array(
            'select' => new CJavaScriptExpression('function(e, ui) { alert("hi"); }')
             ),
          )); ?>

我想知道为什么没有像jquery UI自动完成中可用的选项?

选择的示例如下。

$("#auto_cp").autocomplete({
    minLength: 3,
    //source
    source: function(req, add) {
        $.getJSON("friends.php?callback=?", req, function(data) {
            var suggestions = [];
            $.each(data, function(i, val) {
                suggestions.push({
                    label: val.name,
                    zzz: val.zzz
                });
            });
            add(suggestions);
        });
    },
    //select
    select: function(e, ui) {
        alert(ui.item.zzz);
    }
});​

编辑2

http://www.yiiframework.com/doc/api/1.1/CAutoComplete

代码是这样的,

<?php

class SAutoComplete extends CAutoComplete
{
   public $ddindicator;
   /**
    *
    * @var boolean whether to parse the data assumes data uses an assoc array
    *  array(value => array(name, value, ...), ...). Only works with a model present
    */
   public $parseData;
   /**
    * @var boolean whether to raise the change event
    */
   public $raiseChangeEvent = false;
   /**
    * Initializes the widget.
    * This method registers all needed client scripts and renders
    * the autocomplete input.
    */
   public function init()
   {
      if ( !$this->max )
         $this->max = 50000;

      if ( $this->ddindicator )
         $this->alternateInit();
      else
         parent::init();
   }

   public function alternateInit()
   {
      list($name,$id)=$this->resolveNameID();
      $this->htmlOptions['id'] = $id.'_input';
      $this->minChars = 0;

      echo CHtml::openTag('div', array('class'=>'ac-input-dd'));
      echo CHtml::openTag('div', array('class'=>'ac-input-btn'));
      echo CHtml::closeTag('div');

      if($this->hasModel())
      {
         $htmlOpt = array();

         if ( $this->parseData )
         {
            $menu = $this->data;
            $key = $this->attribute;

            //Change if attribute is apart of a array. eg attribute[0]
            $pos1 = stripos($key, '[');
            $pos2 = stripos($key, ']');
            if($pos1!==false && $pos2!==false)
            {
               $key = str_replace (substr($key,$pos1,$pos2 - $pos1 + 1),'',$key);
               $htmlOpt['value'] = isset($this->model->$key) ? $this->model->$key : '';
            }

            $this->value = isset($menu[$this->model->$key][0]) ? $menu[$this->model->$key][0] : '';
            $this->data = is_array($menu) ? array_values($menu) : array('Error in data.');
         }

         echo CHtml::activeHiddenField($this->model, $this->attribute, array_merge(array('id'=>$id, 'name'=>$name), $htmlOpt));
         echo CHtml::textField('', $this->value, $this->htmlOptions);
      }
      else
      {
         echo CHtml::hiddenField($name, $this->value, array('id'=>$id));
         echo CHtml::textField($name.'_input',$this->value,$this->htmlOptions);
      }
      echo CHtml::closeTag('div');

      $this->methodChain = $this->methodChain.'.result(function(evt, data, formatted) { $("#'.
              $id.'").val(data ? data[1] : "")'.($this->raiseChangeEvent?'.change()':'').'; })'.
              '.parent().find(".ac-input-btn").mousedown(function(){'.
              'jQuery(this).parent().find(".ac_input").toggleResults();})'.
              '.mouseup(function(){jQuery(this).parent().find(".ac_input").focus();});';

      $this->registerClientScript();
   }

   public static function registerScript()
   {
      $cs = Yii::app()->getClientScript();
      $cs->registerCoreScript('jquery');
      $cs->registerCoreScript('bgiframe');
        TK::registerScriptFile('autocomplete');
      $cs->registerCssFile($cs->getCoreScriptUrl().'/autocomplete/jquery.autocomplete.css');
   }

   /**
    * Registers the needed CSS and JavaScript.
    * @since 1.0.1
    */
   public function registerClientScript()
   {
      // can cut this down once YII releases a fix for defect #38
      if ( Yii::app()->request->isAjaxRequest || $this->ddindicator )
      {
         $id=$this->htmlOptions['id'];

         $acOptions=$this->getClientOptions();
         $options=$acOptions===array()?'{}' : CJavaScript::encode($acOptions);

         $cs=Yii::app()->getClientScript();

         if($this->data!==null)
            $data=CJavaScript::encode($this->data);
         else
         {
            $url=CHtml::normalizeUrl($this->url);
            $data='"'.$url.'"';
         }

         if ( Yii::app()->request->isAjaxRequest )
         {
            echo '<script type="text/javascript">jQuery(document).ready('.
                    'function() {jQuery("#'.$id.'").autocomplete('.$data.','.$options.')'.
                    $this->methodChain.';});</script>';
         }
         else
         {
            SAutoComplete::registerScript();
            $cs->registerScript('Yii.CAutoComplete#'.$id,"jQuery(\"#{$id}\").autocomplete($data,{$options}){$this->methodChain};");
         }
      }
      else
         parent::registerClientScript();
   }
}

3 个答案:

答案 0 :(得分:3)

您可以通过包含options数组来传递JUI自动完成小部件支持的任何选项:

$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
    // your other settings here
    'options' => array(
        'select' => new CJavaScriptExpression('function(e, ui) { alert("hi"); }')
    ),
));

如果您要传递的选项包含JavaScript代码,那么您还必须将其包含在CJavaScriptExpression内,如上所述。

答案 1 :(得分:0)

尝试添加此内容,

'methodChain'=>".result(function(event,item){ urFunction(); })",

度过美好的一天!

所以最后看起来会像,

$this->widget('application.components.SAutoComplete', array('width'=>200,
            'model'=>$cssAtapsClient, 'parseData'=>true, 'matchContains'=>true,
            'attribute'=>'suburb_id', 'data'=>$postCode, 'ddindicator'=>true,
            'max'=>50,
            'methodChain'=>".result(function(event,item){ urFucntion(); })",
         ));

答案 2 :(得分:0)

我正在使用CAutoComplete作为以下代码:

在帖子/ _form.php

<?php $this->widget('CAutoComplete', array(
    'model' => $model,
    'attribute' => 'tags',
    'url' => array('suggestTags'),
    'multiple' => true,
    'htmlOptions' => array(
        'size' => 50,
        'class' => 'span11'
    ),
)); ?>

在PostController.php 中 再添加一个操作电话:suggestTags

/**
 * Suggests tags based on the current user input.
 * This is called via AJAX when the user is entering the tags input.
 */
public function actionSuggestTags()
{
    if(isset($_GET['q']) && ($keyword=trim($_GET['q']))!=='')
    {
        $tags=Tag::model()->suggestTags($keyword);
        if($tags!==array())
            echo implode("\n",$tags);
    }
}

在Post.php模型中

private $_oldTags;添加到类的顶部(在类名下)。

添加以下功能:

/**
 * Normalizes the user-entered tags.
 */
public function normalizeTags($attribute, $params)
{
    $this->tags = Post::array2string(array_unique(Post::string2array($this->tags)));
}

public static function string2array($tags)
{
    return preg_split('/\s*,\s*/', trim($tags), -1, PREG_SPLIT_NO_EMPTY);
}

public static function array2string($tags)
{
    return implode(', ', $tags);
}

查看更多Yii tutorials here