live coder refactor fixes #36 and #50

This commit is contained in:
Mark Moser 2016-08-08 17:08:20 -05:00
parent d301547660
commit 5f395dcf41
17 changed files with 117 additions and 165 deletions

View File

@ -15,9 +15,9 @@
//= require turbolinks //= require turbolinks
//= require modernizr-lite/modernizr //= require modernizr-lite/modernizr
//= require jquery-linedtextarea-moser //= require jquery-linedtextarea-moser
//= require button-group //= require button-group
//= require form-animation //= require form-animation
//= require summary-edit //= require summary-edit
//= require test-builder
//= require textarea-limit //= require textarea-limit
//= require live-coder //= require live-coder

View File

@ -1,5 +1,4 @@
function updateResults(elem) { function updateResults(elem) { var resultsContainer = $(elem).find('[data-id="results"]')[0];
var resultsContainer = $(elem).find('[data-id="results"]')[0];
var codeHtml = $(elem).find('.code-html')[0].value.trim(); var codeHtml = $(elem).find('.code-html')[0].value.trim();
var codeCss = $(elem).find('.code-css')[0].value.trim(); var codeCss = $(elem).find('.code-css')[0].value.trim();
var codeJs = $(elem).find('.code-js')[0].value.trim(); var codeJs = $(elem).find('.code-js')[0].value.trim();
@ -92,22 +91,8 @@ function indentSelection(e){
} }
} }
function loadLiveCoders(){
$.each($('.answer-sec.live_code-type, .answer-sec.live_code_text-type'), function(index, elem){
var qid = $(elem).data('qid');
$(elem).find("[data-id='live-coder-answer']").load("/live-coder-entry/" + qid, function(){
$(elem).find('.js-error').addClass('hidden');
$(elem).find(".code-input textarea").linedtextarea();
if(window.location.href.indexOf("summary") > -1) {
$(elem).find(".code-input textarea").attr('disabled', true);
}
updateResults(this);
});
});
}
timer = 0; timer = 0;
$(function(){ $(function(){
// wait a half second before updating results // wait a half second before updating results
// restart the timer if they resume typing // restart the timer if they resume typing
@ -117,14 +102,13 @@ $(function(){
timer = setTimeout(updateResults(elem), 500); timer = setTimeout(updateResults(elem), 500);
}); });
$("[data-id=live-coder-answer]").each(function(){
updateResults(this);
});
$("html").on('keydown', "textarea[data-id^=code-]", function(e){ $("html").on('keydown', "textarea[data-id^=code-]", function(e){
indentSelection(e); indentSelection(e);
}); });
$.when(loadLiveCoders()).done(function(){ $(".code-input textarea").linedtextarea();
//simple live coder for summary page
$("[data-id=live-coder-no-js], [data-id=live-coder-finish-later]").addClass('hidden');
$("[data-id=live-coder]").removeClass('hidden');
});
}); });

View File

@ -177,16 +177,6 @@ $('.answer-block').prop('disabled', true);
// Question events // Question events
$('.answer-sec') $('.answer-sec')
.find('.button-cancel, .button-save').hide().end() .find('.button-cancel, .button-save').hide().end()
// delegating events
.on('click', '.button-edit', editClickHandler) .on('click', '.button-edit', editClickHandler)
.on('click', '.button-cancel', cancelClickHandler) .on('click', '.button-cancel', cancelClickHandler)
.on('click', '.button-save', saveClickHandler); .on('click', '.button-save', saveClickHandler);
// Dynamically load in coders
$.each($('.answer-sec.live_code-type, .answer-sec.live_code_text-type'), function(index, elem){
var qid = $(elem).data('qid');
$(elem).find("[data-id='live-coder-answer']").load("/live-coder-entry/" + qid, function(){
$(elem).find('.js-error').addClass('hidden');
$(elem).find(".code-input textarea").linedtextarea();
});
});

View File

