2015-09-23 116 views
2

我有我的ProductsForm.php:ZF2 - 填充選擇與阿賈克斯

 

    namespace Products\Form; 

    use Zend\Form\Form; 
    use Zend\Db\Adapter\AdapterInterface; 
    use Zend\Db\TableGateway\TableGateway; 
    use Zend\Db\Sql\Select; 

    class ProductsForm extends Form { 

     public function __construct(AdapterInterface $dbAdapter) { 

      $this->adapter = $dbAdapter; 

      parent::__construct('products'); 

      $this->add(array(
       'name' => 'state', 
       'type' => 'select', 
       'attributes' => array(
        'class' => 'form-control', 
       ), 
       'options' => array(
        'empty_option' => 'Select...', 
        'value_options' => $this->getStatesForSelect() 
       ), 
      )); 

      $this->add(array(
       'name' => 'city', 
       'type' => 'select', 
       'attributes' => array(
        'class' => 'form-control', 
       ), 
       'options' => array(
        'empty_option' => 'Select...', 
        'value_options' => $this->getCitiesForSelect() 
       ), 
      )); 

     } 

     public function getStatesForSelect() { 
      $dbAdapter = $this->adapter; 

      $table = new TableGateway('states', $dbAdapter); 
      $result = $table->select(function (Select $select) { 
       $select->order('name DESC'); 
      }); 

      foreach ($result as $res) { 
       $selectData[$res['id']] = $res['name']; 
      } 
      return $selectData; 
     } 

     public function getCitiesForSelect($state_id) { 
      ??? :(
      select from cities where state_id = $state_id ? 
     } 

    } 

我想執行getCitiesForSelect()僅當用戶選擇「狀態」 ......然後用值填充從數據庫基於state.id值

我該怎麼做?

回答

4

首先,不要將方法getStatesForSelectgetCitiesForSelect放在您的表單中。表單是控制器層的一部分,每個數據庫請求屬於模型層: http://framework.zend.com/manual/current/en/modules/zend.mvc.intro.html

第二:如果你這樣做,你可以創建一個動作將返回一個JSON與被請求國,並通過AJAX調用它。要正確和美觀加載的一切,你將不得不作出一些改變你的形式和:

$this->add(array(
    'name' => 'state', 
    'type' => 'select', 
    'attributes' => array(
     'class' => 'form-control', 
     'id' => 'select-state', 
    ), 
    'options' => array(
     'class' => 'state-option', 
     'empty_option' => 'Select...', 
    ), 
)); 

$this->add(array(
    'name' => 'city', 
    'type' => 'select', 
    'attributes' => array(
     'class' => 'form-control', 
     'id' => 'select-city', 
     'style' => 'display:none', 
    ), 
    'options' => array(
     'empty_option' => 'Select...', 
    ), 
)); 

我刪除從數據庫中獲取你的選擇的方法,因爲如上所述,這應該是工作的模型表。您在控制器中設置這些選項NandaKumar已經寫:

$states = $modelTable->getStatesForSelect(); 
$form->get('state')->setValueOptions($states); 

但這隻會填補了美國,我們需要一些東西來填補城市以及! if語句是確保

public function stateCitiesAction() 
{ 
    if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) 
     && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { 
     $stateId = $this->params()->fromRoute("id"); 
     // get your cities table 
     // getCitiesForSelect() needs to return an array! 
     $cities = $citiesTable->getCitiesForSelect(); 
     return new JsonModel($cities); 
    } else { 
     // return a 404 if this action is not called via ajax 
     $this->getResponse()->setStatusCode(404); 
     return NULL; 
    } 
} 

的,這個動作只能通過AJAX訪問:要做到這一點,我們將定義一個ajax行動得到這些。如果不是,它將返回一個404.

我只是假設在這個例子中,模型動作將返回與您的方法相同的數組。儘管您可能會爭論哪個級別應該轉換數據庫結果,模型本身或控制器。但爲了保持簡單的例子,我這​​樣做了。

要正確解析JsonModel,需要在您的module.config.php中包含ViewJsonStrategy。否則,你會得到一個錯誤,因爲Zend會嘗試查找視圖腳本。

'view_manager' => array(
    //... 
    'strategies' => array(
     'ViewJsonStrategy', 
    ), 
), 

另外,我們還需要傳遞id。路由參數是最常用的方法,我們需要在我們的路由定義中包含這個參數。此代碼是不是一個最終的解決方案,應該只告訴你,你怎麼會在你的配置做到這一點:

'poducts' => array(
    'type' => 'Segment', 
    'options' => array(
     'route'  => '/products/[:controller][/:action][/:id]', 
     'constraints' => array(
      'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 
      'action'  => '[a-zA-Z][a-zA-Z0-9_-]*', 
      'id'   => '[0-9]*', 
     ), 
     'defaults' => array(
      '__NAMESPACE__' => 'Application\Controller', 
      'controller' => 'Index', 
      'action'  => 'index', 
     ), 
    ), 
), 

有關路由詳細信息請參閱: http://framework.zend.com/manual/current/en/modules/zend.mvc.routing.html

唷,我們幾乎完成了!唯一剩下的就是填充城市選項的ajax調用。我通過jQuery做到這一點:

$(document).ready(function() { 

    $("#select-state").change(function() { 
     var stateId = $(this).val(); 
     if(stateId !== "") { 
      // you might want to change this 
      var url = "products/index/state-cities/"+stateId; 
      $.getJSON(url, function(data) { 
       var options = ""; 
       $.each(data, function(id, city) { 
        options += "<option value='" + id + "'>" + city + "</option>"; 
       }); 
       $("#select-city").html(options).fadeIn(); 
      }); 
     } 
    }); 

}); 

不是我不知道你的路由,你可能需要更改網址。