2016-12-31 33 views
1

我正在使用神奇的鳳凰網框架,並試圖找出如何爲陣列字段模型創建表單字段。陣列模型數據類型鳳凰表格字段

這裏是從模型的實例字段: field :grateful, {:array, :string}

我已經試過產生這樣的字段:

<%= inputs_for f, :grateful, fn fp -> %> <%= text_input fp, :grateful %> <% end %>

但我得到這個錯誤:無法生成輸入,用於:感謝來自Motivation.DailyPost。檢查現場存在的,它是embeds_one,embeds_many,HAS_ONE,的has_many之一,belongs_to的或MANY_TO_MANY

如果我生成這樣的領域:<%= text_input fp, :grateful %>它生成與名稱的表單字段:daily_post[grateful]這實際上是行不通的。我需要daily_post[grateful][]

下面的代碼工作,但保存後加載數據不起作用。所有數組值都合併到一個輸入字段中。

<div class="form-group" id="grateful-group"> <%= label f, :grateful, class: "control-label" %> <%= text_input f, :grateful, name: "daily_post[grateful][]" %> <%= error_tag f, :grateful %> <input type="button" class="btn btn-success" id="add-grateful" value="add" /> <script> window.onload =() => { $('#add-grateful').click((e) => { $('<input type="text" name="daily_post[grateful][]" />').appendTo("#grateful-group"); }) } </script> </div>

我如何正確地在鳳凰數組類型的工作?

謝謝!

回答

3

好吧,我想我現在明白了。這是我做過什麼:

defmodule Motivation.InputHelpers do 
    use Phoenix.HTML 

    def array_input(form, field, attr \\ []) do 
    values = Phoenix.HTML.Form.input_value(form, field) || [""] 
    id = Phoenix.HTML.Form.input_id(form,field) 
    content_tag :ul, id: container_id(id), data: [index: Enum.count(values) ] do 
     values 
     |> Enum.with_index() 
     |> Enum.map(fn {k, v} -> 
     form_elements(form, field, k, v) 
     end) 
    end 
    end 

    def array_add_button(form, field) do 
    id = Phoenix.HTML.Form.input_id(form,field) 
    # {:safe, content} 
    content = form_elements(form,field,"","__name__") 
     |> safe_to_string 
     # |> html_escape 
    data = [ 
     prototype: content, 
     container: container_id(id) 
    ]; 
    link("Add", to: "#",data: data, class: "add-form-field") 
    end 

    defp form_elements(form, field, k ,v) do 
    type = Phoenix.HTML.Form.input_type(form, field) 
    id = Phoenix.HTML.Form.input_id(form,field) 
    new_id = id <> "_#{v}" 
    input_opts = [ 
     name: new_field_name(form,field), 
     value: k, 
     id: new_id 
    ] 
    content_tag :li do 
     [ 
     apply(Phoenix.HTML.Form, type, [form, field, input_opts]), 
     link("Remove", to: "#", data: [id: new_id], class: "remove-form-field") 
     ] 
    end 
    end 

    defp container_id(id), do: id <> "_container" 

    defp new_field_name(form, field) do 
    Phoenix.HTML.Form.input_name(form, field) <> "[]" 
    end 

end 

我將該文件導入我的web.ex,那麼我可以打印這樣的數組字段:

<%= array_input f, :grateful %>

我還可以打印添加按鈕的這樣的領域:

<%= array_add_button f, :grateful %>

,可方便添加&刪除字段我寫了這個Java類cript:

window.onload =() => { 
    const removeElement = ({target}) => { 
    let el = document.getElementById(target.dataset.id); 
    let li = el.parentNode; 
    li.parentNode.removeChild(li); 
    } 
    Array.from(document.querySelectorAll(".remove-form-field")) 
    .forEach(el => { 
     el.onclick = (e) => { 
     removeElement(e); 
     } 
    }); 
    Array.from(document.querySelectorAll(".add-form-field")) 
    .forEach(el => { 
     el.onclick = ({target}) => { 
     let container = document.getElementById(target.dataset.container); 
     let index = container.dataset.index; 
     let newRow = target.dataset.prototype; 
     container.insertAdjacentHTML('beforeend', newRow.replace(/__name__/g, index)); 
     container.dataset.index = parseInt(container.dataset.index) + 1; 
     container.querySelectorAll('a.remove-form-field').forEach(el => { 
      el.onclick = (e) => { 
      removeElement(e); 
      } 
     }) 
     } 
    }); 
}