H5PEditor.ShowWhen = (function ($) {
// Handler for the 'select' semantics type
function SelectHandler(field, equals) {
this.satisfied = function () {
return (equals.indexOf(field.value) !== -1);
};
}
// Handler for the 'library' semantics type
function LibraryHandler(field, equals) {
this.satisfied = function () {
var value;
if (field.currentLibrary !== undefined && field.params.library) {
value = field.currentLibrary.split(' ')[0];
}
return (equals.indexOf(value) !== -1);
};
}
function BooleanHandler(field, equals) {
this.satisfied = function () {
return field.value === equals;
};
}
// Factory method for creating handlers
// "library", "select" and "boolean" semantics types supported so far
function createFieldHandler(field, equals) {
if (field.field.type === 'library') {
return new LibraryHandler(field, equals);
}
else if (field.field.type === 'select') {
return new SelectHandler(field, equals);
}
else if (field.field.type === 'boolean') {
return new BooleanHandler(field, equals);
}
}
// Handling rules
function RuleHandler(type) {
var TYPE_AND = 'and';
var TYPE_OR = 'or';
var handlers = [];
type = type || TYPE_OR;
this.add = function (handler) {
handlers.push(handler);
};
// Check if rules are satisfied
this.rulesSatisfied = function () {
for (var i = 0; i < handlers.length; i++) {
// check if rule was hit
var ruleHit = handlers[i].satisfied();
if (ruleHit && type === TYPE_OR) {
return true;
}
else if (type === TYPE_AND && !ruleHit) {
return false;
}
}
return (type === TYPE_AND);
};
}
// Main widget class constructor
function ShowWhen(parent, field, params, setValue) {
var self = this;
self.field = field;
// Outsource readies
self.passReadies = true;
self.value = params;
// Create the wrapper:
var $wrapper = $('
', {
'class': 'field h5p-editor-widget-show-when'
});
var showing = false;
var config = self.field.showWhen;
if (config === undefined) {
throw new Error('You need to set the showWhen property in semantics.json when using the showWhen widget');
}
var ruleHandler = new RuleHandler(config.type);
for (var i = 0; i < config.rules.length; i++) {
var rule = config.rules[i];
var targetField = H5PEditor.findField(rule.field, parent);
var handler = createFieldHandler(targetField, rule.equals);
if (handler !== undefined) {
ruleHandler.add(handler);
H5PEditor.followField(parent, rule.field, function () {
if (config.detach) {
if (showing != ruleHandler.rulesSatisfied()) {
showing = !showing;
if (showing) {
$wrapper.appendTo(self.$container);
}
else {
$wrapper.detach();
}
}
}
else {
showing = ruleHandler.rulesSatisfied();
$wrapper.toggleClass('hidden', !showing);
}
if (config.nullWhenHidden && !ruleHandler.rulesSatisfied()) {
setValue(self.field, undefined);
}
});
}
}
// Create the real field:
var widgetName = config.widget || field.type;
var fieldInstance = new H5PEditor.widgets[widgetName](parent, field, params, setValue);
fieldInstance.appendTo($wrapper);
if (typeof fieldInstance.change === 'function') {
self.change = function (callback) {
fieldInstance.change(callback);
};
}
/**
* Add myself to the DOM
*
* @public
* @param {H5P.jQuery} $container
*/
self.appendTo = function ($container) {
if (!config.detach) {
$wrapper.appendTo($container);
}
self.$container = $container;
};
/**
* Validate
*
* @public
* @return {boolean}
*/
self.validate = function () {
// Only validate if field is shown!
return showing ? fieldInstance.validate() : true;
};
self.remove = function () {};
}
return ShowWhen;
})(H5PEditor.$);
// Register widget
H5PEditor.widgets.showWhen = H5PEditor.ShowWhen;