2009-12-22 24 views
1

我想用Zend_Form(Zend_Framework組件)創建一個表單。用戶應該能夠添加任意數量的字段。就像你可以用gmail GUI上傳文件一樣。 例子:Zend_Form任意數量的鍵值對字段

[_____] [+] 

點擊[+]按鈕後:

[_____] 
[_____] [+] 

把事情複雜化,我想補充場,所以它看起來像這樣:

[_____] [_____] 
[_____] [_____] [+] 

如何在實現此功能時保持簡單的內置驗證和分配方法的可用性?我需要一個子表單嗎?我需要別的東西嗎?提交表單後,代碼應該能夠將字段映射到和數組中。

恐怕我必須繼承Zend_Form或SubForm,但我想知道最簡單/最漂亮的方法。

回答

0

這是我自己的解決方案: 我創建了兩個隱藏字段,一個用於鍵,一個用於值。一段javascript代碼在deamand和onChange上創建了假字段對,它使用JSON將所有假域映射到隱藏域。 在服務器端很容易處理,但使用的javascript技術不是離散的。

0

這裏是如何添加十個輸入字段,每個都具有Alpha驗證:

$sub_test = new Zend_Form_SubForm(); 
$num_fields = 10; 
for ($i = 0; $i < $num_fields; $i++) { 
    $element = $form->createElement('text', strval($i)); 
    $element->addValidator('Alpha'); // just to see in action 
    $sub_test->addElement($element); 
} 
$form->addSubForm($sub_test, 'test'); // values mapped to $_POST['test'][0..9] 

要確定有多少個創建/節目,更多的工作是你的一部分必要的,當然,但它看起來非常簡單。

  1. 看$ _POST ['test']查看有多少值被填入 - 總是包含這些值。
  2. 看看另一個隱藏的變量,知道要顯示多少個總字段 - 即使是那些空的。
1

在這裏採取的最簡單的方法是使用一個簡單的自定義Zend的驗證,這將解析輸入元素作爲整個數組PHP把它看成這樣你就能夠自動執行以下。

  1. 獨立驗證每個輸入元素並顯示與每個元素關聯的錯誤消息。
  2. 返回一個可解析數組來重建剛剛提交的表單。

對於使用此來解析與可能的數組作爲一個值的輸入和驗證的每個元素和再生的確切形式提交,用相同的任意字段中Zend_Validator

class Validate_InputArray extends Zend_Validate_Abstract 
{ 
const INVALID = 'invalid'; 
const ERROR = 'error'; 

/** 
    * Failed array elements used to regenerate same elements 
    * on next form build 
    * 
    */ 
protected $_elements = array(); 

    protected $_messageTemplates = array(
     self::INVALID => "Could not locate post element %value%", 
    self::ERROR => "YOUR ERROR MESSAGE|%value% is required" 
    ); 

    public function __construct() 
    {} 

    public function isValid($element) 
    { 
     if (!$_POST[$element]) { 
    $this->_error(self::INVALID); 
    return false; 
    } 

    $elements = array(); 

    if (is_array($_POST[$element])) { 

    $fail = false; 

    foreach ($_POST[$element] as $k => $v) { 
    if (!$this->_validateElement($v)) { 
    $this->_error(self::ERROR); 
    $elements[$k] = self::ERROR; 
    } 
    } 

    $this->_setElements($elements); 

    if ($fail) { 
    return false; 
    } 

    } else { 
    if (!$this->_validateElement($_POST[$element])) { 

    $this->_error(self::ERROR); 
    $elements[0] = self::ERROR; 

    $this->_setElements($elements); 

    return false; 
    } 
    } 
    } 

protected function _setElements($elements) 
{ 
    $this->_elements = $elements; 
    return $this; 
} 

public function getElements() 
{ 
    return $this->_elements; 
} 

private function _validateElement($value) 
{ 
    // do your validation here 
    // return true/false 
} 
} 

現在的代碼。

$fail = false; 

if ($this->getRequest()->isPost()) { 

require 'Validate_InputArray.php'; 

$validator = new Validate_InputArray(); 
$elements = array(); 

if (!$validator->isValid($validator)) { 

    $fail = true; 

    foreach ($validator->getElements() as $k => $v) { 
    $elements[$k] = $v; 
    } 
} 
} 

if ($fail) { 

$messages = $validator->getMessages(); 

foreach ($elements as $k => $v) { 
    // Add custom methods here 
    $element = $form->createElement('text', 'elementName[]'); 
     $element->addErrorMessages($messages[$k]); 
} 

} else { 
$form->addElement('elementName[]'); 
} 

這將允許您驗證任意數量的任意輸入元素的需要,無需子的形式,或擔心需要,如果當一個任意元素驗證失敗並重新添加表單元素需要在客戶端進行重建。

+0

感謝您長時間的回答,我會在幾天內嘗試。 – erenon 2009-12-23 15:41:02

+0

完全沒問題,讓我知道它是怎麼回事;) – nwhiting 2009-12-23 18:30:30