Augmenting default questions
Overview
If you need to change or extend some aspects of client-side behavior of default questions you can use custom views. Supports wide variety of scenarios.
We use a naming convention to distinguish between public and private methods and properties, use of private methods and properties is not supported. Methods and properties names starting with “_” are private and may be changed at any time without warning which could lead to unexpected behaviour or could prevent your survey from working.
API spec
window.Confirmit.pageView = {
// dictionary of default question view types, could be used inherit own classes from them or override pieces of functionality using prototypes
guestionViewTypes: {
"SingleQuestionView": <function>,
"MultiQuestionView": <function>,
...
},
// question view factory used by presentation layer to build views
// initialized with default factory instance, can be replaced with a custom one
questionViewFactory: {
create: function (model) { ... }
},
// helper method to use custom question view for a specific question only (could be useful when invoked from question/skin scripts)
registerCustomQuestionView: function (questionId, createViewFn) { ... }
}
Examples
Question level
Use the default view type, override on an instance (common use: minor tweak for a specific question)
/* typically done in a question or skin script */
var createFn = function (model) {
var factory = Confirmit.pageView.questionViewFactory;
var view = factory.create(model);
view._showErrors = function () { ... }; // make this specific instance to behave in a different way
return view;
};
Confirmit.pageView.registerCustomQuestionView(currentQuestion.id, createFn);
Question type level
Override on a type (common use: minor tweak for all question views of a certain type)
/* typically done in a theme script */
// grab default view type currently in use
var SingleView = Confirmit.pageView.questionViewTypes.SingleQuestionView;
// hijack it to make all instances to behave in a different way
SingleView.prototype._showErrors = function () { ... };
Side by side views
Use custom view types side by side with default ones (common use: fully custom behavior for a bunch of questions, default behavior for the rest - could be controlled by a question skin etc)
// define custom view (typically in a theme script)
var MyCustomView = function (model) { ... };
MyCustomView.prototype = { ... };
// apply custom view (typically in skin script)
var createFn = function (model) {
var view = new MyCustomView(model);
return view;
};
Confirmit.pageView.registerCustomQuestionView(currentQuestion.id, createFn);
Inherit from default views
Create custom types which inherit from default ones (common use: build custom types on top of existing default ones)
/* typically done in a theme script */
// grab the default view type
var DefaultSingleView = Confirmit.api.pageView.questionViewTypes["SingleQuestionView"];
// define a constructor for a custom view
var MyCustomSingleView = function (model) {
DefaultSingleView.call(this, model);
...
};
// inherit from default view type
MyCustomView.prototype = Object.create(DefaultSingleView.prototype);
MyCustomView.prototype.constructor = MyCustomView;
// implement custom logic on top of it
MyCustomView.prototype._showErrors = function () { ... };
/* typically done in a skin script */
// apply custom view
var createFn = function (model) {
var view = new MyCustomSingleView(model);
return view;
};
Confirmit.pageView.registerCustomQuestionView(currentQuestion.id, createFn);
Replace default view with custom
Full control over question view creation (common use: build custom type library to re-use in multiple projects)
/* full control over views creation */
// keep ref to default factory, so we can invoke it for non-custom types
var defaultQuestionViewFactory = Confirmit.pageView.questionViewFactory;
// use default types to either override their default dehavior or use for inheritance
var defaultQuestionViewTypes = Confirmit.pageView.questionViewTypes;
// example: we hijack all default geolocation views to use an alternative postion provider
defaultQuestionViewTypes["GeolocationQuestionView"].prototype._getCurrentPosition = function () { ... };
// define own custom views
var MyCustomSingleQuestionView = function (model) { ... };
var MyCustomMultiQuestionView = function (model) { ... };
// define own question view factory to control view creation
var myCustomViewFactory = {
create: function (model) {
switch (model.type) {
// handle custom types
case 'Single':
return new MyCustomSingleQuestionView(model);
case 'Multi':
return new MyCustomMultiQuestionView(model);
// use default view, but do something with an instance
case 'Ranking':
var view = defaultQuestionViewFactory.create(model);
if (new Date().getDay() === 2) // Tuesday
view._showErrors = function() { alert('May the Force be with you'); };
return view;
// offload the rest to default factory
default:
return defaultQuestionViewFactory.create(model);
}
}
};
// replace the default factory with the custom one
Confirmit.pageView.questionViewFactory = myCustomViewFactory;
Detach question views
If you want to manually manage resources when working with dynamic questions, you need to override the detach()
method in your custom view
var createFn = function (model) {
var factory = Confirmit.pageView.questionViewFactory;
var view = factory.create(model);
view.detach = function () { ... };
return view;
};
Confirmit.pageView.registerCustomQuestionView(currentQuestion.id, createFn);