Skip to content

Commit

Permalink
feat: calculte supports tenary and conditionals
Browse files Browse the repository at this point in the history
 - update to functional programing
  • Loading branch information
frankpagan committed Nov 19, 2023
1 parent 9e2ea92 commit a74713e
Showing 1 changed file with 112 additions and 120 deletions.
232 changes: 112 additions & 120 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,177 +1,169 @@
import observer from '@cocreate/observer';
import { getAttributes } from '@cocreate/utils';
// import { renderValue } from '@cocreate/render';
import '@cocreate/element-prototype';

var CoCreateCalculation = {

init: function () {
let calculationElements = document.querySelectorAll('[calculate]');
this.initElements(calculationElements);
},
function init() {
let calculationElements = document.querySelectorAll('[calculate]');
initElements(calculationElements);
}

initElements: function (elements) {
for (let el of elements)
this.initElement(el);
},
function initElements(elements) {
for (let el of elements)
initElement(el);
}

initElement: function (ele) {
const self = this;
let calculation = ele.getAttribute('calculate');
let selectors = this.getSelectors(calculation);
function initElement(element) {
let calculation = element.getAttribute('calculate');
if (calculation.includes('{{') || calculation.includes('{['))
return;

for (let i = 0; i < selectors.length; i++) {
let id = selectors[i];
if (id.includes('{{')) return;
let selectors = getSelectors(calculation);

// self.initEvents(ele, id);
let inputs = document.querySelectorAll(id);
for (let input of inputs) {
self.initEvent(ele, input);
}
for (let i = 0; i < selectors.length; i++) {
// if (selectors[i].includes('{{')) return;

observer.init({
name: 'calculationSelectorInit',
observe: ['addedNodes'],
target: id,
callback: function (mutation) {
self.initEvent(ele, mutation.target);
self.setCalcationResult(ele);
}
});

self.setCalcationResult(ele);
// initEvents(element, selectors[i]);
let inputs = document.querySelectorAll(selectors[i]);
for (let input of inputs) {
initEvent(element, input);
}
},

initEvent: function (ele, input) {
const self = this;
input.addEventListener('input', function () {
self.setCalcationResult(ele);
observer.init({
name: 'calculationSelectorInit',
observe: ['addedNodes'],
target: selectors[i],
callback(mutation) {
initEvent(element, mutation.target);
setCalcationResult(element);
}
});
}
setCalcationResult(element);
}

// if (input.hasAttribute('calculate')) {
// input.addEventListener('changedCalcValue', function(e) {
// self.setCalcationResult(ele);
// });
// }
// self.setCalcationResult(ele);
},

getSelectors: function (string) {
let tmp = string;

let selectors = [];
if (!tmp) return selectors;
while (tmp.length > 0) {
let firstIndex = tmp.indexOf('{');
let secondIndex = tmp.indexOf('}', firstIndex);

if (firstIndex > -1 && secondIndex > -1) {
let id = tmp.substring(firstIndex + 1, secondIndex);

if (selectors.indexOf(id) == -1) selectors.push(id);
function getSelectors(string) {
let regex = /\{\((?:(?!\{\().)*?\)\}/;
let selectors = [];

tmp = tmp.substring(secondIndex + 1);
let match;
while ((match = regex.exec(string)) !== null) {
// Extract the content inside the braces (excluding the leading '{(' and trailing ')}')
let selector = match[0].slice(2, -2);

}
else {
return selectors;
}
if (selectors.indexOf(selector) === -1) {
selectors.push(selector);
}

return selectors;
},
// Replace the found match with an empty string to avoid reprocessing in the next iteration
string = string.replace(match[0], '');
}

return selectors;
}

getValues: async function (calculation) {
let selectors = this.getSelectors(calculation);
async function getValues(calculation) {
let selectors = getSelectors(calculation);

for (let i = 0; i < selectors.length; i++) {
let selector = selectors[i];
for (let i = 0; i < selectors.length; i++) {
let selector = selectors[i];

let value = null;
let inputs = document.querySelectorAll(selector);
let value = null;
let inputs = document.querySelectorAll(selector);

for (let input of inputs) {
let val = null;
if (input.getValue)
val = Number(await input.getValue());
for (let input of inputs) {
let val = null;
if (input.getValue)
val = Number(await input.getValue());

if (!Number.isNaN(value)) {
value += val;
}
if (!Number.isNaN(value)) {
value += val;
}
}

if (value != null && !Number.isNaN(value)) {
calculation = calculation.replaceAll('{' + selector + '}', value);
}
if (value != null && !Number.isNaN(value)) {
calculation = calculation.replaceAll('{' + selector + '}', value);
}
}

return calculation;
},
return calculation;
}

setCalcationResult: async function (element) {
const { object, isRealtime } = getAttributes(element);
let calculation = element.getAttribute('calculate');
function initEvent(element, input) {
input.addEventListener('input', function () {
setCalcationResult(element);
});

// if (input.hasAttribute('calculate')) {
// input.addEventListener('changedCalcValue', function(e) {
// setCalcationResult(element);
// });
// }
// setCalcationResult(element);
}

let calString = await this.getValues(calculation);
async function setCalcationResult(element) {
const { object, isRealtime } = getAttributes(element);
let calculation = element.getAttribute('calculate');

if (calString) {
let result = calculate(calString);
let calString = await getValues(calculation);

// TODO: input event below triggers save for all input elements but will not save for regular elements
if (element.setValue) {
element.setValue(result)
if (object && isRealtime != "false") {
element.save(element);
}
}
else {
// if (element.value){
if (calString) {
let result = calculate(calString);

// }
// else {
element.innerHTML = result;
// }
// TODO: input event below triggers save for all input elements but will not save for regular elements
if (element.setValue) {
element.setValue(result)
if (object && isRealtime != "false") {
element.save(element);
}
}
else {
// if (element.value){

let inputEvent = new CustomEvent('input', { bubbles: true });
Object.defineProperty(inputEvent, 'target', { writable: false, value: element });
element.dispatchEvent(inputEvent);

//. set custom event
// var event = new CustomEvent('changedCalcValue', {
// bubbles: true,
// });
// element.dispatchEvent(event);
// }
// else {
element.innerHTML = result;
// }
}

},
let inputEvent = new CustomEvent('input', { bubbles: true });
Object.defineProperty(inputEvent, 'target', { writable: false, value: element });
element.dispatchEvent(inputEvent);

};
//. set custom event
// var event = new CustomEvent('changedCalcValue', {
// bubbles: true,
// });
// element.dispatchEvent(event);
}

}

function calculate(string) {
if (!string.match(/[a-z_]/i))
if (/^[0-9+\-*/()%||?\s:=.]*$/.test(string))
return eval(string);
}

observer.init({
name: 'CoCreateCalculationChangeValue',
observe: ['attributes'],
attributeName: ['calculate'],
callback: function (mutation) {
CoCreateCalculation.setCalcationResult(mutation.target);
callback(mutation) {
setCalcationResult(mutation.target);
}
});

observer.init({
name: 'CoCreateCalculationInit',
observe: ['addedNodes'],
target: '[calculate]',
callback: function (mutation) {
CoCreateCalculation.initElement(mutation.target);
callback(mutation) {
initElement(mutation.target);
}
});

CoCreateCalculation.init();
init();

export default CoCreateCalculation;
export default { initElements, initElement, calculate };

0 comments on commit a74713e

Please sign in to comment.