"use strict";
/**
* QueryDataBlock class holds all data relevant for a single section/query (QueryItem), includin InputItems and OptionItems.
*/
class QueryDataBlock {
/**
* Create QueryDataBlock.
* @param {Object} data - Defines QueryItem's data (data for a specific form section).
* @param {string} [data.formIndex] - Current form index used for unique ids.
* @param {string} [data.id] - Section id.
* @param {string} [data.type] - Query type, default is "text".
* @param {string} [data.title] - Query title text.
* @param {string} [data.subtitle] - Query subtitle text.
* @param {string} [data.label] - Query label text.
* @param {string} [data.error] - Query error text.
* @param {string} [data.direction] - Query direction, either "vertical" or "horizontal".
* @param {string} [data.optionsOrder] - Query options order, either "before" or "after" the input items.
* @param {boolean} [data.required] - Sets query filled-in value to be required. Default is false.
* @param {string} [data.css] - Query specific css string.
* @param {(dom|string)} [data.before] - Defines DOM object or a string as text or html to be placed at the beginning of the query.
* @param {(dom|string)} [data.after] - Defines DOM object or a string as text or html to be placed at the end of the query.
* @param {(boolean|string|RegExp|boolean[]|string[]|RegExp[])} [data.checkRules] - Defines possible validation queries. If array passed value must match them all.
* @param {string} [data.arrayMatch] - If set to "and" it will require input value to have a match, if "or" (default) at least one input value will have to have a match.
* @param {Object[]} [data.items] - Defines input items for this Query.
* @param {string} [data.items.id] - Defines input items' ids for this Query.
* @param {string} [data.items.label] - Defines input items' labels for this Query.
* @param {string} [data.items.css] - Defines input items' css strings for this Query.
* @param {string} [data.items.error] - Defines input items' error values - if none set defaults to the general QueryDataBlock error value.
* @param {(boolean|string|RegExp|boolean[]|string[]|RegExp[])} [data.items.checkRules] - Defines input items for this Query.
* @param {string} [data.items.arrayMatch] - If set to "and" it will require input value to have a match, if "or" (default) at least one input value will have to have a match.
* @param {Object[]} [data.options] - Defines option items for this Query.
* @param {string} [data.options.id] - Defines option items' ids for this Query - will be matched with data.items.checkRules.
* @param {string} [data.options.text] - Defines option items' text strings for this Query.
* @param {string} [data.options.css] - Defines option items' css strings for this Query.
*/
constructor(data) {
this.data = data || {};
/* Count of existing QueryDataBlocks */
QueryDataBlock.count = (QueryDataBlock.count || 0) + 1;
this.uniqueInstanceId = QueryDataBlock.count;
this.formIndex = data.formIndex || null;
this.idVal = this.createUniqueId(this.data.id) || "";
this.typeVal = this.data.type || "text";
this.titleVal = this.data.title || null;
this.subtitleVal = this.data.subtitle || null;
this.labelVal = this.data.label || null;
this.errorVal = this.data.error || "This field has not been correctly filled in.";
this.directionVal = this.data.direction || null;
this.optionsOrderVal = this.data.optionsOrder || null;
this.requiredVal = this.data.required || false;
this.cssVal = this.data.css || null;
this.before = this.data.before || null;
this.after = this.data.after || null;
this.items = this.data.items || [];
this.options = this.data.options || [];
this.queryValidator = new QueryValidator(this.data.checkRules);
this.queryValidator.setMatch(this.data.arrayMatch || "or");
this.setProperInputType();
return this;
}
/**
* Get this query item's type.
* @return {string} - query type.
*/
get type() {
return this.typeVal;
}
/**
* Get this query item's id.
* @return {string} - query id.
*/
get id() {
return this.idVal;
}
/**
* Get this query item's title.
* @return {string} - query title.
*/
get title() {
return this.titleVal;
}
/**
* Get this query item's subtitle.
* @return {string} - query subtitle.
*/
get subtitle() {
return this.subtitleVal;
}
/**
* Get this query item's label.
* @return {string} - query label.
*/
get label() {
return this.labelVal;
}
/**
* Get this query item's error.
* @return {string} - query error text.
*/
get error() {
return this.errorVal;
}
/**
* Get this query item's direction. Applicable only for draggable queries.
* @return {string} - query direction - as "horizontal" or "vertical".
*/
get direction() {
return this.directionVal;
}
/**
* Find out whether this query fille-in valueis required or if it is optional.
* @return {boolen} - Returns true if this query is required, false if not.
*/
get required() {
return this.requiredVal;
}
/**
* Get this query item's css.
* @return {string} - query css string.
*/
get css() {
return this.cssVal;
}
/**
* Get this query item's index.
* @return {(string|null)} - query index (order number) in form or null if no index found.
*/
get index() {
if(!isNaN(this.indexVal)) {
return this.indexVal;
}
return null;
}
/**
* Get this query item's items.
* @return {Object[]} - Array containing object data of each input item.
*/
get items() {
if(typeof this.itemsVal !== typeof undefined) {
return this.itemsVal;
}
return [];
}
/**
* Get this query item's options.
* @return {Object[]} - Array containing object data of each option item.
*/
get options() {
return this.optionsVal;
}
/**
* Get this query item's options order.
* @return {string} - Either "before" if option items are rendered above input items or "after" is otherwise.
*/
get optionsOrder() {
return this.optionsOrderVal;
}
/**
* Get this query item's base form DOM object.
* @return {dom} - An object in which all form elements including section queries are placed.
*/
get baseForm() {
if(this.baseFormVal) {
return this.baseFormVal;
}
return null;
}
/**
* Get this query item's section DOM container.
* @return {dom} - Query container.
*/
get sectionContainer() {
if(this.sectionContainerVal) {
return this.sectionContainerVal;
}
return null;
}
/**
* Get proper input type, filtered to a know types only in case unsupported type has been passed.
* @return {string} - A proper input type.
*/
get properInputType() {
return this.inputType;
}
/**
* Get before section dom.
* @return {dom} - A custom element being inserted at the beginning of this query.
*/
get before() {
return this.beforeDOM;
}
/**
* Get after section dom.
* @return {dom} - A custom element being inserted at the end of this query.
*/
get after() {
return this.afterDOM;
}
/**
* Set index.
* @param {number} value - Set this item's index value.
*/
set index(value) {
this.indexVal = value;
if(!this.id) {
this.idVal = this.indexVal;
}
}
/**
* Set baseForm DOM element.
* @param {dom} baseForm - DOM element holding all form fields.
*/
set baseForm(baseForm) {
this.baseFormVal = baseForm;
}
/**
* Set sectionContainer DOM element.
* @param {dom} sectionContainer - DOM element contaning this query.
*/
set sectionContainer(sectionContainer) {
this.sectionContainerVal = sectionContainer;
}
/**
* Takes an array of items (optionally) and generates an Array of Objects, each Object for one item (InputItemWrapper).
* @param {Object[]} [items] - Array with input items data.
* @see {@link constructor} for more information.
*/
set items(items) {
items = items || [];
this.itemsVal = [];
for(var i = 0; i < items.length; i++) {
this.itemsVal[i] = {};
this.itemsVal[i].id = items[i].id;
this.itemsVal[i].htmlId = "input-" + this.id + "-" + items[i].id;
this.itemsVal[i].label = items[i].label || "";
this.itemsVal[i].text = items[i].text || "";
this.itemsVal[i].css = items[i].css || "";
this.itemsVal[i].error = items[i].error || null;
this.itemsVal[i].queryValidator = new QueryValidator(items[i].checkRules);
this.itemsVal[i].queryValidator.setMatch(items[i].arrayMatch || "or");
}
}
/**
* Takes an array of options (optionally) and generates an Array of Objects, each Object for one option (OptionItem).
* @param {Object[]} [options] - Array with option items data.
* @see {@link constructor} for more information.
*/
set options(options) {
options = options || [];
this.optionsVal = [];
for(var i = 0; i < options.length; i++) {
this.optionsVal[i] = {};
this.optionsVal[i].id = options[i].id;
this.optionsVal[i].htmlId = "option-" + this.id + "-" + options[i].id;
this.optionsVal[i].validatorMatch = options[i].id;
this.optionsVal[i].text = options[i].text || "";
this.optionsVal[i].css = options[i].css || "";
}
}
/**
* Sets dom which preceeds the query once rendered.
* @param {dom} element - An element to be placed at the beggining of this query.
*/
set before(element) {
this.beforeDOM = this.createCustomDomContent(element, "before");
}
/**
* Sets dom which follows the query once rendered.
* @param {dom} element - An element to be placed at the end of this query.
*/
set after(element) {
this.afterDOM = this.createCustomDomContent(element, "after");
}
/**
* Creates a unique id for this QuerydataBlock, based on an uniqu InstanceID.
* @param {string} [id] - A string to be connected with the unique instance number to create a unique id.
*/
createUniqueId(id) {
id = id || "";
return CommonFormFunctions.joinStrings(this.uniqueInstanceId, id, "_");
}
/**
* Filters all unsupported input types, picks a default if a wrong input type has been passed.
* @return {QueryDataBlock} - Returns this QueryDataBlock instance.
*/
setProperInputType() {
this.inputType = CommonFormFunctions.filterProperInputTypes(this.type);
return this;
}
/**
* Returns a DOM with "dt-custom-form-content" class name, accepts HTML/text strings as well as DOM structures.
* @param {(dom|string)} [element] - A dom object or a string - as text or HTML.
* @param {string} [customClass] - Custom class name to be added to the final element.
* @return {dom} - An updated or newly created DOM object.
*/
createCustomDomContent(element, customClass) {
if(element) {
var finalDom = null;
if(element.nodeType && element.nodeType === 1) {;
element.classList = [];
finalDom = element;
}
else {
finalDom = document.createElement("div");
finalDom.innerHTML = element;
}
finalDom.classList.add("dt-custom-form-content");
if(customClass) {
finalDom.classList.add(customClass);
}
return finalDom;
}
return null;
}
}