Widget Definitions
In this page you will find all the definitions of the parent class from which childs can inherit to become an ngSurvey widget.
class NGSWidget {
static get type() {
return "NGSWidget"
}
/* Html template that will generate before class gets created
All id's and css classes name will be suffixed by the uniqueId
provided during creation of the widget */
static get template() {}
/* Html template is used during design time of the form
If null the actual widget template will be rendered */
static get designTimeTemplate() {}
/* Html template is when form is shown to be printed */
static get printTemplate() {}
/* Inline css style that will be added to the page
note that style classes names will be scoped
to the widget unique id
*/
static get style() {}
/* Inline javascript code that will be added to
the page as long as the widget */
static get script() {}
static get selectionWidget() {
return true;
}
/* Does this widget support label, the label is the text a form
admin can enter using the form design and which will be displayed
before the widget template */
static get hasLabel() {
return true;
}
/* Displays the ngsurvey native error message box
under the control
*/
static get displayErrorMessage() {
return true;
}
/* Will prefix all CSS classes from the widget style
with a unique value to avoid conflicts if other components
have registered these classes under the same name.
Note that it wont parse external CSS dependencies.
0 : No encapsulation
1 : Shadow CSS - native ngSurvey prefix processor
*/
static get encapsulationMode() {
return 1;
}
/* Allows the answer to be set required or not
from the answer settings page to make
the widget answer required during survey
*/
static get required() {
return false;
}
/* Properties that can be set in from the form designer for each
answer using this widget as an answer type in the answer settings */
static get propertiesDef() {}
/* External javascript code dependencies that will be loaded
before the widget gets created */
static get jsDependencies() {}
/* External css code dependencies that will be loaded
before the widget gets created */
static get cssDependencies() {}
/*
setAnswer; // callback furnction to post a value from the widget eg: answerPosted(widgetAnswerValue)
valueChanges$; // Observable that returns the value of the widget
containerElement;
labelElement;
respondentAnswers = [];
uniqueId;
answerContext;
formContext;
sectionIndex;
properties;
initialValue;
label;
*/
/* containerElement : DOM element holding the template
labelElement: DOM element holding the label
answerContext: Answer context that provides helper methods to interact with the answer
formContext: Form context that provides helper methods to interact with the form
uniqueId: must be used to query as suffix the template element id's or css classes
properties : instance specific property values
setAnswer: function that will set the given text value of the widget setAnswer(textVal)
valueChanges: monitor any value changes of the widget
*/
constructor(containerElement, labelElement, answerContext, formContext,
sectionIndex, uniqueId, properties, setAnswerCallback, valueChanges$) {
this._value = null;
this._subscribers = [];
this.containerElement = containerElement;
this.labelElement = labelElement;
this.uniqueId = uniqueId;
this.formContext = formContext;
this.sectionIndex = sectionIndex;
this.properties = properties;
this.answerContext = answerContext;
this.initialValue = answerContext.initialValue;
this.valueChanges$ = valueChanges$;
this.setAnswer = (value) => {
// Keeps a local copy of the value being set
this._value = value;
setAnswerCallback(value);
};
this.getLabel$(label => {
this.label = label;
})
this.getRespondentAnswers$(respondentAnswers => {
this.respondentAnswers = respondentAnswers;
});
this.getAnswers$(answers => {
this.answers = answers;
});
this.getQuestions$(questions => {
this.questions = questions;
});
}
/* Widget has been template has not yet been added to the DOM
but its properties have been already been set
*/
build() {}
/* Widget has been template has added to the DOM
and its properties have been set
*/
init() {}
/* Subscribe to the observable and keeps
a reference to automatically unsubscribe
it when the widget gets disposed
*/
safeSubscribe(obs, next, error, complete) {
// add to array
if (obs) {
this._subscribers.push(obs.subscribe(next, error, complete));
}
}
// Beta Not for production
remoteValidate() {
var validationParams = [];
for (var key in this.properties) {
validationParams.push(this.getValidationParam(key, this.properties[key]));
}
validationParams.push(this.getValidationParam('secret', '6LeFY6QUAAAAAEwJvr1FYG16rVQpJJ1RQEGV19QM'));
validationParams.push(this.getValidationParam('response', this._value));
var remoteValidationParams = {
validationParams
}
return this.formContext.answerService.validate(this.answerContext.answer.id, remoteValidationParams).subscribe(val => {
console.log('validate')
});
}
// Beta Not for production
remoteValidateProd() {
var validationParams = [];
validationParams.push(this.getValidationParam('secret', '6LeFY6QUAAAAAEwJvr1FYG16rVQpJJ1RQEGV19QM'));
validationParams.push(this.getValidationParam('response', this._value));
var remoteValidationParams = {
validationParams
}
return this.formContext.answerService.validate(this.answerContext.answer.id, remoteValidationParams).subscribe(val => {
console.log('validate')
});
}
getValidationParam(name, value) {
return {
name,
value
}
}
/*
returns the properties of the widget
in the callback
*/
getProperties$(propsCallback) {
this.safeSubscribe(this.answerContext.propertie$, propsCallback, null, null)
}
getLabel$(labelCallback) {
this.safeSubscribe(this.answerContext.label$, labelCallback, null, null)
}
getValue$(valueCallback) {
this.safeSubscribe(this.valueChanges$, (value) => {
// Callback only if value has changed
if (value != this._value) {
valueCallback(value);
}
}, null, null)
}
isDisabled$(stateCallback) {
this.safeSubscribe(this.answerContext.disabled$, stateCallback, null, null)
}
isSelected$(selectionCallback) {
this.safeSubscribe(this.answerContext.isSelected$, selectionCallback, null, null)
}
getRenderMode$(renderModeCallback) {
this.safeSubscribe(this.answerContext.renderMode$, renderModeCallback, null, null)
}
getLanguage$(languageCallback) {
this.safeSubscribe(this.formContext.language$, languageCallback, null, null)
}
getRespondentAnswers$(respondentAnswersCallBack) {
this.safeSubscribe(this.formContext.respondentAnswers$, respondentAnswersCallBack, null, null)
}
getAnswers$(answersCallBack) {
this.safeSubscribe(this.formContext.answers$, answersCallBack, null, null)
}
getQuestions$(questionsCallBack) {
this.safeSubscribe(this.formContext.questions$, questionsCallBack, null, null)
}
/* Will be called by the form to see if the value is valid
If not valid must return '' (no error message shown) or the error message to show
If its valid return null */
isValid() {
return null;
}
/* Returns the html element from the dom that has been generated
from the widget template will match the suffixed ids of the
widget template
*/
getWidgetElementById(id) {
return this.widgetQuerySelector('#' + id);
}
/*
Queryselector only on the container of the widget.
Adds the widget unique id to ids (#) to match to
the suffixed local ids of the widget template
*/
widgetQuerySelector(selector) {
// Suffix the id with the widget unique id
if (selector.indexOf('#') >= 0) {
selector += this.uniqueId;
}
return this.containerElement.querySelector(selector);
}
/*
QueryselectorAll only on the container of the widget.
Adds the widget unique id to ids (#) to match to
the suffixed local ids of the widget template
*/
widgetQuerySelectorAll(selector) {
// Suffix the id with the widget unique id
if (selector.indexOf('#') >= 0) {
selector += this.uniqueId;
}
return this.containerElement.querySelectorAll(selector);
}
/* Cleans up all things that needs to be cleaned
up before the widget gets destroyed from the dom */
dispose() {}
_disposeSubscribers() {
if (this._subscribers) {
this._subscribers.forEach(subscriber => {
if (subscriber) {
subscriber.unsubscribe();
}
})
this._subscribers = [];
}
}
/* Hooks the widget events to keep their
state in sync */
_hookEvents() {}
/* Internal method should not be overriden */
_dispose() {
this._disposeSubscribers();
this.dispose();
}
/* _value;
_subscribers = [];*/
}
class NGSSelectionWidget extends NGSWidget {
static get type() {
return "NGSSelectionWidget"
}
/* containerElement : DOM element holding the template
labelElement: DOM element holding the label
answerContext: Answer context that provides helper methods to interact with the answer
formContext: Form context that provides helper methods to interact with the form
uniqueId: must be used to query as suffix the template element id's or css classes
selectionId: is the unique id of the group of selection
selectAnswerCallback: function that will be called when an answer must be selected from widget
selected$: observable that returns true / false when answer is selected or unselected
properties : instance specific property values
setAnswer: function that will set the given text value of the widget setAnswer(textVal) */
constructor(containerElement, labelElement, answerContext, formContext,
sectionIndex, uniqueId, selectionId, selected, selectedAnswerCallback,
selected$, properties, setAnswerCallback, valueChanges$) {
super(containerElement, labelElement, answerContext,
formContext, sectionIndex, uniqueId, properties, setAnswerCallback, valueChanges$)
this.selectionId = selectionId;
this.isSelected = selected;
this.selected$ = selected$;
this.selectAnswer = (selected) => {
// If its a text answers save value locally (eg: for "other" answers with fields and selections)
if ((selected !== false && selected !== true) || selected == null || selected.length == 0) {
this._value = selected;
}
selectedAnswerCallback(selected);
};
this.isSelected$(selected => {
this.isSelected = selected;
});
}
isSelected$(selectionCallback) {
this.safeSubscribe(this.selected$, selectionCallback, null, null)
}
}
export class AnswerContext {
constructor(
// Answer that is linked to that widget
private answer: Answer,
// Custom user defined properties that have been set for this widget
private propertie$: Observable<any>,
// Current rendering mode of the widget eg: DesignTime (design), Standard (running)
private renderMode$: BehaviorSubject<ControlRenderMode>,
// Should the widget be disabled ?
private disabled$: BehaviorSubject<boolean>,
// Is the label enabled
private showLabel: boolean,
// Angular form control holding the value of the a
private formControl: FormControl,
// Inital value of the answer, could be the default value set
// by the survey admin or the previous respondent answer if the survey
// is being resumed by the respondent
private initialValue: string,
// Label text of the answer, observable will stream the new value
// if value changes in multi languages survey
private label$: Observable<string>) { }
}
export class FormContext {
constructor(
// Actual respondent of the survey
private respondent$: Observable<Respondent>,
// Actual respondent answers of the survey, observable
// will stream any new answer update in realtime
private respondentAnswers$: Observable<RespondentAnswer[]>,
// Survey answers
private answers$: Observable<Answer[]>,
// Survey questions
private questions$: Observable<Question[]>,
// Actual respondent language in multilanguage surveys
private language$: Observable<Language>,
// Helper method to access the angular http client
private httpClient: HttpClient,
// internal ngSurvey answer http services
private answerService: AnswerService) { }
}
Last updated