### Ash Form Builder Development Setup Source: https://hexdocs.pm/ash_form_builder/0.4.0 Steps to set up the development environment for Ash Form Builder, including cloning the repository, fetching dependencies, and running tests. ```bash git clone https://github.com/nagieeb0/ash_form_builder.git cd ash_form_builder mix deps.get mix test ``` -------------------------------- ### Generate Live CRUD Interface Source: https://hexdocs.pm/ash_form_builder/0.4.0 Use the `mix ash_form_builder.gen.live` command to generate a full CRUD LiveView interface for a given resource. This example generates for 'Accounts User'. ```bash mix ash_form_builder.gen.live Accounts User ``` -------------------------------- ### Implement a Custom Theme Source: https://hexdocs.pm/ash_form_builder/0.4.0 Create a custom theme by implementing the `AshFormBuilder.Theme` behaviour. This example shows how to render a text input field using Phoenix Components and custom classes. ```elixir defmodule MyAppWeb.CustomTheme do @behaviour AshFormBuilder.Theme use Phoenix.Component @impl AshFormBuilder.Theme def render_field(assigns, opts) do case assigns.field.type do :text_input -> render_text_input(assigns) :multiselect_combobox -> render_combobox(assigns) # ... etc end end defp render_text_input(assigns) do ~H"""
""" end end ``` -------------------------------- ### Fetch Dependencies Source: https://hexdocs.pm/ash_form_builder/0.4.0 After updating `mix.exs`, run this command to fetch the new dependencies. ```bash mix deps.get ``` -------------------------------- ### Generate Live CRUD with Custom Options Source: https://hexdocs.pm/ash_form_builder/0.4.0 Demonstrates using generator options like `--page-size` to control the number of rows per page and `--out` to specify a custom output directory. ```bash mix ash_form_builder.gen.live Inventory Product --page-size 50 mix ash_form_builder.gen.live Accounts User --out lib/my_app_web/live/admin ``` -------------------------------- ### Using Ash Form Builder in LiveView Source: https://hexdocs.pm/ash_form_builder/0.4.0 Shows how to integrate an Ash Form Builder form into a Phoenix LiveView for creating a user, including mounting the form component and handling submission. ```elixir defmodule MyAppWeb.UserLive.Create do use MyAppWeb, :live_view def mount(_params, _session, socket) do form = MyApp.Users.User.Form.for_create(actor: socket.assigns.current_user) {:ok, assign(socket, form: form)} end def render(assigns) do ~H""" <.live_component module={AshFormBuilder.FormComponent} id="user-form" resource={MyApp.Users.User} form={@form} /> """ end def handle_info({:form_submitted, MyApp.Users.User, user}, socket) do {:noreply, push_navigate(socket, to: ~p"/users/#{user.id}")} end end ``` -------------------------------- ### Scaffold LiveView CRUD Interface Source: https://hexdocs.pm/ash_form_builder/0.4.0 This mix command scaffolds a complete Phoenix LiveView CRUD interface for a given Ash resource, including index and form views, pre-wired with Cinder.collection and AshFormBuilder. ```bash mix ash_form.gen.live -r MyApp.Todos.Task --accent teal --transitions smooth ``` -------------------------------- ### Register Custom Themes Source: https://hexdocs.pm/ash_form_builder/0.4.0 Register your custom themes in config.exs to refer to them by short name within your forms. ```elixir config :ash_form_builder, :themes, my_brand: MyAppWeb.Themes.MyBrand, retro: MyAppWeb.Themes.Retro ``` -------------------------------- ### Generated LiveView Index Module Source: https://hexdocs.pm/ash_form_builder/0.4.0 This is the generated `index.ex` file for a LiveView. It includes necessary `use` statements, aliases, and callback implementations for handling parameters, form submissions, and delete events. ```elixir defmodule MyAppWeb.UserLive.Index do use MyAppWeb, :live_view use Cinder.UrlSync # injects handle_info for URL sync automatically alias MyApp.Accounts.User @collection_id "user-collection" def mount(_params, _session, socket) do {:ok, assign(socket, url_state: false, record: nil, form: nil)} end def handle_params(params, uri, socket) do socket = Cinder.UrlSync.handle_params(params, uri, socket) {:noreply, apply_action(socket, socket.assigns.live_action, params)} end # Triggered by AshFormBuilder.FormComponent after a successful Ash action def handle_info({:form_submitted, User, _result}, socket) do {:noreply, socket |> put_flash(:info, "User saved successfully.") |> Cinder.refresh_table(@collection_id) # async re-query, no page reload |> push_patch(to: ~p"/users")} end def handle_event("delete", %{"id" => id}, socket) do User |> Ash.get!(id, actor: socket.assigns[:current_user]) |> Ash.destroy!(actor: socket.assigns[:current_user]) {:noreply, socket |> put_flash(:info, "User deleted.") |> Cinder.refresh_table(@collection_id)} end end ``` -------------------------------- ### Testing Form Rendering and Creation Source: https://hexdocs.pm/ash_form_builder/0.4.0 Tests for Ash Form Builder's LiveView, verifying form rendering with auto-inferred fields and the task creation process with redirection. ```elixir defmodule MyAppWeb.TaskLiveTest do use MyAppWeb.ConnCase import Phoenix.LiveViewTest test "renders form with auto-inferred fields", %{conn: conn} do {:ok, _view, html} = live_isolated(conn, MyAppWeb.TaskLive.Form) assert html =~ "Task Title" assert html =~ "Description" assert html =~ "Completed" end test "creates task and redirects", %{conn: conn} do {:ok, view, _html} = live_isolated(conn, MyAppWeb.TaskLive.Form) assert form(view, "#task-form", task: %{ title: "Test Task", description: "Test description" }) |> render_submit() assert_redirect(view, ~p"/tasks/*") end end ``` -------------------------------- ### Create Task Form in LiveView Source: https://hexdocs.pm/ash_form_builder/0.4.0 This LiveView component demonstrates how to mount and render a create form for a Task resource using AshFormBuilder. It initializes the form with the current user as the actor. ```elixir defmodule MyAppWeb.TaskLive.New do use MyAppWeb, :live_view def mount(_params, _session, socket) do form = MyApp.Todos.Task.Form.for_create(actor: socket.assigns.current_user) {:ok, assign(socket, form: form)} end def render(assigns) do ~H""" <.live_component module={AshFormBuilder.FormComponent} id="task-create-form" resource={MyApp.Todos.Task} form={@form} /> """ end def handle_info({:form_submitted, MyApp.Todos.Task, task}, socket) do {:noreply, push_navigate(socket, to: ~p"/tasks/#{task.id}")} end end ``` -------------------------------- ### Basic File Upload Configuration Source: https://hexdocs.pm/ash_form_builder/0.4.0 Configures a single file upload field for a user's avatar, specifying accepted image types and size limits. The uploaded file path is stored in the `avatar_path` attribute. ```elixir defmodule MyApp.Users.User do use Ash.Resource, domain: MyApp.Users, extensions: [AshFormBuilder] attributes do uuid_primary_key :id attribute :name, :string, allow_nil?: false attribute :avatar_path, :string end actions do create :create do accept [:name] argument :avatar, :string, allow_nil?: true # Store the uploaded file path in the avatar_path attribute change fn changeset, _ -> case Ash.Changeset.get_argument(changeset, :avatar) do nil -> changeset path -> Ash.Changeset.change_attribute(changeset, :avatar_path, path) end end end end form do action :create submit_label "Create User" field :name do label "Full Name" required true end field :avatar do type :file_upload label "Profile Photo" hint "JPEG or PNG, max 5 MB" accept :images # or ~w(.jpg .png) — see table below max_files 1 max_file_size {5, :mb} # also accepts a raw byte integer cloud MyApp.Buckets.Cloud end end end ``` -------------------------------- ### Configure Glassmorphism Theme Source: https://hexdocs.pm/ash_form_builder/0.4.0 Enable the Glassmorphism theme by updating your application's configuration. This theme offers a premium glass-effect UI with animations and dark mode support. ```elixir config :ash_form_builder, :theme, AshFormBuilder.Themes.Glassmorphism ``` -------------------------------- ### Configure MishkaTheme Source: https://hexdocs.pm/ash_form_builder/0.4.0 Set the MishkaTheme in your application's configuration if you are using the mishka_chelekom dependency. This integrates MishkaChelekom components for styling. ```elixir config :ash_form_builder, :theme, AshFormBuilder.Theme.MishkaTheme ``` -------------------------------- ### Define Create and Update Forms in a Resource Source: https://hexdocs.pm/ash_form_builder/0.4.0 Configure separate 'form' blocks for create and update actions within the same Ash resource. This allows for distinct field configurations and submit labels for each action. ```elixir defmodule MyApp.Todos.Task do use Ash.Resource, domain: MyApp.Todos, extensions: [AshFormBuilder] # ... attributes and relationships actions do defaults [:create, :read, :update, :destroy] end # CREATE form configuration form do action :create submit_label "Create Task" field :title do label "Task Title" placeholder "Enter task title" required true end end # UPDATE form configuration (separate block) form do action :update submit_label "Save Changes" # Can have different field customizations for update field :title do label "Task Title" hint "Changing the title will notify collaborators" end end end ``` -------------------------------- ### Configure Shadcn Theme Source: https://hexdocs.pm/ash_form_builder/0.4.0 Apply the Shadcn theme by modifying your application's configuration. This theme provides a clean, minimal design inspired by shadcn/ui. ```elixir config :ash_form_builder, :theme, AshFormBuilder.Themes.Shadcn ``` -------------------------------- ### Update Task Form in LiveView Source: https://hexdocs.pm/ash_form_builder/0.4.0 This LiveView component shows how to mount and render an update form for an existing Task resource. It fetches the task and initializes the form for updating. ```elixir defmodule MyAppWeb.TaskLive.Edit do use MyAppWeb, :live_view def mount(%{"id" => id}, _session, socket) do task = MyApp.Todos.get_task!(id, actor: socket.assigns.current_user) form = MyApp.Todos.Task.Form.for_update(task, actor: socket.assigns.current_user) {:ok, assign(socket, form: form, mode: :edit)} end def render(assigns) do ~H""" <.live_component module={AshFormBuilder.FormComponent} id="task-edit-form" resource={MyApp.Todos.Task} form={@form} /> """ end def handle_info({:form_submitted, MyApp.Todos.Task, task}, socket) do {:noreply, push_navigate(socket, to: ~p"/tasks/#{task.id}")} end end ``` -------------------------------- ### Custom Action Form Helpers Source: https://hexdocs.pm/ash_form_builder/0.4.0 Demonstrates how Ash Form Builder generates helper functions for custom actions, including record-shaped actions and generic action calls. ```elixir actions do create :create do … update :update do … update :archive, accept: [] do … update :publish, accept: [:published_at] do … end forms do form :create do … end form :update do … end form :archive do submit_label "Archive" end form :publish do submit_label "Publish now" end end ``` ```elixir # Auto-generated: MyApp.Posts.Post.Form.for_create() # :create (resource form) MyApp.Posts.Post.Form.for_update(post) # :update (record form) MyApp.Posts.Post.Form.for_archive(post, actor: user) # :archive (record form) MyApp.Posts.Post.Form.for_publish(post, actor: user) # :publish (record form) # Plus the generic fallback for anything else: MyApp.Posts.Post.Form.for_action(:custom, record: post, actor: user) ``` -------------------------------- ### LiveView Handler for Combobox Search Source: https://hexdocs.pm/ash_form_builder/0.4.0 This LiveView event handler implements the search functionality for the searchable combobox. It filters tags based on the query and pushes the updated options back to the client. ```elixir def handle_event("search_tags", %{"query" => query}, socket) do tags = MyApp.Todos.Tag |> Ash.Query.filter(contains(name: ^query)) |> MyApp.Todos.read!() {:noreply, push_event(socket, "update_combobox_options", %{ field: "tags", options: Enum.map(tags, &{&1.name, &1.id}) })} end ``` -------------------------------- ### Generated LiveView Index Template Source: https://hexdocs.pm/ash_form_builder/0.4.0 This is the generated HEEx template for the LiveView index page. It includes a header with a 'New User' link, a `Cinder.collection` for displaying users, and a modal for creating or editing users using `AshFormBuilder.FormComponent`. ```html <.header> Users <:actions> <.link patch={~p"/users/new"}><.button>New User <%!-- Cinder.collection: filterable, sortable, paginated — state synced to URL --%> <%!-- TODO: Replace with your resource's real attributes (see Customising Columns) --%> <:col :let={user} field="id" sort label="ID">{user.id} <:col :let={user} label="Actions"> <.link patch={~p"/users/#{user}/edit"}>Edit <.link phx-click="delete" phx-value-id={user.id} data-confirm="Delete this user? This cannot be undone.">Delete <%!-- Modal: mounts only for :new and :edit live_actions --%> <.modal :if={@live_action in [:new, :edit]} id="user-modal" show on_cancel={JS.patch(~p"/users")}> <.live_component module={AshFormBuilder.FormComponent} id={if @record, do: "user-edit-#{@record.id}", else: "user-new"} resource={MyApp.Accounts.User} form={@form} submit_label={if @live_action == :new, do: "Create User", else: "Save Changes"} /> ``` -------------------------------- ### Configure Creatable Combobox Field Source: https://hexdocs.pm/ash_form_builder/0.4.0 This DSL configuration enables the 'creatable' feature for a multiselect combobox, allowing users to create new related records directly from the form. It specifies the create action, label, and search event. ```elixir forms do form :create do field :tags do type :multiselect_combobox opts [ creatable: true, create_action: :create, create_label: "Create \"", search_event: "search_tags" ] end end end ``` -------------------------------- ### Configure Dynamic Nested Has-Many Form Source: https://hexdocs.pm/ash_form_builder/0.4.0 This DSL configuration defines a has-many relationship for subtasks and sets up a nested form for managing them. It includes labels for the section, adding, and removing subtasks, and defines fields for the nested resource. ```elixir relationships do has_many :subtasks, MyApp.Todos.Subtask end forms do form :create do nested :subtasks do label "Subtasks" cardinality :many add_label "Add Subtask" remove_label "Remove" field :title do required true end field :done do type :toggle end end end end ``` -------------------------------- ### Add Ash Form Builder Dependency Source: https://hexdocs.pm/ash_form_builder/0.4.0 Add the necessary dependencies to your `mix.exs` file to include Ash Form Builder and its related components. ```elixir defp deps do [ {:ash, "~> 3.0"}, {:ash_phoenix, "~> 2.0"}, {:ash_form_builder, "~> 0.3.0"}, # Required if using mix ash_form_builder.gen.live {:cinder, "~> 0.12"}, # Optional: For MishkaChelekom theme {:mishka_chelekom, "~> 0.0.8"} ] end ``` -------------------------------- ### Multiple File Upload Configuration Source: https://hexdocs.pm/ash_form_builder/0.4.0 Configures a file upload field for multiple attachments, specifying accepted document types, a maximum number of files, and size limits. ```elixir field :attachments do type :file_upload label "Attachments" hint "Upload multiple documents (max 5)" accept :documents max_files 5 max_file_size {10, :mb} cloud MyApp.Buckets.Cloud end ``` -------------------------------- ### Preload Relationships for Update Forms in LiveView Source: https://hexdocs.pm/ash_form_builder/0.4.0 Use the `for_update/2` helper in your LiveView to automatically preload many-to-many relationships for update forms. This ensures existing selections are displayed correctly. ```elixir # In your LiveView def mount(%{"id" => id}, _session, socket) do # for_update/2 automatically preloads required relationships task = MyApp.Todos.Task |> MyApp.Todos.get_task!(id) form = MyApp.Todos.Task.Form.for_update(task, actor: socket.assigns.current_user) {:ok, assign(socket, form: form)} end ``` -------------------------------- ### Configure Default Theme Source: https://hexdocs.pm/ash_form_builder/0.4.0 Optionally configure the default theme for AshFormBuilder in your config.exs file. You can use short atoms or module names. ```elixir config :ash_form_builder, :theme, :default # config :ash_form_builder, :theme, :shadcn # config :ash_form_builder, :theme, AshFormBuilder.Themes.Glassmorphism ``` -------------------------------- ### Extend Ash Resource with AshFormBuilder Source: https://hexdocs.pm/ash_form_builder/0.4.0 Include `AshFormBuilder` in the `extensions` list of your Ash Resource to enable form building capabilities. ```elixir use Ash.Resource, domain: MyApp.Todos, extensions: [AshFormBuilder] ``` -------------------------------- ### Use Domain Code Interfaces for Update Forms Source: https://hexdocs.pm/ash_form_builder/0.4.0 Integrate update forms seamlessly with Domain Code Interfaces by defining helpers for specific actions. This provides a clean interface for generating update forms. ```elixir # Domain configuration defmodule MyApp.Todos do use Ash.Domain resources do resource MyApp.Todos.Task do define :form_to_create_task, action: :create define :form_to_update_task, action: :update # ← Update form helper end end end # LiveView usage form = MyApp.Todos.form_to_update_task(task, actor: current_user) ``` -------------------------------- ### Adding Cinder Dependency Source: https://hexdocs.pm/ash_form_builder/0.4.0 Add the Cinder dependency to your `mix.exs` file to use its data table functionality with Ash Form Builder. ```elixir {:cinder, "~> 0.12"} ``` -------------------------------- ### Customizing Cinder Columns Source: https://hexdocs.pm/ash_form_builder/0.4.0 Customize Cinder data table columns by replacing placeholder slots in `index.html.heex` with resource attributes. Available attributes include filter, filter with select, and sort. ```heex <:col :let={user} field="name" filter sort>{user.name} <:col :let={user} field="email" filter>{user.email} <:col :let={user} field="role" filter={:select}>{user.role} <:col :let={user} field="inserted_at" sort>{user.inserted_at} ``` -------------------------------- ### Generated Router Entries Source: https://hexdocs.pm/ash_form_builder/0.4.0 These are the router entries generated by `mix ash_form_builder.gen.live`. They define the routes for the index, new, and edit LiveViews. ```elixir scope "/", MyAppWeb do pipe_through :browser live "/users", UserLive.Index, :index live "/users/new", UserLive.Index, :new live "/users/:id/edit", UserLive.Index, :edit end ``` -------------------------------- ### Configure Many-to-Many Combobox Field Source: https://hexdocs.pm/ash_form_builder/0.4.0 This DSL configuration defines a many-to-many relationship for tags and explicitly sets the form field type to `:multiselect_combobox` for a searchable interface. It also configures options for search event, debounce, label key, and value key. ```elixir relationships do many_to_many :tags, MyApp.Todos.Tag do through MyApp.Todos.TaskTag end end actions do create :create do accept [:title] manage_relationship :tags, :tags, type: :append_and_remove end end forms do form :create do field :tags do type :multiselect_combobox opts [ search_event: "search_tags", debounce: 300, label_key: :name, value_key: :id ] end end end ``` -------------------------------- ### Add AshFormBuilder to mix.exs Source: https://hexdocs.pm/ash_form_builder/0.4.0 Include the AshFormBuilder dependency in your project's mix.exs file to add it to your Elixir project. ```elixir def deps do [ {:ash_form_builder, "~> 0.4.0"} ] end ``` -------------------------------- ### Configure Default Theme Source: https://hexdocs.pm/ash_form_builder/0.4.0 Set the default theme for AshFormBuilder in your application's configuration. The Default theme provides production-ready Tailwind CSS styling. ```elixir config :ash_form_builder, :theme, AshFormBuilder.Themes.Default ``` -------------------------------- ### Define a Form for an Ash Resource Source: https://hexdocs.pm/ash_form_builder/0.4.0 Add the AshFormBuilder extension to your Ash Resource and define forms using the `forms do ... end` block. Fields are auto-inferred from the action's `accept` list, but can be overridden. ```elixir defmodule MyApp.Todos.Task do use Ash.Resource, domain: MyApp.Todos, extensions: [AshFormBuilder] attributes do uuid_primary_key :id attribute :title, :string, allow_nil?: false, public?: true attribute :description, :string, public?: true attribute :completed, :boolean, default: false, public?: true end actions do defaults [:read, :destroy] create :create do accept [:title, :description, :completed] end update :update do accept [:title, :description, :completed] end end forms do form :create do submit_label "Create Task" accent :teal transitions :smooth field :title do label "Task Title" placeholder "Enter task title" required true end end form :update do submit_label "Update Task" accent :indigo end end end ``` -------------------------------- ### Ash Form Builder Field Type Inference Source: https://hexdocs.pm/ash_form_builder/0.4.0 Ash Form Builder automatically maps Ash types to UI components for form generation. This table outlines the default mappings. ```text Ash Type| Constraint| UI Type| Example ---|---|---|--- `:string`| -| `:text_input`| Text fields `:text`| -| `:textarea`| Multi-line text `:boolean`| -| `:checkbox`| Toggle switches `:integer` / `:float`| -| `:number`| Numeric inputs `:date`| -| `:date`| Date picker `:datetime`| -| `:datetime`| DateTime picker `:atom`| `one_of:`| `:select`| Dropdown `:enum` module| -| `:select`| Enum dropdown `many_to_many`| -| `:multiselect_combobox`| Searchable multi-select `has_many`| -| `:nested_form`| Dynamic nested forms ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.