Friday, April 26, 2024
HomeRuby On RailsConstructing a Questionnaire | Drifting Ruby

Constructing a Questionnaire | Drifting Ruby


# Terminal
bundle add hotwire-rails
rails hotwire:set up
rails g scaffold questionnaire identify
rails g mannequin query questionnaire:belongs_to identify question_type:integer required:boolean
rails g mannequin reply query:belongs_to identify
# fashions/questionnaire.rb
class Questionnaire < ApplicationRecord
  has_many :questions, dependent: :destroy
  accepts_nested_attributes_for :questions, allow_destroy: true
finish
# fashions/query.rb
class Query < ApplicationRecord
  belongs_to :questionnaire
  has_many :solutions, dependent: :destroy
  accepts_nested_attributes_for :solutions, allow_destroy: true

  enum question_type: { single_choice: 0, multiple_choice: 1, long_answer: 2 }

  def self.question_type_select
    question_types.keys.map okay
  finish
finish
# fashions/reply.rb
class Reply < ApplicationRecord
  belongs_to :query
finish
# app/property/javascripts/controllers/nested_form_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  static targets = ["add_item", "template"]

  add_association(occasion) {
    occasion.preventDefault()
    var content material = this.templateTarget.innerHTML.change(/TEMPLATE_RECORD/g, new Date().getTime())
    this.add_itemTarget.insertAdjacentHTML('beforebegin', content material)
  }

  remove_association(occasion) {
    occasion.preventDefault()
    let merchandise = occasion.goal.closest(".nested-fields")
    merchandise.querySelector("enter[name*='_destroy']").worth = 1
    merchandise.fashion.show = 'none'
  }
}
# views/questionnaires/_form.html.erb
<%= form_with(mannequin: questionnaire) do |type| %>
  <div class="subject">
    <%= type.label :identify %>
    <%= type.text_field :identify %>
  </div>

  <div data-controller="nested-form">
    <template data-nested-form-target="template">
      <%= type.fields_for :questions, Query.new, child_index: 'TEMPLATE_RECORD' do |query| %>
        <%= render 'question_fields', type: query %>
      <% finish %>
    </template>

    <%= type.fields_for :questions do |query| %>
      <%= render 'question_fields', type: query %>
    <% finish %>

    <div data-nested-form-target="add_item">
      <%= link_to "Add Query", "#", information: { motion: "nested-form#add_association" } %>
    </div>
  </div>


  <div class="actions">
    <%= type.submit %>
  </div>
<% finish %>
# views/questionnaires/_question_fields.html.erb
<div class="nested-fields field" data-controller="dynamic-select">
  <div class="form-group">
    <%= type.choose :question_type,
        options_for_select(Query.question_type_select, chosen: type.object.question_type),
        {},
        'data-dynamic-select-target': 'choose',
        'data-action': 'dynamic-select#chosen' %>
  </div>

  <div class="form-group">
    <%= type.hidden_field :_destroy %>
    <%= type.text_field :identify, placeholder: 'Query', class: 'form-control' %>
    <small>
      <%= link_to "Take away", "#", information: { motion: "click->nested-form#remove_association" } %>
    </small>
  </div>

  <div data-controller="nested-form" data-dynamic-select-target="alternative">
    <template data-nested-form-target="template">
      <%= type.fields_for :solutions, Reply.new, child_index: 'TEMPLATE_RECORD' do |reply| %>
        <%= render 'answer_fields', type: reply %>
      <% finish %>
    </template>

    <%= type.fields_for :solutions do |reply| %>
      <%= render 'answer_fields', type: reply %>
    <% finish %>

    <div data-nested-form-target="add_item">
      <%= link_to "Add Reply", "#", information: { motion: "nested-form#add_association" } %>
    </div>
  </div>

  <div data-controller="nested-form" data-dynamic-select-target="lengthy">
  </div>
</div>
# questionnaire_controller.rb
  def questionnaire_params
    params.require(:questionnaire).allow(
      :identify,
      questions_attributes: [
        :_destroy,
        :id,
        :question_type,
        :name,
        answers_attributes: [:_destroy, :id, :name]
      ]
    )
  finish
# views/questionnaires/_answer_fields.html.erb
<div class="nested-fields">
  <div class="form-group">
    <%= type.hidden_field :_destroy %>
    <%= type.text_field :identify, placeholder: 'Reply', class: 'form-control' %>
    <small>
      <%= link_to "Take away Reply", "#", information: { motion: "click->nested-form#remove_association" } %>
    </small>
  </div>
</div>
# app/property/javascripts/controllers/dynamic_select_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  static targets = ["select", "choice", "long"]

  join() {
    this.chosen()
  }

  chosen() {
    this.hideFields()
    swap (this.selectTarget.worth) {
      case 'single_choice':
        this.choiceTarget.classList.take away('hidden')
        break;
      case 'multiple_choice':
        this.choiceTarget.classList.take away('hidden')
        break;
      case 'long_answer':
        this.longTarget.classList.take away('hidden')
        break;
    }
  }

  hideFields() {
    this.choiceTarget.classList.add('hidden')
    this.longTarget.classList.add('hidden')
  }
}
# views/questionnaires/present.html.erb
<h1><%= @questionnaire.identify %></h1>

<% @questionnaire.questions.every do |query| %>
  <h2><%= query.identify %></h2>

  <% case query.question_type %>
  <% when 'single_choice' %>
    <% query.solutions.every do |reply| %>
      <p>
        <%= radio_button_tag query.id, reply.id %>
        <%= reply.identify %>
      </p>
    <% finish %>
  <% when 'multiple_choice' %>
    <% query.solutions.every do |reply| %>
      <p>
        <%= check_box_tag query.id, reply.id %>
        <%= reply.identify %>
      </p>
    <% finish %>
  <% when 'long_answer' %>
    <%= text_area_tag query.id %>
  <% finish %>
<% finish %>
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments