-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated for FW v5 compatibility (#9)
* update for v5 compatibility, version bump * remove reference to IE8 - it's not supported by this extension any more (as a result of FW v5 dependency) * use aria-disabled instead of disabled (to match latest FW behaviour) * use ES6 code where sensible * bump FW version to the one with ES6 support * fix eslint errors * Indentation amends * Added triple curly brace to aria label * Theme amends * remove .bowerrc Co-authored-by: Guy Willis <[email protected]>
- Loading branch information
Matt Leathes
authored
Mar 1, 2021
1 parent
21998c5
commit 4039c8b
Showing
6 changed files
with
185 additions
and
193 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,21 @@ | ||
{ | ||
"name": "adapt-submitAll", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/cgkineo/adapt-submitAll.git" | ||
}, | ||
"framework": ">=2", | ||
"homepage": "https://github.com/cgkineo/adapt-submitAll", | ||
"version": "2.1.0", | ||
"displayName": "Submit All", | ||
"extension": "submitAll", | ||
"description": "Extension to allow multiple questions to be submitted via a single submit button", | ||
"main": "/js/adapt-submitAll.js", | ||
"keywords": [ | ||
"adapt-plugin", | ||
"adapt-extension" | ||
], | ||
"license": "GPL-3.0", | ||
"targetAttribute": "_submitAll" | ||
"name": "adapt-submitAll", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/cgkineo/adapt-submitAll.git" | ||
}, | ||
"version": "3.0.0", | ||
"framework": ">=5.3", | ||
"homepage": "https://github.com/cgkineo/adapt-submitAll", | ||
"issues": "https://github.com/cgkineo/adapt-submitAll/issues/new", | ||
"extension": "submitAll", | ||
"displayName": "Submit All", | ||
"description": "Extension to allow multiple questions to be submitted via a single submit button", | ||
"main": "/js/adapt-submitAll.js", | ||
"keywords": [ | ||
"adapt-plugin", | ||
"adapt-extension" | ||
], | ||
"license": "GPL-3.0", | ||
"targetAttribute": "_submitAll" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
// To go in articles.json | ||
"_submitAll": { | ||
// To go in articles.json | ||
"_submitAll": { | ||
"_isEnabled": true, | ||
"_insertAfterBlock": "" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,147 +1,146 @@ | ||
define([ | ||
'core/js/adapt' | ||
'core/js/adapt' | ||
], function(Adapt) { | ||
|
||
var SubmitAll = Backbone.View.extend({ | ||
|
||
events: { | ||
'click .buttons-action': 'onSubmitAllButtonClicked' | ||
}, | ||
|
||
initialize: function() { | ||
this.model.get('_articleView').$el.addClass('noSubmitButtons'); | ||
|
||
this.listenTo(Adapt, { | ||
'componentView:postRender': this.onComponentViewRendered, | ||
remove: function() { | ||
this.removeEventListeners(); | ||
this.remove(); | ||
} | ||
}); | ||
|
||
_.bindAll(this, 'onInteraction', '_onInteractionDelegate'); | ||
|
||
this.render(); | ||
}, | ||
|
||
render: function() { | ||
var submitButtonLabels = Adapt.course.get('_buttons')._submit; | ||
|
||
this.$el.html(Handlebars.templates.submitAll({ | ||
buttonText: submitButtonLabels.buttonText, | ||
ariaLabel: submitButtonLabels.ariaLabel | ||
})); | ||
|
||
this.$el.addClass('submitAll'); | ||
|
||
var $containerDiv = this.getContainerDiv(this.model.get('_articleView').$el, this.model.get('_insertAfterBlock')); | ||
$containerDiv.after(this.$el); | ||
|
||
return this; | ||
}, | ||
|
||
/** | ||
* Returns a reference to the `<div>` we're going to append our view to. | ||
* @param {jQuery} $article JQuery reference to the article we're attached to | ||
* @param {string} [blockId] The id of the block to append our view to. Must be in the article we're attached to... | ||
* @return {jQuery} | ||
*/ | ||
getContainerDiv: function($article, blockId) { | ||
if (blockId) { | ||
var $div = $article.find('.' + blockId); | ||
if ($div.length > 0) return $div; | ||
} | ||
|
||
return $article.find('.block').last(); | ||
}, | ||
|
||
enableSubmitAllButton: function(enable) { | ||
var $submitAllButton = this.$el.find('.buttons-action'); | ||
if (enable) { | ||
$submitAllButton.removeClass('disabled').attr('disabled', false); | ||
return; | ||
} | ||
|
||
$submitAllButton.addClass('disabled').attr('disabled', true); | ||
}, | ||
|
||
/** | ||
* Checks all the questions in the article to see if they're all ready to be submitted or not | ||
* @return {boolean} | ||
*/ | ||
canSubmit: function() { | ||
return this.model.get('_componentViews').every(function(component) { | ||
if (component.model.get('_isEnabled') && component.canSubmit()) { | ||
return true; | ||
} | ||
}); | ||
}, | ||
|
||
removeEventListeners: function() { | ||
this.model.get('_componentViews').forEach(function(view) { | ||
if (view.model.get('_component') === 'textinput') { | ||
view.$el.find('input').off('change.submitAll'); | ||
return; | ||
} | ||
view.$el.off('click.submitAll'); | ||
}); | ||
}, | ||
|
||
/** | ||
* Checks the view to see if it is: | ||
* a) a question component | ||
* b) a child of the article we're attached to | ||
* And, if it is, add it to the list and listen out for the learner interacting with it | ||
* @param {Backbone.View} view | ||
*/ | ||
onComponentViewRendered: function(view) { | ||
if (!view.$el.hasClass('question-component')) return; | ||
|
||
var parentArticleId = view.model.findAncestor('articles').get('_id'); | ||
var submitAllArticleId = this.model.get('_articleView').model.get('_id'); | ||
if (parentArticleId === submitAllArticleId) { | ||
this.model.get('_componentViews').push(view); | ||
if (view.model.get('_component') === 'textinput') { | ||
view.$el.find('input').on('change.submitAll', this.onInteraction); | ||
return; | ||
} | ||
view.$el.on('click.submitAll', this.onInteraction); | ||
} | ||
}, | ||
|
||
onInteraction: function() { | ||
// need to wait until current call stack's done in FF | ||
_.defer(this._onInteractionDelegate); | ||
}, | ||
|
||
_onInteractionDelegate: function() { | ||
if (!!this.model.get('_isSubmitted')) return; | ||
|
||
this.enableSubmitAllButton(this.canSubmit()); | ||
}, | ||
|
||
onSubmitAllButtonClicked: function() { | ||
this.model.get('_componentViews').forEach(function(view) { | ||
$('.buttons-action', view.$el).trigger('click'); | ||
}); | ||
|
||
this.enableSubmitAllButton(false); | ||
|
||
this.model.set('_isSubmitted', true); | ||
|
||
Adapt.trigger('submitAll:submitted', this.model.get('_componentViews')); | ||
} | ||
}); | ||
|
||
Adapt.on('articleView:postRender', function(view) { | ||
var saData = view.model.get('_submitAll'); | ||
if(saData && saData._isEnabled) { | ||
var model = new Backbone.Model(saData); | ||
model.set({ | ||
_articleView: view, | ||
_componentViews: [] | ||
}); | ||
new SubmitAll({ model: model }); | ||
} | ||
}); | ||
}); | ||
const SubmitAll = Backbone.View.extend({ | ||
|
||
className: 'submit-all', | ||
|
||
events: { | ||
'click .js-btn-action': 'onSubmitAllButtonClicked' | ||
}, | ||
|
||
initialize: function() { | ||
this.model.get('_articleView').$el.addClass('no-submit-buttons'); | ||
|
||
this.listenTo(Adapt, { | ||
'componentView:postRender': this.onComponentViewRendered, | ||
remove: () => { | ||
this.removeEventListeners(); | ||
this.remove(); | ||
} | ||
}); | ||
|
||
_.bindAll(this, 'onInteraction', '_onInteractionDelegate'); | ||
|
||
this.render(); | ||
}, | ||
|
||
render: function() { | ||
const submitButtonLabels = Adapt.course.get('_buttons')._submit; | ||
|
||
this.$el.html(Handlebars.templates.submitAll({ | ||
buttonText: submitButtonLabels.buttonText, | ||
ariaLabel: submitButtonLabels.ariaLabel | ||
})); | ||
|
||
const $containerDiv = this.getContainerDiv(this.model.get('_articleView').$el, this.model.get('_insertAfterBlock')); | ||
$containerDiv.after(this.$el); | ||
|
||
return this; | ||
}, | ||
|
||
/** | ||
* Returns a reference to the `<div>` we're going to append our view to. | ||
* @param {jQuery} $article JQuery reference to the article we're attached to | ||
* @param {string} [blockId] The id of the block to append our view to. Must be in the article we're attached to... | ||
* @return {jQuery} | ||
*/ | ||
getContainerDiv: function($article, blockId) { | ||
if (blockId) { | ||
const $div = $article.find('.' + blockId); | ||
if ($div.length > 0) return $div; | ||
} | ||
|
||
return $article.find('.block').last(); | ||
}, | ||
|
||
enableSubmitAllButton: function(enable) { | ||
const $submitAllButton = this.$el.find('.js-btn-action'); | ||
if (enable) { | ||
$submitAllButton.removeClass('is-disabled').attr('aria-disabled', false); | ||
return; | ||
} | ||
|
||
$submitAllButton.addClass('is-disabled').attr('aria-disabled', true); | ||
}, | ||
|
||
/** | ||
* Checks all the questions in the article to see if they're all ready to be submitted or not | ||
* @return {boolean} | ||
*/ | ||
canSubmit: function() { | ||
const allAnswered = this.model.get('_componentViews').every(component => component.model.get('_isEnabled') && component.canSubmit()); | ||
return allAnswered; | ||
}, | ||
|
||
removeEventListeners: function() { | ||
this.model.get('_componentViews').forEach(view => { | ||
if (view.model.get('_component') === 'textinput') { | ||
view.$el.find('input').off('change.submitAll'); | ||
return; | ||
} | ||
view.$el.off('click.submitAll'); | ||
}); | ||
}, | ||
|
||
/** | ||
* Checks the view to see if it is: | ||
* a) a question component | ||
* b) a child of the article we're attached to | ||
* And, if it is, add it to the list and listen out for the learner interacting with it | ||
* @param {Backbone.View} view | ||
*/ | ||
onComponentViewRendered: function(view) { | ||
if (!view.$el.hasClass('is-question')) return; | ||
|
||
const parentArticleId = view.model.findAncestor('articles').get('_id'); | ||
const submitAllArticleId = this.model.get('_articleView').model.get('_id'); | ||
if (parentArticleId !== submitAllArticleId) return; | ||
|
||
this.model.get('_componentViews').push(view); | ||
|
||
if (view.model.get('_component') === 'textinput') { | ||
view.$el.find('input').on('change.submitAll', this.onInteraction); | ||
return; | ||
} | ||
|
||
view.$el.on('click.submitAll', this.onInteraction); | ||
}, | ||
|
||
onInteraction: function() { | ||
// need to wait until current call stack's done in FF | ||
_.defer(this._onInteractionDelegate); | ||
}, | ||
|
||
_onInteractionDelegate: function() { | ||
if (this.model.get('_isSubmitted')) return; | ||
|
||
this.enableSubmitAllButton(this.canSubmit()); | ||
}, | ||
|
||
onSubmitAllButtonClicked: function() { | ||
this.model.get('_componentViews').forEach(view => view.$el.find('.js-btn-action').trigger('click')); | ||
|
||
this.enableSubmitAllButton(false); | ||
|
||
this.model.set('_isSubmitted', true); | ||
|
||
Adapt.trigger('submitAll:submitted', this.model.get('_componentViews')); | ||
} | ||
}); | ||
|
||
Adapt.on('articleView:postRender', view => { | ||
const saData = view.model.get('_submitAll'); | ||
if (!saData || !saData._isEnabled) return; | ||
|
||
const model = new Backbone.Model({ | ||
...saData, | ||
_isSubmitted: false, | ||
_articleView: view, | ||
_componentViews: [] | ||
}); | ||
|
||
new SubmitAll({ model }); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,16 @@ | ||
.noSubmitButtons { | ||
.buttons { | ||
display:none; | ||
} | ||
.no-submit-buttons { | ||
.btn__container { | ||
display: none; | ||
} | ||
} | ||
|
||
.submitAll { | ||
.buttons { | ||
display: block; | ||
|
||
.buttons-cluster { | ||
text-align: center; | ||
} | ||
|
||
.buttons-action { | ||
float:none; | ||
|
||
& .disabled { | ||
|
||
} | ||
} | ||
} | ||
.submit-all { | ||
.btn__container { | ||
display: block; | ||
} | ||
|
||
.btn__action { | ||
width: @device-width-large; | ||
margin: 0 auto; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
<div class="buttons"> | ||
<div class="buttons-inner"> | ||
<div class="buttons-cluster clearfix"> | ||
<button class="buttons-action disabled" aria-label="{{ariaLabel}}" disabled="disabled">{{{buttonText}}}</button> | ||
</div> | ||
</div> | ||
<div class="btn__container"> | ||
<div class="btn__response-container"> | ||
|
||
<button class="btn-text btn__action js-btn-action is-disabled" aria-label="{{{ariaLabel}}}" aria-disabled="true"> | ||
{{{buttonText}}} | ||
</button> | ||
|
||
</div> | ||
</div> |