@ -1,66 +0,0 @@
$(document).ready(function() {
//$(".answer_container").hide();
//$(".test-builder-success").hide();
//$(".question-edit-container").hide();
$(".skills-app-form").each(function () {
var thisQu = $(this),
questionOf = thisQu.find(".question-block").text();
thisQu.find(".testbuilderquestion").val(questionOf);
thisQu.find(".answer_type").change(function(){
if ( $(this).val() == "1" ) {
thisQu.find(".answer_container").hide();
thisQu.find(".answer_container.answer_text").show();
}
if ( $(this).val() == "2" ) {
thisQu.find(".answer_container").hide();
thisQu.find(".answer_container.answer_multiple").show();
}
if ( $(this).val() == "3" ) {
thisQu.find(".answer_container").hide();
thisQu.find(".answer_container.answer_multiple").show();
}
});
thisQu.find(".test-builder-edit").click(function(){
thisQu.find(".question-display").slideUp().fadeOut();
thisQu.find(".question-edit-container").slideDown().fadeIn();
});
thisQu.find(".btn-saveedit").click(function(){
if(thisQu.valid()) {
thisQu.find(".question-display").slideDown().fadeIn();
thisQu.find(".question-edit-container").slideUp().fadeOut();
thisQu.find(".test-builder-success").slideDown().fadeIn();
thisQu.find(".test-builder-success").delay(3000).slideUp().fadeOut();
}
});
thisQu.find(".btn-cancel-edit").click(function(){
thisQu.find(".question-display").slideDown().fadeIn();
thisQu.find(".question-edit-container").slideUp().fadeOut();
});
thisQu.find(".btn-cancel").click(function(){
thisQu.find(".answer_container").hide();
});
thisQu.find(".skills-app-form").submit(function() {
return false;
});
thisQu.find(".test-builder-save").click(function(){
if(thisQu.valid()) {
thisQu.find(".answer_container").hide();
thisQu.find(".test-builder-success").slideDown();
thisQu.find(".test-builder-success").delay(3000).slideUp();
}
else {
thisQu.find(".form-validation-script:invalid").css("border-color", "red");
}
});
thisQu.find( ".btn-save" ).click(function() {
if(thisQu.valid()) {
window.location.href = "test-builder-success.html";
}
});
});
});

View File

@ -5,6 +5,7 @@ class QuizController < ApplicationController
qid = prep_status.current_question_id || params[:question_id] qid = prep_status.current_question_id || params[:question_id]
redirect_to :summary and return if qid.nil? redirect_to :summary and return if qid.nil?
prep_question qid prep_question qid
@answer = prep_answer qid
prep_instance_answer @question prep_instance_answer @question
end end
@ -14,13 +15,6 @@ class QuizController < ApplicationController
send "process_#{prep_question(qid).input_type}" send "process_#{prep_question(qid).input_type}"
end end
def live_coder
prep_question params[:question_id]
prep_instance_answer @question
prep_answer params[:question_id]
render @question.input_type, layout: false
end
def summary def summary
@quiz = current_candidate.my_quiz @quiz = current_candidate.my_quiz
redirect_to :question and return unless prep_status.current_question_id.nil? redirect_to :question and return unless prep_status.current_question_id.nil?

View File

@ -7,6 +7,7 @@
name: "answer[checkbox][]", name: "answer[checkbox][]",
checked: Array(question.answer).include?(option) checked: Array(question.answer).include?(option)
} }
answers = answer.try(:answer) || answer
%> %>
<div class="form-group-multiples"> <div class="form-group-multiples">
<%= form.check_box(:answer, checkbox_html, option, '') %> <%= form.check_box(:answer, checkbox_html, option, '') %>
@ -14,4 +15,4 @@
</div> </div>
<% end %> <% end %>
<%= render partial: "quiz/answer_errors", locals: {question: question, answer: @answer} %> <%= render partial: "quiz/answer_errors", locals: {question: question, answer: answer} %>

