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

时间:2015-04-20 10:11:49

标签: php ajax yii combobox yii-extensions

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

查看

<?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 组合框中的值时,会发生奇怪的事情。创建了一个新的组合框,但显示的值仍然来自生成的第一个组合框。 我收到错误&#34; TypeError:this.input未定义&#34;在Firebug控制台中。

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

如果我改变

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

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

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

有任何想法/建议使这项工作?

1 个答案:

答案 0 :(得分:0)

我找到了解决这个问题的方法。不是动态创建组合框,而是将组合框放置一次,然后在每次请求时动态填充组合框。很像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);
            }
        }
    }