diff --git a/lms/static/coffee/fixtures/calculator.html b/lms/static/coffee/fixtures/calculator.html
index 638dcc0b1f..5398c7a776 100644
--- a/lms/static/coffee/fixtures/calculator.html
+++ b/lms/static/coffee/fixtures/calculator.html
@@ -8,6 +8,14 @@
Hints
diff --git a/lms/static/coffee/spec/calculator_spec.coffee b/lms/static/coffee/spec/calculator_spec.coffee
index ed10bb26a6..8b70262b9b 100644
--- a/lms/static/coffee/spec/calculator_spec.coffee
+++ b/lms/static/coffee/spec/calculator_spec.coffee
@@ -19,16 +19,12 @@ describe 'Calculator', ->
it 'bind the calculator button', ->
expect($('.calc')).toHandleWith 'click', @calculator.toggle
- it 'bind the help button', ->
- # These events are bind by $.hover()
- expect($('#calculator_hint')).toHandle 'mouseover'
- expect($('#calculator_hint')).toHandle 'mouseout'
- expect($('#calculator_hint')).toHandle 'keydown'
+ it 'bind key up on calculator', ->
+ expect($('#calculator_wrapper')).toHandle 'keyup', @calculator.handleKeyUpOnHint
- it 'prevent default behavior on help button', ->
- $('#calculator_hint').click (e) ->
- expect(e.isDefaultPrevented()).toBeTruthy()
- $('#calculator_hint').click()
+ it 'bind the help button', ->
+ # This events is bind by $.click()
+ expect($('#calculator_hint')).toHandle 'click'
it 'bind the calculator submit', ->
expect($('form#calculator')).toHandleWith 'submit', @calculator.calculate
@@ -75,6 +71,12 @@ describe 'Calculator', ->
expect($('.help')).not.toHaveClass('shown')
expect($('.help')).toHaveAttr('aria-hidden', 'true')
+ describe 'handleClickOnHintButton', ->
+ it 'on click hint button hint popup becomes visible ', ->
+ e = jQuery.Event('click');
+ $('#calculator_hint').trigger(e);
+ expect($('.help')).toHaveClass 'shown'
+
describe 'handleClickOnDocument', ->
it 'on click out of the hint popup it becomes hidden', ->
@calculator.showHint()
@@ -82,6 +84,13 @@ describe 'Calculator', ->
$(document).trigger(e);
expect($('.help')).not.toHaveClass 'shown'
+ describe 'handleClickOnHintPopup', ->
+ it 'on click of hint popup it remains visible', ->
+ @calculator.showHint()
+ e = jQuery.Event('click');
+ $('#calculator_input_help').trigger(e);
+ expect($('.help')).toHaveClass 'shown'
+
describe 'selectHint', ->
it 'select correct hint item', ->
spyOn($.fn, 'focus')
@@ -108,7 +117,7 @@ describe 'Calculator', ->
expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'))
- it 'Prev hint item is selected', ->
+ it 'if this was the second item, select the first one', ->
@calculator.activeHint = $('.hint-item').eq(1)
@calculator.prevHint()
@@ -118,20 +127,32 @@ describe 'Calculator', ->
@calculator.activeHint = $('.hint-item').eq(0)
@calculator.prevHint()
+ expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(2).attr('id'))
+
+ it 'if this was the last item, select the second last', ->
+ @calculator.activeHint = $('.hint-item').eq(2)
+ @calculator.prevHint()
+
expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(1).attr('id'))
describe 'nextHint', ->
- it 'Next hint item is selected', ->
+ it 'if this was the first item, select the second one', ->
@calculator.activeHint = $('.hint-item').eq(0)
@calculator.nextHint()
expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(1).attr('id'))
- it 'If this was the last item, select the first one', ->
+ it 'If this was the second item, select the last one', ->
@calculator.activeHint = $('.hint-item').eq(1)
@calculator.nextHint()
+ expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(2).attr('id'))
+
+ it 'If this was the last item, select the first one', ->
+ @calculator.activeHint = $('.hint-item').eq(2)
+ @calculator.nextHint()
+
expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'))
describe 'handleKeyDown', ->
@@ -264,14 +285,6 @@ describe 'Calculator', ->
not_called:
'nextHint': calc
- tab:
- returnedValue: true
- event:
- keyCode: KEY.TAB
- shiftKey: false
- called:
- 'hideHint': calc
-
esc:
returnedValue: false
event:
diff --git a/lms/static/coffee/src/calculator.coffee b/lms/static/coffee/src/calculator.coffee
index 60fe3936fd..ce881e08b4 100644
--- a/lms/static/coffee/src/calculator.coffee
+++ b/lms/static/coffee/src/calculator.coffee
@@ -22,16 +22,17 @@ class @Calculator
$('form#calculator').submit(@calculate).submit (e) ->
e.preventDefault()
@hintButton
- .hover(
- $.proxy(@showHint, @),
- $.proxy(@hideHint, @)
- )
- .keydown($.proxy(@handleKeyDown, @))
- .click (e) -> e.preventDefault()
+ .click(($.proxy(@handleClickOnHintButton, @)))
+
+ @hintPopup
+ .click(($.proxy(@handleClickOnHintPopup, @)))
@hintPopup
.keydown($.proxy(@handleKeyDownOnHint, @))
+ $('#calculator_wrapper')
+ .keyup($.proxy(@handleKeyUpOnHint, @))
+
@handleClickOnDocument = $.proxy(@handleClickOnDocument, @)
KEY:
@@ -140,9 +141,6 @@ class @Calculator
return true
switch e.keyCode
- when @KEY.TAB
- # hide popup with hints
- @hideHint()
when @KEY.ESC
# hide popup with hints
@@ -175,11 +173,27 @@ class @Calculator
# allow the event to propagate
return true
+ handleKeyUpOnHint: (e) ->
+ switch e.keyCode
+ when @KEY.TAB
+ # move focus to hint links and hide hint once focus is out of hint pop up
+ @active_element = document.activeElement
+ if not $(@active_element).parents().is(@hintPopup)
+ @hideHint()
+
handleClickOnDocument: (e) ->
@hideHint()
- # allow the event to propagate
- return true;
+ handleClickOnHintButton: (e) ->
+ e.stopPropagation()
+ if @hintPopup.hasClass 'shown'
+ @hideHint()
+ else
+ @showHint()
+ @activeHint.focus()
+
+ handleClickOnHintPopup: (e) ->
+ e.stopPropagation()
calculate: ->
$.getWithPrefix '/calculate', { equation: $('#calculator_input').val() }, (data) ->