【问题标题】:Multiple Yii EJuiAutoCompleteFkField widgets on a single page: How to assign unique DOM ids to each?单个页面上的多个 Yii EJuiAutoCompleteFkField 小部件:如何为每个小部件分配唯一的 DOM id?
【发布时间】:2012-09-20 17:37:36
【问题描述】:

我正在尝试在单个视图中使用多个 EJuiAutoCompleteFkField 小部件(实际上是视图中的一些 ajax 加载的 div)。有谁知道给 juiautocomplete 小部件一个唯一的 DOM ID 以便它们都可以单独运行的方法?

目前只有第一个有效,因为它不是唯一的。

我希望下面的 'htmloptions' 之类的东西来设置 id,就像你在其他 Yii 小部件中找到的那样

<?php 
 $this->widget('EJuiAutoCompleteFkField', array(
  'model'=>$smpNull, 
  'attribute'=>'cancer_id', //the FK field (from CJuiInputWidget)
  'sourceUrl'=>Yii::app()->createUrl('/samples/cancerAutoComplete'), 
  'showFKField'=>false,
  'FKFieldSize'=>10, 
  'relName'=>'cancer', // the relation name defined above
  'displayAttr'=>'CancerName',  // attribute or pseudo-attribute to display
  'autoCompleteLength'=>50,
  'options'=>array(
    'minLength'=>3,
   ),
  'htmlOptions'=>array(
   'id'=>'Events_cancer_id',
  ),
 ));
?>

谢谢!

【问题讨论】:

  • 之前没有使用过 EJuiAutoCompleteFkField,但是您是否尝试过将 id 添加到 'options' 参数中?
  • 实际上,快速查看源代码(非常快速,如果您已经尝试过,非常抱歉!),如果您查看 v1 的第 197 和 199 行,它看起来确实使用了 htmlOptions .5 它正在设置 htmlOptions,所以您可以添加另一个自定义参数并配置 init() 方法来满足这些选项?
  • Stu,我确实在选项参数中尝试过,但会查看您建议的代码。我想我会先四处打听。谢谢:)

标签: jquery autocomplete yii


【解决方案1】:

以下是我修改扩展以在每页启用多个字段的方法:

新的 EJuiAutoCompleteFkField.php

<?php
/* 
 * EJuiAutoCompleteFkField class file
 *
 * @author Jeremy Dunn <jeremy.j.dunn@gmail.com>
 * @link http://www.yiiframework.com/
 * @version 1.5
 */

Yii::import('zii.widgets.jui.CJuiAutoComplete');
class EJuiAutoCompleteFkField extends CJuiAutoComplete {

    /**
     * @var boolean whether to show the FK field.
     */
    public $showFKField = false;

    /**
     * @var integer length of the FK field if visible
     */
    public $FKFieldSize = 10;
    /**
     * @var string the relation name to the FK table
     */
    public $relName;
    /**
     * @var string the relation name to the FK table
     */
    public $idSuffix;
    /**
     * @var string extension to append to id fields for uniqneness
     */
    public $displayAttr;

    /**
     * @var integer width of the AutoComplete field
     */
    public $autoCompleteLength = 50;

    /**
     * @var string the ID of the FK field
     */
    private $_fieldID;

    /**
     * @var string the ID of the hidden field to save the display value
     */
    private $_saveID;

    /**
     * @var string the ID of the AutoComplete field
     */
    private $_lookupID;

    /**
     * @var string the ID for the hidden field
     */
    private $_hiddenID;

    /**
     * @var string the initial display value
     */
    private $_display;
    /**
     * @var string name of the lookup field
     */
    private $_name;

