|
5 | 5 | = javascript_include_tag('timeout') |
6 | 6 | = javascript_include_tag("two_column_layout") |
7 | 7 | = javascript_include_tag("practice") |
8 | | -.col-12 |
9 | | - %h1 |
10 | | - = @exercise.display_name |
11 | | - - if current_user.andand.can? :edit, @exercise |
12 | | - %small |
13 | | - = link_to "", edit_exercise_path(@exercise), class: 'glyphicon glyphicon-pencil' |
14 | | - - if @exercise_version.stem && !@exercise_version.stem.preamble.blank? |
15 | | - - cache @exercise_version.stem do |
16 | | - = markdown @exercise_version.stem.preamble |
17 | | - -# |
18 | | - This loop repeats the one below in the answer column, so that the |
19 | | - prompt can go up top in the full-width div. This is broken, since it |
20 | | - will really only work for single-part exercises and will look bad for |
21 | | - multi-part exercises ... but we don't have real support for multi-part |
22 | | - exercises yet anyway. |
23 | | - - @exercise_version.prompts.each do |question_prompt| |
24 | | - - cache question_prompt do |
25 | | - = markdown question_prompt.question |
26 | | - - prompt = question_prompt.specific |
27 | | - - if prompt.is_coding? |
28 | | - - if !prompt.hide_examples && prompt.examples.any? |
29 | | - %p Examples: |
30 | | - %pre.examples |
31 | | - - prompt.examples.each do |example| |
32 | | - = example.display_description |
33 | | - %br |
34 | | -.col-md-7#user-deadline{ data: { deadline: @user_deadline, server_now: @server_now } } |
35 | | - %h2 Your Answer: |
36 | | - = semantic_form_for @exercise_version, |
37 | | - url: (@workout_offering ? organization_workout_offering_exercise_evaluate_path(id: @exercise_version.exercise.id, |
38 | | - course_id: @workout_offering.course_offering.course.slug, |
39 | | - organization_id: @workout_offering.course_offering.course.organization.slug, |
40 | | - term_id: @workout_offering.course_offering.term.slug, |
41 | | - workout_offering_id: @workout_offering.id, |
42 | | - lti_launch: @lti_launch) : exercise_evaluate_path(@exercise_version.exercise, |
43 | | - exercise_version_id: @exercise_version.id, |
44 | | - workout_id: @workout.andand.id, |
45 | | - feedback_return: true, lti_launch: @lti_launch, |
46 | | - lis_result_sourcedid: @workout_score.andand.lis_result_sourcedid, |
47 | | - lis_outcome_service_url: @workout_score.andand.lis_outcome_service_url)), remote: true do |f| |
48 | | - = f.semantic_errors |
49 | | - - if @msg |
50 | | - #timer.alert.alert-warning |
51 | | - = "#{@msg}" |
52 | | - #attempts-left |
53 | | - = render 'attempts_left', attempts_left: @attempts_left |
54 | | - - allow_write = true |
55 | | - - coding_questions = false |
| 8 | +.row |
| 9 | + .col-md-12 |
| 10 | + %h1 |
| 11 | + = @exercise.display_name |
| 12 | + - if current_user.andand.can? :edit, @exercise |
| 13 | + %small |
| 14 | + = link_to "", edit_exercise_path(@exercise), class: 'glyphicon glyphicon-pencil' |
| 15 | + - if @exercise_version.stem && !@exercise_version.stem.preamble.blank? |
| 16 | + - cache @exercise_version.stem do |
| 17 | + = markdown @exercise_version.stem.preamble |
| 18 | + -# |
| 19 | + This loop repeats the one below in the answer column, so that the |
| 20 | + prompt can go up top in the full-width div. This is broken, since it |
| 21 | + will really only work for single-part exercises and will look bad for |
| 22 | + multi-part exercises ... but we don't have real support for multi-part |
| 23 | + exercises yet anyway. |
56 | 24 | - @exercise_version.prompts.each do |question_prompt| |
| 25 | + - cache question_prompt do |
| 26 | + = markdown question_prompt.question |
57 | 27 | - prompt = question_prompt.specific |
58 | | - - if prompt.is_mcq? |
59 | | - - answers = @exercise_version.serve_choice_array(question_prompt) |
60 | | - - answers.each do |a| |
61 | | - - a[:answer] = markdown(a[:answer]) |
62 | | - - answer = Choice.new |
63 | | - - if prompt.allow_multiple |
64 | | - %h2 Choose ALL that apply: |
65 | | - .answers |
66 | | - = f.semantic_fields_for answer do |p| |
67 | | - = p.input :id, |
68 | | - as: :check_boxes, |
69 | | - collection: answers, |
70 | | - member_value: :id, |
71 | | - member_label: Proc.new{ |p| "#{p[:answer]}".html_safe }, |
72 | | - selected: false, |
73 | | - label: ' ' |
74 | | - - elsif @exercise_version.prompts.count > 1 |
75 | | - %h3 Select only one answer for each of the sub-questions: |
| 28 | + - if prompt.is_coding? |
| 29 | + - if !prompt.hide_examples && prompt.examples.any? |
| 30 | + %p Examples: |
| 31 | + %pre.examples |
| 32 | + - prompt.examples.each do |example| |
| 33 | + = example.display_description |
| 34 | + %br |
| 35 | + .col-md-7#user-deadline{ data: { deadline: @user_deadline, server_now: @server_now } } |
| 36 | + %h2 Your Answer: |
| 37 | + = semantic_form_for @exercise_version, |
| 38 | + url: (@workout_offering ? organization_workout_offering_exercise_evaluate_path(id: @exercise_version.exercise.id, |
| 39 | + course_id: @workout_offering.course_offering.course.slug, |
| 40 | + organization_id: @workout_offering.course_offering.course.organization.slug, |
| 41 | + term_id: @workout_offering.course_offering.term.slug, |
| 42 | + workout_offering_id: @workout_offering.id, |
| 43 | + lti_launch: @lti_launch) : exercise_evaluate_path(@exercise_version.exercise, |
| 44 | + exercise_version_id: @exercise_version.id, |
| 45 | + workout_id: @workout.andand.id, |
| 46 | + feedback_return: true, lti_launch: @lti_launch, |
| 47 | + lis_result_sourcedid: @workout_score.andand.lis_result_sourcedid, |
| 48 | + lis_outcome_service_url: @workout_score.andand.lis_outcome_service_url)), remote: true do |f| |
| 49 | + = f.semantic_errors |
| 50 | + - if @msg |
| 51 | + #timer.alert.alert-warning |
| 52 | + = "#{@msg}" |
| 53 | + #attempts-left |
| 54 | + = render 'attempts_left', attempts_left: @attempts_left |
| 55 | + - allow_write = true |
| 56 | + - coding_questions = false |
| 57 | + - @exercise_version.prompts.each do |question_prompt| |
| 58 | + - prompt = question_prompt.specific |
| 59 | + - if prompt.is_mcq? |
| 60 | + - answers = @exercise_version.serve_choice_array(question_prompt) |
| 61 | + - answers.each do |a| |
| 62 | + - a[:answer] = markdown(a[:answer]) |
| 63 | + - answer = Choice.new |
| 64 | + - if prompt.allow_multiple |
| 65 | + %h2 Choose ALL that apply: |
| 66 | + .answers |
| 67 | + = f.semantic_fields_for answer do |p| |
| 68 | + = p.input :id, |
| 69 | + as: :check_boxes, |
| 70 | + collection: answers, |
| 71 | + member_value: :id, |
| 72 | + member_label: Proc.new{ |p| "#{p[:answer]}".html_safe }, |
| 73 | + selected: false, |
| 74 | + label: ' ' |
| 75 | + - elsif @exercise_version.prompts.count > 1 |
| 76 | + %h3 Select only one answer for each of the sub-questions: |
| 77 | + - prior_answer = @attempt && @attempt.prompt_answers.where(prompt: prompt.acting_as).first |
| 78 | + - if prior_answer |
| 79 | + - answer = prior_answer.specific.choices.first || answer |
| 80 | + .answers |
| 81 | + = f.semantic_fields_for answer do |p| |
| 82 | + = p.input :id, |
| 83 | + as: :radio, |
| 84 | + input_html: {name: "prompt-" + prompt.id.to_s}, |
| 85 | + collection: answers, |
| 86 | + member_value: :id, |
| 87 | + member_label: Proc.new{ |p| "#{p[:answer]}".html_safe }, |
| 88 | + label: ' ' |
| 89 | + - else |
| 90 | + %h3 Select one answer: |
| 91 | + - prior_answer = @attempt && @attempt.prompt_answers.where(prompt: prompt.acting_as).first |
| 92 | + - if prior_answer |
| 93 | + - answer = prior_answer.specific.choices.first || answer |
| 94 | + .answers |
| 95 | + = f.semantic_fields_for answer do |p| |
| 96 | + = p.input :id, |
| 97 | + as: :radio, |
| 98 | + collection: answers, |
| 99 | + member_value: :id, |
| 100 | + member_label: Proc.new{ |p| "#{p[:answer]}".html_safe }, |
| 101 | + label: ' ' |
| 102 | + - elsif prompt.is_coding? |
| 103 | + - coding_questions = true |
76 | 104 | - prior_answer = @attempt && @attempt.prompt_answers.where(prompt: prompt.acting_as).first |
77 | | - - if prior_answer |
78 | | - - answer = prior_answer.specific.choices.first || answer |
79 | | - .answers |
80 | | - = f.semantic_fields_for answer do |p| |
81 | | - = p.input :id, |
82 | | - as: :radio, |
83 | | - input_html: {name: "prompt-" + prompt.id.to_s}, |
84 | | - collection: answers, |
85 | | - member_value: :id, |
86 | | - member_label: Proc.new{ |p| "#{p[:answer]}".html_safe }, |
87 | | - label: ' ' |
88 | | - - else |
89 | | - %h3 Select one answer: |
90 | | - - prior_answer = @attempt && @attempt.prompt_answers.where(prompt: prompt.acting_as).first |
91 | | - - if prior_answer |
92 | | - - answer = prior_answer.specific.choices.first || answer |
93 | | - .answers |
94 | | - = f.semantic_fields_for answer do |p| |
95 | | - = p.input :id, |
96 | | - as: :radio, |
97 | | - collection: answers, |
98 | | - member_value: :id, |
99 | | - member_label: Proc.new{ |p| "#{p[:answer]}".html_safe }, |
100 | | - label: ' ' |
101 | | - - elsif prompt.is_coding? |
102 | | - - coding_questions = true |
103 | | - - prior_answer = @attempt && @attempt.prompt_answers.where(prompt: prompt.acting_as).first |
104 | | - - if !prior_answer && @workout_offering.andand.continue_from_workout |
105 | | - - prior_score = @workout_offering.continue_from_workout.score_for(@student_user) |
106 | | - - prior_attempt = prior_score.previous_attempt_for(@exercise_version.exercise) |
107 | | - - prior_answer = prior_attempt && prior_attempt.prompt_answers.where(prompt: prompt.acting_as).first |
108 | | - // Getting this user's latest attempt on the exercise in the gym |
109 | | - - if !prior_answer && !@workout_score |
110 | | - - prior_attempt = @exercise.latest_attempt_for(current_user) |
111 | | - - prior_answer = prior_attempt && prior_attempt.prompt_answers.where(prompt: prompt.acting_as).first |
112 | | - - if prior_answer && @workout_offering |
113 | | - - if !@workout_offering.can_be_practiced_by?(current_user) |
114 | | - - allow_write = false |
115 | | - - if allow_write && params[:review_user_id].nil? |
116 | | - = f.input :answer_code, as: :text, class: 'code', |
117 | | - input_html: { class: 'code', readonly: true, autofocus: true, |
118 | | - value: prior_answer ? prior_answer.specific.answer : prompt.prepare_starter_code, |
119 | | - data: { lang: 'text/x-' + (@exercise.language + (@exercise.language == 'C++'?'src':'')|| 'java').downcase, |
120 | | - starter_code: prompt.prepare_starter_code } } |
121 | | - - else |
122 | | - %pre{ data: { lang: 'text/x-java' } } |
123 | | - = prior_answer ? prior_answer.specific.answer : prompt.prepare_starter_code |
124 | | - .actions |
125 | | - - disabled = !current_user.andand.is_staff?(@workout_offering.andand.course_offering) && @attempts_left && @attempts_left == 0 |
126 | | - - if @workout_offering.nil? || @workout_offering.can_be_practiced_by?(current_user) |
127 | | - - if @workout_offering.andand.workout_policy.andand.hide_feedback_before_finish && params[:review_user_id].nil? |
128 | | - = f.submit 'Save my answer!', |
129 | | - class: 'btn btn-primary btn-submit', |
130 | | - id: 'primarybtn', disabled: disabled |
131 | | - - elsif allow_write && params[:review_user_id].nil? |
132 | | - = f.submit 'Check my answer!', |
133 | | - class: 'btn btn-primary btn-submit', |
134 | | - id: 'primarybtn', disabled: disabled |
135 | | - - if coding_questions |
136 | | - %div.btn.btn-default{ data: { toggle: 'modal', target: '#confirm-reset' } } Reset |
137 | | - -if @exercise.tag_list.include? 'Visualizable' |
138 | | - -if @workout |
139 | | - -if @workout_offering |
140 | | - %div.btn.btn-default{id: "visualize", disabled: true, data: {workout: @workout.id, workout_offering: @workout_offering.id}} Visualize |
| 105 | + - if !prior_answer && @workout_offering.andand.continue_from_workout |
| 106 | + - prior_score = @workout_offering.continue_from_workout.score_for(@student_user) |
| 107 | + - prior_attempt = prior_score.previous_attempt_for(@exercise_version.exercise) |
| 108 | + - prior_answer = prior_attempt && prior_attempt.prompt_answers.where(prompt: prompt.acting_as).first |
| 109 | + // Getting this user's latest attempt on the exercise in the gym |
| 110 | + - if !prior_answer && !@workout_score |
| 111 | + - prior_attempt = @exercise.latest_attempt_for(current_user) |
| 112 | + - prior_answer = prior_attempt && prior_attempt.prompt_answers.where(prompt: prompt.acting_as).first |
| 113 | + - if prior_answer && @workout_offering |
| 114 | + - if !@workout_offering.can_be_practiced_by?(current_user) |
| 115 | + - allow_write = false |
| 116 | + - if allow_write && params[:review_user_id].nil? |
| 117 | + = f.input :answer_code, as: :text, class: 'code', |
| 118 | + input_html: { class: 'code', readonly: true, autofocus: true, |
| 119 | + value: prior_answer ? prior_answer.specific.answer : prompt.prepare_starter_code, |
| 120 | + data: { lang: 'text/x-' + (@exercise.language + (@exercise.language == 'C++'?'src':'')|| 'java').downcase, |
| 121 | + starter_code: prompt.prepare_starter_code } } |
| 122 | + - else |
| 123 | + %pre{ data: { lang: 'text/x-java' } } |
| 124 | + = prior_answer ? prior_answer.specific.answer : prompt.prepare_starter_code |
| 125 | + .actions |
| 126 | + - disabled = !current_user.andand.is_staff?(@workout_offering.andand.course_offering) && @attempts_left && @attempts_left == 0 |
| 127 | + - if @workout_offering.nil? || @workout_offering.can_be_practiced_by?(current_user) |
| 128 | + - if @workout_offering.andand.workout_policy.andand.hide_feedback_before_finish && params[:review_user_id].nil? |
| 129 | + = f.submit 'Save my answer!', |
| 130 | + class: 'btn btn-primary btn-submit', |
| 131 | + id: 'primarybtn', disabled: disabled |
| 132 | + - elsif allow_write && params[:review_user_id].nil? |
| 133 | + = f.submit 'Check my answer!', |
| 134 | + class: 'btn btn-primary btn-submit', |
| 135 | + id: 'primarybtn', disabled: disabled |
| 136 | + - if coding_questions |
| 137 | + %div.btn.btn-default{ data: { toggle: 'modal', target: '#confirm-reset' } } Reset |
| 138 | + -if @exercise.tag_list.include? 'Visualizable' |
| 139 | + -if @workout |
| 140 | + -if @workout_offering |
| 141 | + %div.btn.btn-default{id: "visualize", disabled: true, data: {workout: @workout.id, workout_offering: @workout_offering.id}} Visualize |
| 142 | + -else |
| 143 | + %div.btn.btn-default{id: "visualize", disabled: true, data: {workout: @workout.id, workout_offering: 'null'}} Visualize |
141 | 144 | -else |
142 | | - %div.btn.btn-default{id: "visualize", disabled: true, data: {workout: @workout.id, workout_offering: 'null'}} Visualize |
143 | | - -else |
144 | | - %div.btn.btn-default{id: "visualize", disabled: true, data: {workout: 'null', workout_offering: 'null'}} Visualize |
| 145 | + %div.btn.btn-default{id: "visualize", disabled: true, data: {workout: 'null', workout_offering: 'null'}} Visualize |
145 | 146 |
|
146 | | - - if @workout_offering && params[:review_user_id].nil? && @workout_offering.workout.exercise_workouts.size > 1 |
147 | | - = button_link 'Next exercise', |
148 | | - organization_workout_offering_practice_path(exercise_id: @workout.next_exercise(@exercise), |
149 | | - organization_id: @workout_offering.course_offering.course.organization.slug, |
150 | | - course_id: @workout_offering.course_offering.course.slug, |
151 | | - term_id: @workout_offering.course_offering.term.slug, |
152 | | - id: @workout_offering.id, |
153 | | - lti_launch: @lti_launch), |
154 | | - class: 'btn btn-default btn-next', id: 'nextbtn' |
155 | | - - elsif @workout && params[:review_user_id].nil? && @workout.exercise_workouts.size > 1 |
156 | | - = button_link 'Next exercise', |
157 | | - exercise_practice_path(@workout.next_exercise(@exercise), |
158 | | - workout_id: @workout.id, workout_score_id: @workout_score.andand.id, |
159 | | - lti_launch: @lti_launch), |
160 | | - class: 'btn btn-info btn-next', id: 'nextbtn' |
| 147 | + - if @workout_offering && params[:review_user_id].nil? && @workout_offering.workout.exercise_workouts.size > 1 |
| 148 | + = button_link 'Next exercise', |
| 149 | + organization_workout_offering_practice_path(exercise_id: @workout.next_exercise(@exercise), |
| 150 | + organization_id: @workout_offering.course_offering.course.organization.slug, |
| 151 | + course_id: @workout_offering.course_offering.course.slug, |
| 152 | + term_id: @workout_offering.course_offering.term.slug, |
| 153 | + id: @workout_offering.id, |
| 154 | + lti_launch: @lti_launch), |
| 155 | + class: 'btn btn-default btn-next', id: 'nextbtn' |
| 156 | + - elsif @workout && params[:review_user_id].nil? && @workout.exercise_workouts.size > 1 |
| 157 | + = button_link 'Next exercise', |
| 158 | + exercise_practice_path(@workout.next_exercise(@exercise), |
| 159 | + workout_id: @workout.id, workout_score_id: @workout_score.andand.id, |
| 160 | + lti_launch: @lti_launch), |
| 161 | + class: 'btn btn-info btn-next', id: 'nextbtn' |
161 | 162 |
|
162 | | - - if @workout.nil? && !@lti_launch |
163 | | - %br |
164 | | - = link_to "Practice a different #{@exercise.language} exercise", | |
165 | | - (@exercise.language ? | |
166 | | - random_exercise_path(language: @exercise.language) : | |
167 | | - random_exercise_path) | |
168 | | -.col-md-5 |
169 | | - %h2 Feedback |
170 | | - #saved_assurance |
171 | | - #previous_answer.previous_answer |
172 | | - - if @attempt |
173 | | - #exercisefeedback |
174 | | - = render partial: 'sse/ajax_feedback' |
175 | | - - else |
176 | | - #exercisefeedback |
177 | | - %p Your feedback will appear here when you check your answer. |
| 163 | + - if @workout.nil? && !@lti_launch |
| 164 | + %br |
| 165 | + = link_to "Practice a different #{@exercise.language} exercise", | |
| 166 | + (@exercise.language ? | |
| 167 | + random_exercise_path(language: @exercise.language) : | |
| 168 | + random_exercise_path) | |
| 169 | + .col-md-5 |
| 170 | + %h2 Feedback |
| 171 | + #saved_assurance |
| 172 | + #previous_answer.previous_answer |
| 173 | + - if @attempt |
| 174 | + #exercisefeedback |
| 175 | + = render partial: 'sse/ajax_feedback' |
| 176 | + - else |
| 177 | + #exercisefeedback |
| 178 | + %p Your feedback will appear here when you check your answer. |
178 | 179 |
|
179 | 180 | .modal.fade#confirm-reset{ tabindex: '-1', role: 'dialog', aria_labelledby: 'resetModalLabel', aria_hidden: true } |
180 | 181 | .modal-dialog |
|
0 commit comments