/*
* Copyright 2022 Anyware Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Helper for creating a rule or an inconditional jump;
*/
Ext.define('Ametys.plugins.forms.helper.RulesDialogHelper', {
singleton: true,
/**
* @private
* @property {Ext.form.Panel} _formPanel The form panel.
*/
/**
* Open the dialog box
* @param {Object} config The configuration object
* @param {String} config.mode The mode: 'newRule' for a question rule or 'inconditionalJump' for a page rule.
* @param {String} config.formId The form id
* @param {String} config.pageId The page id
* @param {String} [config.questionId] The question id for a new rule
* @param {Function} [config.callback] The callback function
*/
open: function (config)
{
this._mode = config.mode;
this._cbFn = config.callback;
this._formId = config.formId;
this._pageId = config.pageId;
this._questionId = config.questionId;
this._delayedInitialize();
this._initForm(this._formId, this._pageId, this._questionId);
this._box.show();
},
/**
* @private
* Creates the dialog box
*/
_delayedInitialize: function ()
{
if (!this._initialized)
{
this._formPanel = this._createFormPanel();
this._box = Ext.create('Ametys.window.DialogBox', {
title: "{{i18n PLUGINS_FORMS_ADD_RULE_LABEL}}",
iconCls: "ametysicon-turn-right5",
width: 500,
scrollable: false,
items: [this._formPanel],
defaultFocus: 'option',
closeAction: 'hide',
referenceHolder: true,
defaultButton: 'validate',
buttons: [{
reference: 'validate',
text: "{{i18n PLUGINS_FORMS_QUESTIONS_DIALOG_BUTTON_OK}}",
handler: Ext.bind(this._validate, this)
}, {
text: "{{i18n PLUGINS_FORMS_QUESTIONS_DIALOG_BUTTON_CANCEL}}",
handler: Ext.bind(this._cancel, this)
}]
});
this._initialized = true;
}
},
/**
* Creates the form panel of this dialog box.
* @return {Ext.form.Panel} The form panel
* @private
*/
_createFormPanel: function()
{
var formPanel = Ext.create('Ext.form.Panel', {
defaults: {
cls: 'ametys',
labelSeparator: '',
labelAlign: 'right',
labelWidth: 120,
width: '100%',
msgTarget: 'side'
},
border: false,
scrollable: true,
items: [
{
xtype: 'hidden',
name: 'id'
},
{
xtype: 'combo',
name: 'option',
itemId: 'option',
fieldLabel: "{{i18n PLUGINS_FORMS_BRANCH_RULES_CHOOSE}}",
allowBlank: false,
width: 400,
store: {
fields: ['value', 'displayText']
},
valueField: 'value',
displayField: 'displayText',
queryMode: 'local',
forceSelection : true,
triggerAction: 'all'
},
{
xtype: 'component',
itemId: 'rules-hint',
cls: 'rules-hint',
html: "{{i18n PLUGINS_FORMS_BRANCH_RULES_THEN}}"
},
{
xtype: 'radio',
name: 'rule',
cls: 'rules-radio',
inputValue: 'JUMP',
fieldLabel: ' ',
boxLabel: "{{i18n PLUGINS_FORMS_BRANCH_RULES_JUMP}}",
width: 245,
checked: true,
listeners: {'change': Ext.bind(this._onCheckJump, this)}
},
{
xtype: 'combo',
name: 'page',
hideLabel: true,
allowBlank: false,
width: 120,
store: {
fields: ['value', 'displayText']
},
valueField: 'value',
displayField: 'displayText',
queryMode: 'local',
forceSelection : true,
triggerAction: 'all'
},
{
xtype: 'radio',
name: 'rule',
cls: 'rules-radio',
inputValue: 'FINISH',
fieldLabel: ' ',
boxLabel: "{{i18n PLUGINS_FORMS_BRANCH_RULES_FINISH}}",
width: 300
}
]
});
return formPanel;
},
/**
* Disables/enables the 'page' field depending on the 'rule' field check status.
* @param {Ext.form.field.Field} field The field
* @param {Object} newValue The new value
* @param {Object} oldValue The original value
* @private
*/
_onCheckJump: function(field, newValue, oldValue)
{
var form = this._formPanel.getForm();
if (newValue)
{
form.findField('page').enable();
}
else
{
form.findField('page').disable();
form.findField('page').clearInvalid();
}
},
/**
* @private
* Handler for the 'ok' button of the dialog box
*/
_validate: function ()
{
var form = this._formPanel.getForm();
if (!form.isValid())
{
return;
}
var values = form.getValues();
if (this._mode == 'newRule')
{
var params = [values.id, values.option, values.rule, values.page];
Ametys.plugins.forms.dao.FormQuestionDAO.addPageRule(params, this._validateCb, {scope: this, arguments: [values.id]} );
}
else
{
var params = [values.id, values.rule, values.page];
Ametys.plugins.forms.dao.FormPageDAO.addRule(params, this._validateCb, {scope: this, arguments: [values.id]} );
}
},
/**
* Callback function called after adding rule
* @private
*/
_validateCb: function (response, args)
{
if (!response['error'])
{
this._box.close();
if (Ext.isFunction (this._cbFn))
{
this._cbFn (args[0]);
}
}
},
/**
* @private
* Callback for the "cancel" button of the dialog. Close the dialog.
*/
_cancel: function ()
{
this._box.close();
},
/**
* @private
* Initializes the form with some optional values.
* @param {String} formId The form id
* @param {String} pageId The page id
* @param {String} [questionId] The question id for a rule.
*/
_initForm: function (formId, pageId, questionId)
{
var form = this._formPanel.getForm();
form.reset();
if (this._mode === "newRule")
{
this._box.setTitle("{{i18n PLUGINS_FORMS_ADD_RULE_LABEL}}");
form.findField('id').setValue(questionId);
form.findField('option').enable();
form.findField('option').show();
this._box.down('#rules-hint').update("{{i18n PLUGINS_FORMS_BRANCH_RULES_THEN}}");
form.findField('rule').setValue('JUMP');
// Load options
this._loadOptions(questionId);
form.findField('option').setValue('');
form.findField('option').clearInvalid();
}
else // this._mode == 'inconditionalJump'
{
this._box.setTitle("{{i18n PLUGINS_FORMS_BRANCH_INCONDITIONAL_JUMP}}");
form.findField('id').setValue(pageId);
this._box.down('#rules-hint').update("{{i18n PLUGINS_FORMS_BRANCH_INCONDITIONAL_JUMP_NO_RULE}}");
form.findField('rule').setValue('JUMP');
// Disable the option field
form.findField('option').disable();
form.findField('option').hide();
}
// Load pages
this._loadPages(formId, pageId);
form.findField('page').setValue('');
form.findField('page').clearInvalid();
},
/**
* Loads the options of a given question.
* @param {String} questionId The question id.
* @private
*/
_loadOptions: function(questionId)
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.forms.dao.FormQuestionDAO",
methodName: "getChoiceListQuestionOptions",
parameters: [questionId],
callback: {
scope: this,
handler: Ext.bind(this._loadOptionsCb, this),
}
});
},
/**
* Loads the options of a given question. Called by {@link #_loadOptions}.
* @param {Object} options The question options
* @private
*/
_loadOptionsCb: function(options)
{
var form = this._formPanel.getForm();
var store = form.findField('option').getStore();
store.removeAll();
for (var key in options)
{
store.add({
value: key,
displayText: options[key]
});
}
},
/**
* Loads the pages (placed after a certain page) of a given form.
* @param {String} formId The form id
* @param {String} pageId The page id. We only load the pages after this one.
* @private
*/
_loadPages: function(formId, pageId)
{
Ametys.plugins.forms.dao.FormPageDAO.getChildPages([formId], this._loadPagesCb, {scope: this, arguments: [pageId]});
},
/**
* Loads the pages (placed after a certain page) of a given form. Called by {@link #_loadPages}.
* @param {Object} pages The pages object
* @param {Array} args The callback arguments
* @param {String} args.pageId The page id. We only load the pages after this one.
* @private
*/
_loadPagesCb: function(pages, args)
{
var pageId = args[0]
var form = this._formPanel.getForm();
var store = form.findField('page').getStore();
store.removeAll();
var isNextPages = false;
for (var i = 0; i < pages.length; i++) {
var value = pages[i].id
if (isNextPages)
{
store.add({
value: value,
displayText: pages[i].title
});
}
if (pageId == value)
{
isNextPages = true;
}
}
}
});