View File

@ -1,19 +1,17 @@
<% <%
option_id = "#{question.question_id}_finish-later" option_id = "#{question.question_id}_finish-later"
checkbox_html = {class: 'checkbox', checkbox_html = {class: 'checkbox',
id: "answer_#{option_id}", id: "answer_#{option_id}",
name: "answer[#{question.input_type}][later]", name: "answer[#{question.input_type}][later]",
checked: Array(question.answer).include?('finish-later') checked: Array(question.answer).include?('finish-later')
} }
disabled = local_assigns.fetch :disable_input, false
answers = answer.try(:answer) || answer
%> %>
<!-- <div class="js-error">
Please revisit this page with JavaScript enabled to modify your answer.
</div> -->
<%= render partial: "quiz/answer_errors", locals: {question: question, answer: @answer} %> <%= render partial: "quiz/answer_errors", locals: {question: question, answer: answer} %>
<div data-id="live-coder-finish-later"> <div id="nojs<%= question.question_id %>" data-id="live-coder-finish-later">
<p class="warning"> <p class="warning">
This is a question where you will be asked to write code, and it utilizes a JavaScript-enabled This is a question where you will be asked to write code, and it utilizes a JavaScript-enabled
environment. It looks like JavaScript is not loaded. environment. It looks like JavaScript is not loaded.
@ -30,8 +28,27 @@
<% end %> <% end %>
</div> </div>
<div data-id="live-coder-answer"> <div id="answer<%= question.question_id %>" data-id="live-coder-answer" style="display: none;">
<% # answers inserted dynamically via jQuery .load() <div class="code-input">
# to check for JS capability/enabled <label for="answer_live_code_html">HTML</label>
%> <%= text_area_tag 'answer[live_code][html]', (answers['html']), { disabled: disabled, 'data-id' => 'code-html', class: 'code-answer code-html' } %>
</div>
<div class="code-input">
<label for="answer_live_code_css">CSS</label>
<%= text_area_tag 'answer[live_code][css]', (answers['css']), { disabled: disabled, 'data-id' => 'code-css', class: 'code-answer code-css' } %>
</div>
<div class="code-input">
<label for="answer_live_code_js">JS</label>
<%= text_area_tag 'answer[live_code][js]', (answers['js']), { disabled: disabled, 'data-id' => 'code-js', class: 'code-answer code-js' } %>
</div>
<div class="results" data-id="results"></div>
</div> </div>
<script>
<% # removes the no-js message SUPER FAST %>
document.getElementById("nojs<%= question.question_id %>").style.display = "none";
document.getElementById("answer<%= question.question_id %>").style.display = "";
</script>

View File

