I'm working on a Rails app where user can "design" forms. See the image below:
For this I have the following models:
class ProgramPart < ApplicationRecord
has_many :block_elements, dependent: :destroy
class BlockElement < ApplicationRecord
belongs_to :program_part
enum element_types: {
rich_content: 0,
textfield: 1,
textarea: 2
}
has_rich_text :content
I'm not quite sure how to present the dynamic form to the user and what approach to use.
Currently having:
<%= form_with [how should my form look when inputs are dynamic?] %>
<% @program_part.block_elements.each do |block| %>
<% if block.element_type == BlockElement.element_types[:rich_content] %>
<%= block.content %>
<% elsif block.element_type == BlockElement.element_types[:textfield] %>
<%= block.question %>
<!-- not sure how this should look -->
<%= @form_builder.text_field(:answer_value)%>
<% elsif block.element_type == BlockElement.element_types[:textarea] %>
<!-- textarea -->
<% end %>
<% end %>
<% end %>
Have anyone implemented something similar or knows any good resource for it?

I have implemented similar thing with forms configurable by admin and then used by client. Here are the basics:
You need an abstract Page object, abstract DOM object and then an object for each DOM element like this:
The
dom_typewill be the thing that will tell your system what type of object it needs to render. Of cause it also should be stored in DB but it helps you to automatically fill the database field with the type if you are adding a text_field object instead of something abstract. As you see every static dom object nestes from abstractDomObject- which is basically the table of all dom objects created. you can even add such info as width, height or additional css classes as parameters to the dom object table, making every created dom input a uniq and higly customizable entity.Wrapup
This approach is Object oriented and Composite by design. All you need to do is set up each 'brick' and then assemble the 'wall' dynamically with JS and it will be stored in DB neatly. then just get the page object from db and render it wherever you need it.
Hope it helps! :)