{"id":15288040,"url":"https://github.com/jakub-zawislak/formex","last_synced_at":"2025-04-05T06:08:00.850Z","repository":{"id":62429664,"uuid":"79050016","full_name":"jakub-zawislak/formex","owner":"jakub-zawislak","description":"A better form library for Phoenix","archived":false,"fork":false,"pushed_at":"2019-05-05T16:15:48.000Z","size":753,"stargazers_count":218,"open_issues_count":5,"forks_count":21,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-04-25T23:21:12.181Z","etag":null,"topics":["ecto","elixir","elixir-lang","forms","phoenix"],"latest_commit_sha":null,"homepage":"https://hexdocs.pm/formex","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/jakub-zawislak.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-15T18:09:45.000Z","updated_at":"2024-02-27T08:45:11.000Z","dependencies_parsed_at":"2022-11-01T20:04:48.002Z","dependency_job_id":null,"html_url":"https://github.com/jakub-zawislak/formex","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakub-zawislak%2Fformex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakub-zawislak%2Fformex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakub-zawislak%2Fformex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakub-zawislak%2Fformex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jakub-zawislak","download_url":"https://codeload.github.com/jakub-zawislak/formex/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247294539,"owners_count":20915340,"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":["ecto","elixir","elixir-lang","forms","phoenix"],"created_at":"2024-09-30T15:43:54.690Z","updated_at":"2025-04-05T06:08:00.808Z","avatar_url":"https://github.com/jakub-zawislak.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Formex\n\nFormex is an extensible form library for Phoenix.\nWith this library you don't write changeset (as in Ecto), but a separate module that declares\nfields of form\n(like in [Symfony](https://symfony.com/doc/current/forms.html#creating-form-classes)).\n\nYou can also use it with Ecto - see [formex_ecto](https://github.com/jakub-zawislak/formex_ecto).\nThat library will build changeset and additional Ecto queries for itself.\n\nFormex doesn't validate data for itself - it uses\n[validation libraries](https://hexdocs.pm/formex/Formex.Validator.html#available-adapters) instead.\n\nFormex comes with helper functions for templating. For now there is only a Bootstrap 3 form\ntemplate, but you can easily create your own templates.\n\n## TL;DR\n\n\u003cimg src=\"http://i.imgur.com/YIG0R2P.png\" width=\"800px\"\u003e\n\n## Installation\nIn addition to the main library, you have to install some validator adapter.\nIn this example we will use Vex.\n[List of available adapters](https://hexdocs.pm/formex/Formex.Validator.html#available-adapters)\n\n`mix.exs`\n```elixir\ndef deps do\n  [{:formex, \"~\u003e 0.6.0\"},\n   {:formex_vex, \"~\u003e 0.1.0\"}]\nend\n\ndef application do\n  [applications: [:formex]]\nend\n```\n\n`config/config.exs`\n```elixir\nconfig :formex,\n  validator: Formex.Validator.Vex,\n  translate_error: \u0026AppWeb.ErrorHelpers.translate_error/1,  # optional, from /lib/app_web/views/error_helpers.ex\n  template: Formex.Template.BootstrapHorizontal,            # optional, can be overridden in a template\n  template_options: [                                       # optional, can be overridden in a template\n    left_column: \"col-sm-2\",\n    right_column: \"col-sm-10\"\n  ]\n```\n\n`web/web.ex`\n```elixir\ndef controller do\n  quote do\n    use Formex.Controller\n  end\nend\n\ndef view do\n  quote do\n    use Formex.View\n  end\nend\n```\n\n## Usage\n\nLet's create a form for article.\n\n### Model\n\n```elixir\n# /web/model/article.ex\ndefmodule App.Article do\n  defstruct [:title, :content, :hidden]\nend\n```\n\n### Form Type\n\n```elixir\n# /web/form/article_type.ex\ndefmodule App.ArticleType do\n  use Formex.Type\n\n  def build_form(form) do\n    form\n    |\u003e add(:title, :text_input, label: \"Title\", validation: [presence: true])\n    |\u003e add(:content, :textarea, label: \"Content\", phoenix_opts: [\n      rows: 4\n    ], validation: [presence: true])\n    |\u003e add(:hidden, :checkbox, label: \"Is hidden?\", required: false)\n    |\u003e add(:save, :submit, label: \"Submit\", phoenix_opts: [\n      class: \"btn-primary\"\n    ])\n  end\nend\n```\n\nPlease note that `required` option is used only to generate an asterisk.\nAny validation must be done via `validation` option.\n\nThe `:text_input` and so on are function names from\n[`Phoenix.HTML.Form`](https://hexdocs.pm/phoenix_html/Phoenix.HTML.Form.html)\n\n### Controller\n\n```elixir\ndef new(conn, _params) do\n  form = create_form(App.ArticleType, %Article{})\n  render(conn, \"form.html\", form: form)\nend\n\ndef create(conn, %{\"article\" =\u003e article_params}) do\n  App.ArticleType\n  |\u003e create_form(%Article{}, article_params)\n  |\u003e handle_form\n  |\u003e case do\n    {:ok, article} -\u003e\n      # do something with a new article struct\n    {:error, form} -\u003e\n      # display errors\n      render(conn, \"form.html\", form: form)\n  end\nend\n```\n\n### Template\n\n`form.html.eex`\n```elixir\n\u003c%= formex_form_for @form, article_path(@conn, :create), [class: \"form-horizontal\"], fn f -\u003e %\u003e\n  \u003c%= if @form.submitted? do %\u003eOops, something went wrong!\u003c% end %\u003e\n\n  \u003c%= formex_row f, :title %\u003e\n  \u003c%= formex_row f, :content %\u003e\n  \u003c%= formex_row f, :hidden %\u003e\n  \u003c%= formex_row f, :save %\u003e\n\n  \u003c%# or generate all fields at once: formex_rows f %\u003e\n\u003c% end %\u003e\n```\n\nPut an asterisk to required fields:\n```css\n.required .control-label:after {\n  content: '*';\n  margin-left: 3px;\n}\n```\n\nThe final effect after submit:\n\n\u003cimg src=\"http://i.imgur.com/GwFzMjl.png\" width=\"511px\"\u003e\n\n# Documentation\n\n[https://hexdocs.pm/formex](https://hexdocs.pm/formex)\n\n### Basic usage\n* [Creating forms](https://hexdocs.pm/formex/Formex.Type.html)\n* [Usage in a controller](https://hexdocs.pm/formex/Formex.Controller.html)\n* [Usage in a template](https://hexdocs.pm/formex/Formex.View.html)\n* [Validation](https://hexdocs.pm/formex/Formex.Validator.html)\n* [Nested forms](https://hexdocs.pm/formex/Formex.Type.html#module-nested-forms)\n* [Collections of forms](https://hexdocs.pm/formex/Formex.Type.html#module-collections-of-forms)\n\n### Custom fields\n* [Creating a custom field](https://hexdocs.pm/formex/Formex.CustomField.html)\n\n### Templating\n* [Changing a template](https://hexdocs.pm/formex/Formex.View.html#module-changing-a-form-template)\n* [Creating own template](https://hexdocs.pm/formex/Formex.Template.html)\n* [Bootstrap Vertical](https://hexdocs.pm/formex/Formex.Template.BootstrapVertical.html)\n* [Bootstrap Horizontal](https://hexdocs.pm/formex/Formex.Template.BootstrapHorizontal.html)\n\n### Guides\n* [Add new items to collection on the backend](https://hexdocs.pm/formex/guides.html#add-new-items-to-collection-on-the-backend)\n* [Using a select picker plugin with ajax search](https://hexdocs.pm/formex/guides.html#using-a-select-picker-plugin-with-ajax-search)\n* [Uploading files with Arc.Ecto](https://hexdocs.pm/formex_ecto/guides.html#uploading-files-with-arc-ecto) (Formex.Ecto)\n\n\n# Extensions\n\n* [formex_ecto](https://github.com/jakub-zawislak/formex_ecto) - Ecto integration\n\n# Validation adapters\n\n* [formex_vex](https://github.com/jakub-zawislak/formex_vex) - Vex\n* [formex_ecto](https://github.com/jakub-zawislak/formex_ecto) - Ecto.Changeset\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjakub-zawislak%2Fformex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjakub-zawislak%2Fformex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjakub-zawislak%2Fformex/lists"}