@ -1 +1,57 @@
<%= render partial: "quiz/live_code", locals: {question: question, form: form} %> <%
option_id = "#{question.question_id}_finish-later"
checkbox_html = {class: 'checkbox',
id: "answer_#{option_id}",
name: "answer[#{question.input_type}][later]",
checked: Array(question.answer).include?('finish-later')
}
disabled = local_assigns.fetch :disable_input, false
answers = answer.try(:answer) || answer
%>
<%= render partial: "quiz/answer_errors", locals: {question: question, answer: answer} %>
<div id="nojs<%= question.question_id %>" data-id="live-coder-finish-later">
<p class="warning">
This is a question where you will be asked to write code, and it utilizes a JavaScript-enabled
environment. It looks like JavaScript is not loaded.
<% unless params[:action] == 'summary' %>
Please check the box below to acknowledge that you agree to come back at a later time to finish
answering this question before you can submit the test.
<% else %>
You will need to enable JavaScript and answer this question before you can submit the test.
<% end %>
</p>
<% unless params[:action] == 'summary' %>
<%= form.check_box(:answer, checkbox_html, true, '') %>
<%= form.label(option_id, 'I will come back later to finish this code question') %>
<% end %>
</div>
<div id="answer<%= question.question_id %>" data-id="live-coder-answer" style="display: none;">
<label for="answer_live_code_text">Reasoning</label>
<%= text_area_tag 'answer[live_code_text][text]', (answers['text']) %>
<div class="code-input">
<label for="answer_live_code_html">HTML</label>
<%= text_area_tag 'answer[live_code_text][html]', (answers['html']), { disabled: disabled, 'data-id' => 'code-html', class: 'code-answer code-html' } %>
</div>
<div class="code-input">
<label for="answer_live_code_css">CSS</label>
<%= text_area_tag 'answer[live_code_text][css]', (answers['css']), { disabled: disabled, 'data-id' => 'code-css', class: 'code-answer code-css' } %>
</div>
<div class="code-input">
<label for="answer_live_code_js">JS</label>
<%= text_area_tag 'answer[live_code_text][js]', (answers['js']), { disabled: disabled, 'data-id' => 'code-js', class: 'code-answer code-js' } %>
</div>
<div class="results" data-id="results"></div>
</div>
<script>
<% # removes the no-js message SUPER FAST %>
document.getElementById("nojs<%= question.question_id %>").style.display = "none";
document.getElementById("answer<%= question.question_id %>").style.display = "";
</script>

View File

@ -2,6 +2,7 @@
question.input_options.each do | option | question.input_options.each do | option |
option_id = "#{option.parameterize}_#{question.to_i}" option_id = "#{option.parameterize}_#{question.to_i}"
radio_html = {class: 'radio', id: option_id} radio_html = {class: 'radio', id: option_id}
answers = answer.try(:answer) || answer
%> %>
<div class="form-group-multiples"> <div class="form-group-multiples">
<%= radio_button_tag('answer[radio]', option, (question.answer == option), radio_html) %> <%= radio_button_tag('answer[radio]', option, (question.answer == option), radio_html) %>
@ -9,4 +10,4 @@
</div> </div>
<% end %> <% end %>
<%= render partial: "quiz/answer_errors", locals: {question: question, answer: @answer} %> <%= render partial: "quiz/answer_errors", locals: {question: question, answer: answer} %>

View File

@ -1,8 +1,11 @@
<% hidden = params[:action] == 'summary' ? 'hidden' : '' %> <%
hidden = params[:action] == 'summary' ? 'hidden' : ''
answers = answer.try(:answer) || answer
%>
<label for="answer_text">Enter answer here</label> <label for="answer_text">Enter answer here</label>
<textarea id="answer_text" name="answer[text]" rows="10"><%= question.answer %></textarea> <textarea id="answer_text" name="answer[text]" rows="10"><%= answers %></textarea>
<div class="chars <%= hidden %>">Characters remaining: <span></span></div> <div class="chars <%= hidden %>">Characters remaining: <span></span></div>
<%= render partial: "quiz/answer_errors", locals: {question: question, answer: @answer} %> <%= render partial: "quiz/answer_errors", locals: {question: question, answer: answer} %>

View File

@ -1,18 +0,0 @@
<% answer = @answer.answer || {} %>
<div class="code-input">
<label for="answer_live_code_html">HTML</label>
<%= text_area_tag 'answer[live_code][html]', (answer['html']), { 'data-id' => 'code-html', class: 'code-answer code-html' } %>
</div>
<div class="code-input">
<label for="answer_live_code_css">CSS</label>
<%= text_area_tag 'answer[live_code][css]', (answer['css']), { 'data-id' => 'code-css', class: 'code-answer code-css' } %>
</div>
<div class="code-input">
<label for="answer_live_code_js">JS</label>
<%= text_area_tag 'answer[live_code][js]', (answer['js']), { 'data-id' => 'code-js', class: 'code-answer code-js' } %>
</div>
<div class="results" data-id="results"></div>

View File

