尝试使用 ajax 在 yii 中创建依赖组合框

Trying to create a dependent combobox in yii using ajax

我正在尝试在我的 Yii 应用程序中创建一个依赖组合框系统。 第一个组合框填充状态,第二个组合框使用 ajaxrenderPartial() 方法动态生成。
代码如下:

查看

<?php
$this->widget('ext.combobox.EJuiComboBox', array(
    'model' => $adMulti,
    'attribute' => 'state_id',
    // data to populate the select. Must be an array.
    'data' => CHtml::listData(State::model()->findAll(), 'id', 'name'),
    'assoc' => true,
    // options passed to plugin
    'options' => array(
        // JS code to execute on 'select' event, the selected item is
        // available through the 'item' variable.
        'onSelect' => 'getCities(item.value);',
        // If false, field value must be present in the select.
        // Defaults to true.
        'allowText' => false,
    ),
    // Options passed to the text input
    'htmlOptions' => array(
        'style' => 'height: 36px',
    ),
));
?>
<script type="text/javascript">
  function getCities(state) {
      $.ajax({
          url: '<?php echo $this->createUrl('ad/ajaxCities'); ?>',
          data: {state_name: state},
          type: 'POST',
          success: function (data) {
              $('#city_id-carrier').html(data);
          }
      });
  }
</script>
<div id="city_id-carrier" class="textboxes"></div>

AdController

public function actionAjaxCities()
    {
        $stateName = isset($_POST['state_name']) ? $_POST['state_name'] : FALSE;
        if ($stateName) {
            $state = State::model()->findByAttributes(array(
                'name' => $stateName
            ));
            $stateId = $state->id;
            $cities = City::model()->findAllByAttributes(array(
               'state_id' => $stateId
            ));
            $this->renderPartial('_cities', array(
                'cities' => $cities,
                'stateId' => $stateId
                ), FALSE, TRUE
            );
        }
    }

_cities.php

<?php
$this->widget('ext.combobox.EJuiComboBox', array(
    'model' => AdMulti::model(),
    'attribute' => 'city_id',
    // data to populate the select. Must be an array.
    'data' => CHtml::listData($cities, 'id', 'name'),
    'assoc' => true,
    // options passed to plugin
    'options' => array(
        // JS code to execute on 'select' event, the selected item is
        // available through the 'item' variable.
        // 'onSelect' => 'getLocalities(item.value);',
        // If false, field value must be present in the select.
        // Defaults to true.
        'allowText' => false,
    ),
));
?>

代码正在运行并首次创建组合框。但是当我更改 state 组合框中的值时,会发生一些奇怪的事情。创建了一个新的组合框,但显示的值仍然来自生成的第一个组合框。 我在 Firebug 控制台中收到错误 "TypeError: this.input is undefined"。

我尝试使用 uniqid() 为组合框创建唯一 ID,但它不会影响 select 的 ID组合框的元素。

如果我改变

$('#city_id-carrier').html(data)

$('#city_id-carrier').append(data)

它运行良好,但生成了多个组合框。

任何 ideas/suggestions 来完成这项工作?

我找到了一个解决方案来让它工作。不是动态创建组合框,而是放置组合框一次,然后根据每个请求动态填充它。很像 dependent dropdown.
组合框是下拉列表和文本框的组合。因此,记下隐藏下拉列表的 ID 并在 ajax 更新时更新它。

代码:

查看:

<?php
    $this->widget('ext.combobox.EJuiComboBox', array(
        'model' => $adMulti,
        'attribute' => 'state_id',
        // data to populate the select. Must be an array.
        'data' => CHtml::listData(State::model()->findAll(), 'id', 'name'),
        'assoc' => true,
        // options passed to plugin
        'options' => array(
            // JS code to execute on 'select' event, the selected item is
            // available through the 'item' variable.
            'onSelect' => 'getCities(item.value);',
            // If false, field value must be present in the select.
            // Defaults to true.
            'allowText' => false,
        ),
    ));
    ?>
<script type="text/javascript">
      function getCities(state) {
          $.ajax({
              url: '<?php echo $this->createUrl('ad/ajaxCities'); ?>',
              data: {state_id: state},
              type: 'POST',
              beforeSend: function() {
                  $('#AdMulti_city_id_combobox').val(''); // emptying textbox in case a value is previously selected.
              },
              success: function (data) {
                  $('#AdMulti_city_id').html(data); // populating the hidden dropdown.
              }
          });
      }
  </script>
<?php
$this->widget('ext.combobox.EJuiComboBox', array(
    'model' => $adMulti,
    'attribute' => 'city_id',
    // data to populate the select. Must be an array.
    'data' => CHtml::listData(array(''), 'id', 'name'),
    'assoc' => true,
    // options passed to plugin
    'options' => array(
        'allowText' => false,
    ),
));
?>

AdController

    public function actionAjaxCities()
    {
        $stateName = isset($_POST['state_id']) ? $_POST['state_id'] : FALSE;
        if ($stateName) {
            $state = State::model()->findByAttributes(array(
                'name' => $stateName
            ));
            $cities = City::model()->findAllByAttributes(array(
               'state_id' => $state->id
            ));
            $data = CHtml::listData($cities, 'id', 'name');
            foreach ($data as $id => $name) {
                echo CHtml::tag('option', array('value' => $id),
                    CHtml::encode($name), TRUE);
            }
        }
    }