diff --git a/Guide/form.markdown b/Guide/form.markdown index f1981f161..1f8c3ff20 100644 --- a/Guide/form.markdown +++ b/Guide/form.markdown @@ -666,26 +666,19 @@ formFor subscription [hsx| allContentTypes = allEnumValues @ContentType ``` -### Force Seelction of Custom Enums +### Set Default Value for Custom Enums -You will notice that if we use `selectField` on enums, the first enum value is always selected. The reason is that the select field is always displaying the value it gets from the model passed to `formFor`. +When creating a new record, by default the field value will be empty. If you'd like to set a default enum, you can set it from the controller. -For a new record, that value will always be the first enum. And the reason lies in the `newRecord @Record` call in the controller. The `newRecord` creates an empty record setting all fields to a default empty value. -The default empty value for UUIDs is `00000000-0000-0000-0000-000000000000` and the default empty value for enums is the first enum value. - -Now, if we have a required field, and we want to make sure the user selects a value, in the same way they have to select for a reference field. -So we check if the model is new and the field was not submitted yet, then we set the field value to an empty string. Otherwise, we use the value from the model. +Note that by default the `newRecord` populates the first enum on the record. However, when showing the form, IHP will check if the field was not explicetly set, and if so, will not render the default value. ```haskell - formFor subscription [hsx| - {selectFieldEmptyFieldValueWhenIsNew #contentType allContentTypes} -|] - where - allContentTypes = allEnumValues @ContentType +action NewPostAction = do + let post = newRecord + let postWithDefault = newRecord |> set #postType Article + render NewView { .. } ``` -You can use radio buttons using the `radioFieldEmptyFieldValueWhenIsNew` - ### Select Inputs with Integers It's a common use case to have a select field consisting of ints, e.g. inside a shopping cart to select the quantity of an item. diff --git a/IHP/View/Form.hs b/IHP/View/Form.hs index 6412180fc..63517a023 100644 --- a/IHP/View/Form.hs +++ b/IHP/View/Form.hs @@ -25,7 +25,6 @@ import IHP.View.Types import IHP.View.Classes () import Network.Wai (pathInfo) import IHP.Controller.Context -import IHP.Controller.Param (paramList) -- | Forms usually begin with a 'formFor' expression. -- @@ -723,7 +722,6 @@ checkboxField field = FormField -- > render NewView { .. } selectField :: forall fieldName model item. ( ?formContext :: FormContext model - , ?context :: ControllerContext , HasField fieldName model (SelectValue item) , HasField "meta" model MetaBag , KnownSymbol fieldName @@ -765,41 +763,6 @@ selectField field items = FormField FormContext { model } = ?formContext {-# INLINE selectField #-} -{- Select field where @fieldValue@ is empty text when the model is new. - -You will notice that if we use `selectField` on enums, the first enum value is always selected. -The reason is that the select field is always displaying the value it gets from the -model passed to @formFor@. - -For a new record, that value will always be the first enum. And the reason lies in the newRecord @Record call in the controller. -The @newRecord@ creates an empty record setting all fields to a default empty value. -The default empty value for UUIDs is 00000000-0000-0000-0000-000000000000 and the default empty value for enums is the first enum value. - -Now, if we have a required field, and we want to make sure the user selects a value, in the same way they have to select for a reference field. -So we check if the model is new and the field was not submitted yet, then we set the field value to an empty string. Otherwise, we use the value from the model. --} -selectFieldEmptyFieldValueWhenIsNew :: forall fieldName model item. - ( ?formContext :: FormContext model - , ?context :: ControllerContext - , HasField fieldName model (SelectValue item) - , HasField "meta" model MetaBag - , KnownSymbol fieldName - , KnownSymbol (GetModelName model) - , CanSelect item - , InputValue (SelectValue item) - , Typeable model - , Eq (SelectValue item) - ) => Proxy fieldName -> [item] -> FormField -selectFieldEmptyFieldValueWhenIsNew field items = (selectField field items) - { fieldValue = if isNew model && isEmpty (paramList @Text (cs fieldName)) - then "" - else inputValue (getField @fieldName model :: SelectValue item) - } - where - fieldName = symbolVal field - FormContext { model } = ?formContext -{-# INLINE selectFieldEmptyFieldValueWhenIsNew #-} - -- | Radio require you to pass a list of possible values to select. We use the same mechanism as for for 'selectField'. -- -- > formFor project [hsx| @@ -843,7 +806,6 @@ selectFieldEmptyFieldValueWhenIsNew field items = (selectField field items) -- > render NewView { .. } radioField :: forall fieldName model item. ( ?formContext :: FormContext model - , ?context::ControllerContext , HasField fieldName model (SelectValue item) , HasField "meta" model MetaBag , KnownSymbol fieldName @@ -864,30 +826,6 @@ radioField field items = (selectField field items) } {-# INLINE radioField #-} -{- Radio field where @fieldValue@ is empty text when the model is new. - -See `selectFieldEemptyFieldValueWhenIsNew` for more details. --} -radioFieldEmptyFieldValueWhenIsNew :: forall fieldName model item. - ( ?formContext :: FormContext model - , ?context::ControllerContext - , HasField fieldName model (SelectValue item) - , HasField "meta" model MetaBag - , KnownSymbol fieldName - , KnownSymbol (GetModelName model) - , CanSelect item - , InputValue (SelectValue item) - , Typeable model - , Eq (SelectValue item) - ) => Proxy fieldName -> [item] -> FormField -radioFieldEmptyFieldValueWhenIsNew field items = (radioField field items) - { fieldValue = selectField.fieldValue - } - where - selectField = selectFieldEmptyFieldValueWhenIsNew field items - -{-# INLINE radioFieldEmptyFieldValueWhenIsNew #-} - class CanSelect model where -- | Here we specify the type of the @