@ -1,21 +0,0 @@
<% answer = @answer.answer || {} %>
<label for="answer_live_code_text">Reasoning</label>
<%= text_area_tag 'answer[live_code_text][text]', (answer['text']) %>
<div class="code-input">
<label for="answer_live_code_html">HTML</label>
<%= text_area_tag 'answer[live_code_text][html]', (answer['html']), { 'data-id' => 'code-html', class: 'code-answer code-html' } %>
</div>
<div class="code-input">
<label for="answer_live_code_css">CSS</label>
<%= text_area_tag 'answer[live_code_text][css]', (answer['css']), { 'data-id' => 'code-css', class: 'code-answer code-css' } %>
</div>
<div class="code-input">
<label for="answer_live_code_js">JS</label>
<%= text_area_tag 'answer[live_code_text][js]', (answer['js']), { 'data-id' => 'code-js', class: 'code-answer code-js' } %>
</div>
<div class="results" data-id="results"></div>

View File

@ -16,7 +16,7 @@
<div class="content-well"> <div class="content-well">
<%= hidden_field_tag 'answer[question_id]', @question.question_id %> <%= hidden_field_tag 'answer[question_id]', @question.question_id %>
<%= hidden_field_tag 'answer[answer_id]', @question.answer_id %> <%= hidden_field_tag 'answer[answer_id]', @question.answer_id %>
<%= render partial: @question.input_type, locals: {question: @question, form: form} %> <%= render partial: @question.input_type, locals: {question: @question, form: form, answer: @answer } %>
</div> </div>
<% if @status.on_summary %> <% if @status.on_summary %>

View File

@ -34,7 +34,8 @@
<fieldset disabled class="answer-block"> <fieldset disabled class="answer-block">
<%= hidden_field_tag 'answer[question_id]', question.question_id %> <%= hidden_field_tag 'answer[question_id]', question.question_id %>
<%= render partial: question.input_type, locals: {question: question, form: form} %> <%= hidden_field_tag 'answer[answer_id]', question.answer_id %>
<%= render partial: question.input_type, locals: {question: question, form: form, answer: question.answer, disable_input: true} %>
</fieldset> </fieldset>
</div> </div>
</article> </article>

View File

@ -21,7 +21,7 @@
<% end %> <% end %>
<fieldset disabled class="answer-block"> <fieldset disabled class="answer-block">
<%= hidden_field_tag 'answer[question_id]', question.question_id %> <%= hidden_field_tag 'answer[question_id]', question.question_id %>
<%= render partial: "quiz/#{question.input_type}", locals: {question: question, form: form} %> <%= render partial: "quiz/#{question.input_type}", locals: {question: question, answer: question.answer, form: form} %>
</fieldset> </fieldset>
</div> </div>
</article> </article>

View File

@ -9,7 +9,6 @@ Rails.application.routes.draw do
post "/question(/:answer_id)", to: "quiz#update_answer", as: :post_answer post "/question(/:answer_id)", to: "quiz#update_answer", as: :post_answer
get "/question(/:question_id)", to: "quiz#question", as: :question get "/question(/:question_id)", to: "quiz#question", as: :question
get "/live-coder-entry/:question_id", to: "quiz#live_coder", as: :live_coder
post "/summary", to: "quiz#update_summary", as: :post_summary post "/summary", to: "quiz#update_summary", as: :post_summary
get "/summary", to: "quiz#summary", as: :summary get "/summary", to: "quiz#summary", as: :summary

View File

@ -15,4 +15,15 @@ class QuestionLiveCoderTest < ActionDispatch::IntegrationTest
# TODO: add in capybara and test form post # TODO: add in capybara and test form post
# assert_redirected summary_path # assert_redirected summary_path
end end
test "can load a live coder TEXT question" do
setup_auth candidates(:dawn)
question = questions(:fed3)
get question_path(question.id)
assert_response :success
assert_select '.question-text', question.question
# TODO: add in capybara and test form post
# assert_redirected summary_path
end
end end