2016-12-09 109 views
0

我有一個Redux形式,它應該像它一樣工作,除了一件事:我需要創建一個複選框數組,以便用戶可以在多個選項之間進行選擇。複數形式的複選框

在HTML/PHP一個會寫類似的東西:

<form> 
    … 
    <input type="checkbox" name="item[]" value="120" /> 
    <input type="checkbox" name="item[]" value="231" /> 
    … 
</form> 

所以上了Serverside(檢查假定每個盒)一個將接收像這樣的數組:$item = [120, 231],其中所述陣列中的每個項目對應於該複選框的值。

做同樣的一個終極版形式像這樣:

let items = [{name:…, value:…}, …]; 

<form> 
    {items.map(item => { 
    <Field component="input" 
      type="checkbox" 
      name={item.name + '[]'} 
      value={item.value} 
    })} 
</form> 

導致這些輸入:<input type="checkbox" name="item[]" value="true" />,究竟是不是我所期待的。另外,選中複選框,檢查每個數組。

所以我改變了<Field />的name屬性

name={`item[${item.value}]`} 

什麼使複選框按預期,但反過來導致數據提交時:

{ 
      //index: 0, 1,  ,…, 120, 121, … ,231, …      
    item: [undefinded,undefined,…,true,undefined,…,true,undefined,…] 
} 

所以我的問題是:我是否在創建複選框時出錯,尤其是它們的名稱,或者是否需要在初始化時和第二次提交時轉換數據?

如果我必須轉換數據,那麼最好的地方在哪?

+0

刪除值屬性。 –

回答

0

您可以如下所示渲染複選框/項目的數組,並使用onChange事件跟蹤選中的複選框。例如,在狀態上使用selectedItems陣列,並在onItemChange實施上添加/刪除項目。在表單提交處理程序上,您將擁有該狀態下所有可用的檢查項目。

{ 
    items.map((item, index) => { 
    return (
     <div className="checkbox" key={ index }> 
     <label> 
      <input type="checkbox" 
      onChange={ this.onItemChange.bind(this, index) } /> 
      { item.name } 
     </label> 
     </div> 
    ); 
    }) 
} 
+0

在渲染函數中綁定是一個不好的習慣。在構造函數中做。 – Anarion

+0

@Anarion這通常是正確的,但是在這種情況下,他通過一系列項目進行映射並將onItemChange綁定到索引以消耗輸入值。這是一種常見的模式。 – Splitty

+0

@Splitty不是我所建議的嗎? – Anarion

3

這是我落得這樣做:

<Field component="input" 
     type="checkbox" 
     name={`item.${item.value}`} /> 

這給你一個對象(而不是數組)作爲輸出數據結構。這不是你所要求的,但它很方便(和IMO相比,需要刪除值時需要搜索數組的其他選項更自然)。相反,越來越[120, 231]的你

{ 
    120: true, 
    231: true, 
    165: false // be aware that things that have been checked, and then unchecked, will be explicitly marked false 
} 

如果你想用truthy值找到鑰匙將其轉換爲一個數組,這是一個簡單的事onSubmit()。我正在使用lodash:_.keys(_.pickBy(itemValue))很好地完成了轉換。

+0

聽起來像個好主意!將在幾天內檢查出來...... – philipp