Skip to content

Commit a6ccf5c

Browse files
committed
fixes #187
1 parent 16d1db1 commit a6ccf5c

File tree

3 files changed

+170
-169
lines changed

3 files changed

+170
-169
lines changed

app/assets/stylesheets/custom.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ html, body { height: 100%; }
1818
padding-left: 0px;
1919
padding-right: 0px;
2020
}
21-
.content, .maincol {
22-
padding-bottom: 40px;
21+
.content .inner, .maincol {
22+
padding-bottom: 60px;
2323
}
2424
.content {
2525
h1.left-padded {

app/views/exercises/practice.html.haml

Lines changed: 165 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -5,176 +5,177 @@
55
= javascript_include_tag('timeout')
66
= javascript_include_tag("two_column_layout")
77
= 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.
5624
- @exercise_version.prompts.each do |question_prompt|
25+
- cache question_prompt do
26+
= markdown question_prompt.question
5727
- 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
76104
- 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
141144
-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
145146

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'
161162

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.
178179

179180
.modal.fade#confirm-reset{ tabindex: '-1', role: 'dialog', aria_labelledby: 'resetModalLabel', aria_hidden: true }
180181
.modal-dialog

app/views/layouts/two_columns.html.haml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
- main_content_width = ['col-md-12']
55
- if !@hide_sidebar # if this flag is not set, show the sidebar by default
66
- main_content_width = ['col-md-9']
7-
.col-md-3.scrollable.max-height.sidebar
8-
.inner.max-height
7+
.col-md-3.scrollable.full-height.sidebar
8+
.inner.full-height
99
.below-nav#sidebar
1010
= render partial: 'layouts/sidebar', locals: { user: @student_user ? @student_user : current_user }
1111
- main_content = main_content + main_content_width
1212
%div{ class: main_content }
1313
%button.btn-primary.toggle-slider{ style: 'display: none', data: { is_open: false } }
1414
%i.fa.fa-bars
1515
Exercises
16-
.inner.max-height
16+
.inner.full-height
1717
.below-nav
1818
= render partial: 'layouts/flash'
1919
= yield

0 commit comments

Comments
 (0)