diff --git a/src/AddRule.js b/src/AddRule.js new file mode 100644 index 0000000..421043a --- /dev/null +++ b/src/AddRule.js @@ -0,0 +1,62 @@ +import { nanoid } from 'nanoid'; + +export default class AddRule { + #id; + + #field; + + #operator; + + #value; + + #ruleObject; + + constructor(field = 'First Name', operator = '=', value = '') { + this.#id = nanoid(); + this.#field = field; + this.#operator = operator; + this.#value = value; + + this.#ruleObject = {}; + + this.createRuleObject(); + } + + set setField(value) { + this.#field = value; + } + + get getField() { + return this.#field; + } + + set setOperator(value) { + this.#operator = value; + } + + get getOperator() { + return this.#operator; + } + + set setValue(value) { + this.#value = value; + } + + get getValue() { + return this.#value; + } + + getRuleObject() { + return this.#ruleObject; + } + + createRuleObject() { + this.#ruleObject = { + id: this.#id, + field: this.#field, + operator: this.#operator, + value: this.#value, + }; + return this; + } +} diff --git a/src/Query.js b/src/Query.js new file mode 100644 index 0000000..c4a53a2 --- /dev/null +++ b/src/Query.js @@ -0,0 +1,92 @@ +import { nanoid } from 'nanoid'; +import logicalOperators from './logicalOperators'; + +export default class Query { + #id; + + #combinator; + + #rules; + + #queryObject; + + constructor(combinator = 'AND') { + this.#id = nanoid(); + this.#combinator = combinator; + this.#rules = []; + + this.#queryObject = {}; + + this.logicalSelect = null; + + this.init(); + } + + init() { + this.createQueryObject(); + this.createLogicalSelect(); + this.addEventListener(); + } + + setCombinator(value) { + this.#combinator = value; + } + + getCombinator() { + return this.#combinator; + } + + setRules(value) { + this.#rules = value; + } + + getRules() { + return this.#rules; + } + + getLogicalElement() { + return this.logicalSelect; + } + + getQueryObject() { + return this.#queryObject; + } + + createQueryObject() { + this.#queryObject = { + id: this.#id, + combinator: this.#combinator, + rules: this.#rules, + }; + + return this; + } + + createLogicalSelect() { + this.logicalSelect = document.getElementById('logical'); + + logicalOperators.forEach((item) => { + const option = document.createElement('option'); + option.value = item; + option.innerHTML = item; + this.logicalSelect.appendChild(option); + }); + + return this; + } + + addEventListener() { + if (this.logicalSelect) { + this.logicalSelect.addEventListener('change', (event) => { + this.#combinator = event.target.value; + if (this.onChangeLogicalCallback) { + this.onChangeLogicalCallback(this.#combinator); + } + }); + } + } + + onChangeLogical(callback) { + this.onChangeLogicalCallback = callback; + } +} diff --git a/src/Rule.js b/src/Rule.js new file mode 100644 index 0000000..f0b1b2f --- /dev/null +++ b/src/Rule.js @@ -0,0 +1,157 @@ +import studentsInfo from './studentsInfo'; +import comparisonOperators from './comparisonOperators'; + +export default class Rule { + constructor(wrapper) { + this.wrapper = wrapper; + + // initialise values + this.field = ''; + this.operator = ''; + this.value = ''; + + // initialise elements + this.comparisonSelect = null; + this.fieldSelect = null; + this.valueElement = null; + this.deleteElement = null; + + // properly initialise rule + this.init(); + } + + static createSelectElement(dropDownData, id) { + const selectElement = document.createElement('select'); + selectElement.id = id; + + dropDownData.forEach((item) => { + const option = document.createElement('option'); + option.value = item; + option.innerHTML = item; + selectElement.appendChild(option); + }); + return selectElement; + } + + get getFieldElement() { + return this.fieldSelect; + } + + get getValueElement() { + return this.valueElement; + } + + get getComparisonElement() { + return this.comparisonSelect; + } + + get getDeleteElement() { + return this.deleteElement; + } + + init() { + this.createFieldSelect() + .createOperatorSelect() + .createValueInput() + .createDeleteElement(); + this.addElementsToWrapper(); + this.addEventListeners(); + } + + createFieldSelect() { + this.fieldSelect = Rule.createSelectElement( + studentsInfo, + 'select-student-info', + ); + + return this; + } + + createOperatorSelect() { + this.comparisonSelect = Rule.createSelectElement( + comparisonOperators, + 'select-comparison-operator', + ); + + return this; + } + + createValueInput() { + this.valueElement = document.createElement('input'); + this.valueElement.id = 'input-value'; + + return this; + } + + createDeleteElement() { + this.deleteElement = document.createElement('button'); + this.deleteElement.id = 'btn-delete-rule'; + this.deleteElement.appendChild(document.createTextNode('DELETE')); + + return this; + } + + addElementsToWrapper() { + if (this.wrapper) { + this.wrapper.appendChild(this.fieldSelect); + this.wrapper.appendChild(this.comparisonSelect); + this.wrapper.appendChild(this.valueElement); + this.wrapper.appendChild(this.deleteElement); + } else { + throw new Error('A wrapper element is required!'); + } + } + + addEventListeners() { + if (this.fieldSelect) { + this.fieldSelect.addEventListener('change', (event) => { + this.field = event.target.value; + if (this.onChangeFieldCallback) { + this.onChangeFieldCallback(this.field); + } + }); + } + + if (this.comparisonSelect) { + this.comparisonSelect.addEventListener('change', (event) => { + this.operator = event.target.value; + if (this.onChangeComparisonCallback) { + this.onChangeComparisonCallback(this.operator); + } + }); + } + + if (this.valueElement) { + this.valueElement.addEventListener('change', (event) => { + this.value = event.target.value; + if (this.onChangeValueCallback) { + this.onChangeValueCallback(this.value); + } + }); + } + + if (this.deleteElement) { + this.deleteElement.addEventListener('click', () => { + if (this.onDeleteCallback) { + this.onDeleteCallback(); + } + }); + } + } + + onChangeField(callback) { + this.onChangeFieldCallback = callback; + } + + onChangeComparison(callback) { + this.onChangeComparisonCallback = callback; + } + + onChangeValue(callback) { + this.onChangeValueCallback = callback; + } + + onDelete(callback) { + this.onDeleteCallback = callback; + } +} diff --git a/src/index.js b/src/index.js index 2e00316..a42d48b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,132 +1,68 @@ -import { nanoid } from 'nanoid'; -import logicalOperators from './logicalOperators'; -import comparisonOperators from './comparisonOperators'; -import studentsInfo from './studentsInfo'; import './styles.css'; +import AddRule from './AddRule'; +import Rule from './Rule'; +import Query from './Query'; -const logicalDropdownList = document.getElementById('logical'); -logicalOperators.forEach((item) => { - const option = document.createElement('option'); - option.value = option.innerHTML; - option.innerHTML = item; - logicalDropdownList.appendChild(option); +const query = new Query(); + +const queryObject = query.getQueryObject(); + +query.onChangeLogical((value) => { + queryObject.combinator = value; }); -const combinator = 'AND'; +const rulesList = document.getElementById('rules-list'); +const arrayRules = {}; -const queryObject = { - id: nanoid(), - combinator, - rules: [], -}; +document.getElementById('btn-add-rule').addEventListener('click', () => { + const addRule = new AddRule(); -logicalDropdownList.addEventListener('change', (e) => { - queryObject.combinator = e.target[e.target.selectedIndex].text; -}); + queryObject.rules.push(addRule.getRuleObject()); -function ruleObject(field, operator, value) { - return { - id: nanoid(), - field, - operator, - value, - }; -} + const { id: idx } = queryObject.rules[queryObject.rules.length - 1]; -const rulesList = document.getElementById('rules-list'); + const li = document.createElement('li'); + li.id = idx; + const newRule = new Rule(li); + rulesList.appendChild(li); + + arrayRules.instance = newRule; -function onFieldChange(selectStudentInfo, id) { - selectStudentInfo.addEventListener('change', (e) => { + newRule.onChangeField((value) => { queryObject.rules.forEach((rule) => { - if (rule.id === id) { - const updatedFieldValue = rule; - updatedFieldValue.field = e.target[e.target.selectedIndex].text; + if (rule.id === idx) { + const updateFieldValue = rule; + updateFieldValue.field = value; } }); }); -} -function onOperatorChange(selectComparisonOperator, id) { - selectComparisonOperator.addEventListener('change', (e) => { + newRule.onChangeComparison((value) => { queryObject.rules.forEach((rule) => { - if (rule.id === id) { - const updatedOperatorValue = rule; - updatedOperatorValue.operator = e.target[e.target.selectedIndex].text; + if (rule.id === idx) { + const updateOperatorValue = rule; + updateOperatorValue.operator = value; } }); }); -} -function onValueChange(input, id) { - input.addEventListener('input', (e) => { + newRule.onChangeValue((value) => { queryObject.rules.forEach((rule) => { - if (rule.id === id) { - const updatedInputValue = rule; - updatedInputValue.value = e.target.value; + if (rule.id === idx) { + const updateInputValue = rule; + updateInputValue.value = value; } }); }); -} -function onDeleteRule(deleteRule, id) { - deleteRule.addEventListener('click', () => { - queryObject.rules = queryObject.rules.filter((rule) => rule.id !== id); + newRule.onDelete(() => { + queryObject.rules = queryObject.rules.filter((rule) => rule.id !== idx); - const node = document.getElementById(id); + const node = document.getElementById(idx); rulesList.removeChild(node); - }); -} - -function createSelectElement(dropDownData, id) { - const selectElement = document.createElement('select'); - selectElement.id = id; - dropDownData.forEach((item) => { - const option = document.createElement('option'); - option.value = option.innerHTML; - option.innerHTML = item; - selectElement.appendChild(option); + if (queryObject.rules.length === 0) { + arrayRules.instance = null; + } }); - return selectElement; -} - -function addRule() { - const field = 'First Name'; - const operator = '='; - - const selectStudentInfo = createSelectElement( - studentsInfo, - 'select-student-info', - ); - const selectComparisonOperator = createSelectElement( - comparisonOperators, - 'select-comparison-operator', - ); - - const input = document.createElement('input'); - input.id = 'input-value'; - const { value } = input; - - const deleteRule = document.createElement('button'); - deleteRule.id = 'btn-delete-rule'; - deleteRule.appendChild(document.createTextNode('DELETE')); - - queryObject.rules.push(ruleObject(field, operator, value)); - - const { id: idx } = queryObject.rules[queryObject.rules.length - 1]; - - const li = document.createElement('li'); - li.id = idx; - li.appendChild(selectStudentInfo); - li.appendChild(selectComparisonOperator); - li.appendChild(input); - li.appendChild(deleteRule); - rulesList.appendChild(li); - - onFieldChange(selectStudentInfo, idx); - onOperatorChange(selectComparisonOperator, idx); - onValueChange(input, idx); - onDeleteRule(deleteRule, idx); -} - -document.getElementById('btn-add-rule').addEventListener('click', addRule); +});