    public function init() {
        parent::init(); // ensure necessary assets are loaded

        // JJD 8/3/11 make EJuiAutoCompleteFkField work for child rows where attribute like [$i]FieldName
        // get the ID which will be created for the actual field when it is rendered.
        // don't let resolveNameID() change $this->attribute which is needed to generate the actual field
        $attr = $this->attribute;
        $tempHtmlOpts = array();
        CHtml::resolveNameID($this->model, $attr, $tempHtmlOpts);
        $id = $tempHtmlOpts['id'].'_'.$this->idSuffix;
        $this->_fieldID = $id;
        $this->_saveID = $id . '_save';
        $this->_lookupID = $id .'_lookup';
        $this->_hiddenID = $id .'_hidden';
        $this->_name = $tempHtmlOpts['id'].'_lookup';

        $related = $this->model->{$this->relName}; // get the related record
        $value = CHtml::resolveValue($this->model, $this->attribute);
        $this->_display=(!empty($value) ? $related->{$this->displayAttr} : '');

        if (!isset($this->options['minLength']))
            $this->options['minLength'] = 2;

        if (!isset($this->options['maxHeight']))
            $this->options['maxHeight']='100';

        $this->htmlOptions['size'] = $this->autoCompleteLength;
        // fix problem with Chrome 10 validating maxLength for the auto-complete field
        $this->htmlOptions['maxlength'] = $this->autoCompleteLength;

        // setup javascript to do the work
        $this->options['create']="js:function(event, ui){\$(this).val('".addslashes($this->_display)."');}";  // show initial display value
        // after user picks from list, save the ID in model/attr field, and Value in _save field for redisplay
        $this->options['select']="js:function(event, ui){\$('#".$this->_fieldID."').val(ui.item.id);\$('#".$this->_saveID."').val(ui.item.value);}";
        // when the autoComplete field loses focus, refresh the field with current value of _save
        // this is either the previous value if user didn't pick anything; or the new value if they did
        // $this->htmlOptions['onblur']="$(this).val($('#".$this->_saveID."').val());";
    }

    public function run() {
        // first render the FK field.  This is the actual data field, populated by autocomplete.select()
        if ($this->showFKField) {
            echo CHtml::activeTextField($this->model, $this->attribute, array('size'=>$this->FKFieldSize, 'readonly'=>'readonly'));
        } else {
            echo CHtml::activeHiddenField($this->model,$this->attribute, array('id'=>$this->_hiddenID));
        }

        // second, the hidden field used to refresh the display value
        echo CHtml::hiddenField($this->_saveID,$this->_display, array('id'=>$this->_saveID)); 

        // third, the autoComplete field itself
        $this->htmlOptions['id'] = $this->_lookupID;
        $this->htmlOptions['name'] = $this->_name;       
        parent::run();

        // fouth, an image button to empty all three fields
        /*
        $label=Yii::t('DR','Remove '). ucfirst($this->relName); // TODO: how to translate relname?
        $deleteImageURL = '/images/text_field_remove.png'; 
        echo CHtml::image($deleteImageURL, $label,
            array('title'=>$label,
                'name' => 'remove'.$this->_fieldID,
                'style'=>'margin-left:6px;',
                // JJD 4/27/12 #1350 trigger onchange event for display field, in case there's an event attached (e.g. unsaved-changes-warning)
                'onclick'=>"$('#".$this->_fieldID."').val('').trigger('change');$('#".$this->_saveID."').val('');$('#".$this->_lookupID."').val('');",
            )
        );
         * 
         */
    }
}
?>

以及视图中的用法:

<?php 
$this->widget('EJuiAutoCompleteFkField', array(
'model'=>$smpCancerDefault, 
'attribute'=>'cancer_id', //the FK field (from CJuiInputWidget)
'sourceUrl'=>Yii::app()->createUrl('/samples/cancerAutoComplete'), 
'showFKField'=>false,
'FKFieldSize'=>10, 
'relName'=>'cancer', // the relation name defined above
'displayAttr'=>'CancerName',  // attribute or pseudo-attribute to display
'autoCompleteLength'=>50,
'idSuffix'=>"myUniqueSuffix", // added this var to allow for unique field ids
'options'=>array(
'minLength'=>3,
 ),
));
?>

【讨论】:

  • 当使用最新的可用扩展“EJuiAutoCompleteFkField”时,我可以毫无问题地使用小部件,但是当我实施此解决方案以在单个页面上使用多个小部件时,我无法检索 FK 密钥。有任何想法吗?我使用的代码与此处发布的完全相同。
  • @WebDevPT 这可能是版本问题。我正在使用 1.5
猜你喜欢
  • 1970-01-01
  • 2020-07-16
  • 1970-01-01
  • 2015-02-28
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
相关资源
最近更新 更多