Commit 28bdb0bb by Valera Rozuvan

Merge pull request #2822 from edx/valera/convert_collapsible_to_js

Converting Collapsible module to JS.
parents 5be58fc1 1136336f
......@@ -40,11 +40,16 @@ class AnnotatableFields(object):
class AnnotatableModule(AnnotatableFields, XModule):
js = {'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee'),
resource_string(__name__, 'js/src/collapsible.coffee'),
resource_string(__name__, 'js/src/html/display.coffee'),
resource_string(__name__, 'js/src/annotatable/display.coffee')],
'js': []}
js = {
'coffee': [
resource_string(__name__, 'js/src/javascript_loader.coffee'),
resource_string(__name__, 'js/src/html/display.coffee'),
resource_string(__name__, 'js/src/annotatable/display.coffee'),
],
'js': [
resource_string(__name__, 'js/src/collapsible.js'),
]
}
js_module_name = "Annotatable"
css = {'scss': [resource_string(__name__, 'css/annotatable/display.scss')]}
icon_class = 'annotatable'
......
......@@ -23,13 +23,17 @@ class CapaModule(CapaMixin, XModule):
"""
icon_class = 'problem'
js = {'coffee': [resource_string(__name__, 'js/src/capa/display.coffee'),
resource_string(__name__, 'js/src/collapsible.coffee'),
resource_string(__name__, 'js/src/javascript_loader.coffee'),
],
'js': [resource_string(__name__, 'js/src/capa/imageinput.js'),
resource_string(__name__, 'js/src/capa/schematic.js')
]}
js = {
'coffee': [
resource_string(__name__, 'js/src/capa/display.coffee'),
resource_string(__name__, 'js/src/javascript_loader.coffee'),
],
'js': [
resource_string(__name__, 'js/src/collapsible.js'),
resource_string(__name__, 'js/src/capa/imageinput.js'),
resource_string(__name__, 'js/src/capa/schematic.js'),
]
}
js_module_name = "Problem"
css = {'scss': [resource_string(__name__, 'css/capa/display.scss')]}
......
......@@ -395,12 +395,13 @@ class CombinedOpenEndedModule(CombinedOpenEndedFields, XModule):
icon_class = 'problem'
js = {
'coffee':
[
resource_string(__name__, 'js/src/combinedopenended/display.coffee'),
resource_string(__name__, 'js/src/collapsible.coffee'),
resource_string(__name__, 'js/src/javascript_loader.coffee'),
]
'coffee': [
resource_string(__name__, 'js/src/combinedopenended/display.coffee'),
resource_string(__name__, 'js/src/javascript_loader.coffee'),
],
'js': [
resource_string(__name__, 'js/src/collapsible.js'),
]
}
js_module_name = "CombinedOpenEnded"
......
......@@ -63,10 +63,15 @@ class ConditionalModule(ConditionalFields, XModule):
"""
js = {'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee'),
resource_string(__name__, 'js/src/conditional/display.coffee'),
resource_string(__name__, 'js/src/collapsible.coffee'),
]}
js = {
'coffee': [
resource_string(__name__, 'js/src/javascript_loader.coffee'),
resource_string(__name__, 'js/src/conditional/display.coffee'),
],
'js': [
resource_string(__name__, 'js/src/collapsible.js'),
]
}
js_module_name = "Conditional"
css = {'scss': [resource_string(__name__, 'css/capa/display.scss')]}
......
......@@ -42,12 +42,12 @@ class HtmlModule(HtmlFields, XModule):
js = {
'coffee': [
resource_string(__name__, 'js/src/javascript_loader.coffee'),
resource_string(__name__, 'js/src/collapsible.coffee'),
resource_string(__name__, 'js/src/html/display.coffee')
resource_string(__name__, 'js/src/html/display.coffee'),
],
'js': [
resource_string(__name__, 'js/src/collapsible.js'),
resource_string(__name__, 'js/src/html/imageModal.js'),
resource_string(__name__, 'js/common_static/js/vendor/draggabilly.pkgd.js')
resource_string(__name__, 'js/common_static/js/vendor/draggabilly.pkgd.js'),
]
}
js_module_name = "HTMLModule"
......
......@@ -5,3 +5,4 @@
# Tests for Time are written in pure JavaScript.
!time_spec.js
!collapsible_spec.js
describe 'Collapsible', ->
html = custom_labels = html_custom = el = undefined
initialize = (template) =>
setFixtures(template)
el = $('.collapsible')
Collapsible.setCollapsibles(el)
disableFx = () =>
$.fx.off = true
enableFx = () =>
$.fx.off = false
beforeEach ->
html = '''
<section class="collapsible">
<div class="shortform">
shortform message
</div>
<div class="longform">
<p>longform is visible</p>
</div>
</section>
'''
html_custom = '''
<section class="collapsible">
<div class="shortform-custom" data-open-text="Show shortform-custom" data-close-text="Hide shortform-custom">
shortform message
</div>
<div class="longform">
<p>longform is visible</p>
</div>
</section>
'''
describe 'setCollapsibles', ->
it 'Default container initialized correctly', ->
initialize(html)
expect(el.find('.shortform')).toContain '.full-top'
expect(el.find('.shortform')).toContain '.full-bottom'
expect(el.find('.longform')).toBeHidden()
expect(el.find('.full')).toHandle('click')
it 'Custom container initialized correctly', ->
initialize(html_custom)
expect(el.find('.shortform-custom')).toContain '.full-custom'
expect(el.find('.full-custom')).toHaveText "Show shortform-custom"
expect(el.find('.longform')).toBeHidden()
expect(el.find('.full-custom')).toHandle('click')
describe 'toggleFull', ->
beforeEach ->
disableFx()
afterEach ->
enableFx()
it 'Default container', ->
initialize(html)
event = jQuery.Event('click', {
target: el.find('.full').get(0)
})
assertChanges = (state='closed') =>
anchors = el.find('.full')
if state is 'closed'
expect(el.find('.longform')).toBeHidden()
expect(el).not.toHaveClass('open')
text = "See full output"
else
expect(el.find('.longform')).toBeVisible()
expect(el).toHaveClass('open')
text = "Hide output"
$.each anchors, (index, el) =>
expect(el).toHaveText text
Collapsible.toggleFull(event, "See full output", "Hide output")
assertChanges('opened')
Collapsible.toggleFull(event, "See full output", "Hide output")
assertChanges('closed')
it 'Custom container', ->
initialize(html_custom)
event = jQuery.Event('click', {
target: el.find('.full-custom').get(0)
})
assertChanges = (state='closed') =>
anchors = el.find('.full-custom')
if state is 'closed'
expect(el.find('.longform')).toBeHidden()
expect(el).not.toHaveClass('open')
text = "Show shortform-custom"
else
expect(el.find('.longform')).toBeVisible()
expect(el).toHaveClass('open')
text = "Hide shortform-custom"
$.each anchors, (index, el) =>
expect(el).toHaveText text
Collapsible.toggleFull(event, "Show shortform-custom", "Hide shortform-custom")
assertChanges('opened')
Collapsible.toggleFull(event, "Show shortform-custom", "Hide shortform-custom")
assertChanges('closed')
(function (undefined) {
'use strict';
describe('Collapsible', function () {
var el, html, html_custom,
initialize = function (template) {
setFixtures(template);
el = $('.collapsible');
Collapsible.setCollapsibles(el);
},
disableFx = function () {
$.fx.off = true;
},
enableFx = function () {
$.fx.off = false;
};
beforeEach(function () {
html = '' +
'<section class="collapsible">' +
'<div class="shortform">shortform message</div>' +
'<div class="longform">' +
'<p>longform is visible</p>' +
'</div>' +
'</section>';
html_custom = '' +
'<section class="collapsible">' +
'<div ' +
'class="shortform-custom" ' +
'data-open-text="Show shortform-custom" ' +
'data-close-text="Hide shortform-custom"' +
'>shortform message</div>' +
'<div class="longform">' +
'<p>longform is visible</p>' +
'</div>' +
'</section>';
});
describe('setCollapsibles', function () {
it('Default container initialized correctly', function () {
initialize(html);
expect(el.find('.shortform')).toContain('.full-top');
expect(el.find('.shortform')).toContain('.full-bottom');
expect(el.find('.longform')).toBeHidden();
expect(el.find('.full')).toHandle('click');
});
it('Custom container initialized correctly', function () {
initialize(html_custom);
expect(el.find('.shortform-custom')).toContain('.full-custom');
expect(el.find('.full-custom')).toHaveText('Show shortform-custom');
expect(el.find('.longform')).toBeHidden();
expect(el.find('.full-custom')).toHandle('click');
});
});
describe('toggleFull', function () {
var assertChanges = function (state, anchorsElClass, showText, hideText) {
var anchors, text;
if (state == null) {
state = 'closed';
}
anchors = el.find('.' + anchorsElClass);
if (state === 'closed') {
expect(el.find('.longform')).toBeHidden();
expect(el).not.toHaveClass('open');
text = showText;
} else {
expect(el.find('.longform')).toBeVisible();
expect(el).toHaveClass('open');
text = hideText;
}
$.each(anchors, function (index, el) {
expect(el).toHaveText(text);
});
};
beforeEach(function () {
disableFx();
});
afterEach(function () {
enableFx();
});
it('Default container', function () {
var event;
initialize(html);
event = jQuery.Event('click', {
target: el.find('.full').get(0)
});
Collapsible.toggleFull(event, 'See full output', 'Hide output');
assertChanges('opened', 'full', 'See full output', 'Hide output');
Collapsible.toggleFull(event, 'See full output', 'Hide output');
assertChanges('closed', 'full', 'See full output', 'Hide output');
});
it('Custom container', function () {
var event;
initialize(html_custom);
event = jQuery.Event('click', {
target: el.find('.full-custom').get(0)
});
Collapsible.toggleFull(event, 'Show shortform-custom', 'Hide shortform-custom');
assertChanges('opened', 'full-custom', 'Show shortform-custom', 'Hide shortform-custom');
Collapsible.toggleFull(event, 'Show shortform-custom', 'Hide shortform-custom');
assertChanges('closed', 'full-custom', 'Show shortform-custom', 'Hide shortform-custom');
});
});
});
}).call(this);
......@@ -11,3 +11,4 @@
# Converted to JS from CoffeeScript.
!time.js
!collapsible.js
class @Collapsible
# Set of library functions that provide a simple way to add collapsible
# functionality to elements.
# setCollapsibles:
# Scan element's content for generic collapsible containers
@setCollapsibles: (el) =>
###
el: container
###
linkTop = '<a href="#" class="full full-top">See full output</a>'
linkBottom = '<a href="#" class="full full-bottom">See full output</a>'
# standard longform + shortfom pattern
el.find('.longform').hide()
el.find('.shortform').append(linkTop, linkBottom)
# custom longform + shortform text pattern
short_custom = el.find('.shortform-custom')
# set up each one individually
short_custom.each (index, elt) =>
open_text = $(elt).data('open-text')
close_text = $(elt).data('close-text')
$(elt).append("<a href='#' class='full-custom'>"+ open_text + "</a>")
$(elt).find('.full-custom').click (event) => @toggleFull(event, open_text, close_text)
# collapsible pattern
el.find('.collapsible header + section').hide()
# set up triggers
el.find('.full').click (event) => @toggleFull(event, "See full output", "Hide output")
el.find('.collapsible header a').click @toggleHint
@toggleFull: (event, open_text, close_text) =>
event.preventDefault()
parent = $(event.target).parent()
parent.siblings().slideToggle()
parent.parent().toggleClass('open')
if $(event.target).text() == open_text
new_text = close_text
else
new_text = open_text
if $(event.target).hasClass('full')
el = parent.find('.full')
else
el = $(event.target)
el.text(new_text)
@toggleHint: (event) =>
event.preventDefault()
$(event.target).parent().siblings().slideToggle()
$(event.target).parent().parent().toggleClass('open')
(function (undefined) {
'use strict';
// [module Collapsible]
//
// [description]
// Set of library functions that provide a simple way to add
// collapsible functionality to elements.
this.Collapsible = {
setCollapsibles: setCollapsibles,
toggleFull: toggleFull,
toggleHint: toggleHint
};
return;
// [function setCollapsibles]
//
// [description]
// Scan element's content for generic collapsible containers.
//
// [params]
// el: container
function setCollapsibles(el) {
var linkBottom, linkTop, short_custom;
linkTop = '<a href="#" class="full full-top">See full output</a>';
linkBottom = '<a href="#" class="full full-bottom">See full output</a>';
// Standard longform + shortfom pattern.
el.find('.longform').hide();
el.find('.shortform').append(linkTop, linkBottom);
// Custom longform + shortform text pattern.
short_custom = el.find('.shortform-custom');
// Set up each one individually.
short_custom.each(function (index, elt) {
var close_text, open_text;
open_text = $(elt).data('open-text');
close_text = $(elt).data('close-text');
$(elt).append("<a href='#' class='full-custom'>" + open_text + "</a>");
$(elt).find('.full-custom').click(function (event) {
Collapsible.toggleFull(event, open_text, close_text);
});
});
// Collapsible pattern.
el.find('.collapsible header + section').hide();
// Set up triggers.
el.find('.full').click(function (event) {
Collapsible.toggleFull(event, "See full output", "Hide output");
});
el.find('.collapsible header a').click(Collapsible.toggleHint);
}
// [function toggleFull]
//
// [description]
// Toggle the display of full text for a collapsible element.
//
// [params]
// event: jQuery event object associated with the event that
// triggered this callback function.
// open_text: text that should be displayed when the collapsible
// is open.
// close_text: text that should be displayed when the collapsible
// is closed.
function toggleFull(event, open_text, close_text) {
var el, new_text, parent;
event.preventDefault();
parent = $(event.target).parent();
parent.siblings().slideToggle();
parent.parent().toggleClass('open');
if ($(event.target).text() === open_text) {
new_text = close_text;
} else {
new_text = open_text;
}
if ($(event.target).hasClass('full')) {
el = parent.find('.full');
} else {
el = $(event.target);
}
el.text(new_text);
}
// [function toggleHint]
//
// [description]
// Toggle the collapsible open to show the hint.
//
// [params]
// event: jQuery event object associated with the event that
// triggered this callback function.
function toggleHint(event) {
event.preventDefault();
$(event.target).parent().siblings().slideToggle();
$(event.target).parent().parent().toggleClass('open');
}
}).call(this);
......@@ -100,8 +100,10 @@ class PeerGradingModule(PeerGradingFields, XModule):
'coffee': [
resource_string(__name__, 'js/src/peergrading/peer_grading.coffee'),
resource_string(__name__, 'js/src/peergrading/peer_grading_problem.coffee'),
resource_string(__name__, 'js/src/collapsible.coffee'),
resource_string(__name__, 'js/src/javascript_loader.coffee'),
],
'js': [
resource_string(__name__, 'js/src/collapsible.js'),
]
}
js_module_name = "PeerGrading"
......@@ -718,4 +720,3 @@ class PeerGradingDescriptor(PeerGradingFields, RawDescriptor):
show_calibration_essay = module_attr('show_calibration_essay')
use_for_single_location_local = module_attr('use_for_single_location_local')
_find_corresponding_module_for_location = module_attr('_find_corresponding_module_for_location')
......@@ -35,12 +35,16 @@ class AnnotatableFields(object):
class VideoAnnotationModule(AnnotatableFields, XModule):
'''Video Annotation Module'''
js = {'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee'),
resource_string(__name__, 'js/src/collapsible.coffee'),
resource_string(__name__, 'js/src/html/display.coffee'),
resource_string(__name__, 'js/src/annotatable/display.coffee')
],
'js': []}
js = {
'coffee': [
resource_string(__name__, 'js/src/javascript_loader.coffee'),
resource_string(__name__, 'js/src/html/display.coffee'),
resource_string(__name__, 'js/src/annotatable/display.coffee'),
],
'js': [
resource_string(__name__, 'js/src/collapsible.js'),
]
}
css = {'scss': [resource_string(__name__, 'css/annotatable/display.scss')]}
icon_class = 'videoannotation'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment