{"id":15010121,"url":"https://github.com/mamespalmero/dynamic_inputs_for","last_synced_at":"2025-04-09T21:23:42.982Z","repository":{"id":57492091,"uuid":"209971265","full_name":"MamesPalmero/dynamic_inputs_for","owner":"MamesPalmero","description":"Dynamically add/remove nested fields to your Phoenix forms","archived":false,"fork":false,"pushed_at":"2020-10-22T16:31:56.000Z","size":77,"stargazers_count":16,"open_issues_count":3,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-18T06:57:09.990Z","etag":null,"topics":["dynamic-forms","elixir","nested-forms","phoenix"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MamesPalmero.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-09-21T11:09:37.000Z","updated_at":"2023-01-27T09:36:21.000Z","dependencies_parsed_at":"2022-08-28T11:50:30.477Z","dependency_job_id":null,"html_url":"https://github.com/MamesPalmero/dynamic_inputs_for","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MamesPalmero%2Fdynamic_inputs_for","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MamesPalmero%2Fdynamic_inputs_for/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MamesPalmero%2Fdynamic_inputs_for/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MamesPalmero%2Fdynamic_inputs_for/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MamesPalmero","download_url":"https://codeload.github.com/MamesPalmero/dynamic_inputs_for/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248113165,"owners_count":21049795,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dynamic-forms","elixir","nested-forms","phoenix"],"created_at":"2024-09-24T19:30:22.955Z","updated_at":"2025-04-09T21:23:42.960Z","avatar_url":"https://github.com/MamesPalmero.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DynamicInputsFor\n\nDynamically add/remove nested fields to your Phoenix forms from the client with a\nthin JavaScript layer.\n\n## Installation\n\n1. The package can be installed by adding `dynamic_inputs_for` to your list of\n   dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [{:dynamic_inputs_for, \"~\u003e 1.1.0\"}]\nend\n```\n\n2. Then add `dynamic_inputs_for` to your list of dependencies in `package.json` and\n   run `npm install`. For the default Phoenix structure, in `assets/package.json`:\n\n```json\n\"dependencies\": {\n  \"dynamic_inputs_for\": \"file:../deps/dynamic_inputs_for\"\n}\n```\n\n3. Finally, don't forget to import the module. For the default Phoenix structure, in\n   `assets/js/app.js`:\n\n```js\nimport \"dynamic_inputs_for\";\n```\n\n## Usage example\n\nImagine the following Ecto schemas:\n\n```elixir\ndefmodule Shop do\n  use Ecto.Schema\n\n  schema \"shops\" do\n    field :name, :string\n    has_many :products, Product\n  end\nend\n\ndefmodule Product do\n  use Ecto.Schema\n\n  schema \"products\" do\n    field :name, :string\n    ...\n\n    belongs_to(:shop, Shop)\n  end\nend\n```\n\nIf you want to be able to dynamically add products in a form, use the\n`dynamic_inputs_for` helper in combination with `dynamic_add_button` to generate\nthe form.\n\nIf you also want to allow the deletion of nested fields, this library follows the\nstrategy suggested in the\n[Ecto.Changeset](https://hexdocs.pm/ecto/Ecto.Changeset.html) documentation. Add a\nseparate boolean virtual field to the changeset function that will allow you to\nmanually mark the associated data for deletion and use the `dynamic_delete_button`\nhelper inside the function that you pass to `dynamic_inputs_for` to generate a delete\nbutton for each associated data.\n\n```elixir\ndefmodule Product do\n  use Ecto.Schema\n  import Ecto.Changeset\n\n  schema \"products\" do\n    field :name, :string\n    ...\n    field :delete, :boolean, virtual: true\n\n    belongs_to(:shop, Shop)\n  end\n\n  def changeset(product, params) do\n    product\n    |\u003e cast(params, [:name, :delete])\n    |\u003e maybe_mark_for_deletion\n  end\n\n  defp maybe_mark_for_deletion(changeset) do\n    if get_change(changeset, :delete) do\n      %{changeset | action: :delete}\n    else\n      changeset\n    end\n  end\nend\n```\n\n```eex\n\u003c%= form_for @changeset, Routes.shop_path(@conn, :create), fn f -\u003e %\u003e\n  \u003c%= text_input f, :name %\u003e\n\n  \u003c%= dynamic_inputs_for f, :products, %Product{}, fn f_product -\u003e %\u003e\n    \u003c%= text_input f_product, :name %\u003e\n\n    \u003c%= dynamic_delete_button(\"Delete\") %\u003e\n  \u003c% end%\u003e\n\n  \u003c%= dynamic_add_button :products, \"Add\" %\u003e\n\u003c% end %\u003e\n```\n\nIf you want the new fields to have default values, you can pass them to the schema\nyou pass to `dynamic_inputs_for`. In the previous example `%Product{name: \"ASDF\"}`.\n\n```eex\n\u003c%= dynamic_inputs_for f, :products, %Product{name: \"ASDF\"}, fn f_product -\u003e %\u003e\n```\n\n## Custom JavaScript events\n\nWhen you add or delete an element, the events `dynamic:addedFields` and\n`dynamic:deletedFields` are triggered. These events can be listened to modify the\nnested fields or integrate them with third party javascript libraries.\n\n```js\ndocument.addEventListener(\n  \"dynamic:addedFields\",\n  function(e) {\n    e.target.style.backgroundColor = \"red\";\n  },\n  false\n);\n```\n\nor if you use jQuery\n\n```js\n$(document).on(\"dynamic:addedFields\", e =\u003e {\n  e.target.style.backgroundColor = \"red\";\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmamespalmero%2Fdynamic_inputs_for","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmamespalmero%2Fdynamic_inputs_for","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmamespalmero%2Fdynamic_inputs_for/lists"}