Git Product home page Git Product logo

dynamic_inputs_for's Introduction

DynamicInputsFor

Dynamically add/remove nested fields to your Phoenix forms from the client with a thin JavaScript layer.

Installation

  1. The package can be installed by adding dynamic_inputs_for to your list of dependencies in mix.exs:
def deps do
  [{:dynamic_inputs_for, "~> 1.1.0"}]
end
  1. Then add dynamic_inputs_for to your list of dependencies in package.json and run npm install. For the default Phoenix structure, in assets/package.json:
"dependencies": {
  "dynamic_inputs_for": "file:../deps/dynamic_inputs_for"
}
  1. Finally, don't forget to import the module. For the default Phoenix structure, in assets/js/app.js:
import "dynamic_inputs_for";

Usage example

Imagine the following Ecto schemas:

defmodule Shop do
  use Ecto.Schema

  schema "shops" do
    field :name, :string
    has_many :products, Product
  end
end

defmodule Product do
  use Ecto.Schema

  schema "products" do
    field :name, :string
    ...

    belongs_to(:shop, Shop)
  end
end

If you want to be able to dynamically add products in a form, use the dynamic_inputs_for helper in combination with dynamic_add_button to generate the form.

If you also want to allow the deletion of nested fields, this library follows the strategy suggested in the Ecto.Changeset documentation. Add a separate boolean virtual field to the changeset function that will allow you to manually mark the associated data for deletion and use the dynamic_delete_button helper inside the function that you pass to dynamic_inputs_for to generate a delete button for each associated data.

defmodule Product do
  use Ecto.Schema
  import Ecto.Changeset

  schema "products" do
    field :name, :string
    ...
    field :delete, :boolean, virtual: true

    belongs_to(:shop, Shop)
  end

  def changeset(product, params) do
    product
    |> cast(params, [:name, :delete])
    |> maybe_mark_for_deletion
  end

  defp maybe_mark_for_deletion(changeset) do
    if get_change(changeset, :delete) do
      %{changeset | action: :delete}
    else
      changeset
    end
  end
end
<%= form_for @changeset, Routes.shop_path(@conn, :create), fn f -> %>
  <%= text_input f, :name %>

  <%= dynamic_inputs_for f, :products, %Product{}, fn f_product -> %>
    <%= text_input f_product, :name %>

    <%= dynamic_delete_button("Delete") %>
  <% end%>

  <%= dynamic_add_button :products, "Add" %>
<% end %>

If you want the new fields to have default values, you can pass them to the schema you pass to dynamic_inputs_for. In the previous example %Product{name: "ASDF"}.

<%= dynamic_inputs_for f, :products, %Product{name: "ASDF"}, fn f_product -> %>

Custom JavaScript events

When you add or delete an element, the events dynamic:addedFields and dynamic:deletedFields are triggered. These events can be listened to modify the nested fields or integrate them with third party javascript libraries.

document.addEventListener(
  "dynamic:addedFields",
  function(e) {
    e.target.style.backgroundColor = "red";
  },
  false
);

or if you use jQuery

$(document).on("dynamic:addedFields", e => {
  e.target.style.backgroundColor = "red";
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.