Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add nested form field into current form dynamically?

I have a many to many relationship between Users and Chatgroups. Intuitively, Users can have many Chatgroups and each Chatgroup can have many users.

I've implemented this with a join table called UserChatGroup.

In my Chatgroup controller, when routed to the new function, I can hardcode the number of members in a chatgroup by specifying userChatGroups:[%UserChatGroup{},%UserChatGroup{}] etc, where the hardcoded number is the size of this array.

For example, my controller for a new chat group hardcodes 1 user:

def new(conn, _params) do
    changeset = ChatGroup.changeset(%ChatGroup{userChatGroups: [%UserChatGroup{}]})
    render(conn, "new.html", changeset: changeset)
end

and in my template for new, it references a form. The relevent section of the form is below:

 <%= inputs_for f, :userChatGroups, fn i -> %>
    <div class="form-group">
      <%= label i, :user_id, "User Id", class: "control-label" %>
      <%= number_input i, :user_id, class: "form-control" %>

    </div>
 <% end %>

However I'd like to remove this hardcoded number of members in the chat group. Instead I'd like the user to be able to add members dynamically.

I'm having trouble with this however. The rails way of doing this is to call a function that accesses the form object and updates it. Then insert input fields with javascript. On submitting, the new input fields would be fields for the new form object.

However I can't figure out how to do this with the Phoenix Framework.

My first question:

  1. How do I define functions in my view.html.eex so that they can be called on click and not simply rendered immediately? Seems like when I try using <%= functionFromMyView %> the function is rendered on initial load of my page. I want to call this function when I click an 'add' button so I need to figure out how to call this function only on click. Is that possible?

Question 2, more specific to my use case:

  1. How do I add %UserChatGroup{} dynamically to my form?

I'm assuming that once I can figure out how to call a function from my view on a click, then I can use that function to insert a %UserChatGroup{} to my form and then using javascript, insert an input field that connects to the newly inserted nested UserChatGroup field.

Any guidance would be greatly appreciated.

like image 662
Terence Chow Avatar asked Oct 06 '15 01:10

Terence Chow


1 Answers

I wasn't able to add a %UserChatGroup{} to my form.

I believe this is because the web is HTML, CSS, and JS, whereas the above was Elixir.

Therefore I assume my solution must be javascript.

I examined the html on the page which told me the %UserChatGroup{} input field had a name name="chat_group[userChatGroups][0][user_id]"

chat_group is the name of the model I am creating,

userChatGroups is the array I created to handle the members of the chat group,

[0] is the index of the input array and can go as big as you want a group to be

user_id is the field in my join table.

The index is the only value you need to change.

With javascript, I inserted input fields within my form, with a name="chat_group[userChatGroups][--indexnumber--][user_id]" and when submitting, the form would naturally also submit my newly added input. (replace indexNumber)

This way can handle adding as many chat group users as I needed.

like image 173
Terence Chow Avatar answered Oct 08 '22 23:10

Terence Chow