-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement data-map attribute #61
base: main
Are you sure you want to change the base?
Changes from all commits
bf6cec0
2228533
6d5b7d7
7b84ee3
f85385d
b72eaed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,64 @@ | ||
{{> components}} | ||
|
||
<!-- This is an input that --> | ||
<br/> | ||
<pre> | ||
Elements with: | ||
class="lux-component" | ||
data-lux-[attribute name] | ||
will set the attribute to the value of the variable | ||
</pre> | ||
<input class="lux-component" data-lux-value="input.color"> | ||
<input class="lux-component" data-lux-rudder="testData" data-lux-heading="testData2" /> | ||
<br/> | ||
<br/> | ||
<pre> | ||
Elements with: | ||
data-lux-map="[JSON]" | ||
JSON: | ||
{ | ||
[property name] : [variable name], | ||
[property name] : [variable name], | ||
} | ||
{ | ||
[property name] : { | ||
'data-var-name' : [variable name], | ||
'machine': [machine name] | ||
}, | ||
[property name] : { | ||
'data-var-name' : [variable name], | ||
'machine': [machine name] | ||
} | ||
} | ||
{ | ||
@[attribute name] : [variable name], | ||
@[attribute name] : [variable name] | ||
} | ||
{ | ||
@[attribute name] : { | ||
'data-var-name' : [variable name], | ||
'machine': [machine name] | ||
}, | ||
@[attribute name] : { | ||
'data-var-name' : [variable name], | ||
'machine': [machine name] | ||
} | ||
} | ||
</pre> | ||
<!-- These are std inputs to local variables --> | ||
<br/> | ||
color: | ||
<input class="lux-text-value" data-var-name="input.color" /> | ||
width: | ||
<input class="lux-text-value" data-var-name="input.width" /> | ||
<br/> | ||
|
||
<input data-lux-map="{'rudder' :'testData', 'heading':'testdata2'}" /> | ||
<input data-lux-map="{'rudder' :{'data-var-name':'testData'}, 'heading':'testdata2'}" /> | ||
<input data-lux-map="{'@rudder':{'data-var-name':'testData'}, 'heading':'testdata2'}" /> | ||
<input data-lux-map="{'value' :{'data-var-name':'testData'}, 'style.backgroundColor':'input.color', 'style.width':'input.width'}" /> | ||
|
||
|
||
|
||
<comp data-heading="machine['myVar']"> | ||
|
||
{{> components}} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,6 +96,80 @@ function isEqual(in1, in2) { | |
|
||
} | ||
|
||
/** | ||
* @function setDeepObjectValue | ||
* @param {Object} obj The object to set the value on | ||
* @param {string | [string]} prop The deep property to set. Can be a string or an array of strings | ||
* @param {any} value | ||
* @returns | ||
* @example setDeepObjectValue(obj, 'a.b.c', 1) | ||
*/ | ||
LUX.setDeepObjectValue = function (obj, prop, value) { | ||
//Note: This function was pulled out of Lux | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you clarify the meaning of "this function was pulled out of LUX"? Maybe it was pulled from a separate file in the repo? I find it confusing since this still is in the LUX repo. Also, it is unclear why this is "risky" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there is a setDeepValue in Lux.js. I didn't want to modify that because i don't know if there are ramifications to the way it was functioning |
||
// so that it can be used in other places | ||
// It is modified from the original to | ||
// check if an object is more generic than just | ||
// Object.prototype.toString.call(obj) === '[object Object]' | ||
// It's possible that this could be pulled back into lux | ||
// But that feels more risky than just leaving it here | ||
// Since this is a new use case.. | ||
var e, startArrayIndex, type, i; | ||
|
||
// First time through, split prop | ||
if (typeof prop === "string") { | ||
prop = prop.split("."); | ||
} | ||
|
||
if (prop.length > 1) { | ||
|
||
// If not at bottom of prop, keep going | ||
e = prop.shift(); | ||
|
||
// Check for array elements | ||
startArrayIndex = e.indexOf('['); | ||
|
||
if (startArrayIndex === -1) { | ||
// If element does not exist, create it | ||
if (typeof obj[e] === "undefined") { | ||
obj[e] = {}; | ||
} | ||
return LUX.setDeepObjectValue(obj[e], prop, value); | ||
} else { | ||
i = parseInt(e.substring(startArrayIndex + 1), 10); | ||
e = e.substring(0, startArrayIndex); | ||
// If array does not exist, create it | ||
if (typeof obj[e] === "undefined") { | ||
obj[e] = []; | ||
} | ||
// If element does not exist, create it | ||
if ( typeof obj[e] === "undefined") { | ||
obj[e][i] = {}; | ||
} | ||
return LUX.setDeepObjectValue(obj[e][i], prop, value); | ||
} | ||
|
||
} else { | ||
|
||
e = prop[0]; | ||
|
||
// Check for array elements | ||
startArrayIndex = e.indexOf('['); | ||
if (startArrayIndex === -1) { | ||
obj[e] = value; | ||
return obj[e]; | ||
} else { | ||
i = parseInt(e.substring(startArrayIndex + 1), 10); | ||
e = e.substring(0, startArrayIndex); | ||
// If array does not exist, create it | ||
if (typeof obj[e] === "undefined") { | ||
obj[e] = []; | ||
} | ||
obj[e][i] = value; | ||
return obj[e][i]; | ||
} | ||
} | ||
} | ||
|
||
// Get attribute values | ||
//---------------------- | ||
|
||
|
@@ -423,6 +497,109 @@ LUX.updateHide = function () { | |
|
||
} | ||
|
||
LUX.queryDataMaps = function () { | ||
LUX.elems.datamap = Array.from(document.querySelectorAll('.lux-component, [data-lux-map]')).filter(el => | ||
Array.from(el.attributes).some(attr => attr.name.startsWith('data-lux')) | ||
); | ||
} | ||
|
||
LUX.updateDataMaps = function () { | ||
LUX.visibleElems.datamap.forEach((el) => { | ||
let mapping = el.dataMapObject; | ||
if (!mapping) { | ||
el.dataMapObject = this.updateDataMaps.parseDataMap(el); | ||
} | ||
let $element = $(el); | ||
var localMachine = LUX.getMachine($element); // NOTE: Try this here before migrating everything else... | ||
for (let key in mapping) { | ||
this.updateDataMaps.updateParameter($element, localMachine, key, mapping[key]); | ||
} | ||
}); | ||
} | ||
|
||
LUX.updateDataMaps.parseDataMap = function(el) { | ||
let map = {}; | ||
Array.from(el.attributes).forEach(attr => { | ||
if (attr.name.startsWith('data-lux')) { | ||
let key = attr.name.replace('data-lux-', '').replace('-', '.'); | ||
if(key == 'map') return; | ||
let value = attr.value; | ||
map[key] = {'data-var-name':value, attribute:true}; | ||
} | ||
}); | ||
let dataMap = el.getAttribute('data-lux-map'); | ||
if(dataMap) { | ||
dataMap = dataMap.replace(/'/g, '"'); | ||
try { | ||
dataMap = JSON.parse(dataMap); | ||
for (let key in dataMap) { | ||
let value = dataMap[key]; | ||
if (typeof value === 'string') { | ||
dataMap[key] = {'data-var-name':value}; | ||
} | ||
if(key.startsWith('@')){ | ||
let value = dataMap[key]; | ||
delete dataMap[key]; | ||
key = key.replace('@', ''); | ||
dataMap[key] = value; | ||
dataMap[key].attribute = true; | ||
} | ||
else{ | ||
if( typeof dataMap[key].attribute === 'undefined'){ | ||
dataMap[key].attribute = false; | ||
} | ||
} | ||
|
||
} | ||
} | ||
catch(e){ | ||
console.error('Error parsing data-lux-map attribute for element', el, e); | ||
dataMap = {}; | ||
} | ||
} | ||
return Object.assign(map, dataMap); | ||
} | ||
|
||
LUX.updateDataMaps.updateParameterValue = function($element, localMachine, key, dataVarName) { | ||
let keyname = key.replace('.','-') | ||
if ($element.attr('data-var-name-added-' + keyname) != dataVarName) { | ||
$element.attr('data-var-name-added-' + keyname, dataVarName) | ||
localMachine.initCyclicReadGroup(LUX.getDataReadGroup($element), dataVarName); | ||
} | ||
let value = localMachine.value(dataVarName); | ||
if ($element.attr('data-machine-value-' + keyname) != value) { | ||
$element.attr('data-machine-value-' + keyname, value) | ||
$element.each((index, val) => { | ||
if(val.dataMapObject[key].attribute){ | ||
val.setAttribute(key, value); | ||
return; | ||
} | ||
else{ | ||
LUX.setDeepObjectValue(val, key, value); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
LUX.updateDataMaps.updateParameter = function($element, elMachine, key, value) { | ||
if (typeof value === 'string') { | ||
this.updateParameterValue($element, elMachine, key, value); | ||
return | ||
} | ||
|
||
if (typeof value === 'object' && value['data-var-name']) { | ||
let { | ||
['data-var-name']:dataVarName, | ||
machine | ||
} = value; | ||
let localMachine = window[machine] | ||
if(localMachine == undefined){ | ||
localMachine = elMachine; | ||
} | ||
this.updateParameterValue($element, localMachine, key, dataVarName); | ||
return | ||
} | ||
} | ||
// find lock/unlock elems | ||
LUX.queryLock = function () { | ||
LUX.elems.lock = Array.prototype.slice.call(document.querySelectorAll('.lux-lock, .lux-unlock, [min-user-level-unlock]')); | ||
|
@@ -1107,6 +1284,7 @@ LUX.observers = []; | |
* @property {Element[]} range | ||
* @property {Element[]} tab | ||
* @property {Element[]} component | ||
* @property {Element[]} datamap | ||
* @property {Element[]} hide | ||
* @property {Element[]} lock | ||
*/ | ||
|
@@ -1125,6 +1303,7 @@ LUX.elems = { | |
range: [], | ||
tab: [], | ||
component: [], | ||
datamap: [], | ||
hide: [], | ||
lock: [] | ||
}; | ||
|
@@ -1143,6 +1322,7 @@ LUX.visibleElems = { | |
range: [], | ||
tab: [], | ||
component: [], | ||
datamap: [], | ||
hide: [], | ||
lock: [] | ||
}; | ||
|
@@ -1159,14 +1339,17 @@ LUX.checkVisibility = function () { | |
|
||
LUX.queryDom = function () { | ||
// TODO: insted of querying document for each class, first query document for class*=lux and then sort based on the different types | ||
performance.mark('queryDom-start'); | ||
LUX.queryInputs(); | ||
LUX.queryToggleButtons(); | ||
LUX.queryLEDs(); | ||
LUX.queryRange(); | ||
LUX.queryTabs(); | ||
LUX.queryComponents(); | ||
LUX.queryDataMaps(); | ||
LUX.queryHide(); | ||
LUX.queryLock(); | ||
console.log(performance.measure('queryDom', 'queryDom-start')); | ||
}; | ||
|
||
LUX.updateHMI = function () { | ||
|
@@ -1179,6 +1362,7 @@ LUX.updateHMI = function () { | |
LUX.updateRange(); | ||
LUX.updateTabs(); | ||
LUX.updateComponents(); | ||
LUX.updateDataMaps(); | ||
LUX.updateHide(); | ||
LUX.updateLock(); | ||
LUX.updateReadGroupComms(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requesting to add a docstring for what these arguments signify