forms

Forms

New and edit forms are built from declared fields. Each field maps by :as to an input type:

:asInput
stringtext input
texttextarea
selectdropdown (from :collection)
booleancheckbox
datedate picker
timetime picker
datetimedatetime-local picker
numbernumber input
passwordpassword input
hiddenhidden input
filefile input
field('title',     :as<string>, :placeholder<Headline>, :hint('Keep it short.'));
field('body',      :as<text>);
field('published', :as<boolean>);
field('author-id', :as<select>, :collection({ Author.all.all.map(-> $a { $a.id => $a.name }) }));
field('tag-ids',   :as<select>, :multiple, :collection({ Tag.all.all.map(-> $t { $t.id => $t.name }) }));

Field labels resolve through I18n (human-attribute-name), or pass :label to set one explicitly for a single field. A :hint and :placeholder render alongside the input. A select renders a dropdown from its explicit collection, and with :multiple it renders a multi-select for a collection association.

Persistence

Create and update assign only the attributes named in the resource's permit allowlist, so an unlisted parameter is never mass-assigned. On success the action redirects to the show page with a flash; on a validation failure it re-renders the form with the submitted values.

permit(<title body published author-id>);

Because an HTML form cannot issue a PATCH, the engine also accepts a plain POST to the member path for the update action, so editing works without JavaScript.

Validation errors

A failed save re-renders the form. ORM validation errors show inline beneath each field and in a summary at the top, using the ORM's full-messages.

Nested attributes

Declare a nested association with nested, giving its own sub-fields. The model must back it with accepts-nested-attributes-for.

nested('posts', :multiple, {
  field('title', :as<string>);
});

A singular association renders one nested fieldset; a :multiple (has-many) association renders one fieldset per existing child plus a blank row for adding one. Submitting posts posts-attributes to the model, which creates new children, updates those with an id, and (with allow-destroy) removes those marked for deletion. Use the model's reject-if to skip a blank add-row.

File uploads

A file field stores its upload through Active Storage. The form becomes multipart/form-data, and on save the upload is attached to the record by its type, id, and the field name (no storage role on the model required):

field('cover', :as<file>);

Uploading a new file on update replaces the field's previous attachment, deleting the old blob record and its stored bytes. Saving without choosing a file leaves the existing attachment in place. Deleting a record purges its file attachments, so no blob record or stored file is left orphaned.

Configure a storage service and repository in your application's setup, the same as any Active Storage integration.

MVC::Keayl::Admin v0.9.0

Generated administration interface for MVC::Keayl applications

Authors

  • Greg Donald

License

Artistic-2.0

Dependencies

MVC::Keayl:auth<zef:gdonald>ORM::ActiveRecord:auth<zef:gdonald>Template::HAML:auth<zef:gdonald>

Provides

  • MVC::Keayl::Admin
  • MVC::Keayl::Admin::ActionItem
  • MVC::Keayl::Admin::Assets
  • MVC::Keayl::Admin::AssetsController
  • MVC::Keayl::Admin::Attachments
  • MVC::Keayl::Admin::Attribute
  • MVC::Keayl::Admin::Authentication
  • MVC::Keayl::Admin::Authentication::Basic
  • MVC::Keayl::Admin::Authentication::Session
  • MVC::Keayl::Admin::Authorization
  • MVC::Keayl::Admin::Authorization::Abilities
  • MVC::Keayl::Admin::Authorization::Policy
  • MVC::Keayl::Admin::Authorization::Role
  • MVC::Keayl::Admin::BatchAction
  • MVC::Keayl::Admin::Chrome
  • MVC::Keayl::Admin::Column
  • MVC::Keayl::Admin::Config
  • MVC::Keayl::Admin::Controller
  • MVC::Keayl::Admin::CustomAction
  • MVC::Keayl::Admin::DSL
  • MVC::Keayl::Admin::Dashboard
  • MVC::Keayl::Admin::DashboardController
  • MVC::Keayl::Admin::Engine
  • MVC::Keayl::Admin::ExportSpec
  • MVC::Keayl::Admin::Field
  • MVC::Keayl::Admin::Filter
  • MVC::Keayl::Admin::FilterPanel
  • MVC::Keayl::Admin::Form
  • MVC::Keayl::Admin::Formatter
  • MVC::Keayl::Admin::Generators
  • MVC::Keayl::Admin::I18n
  • MVC::Keayl::Admin::IndexView
  • MVC::Keayl::Admin::Inflection
  • MVC::Keayl::Admin::Menu
  • MVC::Keayl::Admin::MenuEntry
  • MVC::Keayl::Admin::Nested
  • MVC::Keayl::Admin::Page
  • MVC::Keayl::Admin::PageController
  • MVC::Keayl::Admin::Pages
  • MVC::Keayl::Admin::Pagination
  • MVC::Keayl::Admin::Panel
  • MVC::Keayl::Admin::Panels
  • MVC::Keayl::Admin::Paths
  • MVC::Keayl::Admin::Predicate
  • MVC::Keayl::Admin::Registry
  • MVC::Keayl::Admin::Resource
  • MVC::Keayl::Admin::ResourceController
  • MVC::Keayl::Admin::Scope
  • MVC::Keayl::Admin::Scopes
  • MVC::Keayl::Admin::Show
  • MVC::Keayl::Admin::Table
  • MVC::Keayl::Admin::TestSupport
  • MVC::Keayl::Admin::Url
  • MVC::Keayl::Admin::View

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.