Closed type1fool closed 1 year ago
The webauthn_live_component_demo
app includes a change_user/2
function in Demo.Accounts.User
. The changeset struct includes some helpful keys which may allow for dynamic form field generation.
iex(11)> changeset = Demo.Accounts.change_user(%Demo.Accounts.User{})
#Ecto.Changeset<
action: nil,
changes: %{},
errors: [username: {"can't be blank", [validation: :required]}],
data: #Demo.Accounts.User<>,
valid?: false
>
iex(12)> changeset.
__struct__ action changes constraints
data empty_values errors filters
params prepare repo repo_opts
required types valid? validations
iex(12)> changeset.__struct__
Ecto.Changeset
iex(13)> changeset.data
%Demo.Accounts.User{
__meta__: #Ecto.Schema.Metadata<:built, "users">,
id: nil,
inserted_at: nil,
keys: #Ecto.Association.NotLoaded<association :keys is not loaded>,
tokens: #Ecto.Association.NotLoaded<association :tokens is not loaded>,
updated_at: nil,
username: nil
}
iex(14)> changeset.params
%{}
iex(15)> changeset.required
[:username]
iex(16)> changeset.empty_values
[""]
iex(17)> changeset.prepare
[]
iex(18)> changeset.types
%{
id: :binary_id,
inserted_at: :naive_datetime,
keys: {:assoc,
%Ecto.Association.Has{
cardinality: :many,
defaults: [],
field: :keys,
on_cast: &Demo.Authentication.UserKey.new_changeset/2,
on_delete: :nothing,
on_replace: :raise,
ordered: false,
owner: Demo.Accounts.User,
owner_key: :id,
preload_order: [],
queryable: Demo.Authentication.UserKey,
related: Demo.Authentication.UserKey,
related_key: :user_id,
relationship: :child,
unique: true,
where: []
}},
tokens: {:assoc,
%Ecto.Association.Has{
cardinality: :many,
defaults: [],
field: :tokens,
on_cast: #Function<19.50136996/2 in Ecto.Changeset.on_cast_default/2>,
on_delete: :nothing,
on_replace: :raise,
ordered: false,
owner: Demo.Accounts.User,
owner_key: :id,
preload_order: [],
queryable: Demo.Authentication.UserToken,
related: Demo.Authentication.UserToken,
related_key: :user_id,
relationship: :child,
unique: true,
where: []
}},
updated_at: :naive_datetime,
username: :string
}
iex(19)> changeset.changes
%{}
iex(20)> changeset.errors
[username: {"can't be blank", [validation: :required]}]
iex(21)> changeset.repo
nil
iex(22)> changeset.valid?
false
iex(23)> changeset.constraints
[
%{
constraint: "users_username_index",
error_message: "has already been taken",
error_type: :unique,
field: :username,
match: :exact,
type: :unique
}
]
iex(24)> changeset.filters
%{}
iex(25)> changeset.repo_opts
[]
iex(26)> changeset.valid
valid? validations
iex(26)> changeset.validations
[]
Hello!
Thanks for your work on this LV component.
Instead of trying to implement and/or build some HTML/UI in the component, why not just "ask" the end-developer to implement the render
with the HTML, buttons and classes he wants and the component would just take care of everything else?
Hey @nicolasblanco! Thank you for checking out the repo.
I have been thinking about moving in this direction, allowing user-supplied forms. Phx 0.18 will make this a bit easier to implement. That should be better than trying to guess what controls to use based on changeset types - select vs radio vs checkbox for example.
User Story
As a user of this component, I would like to provide my own changeset from my custom LiveView and see the form render fields based on the changeset's required fields.
Acceptance Criteria
changeset
prop of typestruct
changeset