expertiza/expertiza

View on GitHub
app/models/criterion.rb

Summary

Maintainability
C
1 day
Test Coverage
F
8%
# Initial commit
class Criterion < ScoredQuestion
  include ActionView::Helpers
  validates :size, presence: true

  # This method returns what to display if an instructor (etc.) is creating or editing a questionnaire (questionnaires_controller.rb)
  def edit(_count)
    html = '<td align="center"><a rel="nofollow" data-method="delete" href="/questions/' + id.to_s + '">Remove</a></td>'

    html += '<td><input size="6" value="' + seq.to_s + '" name="question[' + id.to_s + '][seq]"'
    html += ' id="question_' + id.to_s + '_seq" type="text"></td>'

    html += '<td><textarea cols="50" rows="1" name="question[' + id.to_s + '][txt]"'
    html += ' id="question_' + id.to_s + '_txt" placeholder="Edit question content here">' + txt + '</textarea></td>'

    html += '<td><input size="10" disabled="disabled" value="' + type + '" name="question[' + id.to_s + '][type]"'
    html += ' id="question_' + id.to_s + '_type" type="text"></td>'

    html += '<td><input size="2" value="' + weight.to_s
    html += '" name="question[' + id.to_s + '][weight]" id="question_' + id.to_s + '_weight" type="text"></td>'

    html += '<td>text area size <input size="3" value="' + size.to_s
    html += '" name="question[' + id.to_s + '][size]" id="question_' + id.to_s + '_size" type="text"></td>'

    html += '<td> min_label <input size="12" value="' + min_label.to_s
    html += '" name="question[' + id.to_s + '][min_label]" id="question_' + id.to_s + '_min_label" type="text">  max_label <input size="10" value="' + max_label.to_s + '" name="question[' + id.to_s
    html += '][max_label]" id="question_' + id.to_s + '_max_label" type="text"></td>'

    safe_join(['<tr>'.html_safe, '</tr>'.html_safe], html.html_safe)
  end

  # This method returns what to display if an instructor (etc.) is viewing a questionnaire
  def view_question_text
    html = '<TD align="left"> ' + txt + ' </TD>'
    html += '<TD align="left">' + type + '</TD>'
    html += '<td align="center">' + weight.to_s + '</TD>'
    questionnaire = self.questionnaire
    if !max_label.nil? && !min_label.nil?
      html += '<TD align="center"> (' + min_label + ') ' + questionnaire.min_question_score.to_s
      html += ' to ' + questionnaire.max_question_score.to_s + ' (' + max_label + ')</TD>'
    else
      html += '<TD align="center">' + questionnaire.min_question_score.to_s + ' to ' + questionnaire.max_question_score.to_s + '</TD>'
    end
    safe_join(['<TR>'.html_safe, '</TR>'.html_safe], html.html_safe)
  end

  # Reduced the number of lines. Removed some redundant if-else statements, and combined some HTML concatenations.
  # Display for the students when they are filling the questionnaire
  def complete(count, answer = nil, questionnaire_min, questionnaire_max, dropdown_or_scale)
    html = '<div><label for="responses_' + count.to_s + '">' + txt + '</label></div>'
    question_advices = QuestionAdvice.where(question_id: id).sort_by(&:id)
    advice_total_length = 0
    question_advices.each do |question_advice|
      advice_total_length += question_advice.advice.length if question_advice.advice && question_advice.advice != ''
    end
    # show advice given for different questions
    html += advices_criterion_question(count, question_advices) if !question_advices.empty? && (advice_total_length > 0)
    # dropdown options to rate a project based on the question
    html += dropdown_criterion_question(count, answer, questionnaire_min, questionnaire_max) if dropdown_or_scale == 'dropdown'
    # scale options to rate a project based on the question
    html += scale_criterion_question(count, answer, questionnaire_min, questionnaire_max) if dropdown_or_scale == 'scale'
    safe_join([''.html_safe, ''.html_safe], html.html_safe)
  end

  # show advice for each criterion question
  def advices_criterion_question(count, question_advices)
    html = '<a id="showAdvice_' + id.to_s + '" onclick="showAdvice(' + id.to_s + ')">Show advice</a><script>'
    html += 'function showAdvice(i){var element = document.getElementById("showAdvice_" + i.toString());'
    html += 'var show = element.innerHTML == "Hide advice";'
    html += 'if (show){element.innerHTML="Show advice";} else{element.innerHTML="Hide advice";}toggleAdvice(i);}'
    html += 'function toggleAdvice(i) {var elem = document.getElementById(i.toString() + "_myDiv");'
    html += 'if (elem.style.display == "none") {elem.style.display = "";} else {elem.style.display = "none";}}</script>'
    html += '<div id="' + id.to_s + '_myDiv" style="display: none;">'
    # [2015-10-26] Zhewei:
    # best to order advices high to low, e.g., 5 to 1
    # each level used to be a link;
    # clicking on the link caused the dropbox to be filled in with the corresponding number
    question_advices.reverse.each_with_index do |question_advice, index|
      html += '<a id="changeScore_>' + id.to_s + '" onclick="changeScore(' + count.to_s + ',' + index.to_s + ')">'
      html += (questionnaire.max_question_score - index).to_s + ' - ' + question_advice.advice + '</a><br/><script>'
      html += 'function changeScore(i, j) {var elem = jQuery("#responses_" + i.toString() + "_score");'
      html += 'var opts = elem.children("option").length;'
      html += 'elem.val((' + questionnaire.max_question_score.to_s + ' - j).toString());}</script>'
    end
    html += '</div>'
  end

  # dropdown options to rate a project based on the question
  def dropdown_criterion_question(count, answer = nil, questionnaire_min, questionnaire_max)
    current_value = ''
    current_value += 'data-current-rating =' + answer.answer.to_s unless answer.nil?
    html = '<div><select id="responses_' + count.to_s + '_score" name="responses[' + count.to_s + '][score]" class="review-rating" ' + current_value + '>'
    html += "<option value = ''>--</option>"
    questionnaire_min.upto(questionnaire_max).each do |j|
      html += '<option value=' + j.to_s
      html += ' selected="selected"' if !answer.nil? && j == answer.answer
      html += '>' + j.to_s
      html += '-' + min_label if min_label.present? && j == questionnaire_min
      html += '-' + max_label if max_label.present? && j == questionnaire_max
      html += '</option>'
    end

    html += '</select></div><br><br><textarea' + ' id="responses_' + count.to_s + '_comments"'
    html += ' name="responses[' + count.to_s + '][comment]" class="tinymce">'
    html += answer.comments if !answer.nil? && !answer.comments.nil?
    html += '</textarea></td>'
  end

  # scale options to rate a project based on the question
  def scale_criterion_question(count, answer = nil, questionnaire_min, questionnaire_max)
    if size.nil? || size.blank?
      cols = '70'
      rows = '1'
    else
      cols = size.split(',')[0]
      rows = size.split(',')[1]
    end
    html = '<input id="responses_' + count.to_s + '_score" name="responses[' + count.to_s + '][score]" type="hidden"'
    html += 'value="' + answer.answer.to_s + '"' unless answer.nil?
    html += '><table><tr><td width="10%"></td>'

    (questionnaire_min..questionnaire_max).each do |j|
      html += '<td width="10%"><label>' + j.to_s + '</label></td>'
    end

    html += '<td width="10%"></td></tr><tr><td width="10%">'
    html += min_label unless min_label.nil?
    html += '</td>'

    (questionnaire_min..questionnaire_max).each do |j|
      html += '<td width="10%"><input type="radio" id="' + j.to_s + '" value="' + j.to_s + '" name="Radio_' + id.to_s + '"'
      html += 'checked="checked"' if (!answer.nil? && answer.answer == j) || (answer.nil? && questionnaire_min == j)
      html += '></td>'
    end
    html += '<script>jQuery("input[name=Radio_' + id.to_s + ']:radio").change(function() {'
    html += 'var response_score = jQuery("#responses_' + count.to_s + '_score");'
    html += 'var checked_value = jQuery("input[name=Radio_' + id.to_s + ']:checked").val();'
    html += 'response_score.val(checked_value);});</script><td width="10%">'
    html += max_label unless max_label.nil?
    html += '</td><td width="10%"></td></tr></table>'
    html += '<textarea cols=' + cols + ' rows=' + rows + ' id="responses_' + count.to_s + '_comments"' \
      ' name="responses[' + count.to_s + '][comment]" class="tinymce">'
    html += answer.comments if !answer.nil? && !answer.comments.nil?
    html += '</textarea>'
  end

  # This method returns what to display if a student is viewing a filled-out questionnaire
  def view_completed_question(count, answer, questionnaire_max, tag_prompt_deployments = nil, current_user = nil)
    html = '<b>' + count.to_s + '. ' + txt + ' [Max points: ' + questionnaire_max.to_s + ']</b>'
    score = answer && !answer.answer.nil? ? answer.answer.to_s : '-'
    score_percent = score != '-' ? answer.answer * 1.0 / questionnaire_max : 0
    score_color = if score_percent > 0.8
                    'c5'
                  elsif score_percent > 0.6
                    'c4'
                  elsif score_percent > 0.4
                    'c3'
                  elsif score_percent > 0.2
                    'c2'
                  else
                    'c1'
                  end

    html += '<table cellpadding="5"><tr><td>'
    html += '<div class="' + score_color + '" style="width:30px; height:30px;' \
      ' border-radius:50%; font-size:15px; color:black; line-height:30px; text-align:center;">'
    html += score + '</div></td>'

    if answer && !answer.comments.nil?
      html += '<td style="padding-left:10px"><br>' + answer.comments.html_safe + '</td>'
      #### start code to show tag prompts ####
      if !tag_prompt_deployments.nil? && tag_prompt_deployments.count > 0
        # show check boxes for answer tagging
        question = Question.find(answer.question_id)
        html += '<tr><td colspan="2">'
        tag_prompt_deployments.each do |tag_dep|
          tag_prompt = TagPrompt.find(tag_dep.tag_prompt_id)
          if tag_dep.question_type == question.type && answer.comments.length > tag_dep.answer_length_threshold.to_i
            html += tag_prompt.html_control(tag_dep, answer, current_user)
          end
        end
        html += '</td></tr>'
      end
      #### end code to show tag prompts ####
    end
    html += '</tr></table>'
    safe_join([''.html_safe, ''.html_safe], html.html_safe)
  end
end