From 191b32af17afce37b1f1426e54905229f1e09132 Mon Sep 17 00:00:00 2001 From: APIYOJENNIFER Date: Tue, 25 Apr 2023 11:32:32 +0300 Subject: [PATCH 1/8] Refactor functions to exist inside a class --- src/AddRule.js | 130 +++++++++++++++++++++++++++++++++++++++++++++++++ src/index.js | 101 ++++---------------------------------- 2 files changed, 139 insertions(+), 92 deletions(-) create mode 100644 src/AddRule.js diff --git a/src/AddRule.js b/src/AddRule.js new file mode 100644 index 0000000..e04327f --- /dev/null +++ b/src/AddRule.js @@ -0,0 +1,130 @@ +export default class AddRule { + constructor(field = 'First Name', operator = '=', value = '') { + this.field = field; + this.operator = operator; + this.value = value; + } + + 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; + } + + static onFieldChange(queryObject, selectStudentInfo, id) { + selectStudentInfo.addEventListener('change', (e) => { + queryObject.rules.forEach((rule) => { + if (rule.id === id) { + const updatedFieldValue = rule; + updatedFieldValue.field = e.target[e.target.selectedIndex].text; + } + }); + }); + } + + static onOperatorChange(queryObject, selectComparisonOperator, id) { + selectComparisonOperator.addEventListener('change', (e) => { + queryObject.rules.forEach((rule) => { + if (rule.id === id) { + const updatedOperatorValue = rule; + updatedOperatorValue.operator = e.target[e.target.selectedIndex].text; + } + }); + }); + } + + static onValueChange(queryObject, input, id) { + input.addEventListener('input', (e) => { + queryObject.rules.forEach((rule) => { + if (rule.id === id) { + const updatedInputValue = rule; + updatedInputValue.value = e.target.value; + } + }); + }); + } + + static onDeleteRule(queryObject, rulesList, deleteRule, id) { + deleteRule.addEventListener('click', () => { + const returnedRules = queryObject; + returnedRules.rules = queryObject.rules.filter((rule) => rule.id !== id); + + const node = document.getElementById(id); + rulesList.removeChild(node); + }); + } + + static 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); + }); + return selectElement; + } + + addRule( + queryObject, + ruleObject, + rulesList, + studentsInfo, + comparisonOperators, + ) { + const selectStudentInfo = AddRule.createSelectElement( + studentsInfo, + 'select-student-info', + ); + const selectComparisonOperator = AddRule.createSelectElement( + comparisonOperators, + 'select-comparison-operator', + ); + + const input = document.createElement('input'); + input.id = 'input-value'; + + const deleteRule = document.createElement('button'); + deleteRule.id = 'btn-delete-rule'; + deleteRule.appendChild(document.createTextNode('DELETE')); + + queryObject.rules.push( + ruleObject(this.getField, this.getOperator, this.getValue), + ); + + 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); + + AddRule.onFieldChange(queryObject, selectStudentInfo, idx); + AddRule.onOperatorChange(queryObject, selectComparisonOperator, idx); + AddRule.onValueChange(queryObject, input, idx); + AddRule.onDeleteRule(queryObject, rulesList, deleteRule, idx); + } +} diff --git a/src/index.js b/src/index.js index 2e00316..9958b26 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,9 @@ import logicalOperators from './logicalOperators'; import comparisonOperators from './comparisonOperators'; import studentsInfo from './studentsInfo'; import './styles.css'; +import AddRule from './AddRule'; + +const addRule = new AddRule(); const logicalDropdownList = document.getElementById('logical'); logicalOperators.forEach((item) => { @@ -35,98 +38,12 @@ function ruleObject(field, operator, value) { const rulesList = document.getElementById('rules-list'); -function onFieldChange(selectStudentInfo, id) { - selectStudentInfo.addEventListener('change', (e) => { - queryObject.rules.forEach((rule) => { - if (rule.id === id) { - const updatedFieldValue = rule; - updatedFieldValue.field = e.target[e.target.selectedIndex].text; - } - }); - }); -} - -function onOperatorChange(selectComparisonOperator, id) { - selectComparisonOperator.addEventListener('change', (e) => { - queryObject.rules.forEach((rule) => { - if (rule.id === id) { - const updatedOperatorValue = rule; - updatedOperatorValue.operator = e.target[e.target.selectedIndex].text; - } - }); - }); -} - -function onValueChange(input, id) { - input.addEventListener('input', (e) => { - queryObject.rules.forEach((rule) => { - if (rule.id === id) { - const updatedInputValue = rule; - updatedInputValue.value = e.target.value; - } - }); - }); -} - -function onDeleteRule(deleteRule, id) { - deleteRule.addEventListener('click', () => { - queryObject.rules = queryObject.rules.filter((rule) => rule.id !== id); - - const node = document.getElementById(id); - 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); - }); - return selectElement; -} - -function addRule() { - const field = 'First Name'; - const operator = '='; - - const selectStudentInfo = createSelectElement( +document.getElementById('btn-add-rule').addEventListener('click', () => { + addRule.addRule( + queryObject, + ruleObject, + rulesList, 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); +}); From 5a0553606bb7fce3c72fe05fc070ab78178bba7d Mon Sep 17 00:00:00 2001 From: "Edwin P. Magezi" Date: Tue, 25 Apr 2023 14:26:32 +0300 Subject: [PATCH 2/8] Add basic Rule class --- src/Rule.js | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/index.js | 20 +++++++++------ 2 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 src/Rule.js diff --git a/src/Rule.js b/src/Rule.js new file mode 100644 index 0000000..5f3be31 --- /dev/null +++ b/src/Rule.js @@ -0,0 +1,71 @@ +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; + + // 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 = option.innerHTML; + option.innerHTML = item; + selectElement.appendChild(option); + }); + return selectElement; + } + + init() { + this.createFieldSelect().createOperatorSelect().createValueInput(); + this.addElementsToWrapper(); + } + + 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; + } + + addElementsToWrapper() { + if (this.wrapper) { + this.wrapper.appendChild(this.fieldSelect); + this.wrapper.appendChild(this.comparisonSelect); + this.wrapper.appendChild(this.valueElement); + } else { + throw new Error('A wrapper element is required!'); + } + } +} diff --git a/src/index.js b/src/index.js index 9958b26..9d8c1be 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,7 @@ import comparisonOperators from './comparisonOperators'; import studentsInfo from './studentsInfo'; import './styles.css'; import AddRule from './AddRule'; +import Rule from './Rule'; const addRule = new AddRule(); @@ -39,11 +40,16 @@ function ruleObject(field, operator, value) { const rulesList = document.getElementById('rules-list'); document.getElementById('btn-add-rule').addEventListener('click', () => { - addRule.addRule( - queryObject, - ruleObject, - rulesList, - studentsInfo, - comparisonOperators, - ); + // addRule.addRule( + // queryObject, + // ruleObject, + // rulesList, + // studentsInfo, + // comparisonOperators, + // ); + const li = document.createElement('li'); + const newRule = new Rule(li); + rulesList.appendChild(li); + + console.log(newRule); }); From 464e741f66a42066616e93eca4baa81f500e8e62 Mon Sep 17 00:00:00 2001 From: "Edwin P. Magezi" Date: Tue, 25 Apr 2023 14:34:33 +0300 Subject: [PATCH 3/8] Get input elements from class instance --- src/Rule.js | 12 ++++++++++++ src/index.js | 26 +++++++++++++------------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/Rule.js b/src/Rule.js index 5f3be31..75ef79a 100644 --- a/src/Rule.js +++ b/src/Rule.js @@ -32,6 +32,18 @@ export default class Rule { return selectElement; } + get getFieldElement() { + return this.fieldSelect; + } + + get getValueElement() { + return this.valueElement; + } + + get getComparisonElement() { + return this.comparisonSelect; + } + init() { this.createFieldSelect().createOperatorSelect().createValueInput(); this.addElementsToWrapper(); diff --git a/src/index.js b/src/index.js index 9d8c1be..fff7fa3 100644 --- a/src/index.js +++ b/src/index.js @@ -1,12 +1,10 @@ import { nanoid } from 'nanoid'; import logicalOperators from './logicalOperators'; -import comparisonOperators from './comparisonOperators'; -import studentsInfo from './studentsInfo'; import './styles.css'; -import AddRule from './AddRule'; +// import AddRule from './AddRule'; import Rule from './Rule'; -const addRule = new AddRule(); +// const addRule = new AddRule(); const logicalDropdownList = document.getElementById('logical'); logicalOperators.forEach((item) => { @@ -28,14 +26,14 @@ logicalDropdownList.addEventListener('change', (e) => { queryObject.combinator = e.target[e.target.selectedIndex].text; }); -function ruleObject(field, operator, value) { - return { - id: nanoid(), - field, - operator, - value, - }; -} +// function ruleObject(field, operator, value) { +// return { +// id: nanoid(), +// field, +// operator, +// value, +// }; +// } const rulesList = document.getElementById('rules-list'); @@ -51,5 +49,7 @@ document.getElementById('btn-add-rule').addEventListener('click', () => { const newRule = new Rule(li); rulesList.appendChild(li); - console.log(newRule); + newRule.getFieldElement.addEventListener('change', () => { + console.log('Changed!'); + }); }); From 75d1c5c0ae187a1ea4a2225010cfee0407c930e1 Mon Sep 17 00:00:00 2001 From: "Edwin P. Magezi" Date: Tue, 25 Apr 2023 15:04:06 +0300 Subject: [PATCH 4/8] Add event listeners --- src/Rule.js | 23 ++++++++++++++++++++++- src/index.js | 2 +- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Rule.js b/src/Rule.js index 75ef79a..b6765dc 100644 --- a/src/Rule.js +++ b/src/Rule.js @@ -25,7 +25,7 @@ export default class Rule { dropDownData.forEach((item) => { const option = document.createElement('option'); - option.value = option.innerHTML; + option.value = item; option.innerHTML = item; selectElement.appendChild(option); }); @@ -47,6 +47,7 @@ export default class Rule { init() { this.createFieldSelect().createOperatorSelect().createValueInput(); this.addElementsToWrapper(); + this.addEventListeners(); } createFieldSelect() { @@ -80,4 +81,24 @@ export default class Rule { throw new Error('A wrapper element is required!'); } } + + addEventListeners() { + if (this.fieldSelect) { + this.fieldSelect.addEventListener('change', (event) => { + this.field = event.target.value; + }); + } + + if (this.comparisonSelect) { + this.comparisonSelect.addEventListener('change', (event) => { + this.operator = event.target.value; + }); + } + + if (this.valueElement) { + this.valueElement.addEventListener('change', (event) => { + this.value = event.target.value; + }); + } + } } diff --git a/src/index.js b/src/index.js index fff7fa3..af35ce4 100644 --- a/src/index.js +++ b/src/index.js @@ -50,6 +50,6 @@ document.getElementById('btn-add-rule').addEventListener('click', () => { rulesList.appendChild(li); newRule.getFieldElement.addEventListener('change', () => { - console.log('Changed!'); + console.log('Changed!', newRule.field); }); }); From a866a0afeac91fdece00a39a461c474606f5e3b1 Mon Sep 17 00:00:00 2001 From: "Edwin P. Magezi" Date: Tue, 25 Apr 2023 15:12:55 +0300 Subject: [PATCH 5/8] Abstract onChange for field --- src/Rule.js | 11 +++++++++++ src/index.js | 11 +++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/Rule.js b/src/Rule.js index b6765dc..e67e31b 100644 --- a/src/Rule.js +++ b/src/Rule.js @@ -86,6 +86,9 @@ export default class Rule { if (this.fieldSelect) { this.fieldSelect.addEventListener('change', (event) => { this.field = event.target.value; + if (this.onChangeFieldCallback) { + this.onChangeFieldCallback(this.field); + } }); } @@ -101,4 +104,12 @@ export default class Rule { }); } } + + onChangeField(callback) { + this.onChangeFieldCallback = callback; + } + + onDelete(callback) { + this.onDeleteCallback = callback; + } } diff --git a/src/index.js b/src/index.js index af35ce4..c2a2c42 100644 --- a/src/index.js +++ b/src/index.js @@ -36,6 +36,7 @@ logicalDropdownList.addEventListener('change', (e) => { // } const rulesList = document.getElementById('rules-list'); +const arrayRules = []; document.getElementById('btn-add-rule').addEventListener('click', () => { // addRule.addRule( @@ -49,7 +50,13 @@ document.getElementById('btn-add-rule').addEventListener('click', () => { const newRule = new Rule(li); rulesList.appendChild(li); - newRule.getFieldElement.addEventListener('change', () => { - console.log('Changed!', newRule.field); + newRule.onChangeField((value) => { + console.log('Changed!', value); }); + + newRule.onDelete(() => { + li.remove(); + }); + + arrayRules.push(newRule); }); From c05d510d7e7e9c0f7dc93355be160d97db44d09a Mon Sep 17 00:00:00 2001 From: APIYOJENNIFER Date: Tue, 25 Apr 2023 18:03:45 +0300 Subject: [PATCH 6/8] Delete rule, and listen to element changes from class --- src/AddRule.js | 99 -------------------------------------------------- src/Rule.js | 46 ++++++++++++++++++++++- src/index.js | 80 +++++++++++++++++++++++++++------------- 3 files changed, 99 insertions(+), 126 deletions(-) diff --git a/src/AddRule.js b/src/AddRule.js index e04327f..cb2b42e 100644 --- a/src/AddRule.js +++ b/src/AddRule.js @@ -28,103 +28,4 @@ export default class AddRule { get getValue() { return this.value; } - - static onFieldChange(queryObject, selectStudentInfo, id) { - selectStudentInfo.addEventListener('change', (e) => { - queryObject.rules.forEach((rule) => { - if (rule.id === id) { - const updatedFieldValue = rule; - updatedFieldValue.field = e.target[e.target.selectedIndex].text; - } - }); - }); - } - - static onOperatorChange(queryObject, selectComparisonOperator, id) { - selectComparisonOperator.addEventListener('change', (e) => { - queryObject.rules.forEach((rule) => { - if (rule.id === id) { - const updatedOperatorValue = rule; - updatedOperatorValue.operator = e.target[e.target.selectedIndex].text; - } - }); - }); - } - - static onValueChange(queryObject, input, id) { - input.addEventListener('input', (e) => { - queryObject.rules.forEach((rule) => { - if (rule.id === id) { - const updatedInputValue = rule; - updatedInputValue.value = e.target.value; - } - }); - }); - } - - static onDeleteRule(queryObject, rulesList, deleteRule, id) { - deleteRule.addEventListener('click', () => { - const returnedRules = queryObject; - returnedRules.rules = queryObject.rules.filter((rule) => rule.id !== id); - - const node = document.getElementById(id); - rulesList.removeChild(node); - }); - } - - static 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); - }); - return selectElement; - } - - addRule( - queryObject, - ruleObject, - rulesList, - studentsInfo, - comparisonOperators, - ) { - const selectStudentInfo = AddRule.createSelectElement( - studentsInfo, - 'select-student-info', - ); - const selectComparisonOperator = AddRule.createSelectElement( - comparisonOperators, - 'select-comparison-operator', - ); - - const input = document.createElement('input'); - input.id = 'input-value'; - - const deleteRule = document.createElement('button'); - deleteRule.id = 'btn-delete-rule'; - deleteRule.appendChild(document.createTextNode('DELETE')); - - queryObject.rules.push( - ruleObject(this.getField, this.getOperator, this.getValue), - ); - - 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); - - AddRule.onFieldChange(queryObject, selectStudentInfo, idx); - AddRule.onOperatorChange(queryObject, selectComparisonOperator, idx); - AddRule.onValueChange(queryObject, input, idx); - AddRule.onDeleteRule(queryObject, rulesList, deleteRule, idx); - } } diff --git a/src/Rule.js b/src/Rule.js index e67e31b..f0b1b2f 100644 --- a/src/Rule.js +++ b/src/Rule.js @@ -14,6 +14,7 @@ export default class Rule { this.comparisonSelect = null; this.fieldSelect = null; this.valueElement = null; + this.deleteElement = null; // properly initialise rule this.init(); @@ -44,14 +45,24 @@ export default class Rule { return this.comparisonSelect; } + get getDeleteElement() { + return this.deleteElement; + } + init() { - this.createFieldSelect().createOperatorSelect().createValueInput(); + this.createFieldSelect() + .createOperatorSelect() + .createValueInput() + .createDeleteElement(); this.addElementsToWrapper(); this.addEventListeners(); } createFieldSelect() { - this.fieldSelect = Rule.createSelectElement(studentsInfo, 'select-student-info'); + this.fieldSelect = Rule.createSelectElement( + studentsInfo, + 'select-student-info', + ); return this; } @@ -72,11 +83,20 @@ export default class Rule { 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!'); } @@ -95,12 +115,26 @@ export default class Rule { 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(); + } }); } } @@ -109,6 +143,14 @@ export default class Rule { 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 c2a2c42..6d0d509 100644 --- a/src/index.js +++ b/src/index.js @@ -1,15 +1,13 @@ import { nanoid } from 'nanoid'; import logicalOperators from './logicalOperators'; import './styles.css'; -// import AddRule from './AddRule'; +import AddRule from './AddRule'; import Rule from './Rule'; -// const addRule = new AddRule(); - const logicalDropdownList = document.getElementById('logical'); logicalOperators.forEach((item) => { const option = document.createElement('option'); - option.value = option.innerHTML; + option.value = item; option.innerHTML = item; logicalDropdownList.appendChild(option); }); @@ -23,40 +21,72 @@ const queryObject = { }; logicalDropdownList.addEventListener('change', (e) => { - queryObject.combinator = e.target[e.target.selectedIndex].text; + queryObject.combinator = e.target.value; }); -// function ruleObject(field, operator, value) { -// return { -// id: nanoid(), -// field, -// operator, -// value, -// }; -// } +function ruleObject(field, operator, value) { + return { + id: nanoid(), + field, + operator, + value, + }; +} const rulesList = document.getElementById('rules-list'); -const arrayRules = []; +const arrayRules = {}; document.getElementById('btn-add-rule').addEventListener('click', () => { - // addRule.addRule( - // queryObject, - // ruleObject, - // rulesList, - // studentsInfo, - // comparisonOperators, - // ); + const addRule = new AddRule(); + + queryObject.rules.push( + ruleObject(addRule.getField, addRule.getOperator, addRule.getValue), + ); + + const { id: idx } = queryObject.rules[queryObject.rules.length - 1]; + const li = document.createElement('li'); + li.id = idx; const newRule = new Rule(li); rulesList.appendChild(li); + arrayRules.instance = newRule; + newRule.onChangeField((value) => { - console.log('Changed!', value); + queryObject.rules.forEach((rule) => { + if (rule.id === idx) { + const updateFieldValue = rule; + updateFieldValue.field = value; + } + }); }); - newRule.onDelete(() => { - li.remove(); + newRule.onChangeComparison((value) => { + queryObject.rules.forEach((rule) => { + if (rule.id === idx) { + const updateOperatorValue = rule; + updateOperatorValue.operator = value; + } + }); }); - arrayRules.push(newRule); + newRule.onChangeValue((value) => { + queryObject.rules.forEach((rule) => { + if (rule.id === idx) { + const updateInputValue = rule; + updateInputValue.value = value; + } + }); + }); + + newRule.onDelete(() => { + queryObject.rules = queryObject.rules.filter((rule) => rule.id !== idx); + + const node = document.getElementById(idx); + rulesList.removeChild(node); + + if (queryObject.rules.length === 0) { + arrayRules.instance = null; + } + }); }); From 08ea46b260849a3fd6dd9262cc713ac409d28c30 Mon Sep 17 00:00:00 2001 From: APIYOJENNIFER Date: Wed, 26 Apr 2023 12:09:17 +0300 Subject: [PATCH 7/8] Abstract rule object --- src/AddRule.js | 38 +++++++++++++++++++++++++++++--------- src/index.js | 13 +------------ 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/AddRule.js b/src/AddRule.js index cb2b42e..6c5dc72 100644 --- a/src/AddRule.js +++ b/src/AddRule.js @@ -1,31 +1,51 @@ +import { nanoid } from 'nanoid'; + export default class AddRule { + #id; + + #field; + + #operator; + + #value; + constructor(field = 'First Name', operator = '=', value = '') { - this.field = field; - this.operator = operator; - this.value = value; + this.#id = nanoid(); + this.#field = field; + this.#operator = operator; + this.#value = value; } set setField(value) { - this.field = value; + this.#field = value; } get getField() { - return this.field; + return this.#field; } set setOperator(value) { - this.operator = value; + this.#operator = value; } get getOperator() { - return this.operator; + return this.#operator; } set setValue(value) { - this.value = value; + this.#value = value; } get getValue() { - return this.value; + return this.#value; + } + + createRuleObject() { + return { + id: this.#id, + field: this.#field, + operator: this.#operator, + value: this.#value, + }; } } diff --git a/src/index.js b/src/index.js index 6d0d509..2641771 100644 --- a/src/index.js +++ b/src/index.js @@ -24,24 +24,13 @@ logicalDropdownList.addEventListener('change', (e) => { queryObject.combinator = e.target.value; }); -function ruleObject(field, operator, value) { - return { - id: nanoid(), - field, - operator, - value, - }; -} - const rulesList = document.getElementById('rules-list'); const arrayRules = {}; document.getElementById('btn-add-rule').addEventListener('click', () => { const addRule = new AddRule(); - queryObject.rules.push( - ruleObject(addRule.getField, addRule.getOperator, addRule.getValue), - ); + queryObject.rules.push(addRule.createRuleObject()); const { id: idx } = queryObject.rules[queryObject.rules.length - 1]; From e9009303344520a357f735e2314e28f020e097ee Mon Sep 17 00:00:00 2001 From: APIYOJENNIFER Date: Thu, 27 Apr 2023 12:09:41 +0300 Subject: [PATCH 8/8] Encapsulate rule and query object, and abstract logical select event listener --- src/AddRule.js | 13 ++++++- src/Query.js | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/index.js | 25 ++++---------- 3 files changed, 110 insertions(+), 20 deletions(-) create mode 100644 src/Query.js diff --git a/src/AddRule.js b/src/AddRule.js index 6c5dc72..421043a 100644 --- a/src/AddRule.js +++ b/src/AddRule.js @@ -9,11 +9,17 @@ export default class AddRule { #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) { @@ -40,12 +46,17 @@ export default class AddRule { return this.#value; } + getRuleObject() { + return this.#ruleObject; + } + createRuleObject() { - return { + 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/index.js b/src/index.js index 2641771..a42d48b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,27 +1,14 @@ -import { nanoid } from 'nanoid'; -import logicalOperators from './logicalOperators'; 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 = item; - option.innerHTML = item; - logicalDropdownList.appendChild(option); -}); - -const combinator = 'AND'; +const query = new Query(); -const queryObject = { - id: nanoid(), - combinator, - rules: [], -}; +const queryObject = query.getQueryObject(); -logicalDropdownList.addEventListener('change', (e) => { - queryObject.combinator = e.target.value; +query.onChangeLogical((value) => { + queryObject.combinator = value; }); const rulesList = document.getElementById('rules-list'); @@ -30,7 +17,7 @@ const arrayRules = {}; document.getElementById('btn-add-rule').addEventListener('click', () => { const addRule = new AddRule(); - queryObject.rules.push(addRule.createRuleObject()); + queryObject.rules.push(addRule.getRuleObject()); const { id: idx } = queryObject.rules[queryObject.rules.length - 1];