Handling changes in single and multiple select/input in Vanilla JavaScript - javascript

I have a webpage with two select menus, one input, three buttons, and a checkbox. Everything is added and manipulated by JavaScript. On page page load, there is an object initiated with no values ( either value correspond either one of select or input ). You can select values and update it ( target is array of objects ) in array. Then, you can choose one of the buttons to copy selected options. Each object has three value (copying means that you copy the segment containing those values) times as many as you typed in input. After that, all objects are shown on screen. You can click a button to check all checkboxes and all objects change value. Value is updated in all selects of changed type and in the corresponding array.
Now my problems begin. When you unselect all checkboxes and want to change only 1 object all objects are updated and I have no idea why. There are conditions to check for each object if the checkbox is unchecked. If a single object is updated (either select or input) all of the other objects are updated ( none of checkbox is checked).
Here is github link to this project to check everything out without problems.
Also one more thing... whenever I update all values handleDOMChange function should fire automatically, but as you can see I have to fire it up manually so the changes are "visible" on my target array
const collectedData = [ {
cableType: "",
calbleLen_m: 0,
deviceType: ""
} ];
const completeData = {};
window.addEventListener('load', () => {
handleButtonEvents();
const segments = document.querySelectorAll('.installationSegment');
segments.forEach((segment, i) => {
handleInputAndSelectChange(segment, i);
});
const targetNode = document.getElementById("installationContainer");
targetNode.append(selectAllCheckboxesButton);
const config = {
childList: true,
subtree: true,
attributes: true,
characterData: true
};
const observer = new MutationObserver(handleDOMChange);
observer.observe(targetNode, config);
}
//Handling DOMChanges
const handleDOMChange = function() {
const powerSupplyElement = document.getElementById('powerSupply');
powerSupplyElement.addEventListener('change', e => completeData.supplyType = e.target.value);
const segments = document.querySelectorAll('.installationSegment');
if( segments.length >= 2 ) {
segments.forEach((segment, i) => {
const checkbox = segment.querySelector('input[type="checkbox"]');
if( !checkbox.checked ) {
//updating value for single change, i is index of element in array and none of checkboxes is checked.
handleInputAndSelectChange(segment, i);
} else if( checkbox.checked ) {
//updating value for every segment exisitng in DOM whose checkbox has been checked.
handleManySegmentsChange(segment);
}
});
}
completeData.bus = [ ...collectedData ];
console.table(completeData.bus);
}
//handling ButtonEvents
handleButtonEvents = function() {
const installationSegment = document.getElementById('installationContainer');
installationSegment.addEventListener('click', e => {
if( e.target.id.includes("Skopiuj") ) {
handleCopyNthTimes(e);
} else if( e.target.id.includes("Usun") ) {
handleDeleteDevice(e);
} else if( e.target.id === 'selectAllCheckboxes' ) {
checkAllCheckboxes(e);
}
});
}
//handling all checkboxes select and unselect
const checkAllCheckboxes = function() {
const segments = document.querySelectorAll('.installationSegment');
segments.forEach((segment, i) => {
const checkbox = segment.querySelector('input[type="checkbox"]');
checkbox.checked = !checkbox.checked;
handleDOMChange();
});
};
//handling single and multiple changes in select/input
handleManySegmentsChange = function(segment) {
segment.addEventListener('change', (e) => {
switch( e.target.name ) {
case 'cableSelect': {
const cableSelect = document.querySelectorAll('.cableSelect');
cableSelect.forEach(cable => cable.value = e.target.value);
collectedData.forEach(cable => cable.cableType = e.target.value);
handleDOMChange();
break;
}
case 'deviceSelect': {
const deviceSelect = document.querySelectorAll('.deviceSelect');
deviceSelect.forEach(device => device.value = e.target.value);
collectedData.forEach(device => device.deviceType = e.target.value);
handleDOMChange();
break;
}
case 'cableInput': {
const cableInput = document.querySelectorAll('input[name="cableInput"]');
cableInput.forEach(input => input.value = e.target.value);
collectedData.forEach(input => input.calbleLen_m = parseInt(e.target.value));
handleDOMChange();
break;
}
}
})
}
handleInputAndSelectChange = function(segment, index) {
segment.addEventListener('change', (event) => {
switch( event.target.name ) {
case 'cableSelect': {
collectedData[index].cableType = event.target.value;
break;
}
case 'deviceSelect': {
collectedData[index].deviceType = event.target.value;
break;
}
case 'cableInput': {
collectedData[index].calbleLen_m = parseInt(event.target.value);
break;
}
}
});
}

All right, I've found the answer. The reason it didn't work is that handleManySegmentsChange function is going to be fired in one circumstance - if user changes many select values at once. But this cannot be the case. My solution to the problem is to detect one change in segment, check for checkbox value, pass it to the function and depending on the checkbox value either update one value or all of them. Like so:
const segments = document.querySelectorAll('.installationSegment');
segments.forEach((segment, i) => {
segment.addEventListener('change', e => {
const checkbox = segment.querySelector('input[type="checkbox"]');
handleInputAndSelectChange(segment, e, i, checkbox.checked);
})
});
and then in function
handleInputAndSelectChange = function(segment, event, index, checked) {
switch( event.target.name ) {
case 'cableSelect': {
if( checked ) {
const cableSelect = document.querySelectorAll('.cableSelect');
cableSelect.forEach(cable => cable.value = event.target.value);
collectedData.forEach(data => data.cableType = event.target.value);
} else if( !checked ) {
collectedData[index].cableType = event.target.value;
}
break;
}
case 'deviceSelect': {
if( checked ) {
const deviceSelect = document.querySelectorAll('.deviceSelect');
deviceSelect.forEach(device => device.value = event.target.value);
collectedData.forEach(device => device.deviceType = event.target.value);
} else if( !checked ) {
collectedData[index].deviceType = event.target.value;
}
break;
}
case 'cableInput': {
if( checked ) {
const cableInput = document.querySelectorAll('input[name="cableInput"]');
cableInput.forEach(input => input.value = event.target.value);
collectedData.forEach(input => input.calbleLen_m = parseInt(event.target.value));
} else if( !checked ) {
collectedData[index].calbleLen_m = parseInt(event.target.value);
}
break;
}
}
}

Related

React slow event firing on vanilla mouseover event

I have the following code that highlights all the elements that have the same 4 classes, position 0,1 3 and 4.
I have written it in vanilla js and React, the vanilla version works as expected but the react implementation works in a weird way.
Sometimes works, sometimes doesn't, it's like the onExit event is not being called at the right time but just a little bit after so that the prev variable which stores the last hovered item, has another value and didn't had the chance to remove the highlight class.
It's worth saying that this is being used in a Chrome Extension to highlight items on a webpage so everything that is highlighted is outise the react tree, when someone clicks my extension, the following code registers the event on the active tab.
There is also a onClick event which I didn't include to capture all the elements into a variable and then display some tools (which are React components) showing those elments and for that I need to somehow make the React to properly capture the onExit event on time or to connect the vanilla code to some React components to get the captured elements.
// vanilla script, first one
export const initEvents: any = () => {
let _accountantUtils = function () {
this.currClasses = [];
this.selected = [];
if (this.constructor.instance) return this.constructor.instance;
this.constructor.instance = this;
let prev;
this.initOnHover = () => {
const handler = (event) => {
if (event.target === document.body || (prev && prev === event.target)) {
return;
}
if (prev) {
this.onExit(prev);
prev.className = prev.className.replace(/\bh3-highlight\b/, "");
prev = undefined;
}
if (event.target) {
this.onHover(event.target);
prev = event.target;
prev.className += " h3-highlight";
}
}
if (document.body.addEventListener) {
document.body.addEventListener("mouseover", handler);
} else {
alert("browser not supported");
return;
}
};
this.onHover = function (eventEl) {
let classes = [
eventEl.classList[0],
eventEl.classList[1],
eventEl.classList[3],
eventEl.classList[4],
];
let selector = `.${classes.join(".")}`;
const elsWithClasses = Array.from(document.querySelectorAll(selector));
elsWithClasses.map((el) => el.classList.add("highlight"));
this.currClasses = classes;
};
this.onExit = function (eventEl) {
let classes = [
eventEl.classList[0],
eventEl.classList[1],
eventEl.classList[3],
eventEl.classList[4],
];
let selector = `.${classes.join(".")}`;
const elsWithClasses = Array.from(document.querySelectorAll(selector));
elsWithClasses.map((el) => el.classList.remove("highlight"));
this.currClasses = [];
};
};
const accountantUtils = new _accountantUtils();
return accountantUtils;
}
// then init it this this where it's imported:
const accountantUtils = initEvents();
accountantUtils.initOnHover();
const root = ReactDOM.createRoot(document.querySelector("#h3-app") as HTMLElement);
// React implementation
let prev = null;
export const HoverListener = function () {
useEffect(() => {
initOnHover(onExit, onHover);
}, []);
const initOnHover = function (onHover, onExit) {
if (document.body.addEventListener) {
eventListener = document.body.addEventListener('mouseover', handler);
}
else {
alert("browser not supported")
return;
}
function handler(event) {
if (event.target === document.body ||
(prev && prev === event.target)) {
return;
}
if (prev) {
if (onExit) onExit(prev)
prev.className = prev.className.replace(/\bh3-highlight\b/, '');
prev = undefined;
}
if (event.target) {
if (onHover) onHover(event.target)
prev = event.target;
prev.className += " h3-highlight";
}
}
}
const onExit = function (eventEl) {
let classes = [
eventEl.classList[0],
eventEl.classList[1],
eventEl.classList[3],
eventEl.classList[4],
];
let selector = `.${classes.join(".")}`;
const elsWithClasses = Array.from(document.querySelectorAll(selector));
elsWithClasses.map(el => el.classList.remove("h3-highlight"));
}
const onHover = function (eventEl) {
let classes = [
eventEl.classList[0],
eventEl.classList[1],
eventEl.classList[3],
eventEl.classList[4],
];
let selector = `.${classes.join(".")}`;
const elsWithClasses = Array.from(document.querySelectorAll(selector));
elsWithClasses.map(el => el.classList.add("h3-highlight"));
}
return (
<div>
<h1>Listener...</h1>
</div>
);
}
React implementation
Vanilla code

Null of the increment for empty input does not work

const formSteps = [...multiStepForm.querySelectorAll("[data-step]")]
let currentStep = formSteps.findIndex(step => {
return step.classList.contains("active")
})
if (currentStep < 0) {
currentStep = 0
showCurrentStep()
}
multiStepForm.addEventListener("click", e => {
let incrementor
if (e.target.matches("[data-next]")) {
incrementor = 1
} else if (e.target.matches("[data-previous]")) {
incrementor = -1
}
if (incrementor == null) return
const inputs = [...formSteps[currentStep].querySelectorAll("input")]
const allValid = inputs.every(input => input.reportValidity())
if (allValid) {
currentStep += incrementor
showCurrentStep()
}
})
formSteps.forEach(step => {
step.addEventListener("animationend", e => {
formSteps[currentStep].classList.remove("hide")
e.target.classList.toggle("hide", !e.target.classList.contains("active"))
})
})
function showCurrentStep() {
formSteps.forEach((step, index) => {
step.classList.toggle("active", index === currentStep)
})
}
In this case of code, the validation of the data entry does not work and then the incriment for the other steps does not work. I also tried to add required in the inputs ignoring this code, the problem that making a "previous", the user does not have the possibility to go back blocked by the inserted required.
In the code, the incrementor object is already null, seen in log.console does not see it. I think the problem in this case is the querySelection as I noticed from the log.console that it takes data that is not of interest to me.

How to auto grow text on input value?

I have an input form field that outputs text on submit to another created input, essentially an editable todo list. I have tried to make the input text value auto grow, but cannot figure out how to do it. Right now the user has to scroll over to see the rest of the text on each list item. This should not be.
What I tried:
I have tried creating a span and attaching editableContent but that makes my input text disappear.
I have tried setting an attribute on max-length on the created input but cannot get it to work. What is the best way to accomplish auto growing the text input value?
Here is the full codepen
const createTodoText = (todo) => {
const itemText = document.createElement("INPUT");
// const itemText = document.createElement("span");
// itemText.contentEditable
// itemText.contentEditable = 'true'
itemText.classList.add("todoText");
itemText.value = todo.name;
itemText.addEventListener("click", (e) => {
e.currentTarget.classList.add("active");
});
// update todo item when user clicks away
itemText.addEventListener("blur", (e) => {
todo.name = e.currentTarget.value;
renderTodos();
});
return itemText;
};
There you go: -
// select DOM elements
const todoForm = document.querySelector(".todo-form");
const addButton = document.querySelector(".add-button");
const input = document.querySelector(".todo-input");
const ul = document.getElementById("todoList");
let todos = [];
todoForm.addEventListener("submit", function (e) {
e.preventDefault();
addTodo(input.value);
});
const addTodo = (input) => {
if (input !== "") {
const todo = {
id: Date.now(),
name: input,
completed: false
};
todos.push(todo);
renderTodos();
todoForm.reset();
}
};
const renderTodos = (todo) => {
ul.innerHTML = "";
todos.forEach((item) => {
let li = document.createElement("LI");
// li.classList.add('item');
li.setAttribute("class", "item");
li.setAttribute("data-key", item.id);
const itemText = createTodoText(item);
const cb = buildCheckbox(item);
const db = buildDeleteButton(item);
// if (item.completed === true) {
// li.classList.add('checked');
// }
li.append(cb);
li.append(db);
li.append(itemText);
ul.append(li);
});
};
const createTodoText = (todo) => {
const itemText = document.createElement("span");
itemText.setAttribute('role','textbox');
itemText.setAttribute('contenteditable',"true");
itemText.classList.add("todoText");
itemText.innerHTML = todo.name;
itemText.addEventListener("click", (e) => {
e.currentTarget.classList.add("active");
});
// update todo item when user clicks away
itemText.addEventListener("blur", (e) => {
todo.name = e.target.textContent;
renderTodos();
});
return itemText;
};
const buildCheckbox = (todo) => {
const cb = document.createElement('input');
cb.type = 'checkbox';
cb.name = 'checkbox';
cb.classList.add('checkbox');
cb.checked = todo.completed;
// checkbox not staying on current state ??
cb.addEventListener('click', function (e) {
if (e.target.type === 'checkbox') {
// todo.completed = e.target.value;
todo.completed = e.currentTarget.checked
e.target.parentElement.classList.toggle('checked');
}
});
return cb;
};
const buildDeleteButton = (todo) => {
const deleteButton = document.createElement("button");
deleteButton.className = "delete-button";
deleteButton.innerText = "x";
deleteButton.addEventListener("click", function (e) {
// duplicates children sometimes ??
const div = this.parentElement;
div.style.display = "none";
todos = todos.filter((item) => item.id !== todo.id);
});
return deleteButton;
};
// //------ Local Storage ------
function addToLocalStorage(todos) {}
function getFromLocalStorage() {}
// getFromLocalStorage();
This is the Javscript code part. In createTodoText, you can see the changes i've made. It's working according to what you want. What i've done is simple used 'span' instead of 'input'.
How about trying something like
if (todo.name.length) {itemText.size = todo.name.length;}

Multiple elements -> one function while the elements do not colide with each other

I have multiple selectiontags on different picture slides but same page. Each slide has a set of selectiontags and I want users to only choose 1 selectiontag. I have written the code to do this but I wonder if there is another way.
So, basically I want:
Slide1 w. selectiontags1: Choose 1 selectiontag (out of 4)
Slide2 w.selectiontags2: Choose 1 selectiontag
Slide3 w. selectiontags3: Choose 1 selectiontag
Slide4 w. selectiontags4: Choose 1 selectiontag
This is my code so far.
var prevSelectedValue = null;
var prevSelectedValue2 = null;
var prevSelectedValue3 = null;
var prevSelectedValue4 = null;
$w.onReady(function () {
//TODO: write your page related code here...
let tags = $w('#selectionTags1');
if (tags.value.length === 1) {
prevSelectedValue = tags.value[0];
} else if (tags.value.length > 1) {
tags.value = [];
}
let tags2 = $w('#selectionTags2');
if (tags2.value.length === 1) {
prevSelectedValue2 = tags2.value[0];
} else if (tags2.value.length > 1) {
tags2.value = [];
}
let tags3 = $w('#selectionTags3');
if (tags3.value.length === 1) {
prevSelectedValue3 = tags3.value[0];
} else if (tags3.value.length > 1) {
tags3.value = [];
}
let tags4 = $w('#selectionTags4');
if (tags4.value.length === 1) {
prevSelectedValue4 = tags4.value[0];
} else if (tags4.value.length > 1) {
tags4.value = [];
}
});
export function selectionTags1_change(event) {
//Add your code for this event here:
if (!event.target.value || event.target.value.length === 0) {
event.target.value = [prevSelectedValue];
} else {
event.target.value = event.target.value.filter(x => x !== prevSelectedValue);
prevSelectedValue = event.target.value[0];
}
}
export function selectionTags2_change(event) {
//Add your code for this event here:
if (!event.target.value || event.target.value.length === 0) {
event.target.value = [prevSelectedValue2];
} else {
event.target.value = event.target.value.filter(x => x !== prevSelectedValue2);
prevSelectedValue2 = event.target.value[0];
}
}
export function selectionTags3_change(event) {
//Add your code for this event here:
if (!event.target.value || event.target.value.length === 0) {
event.target.value = [prevSelectedValue3];
} else {
event.target.value = event.target.value.filter(x => x !== prevSelectedValue3);
prevSelectedValue3 = event.target.value[0];
}
}
export function selectionTags4_change(event) {
//Add your code for this event here:
if (!event.target.value || event.target.value.length === 0) {
event.target.value = [prevSelectedValue4];
} else {
event.target.value = event.target.value.filter(x => x !== prevSelectedValue4);
prevSelectedValue4 = event.target.value[0];
}
}
Just a couple notes to help clean up the code:
It is better to use event.target.value[event.target.value.length-1] instead of .filter(). While it doesn't make a huge performance difference since our array is so small, we know that the most recently selected item is the last in the array, so using length-1 is more efficient code.
It is better to manipulate the selector and not the event, so I would recommend replacing event.target.value = event.target.value.filter... with $w('#selectionTags2') = event.target.value[..... This will also make your code more readable as you know which element is being updated.
If you are not preloading anything into the $w('#selectionTags') value array, I am not sure the code in your onReady function is necessary (unless I am missing a step where you do populate that selection value array).

How to refactor this double forLoop with lodash?

I have selectedTags which holds up to 3 tags.
vm.tags Could contain thousands, most likely just hundreds of tags that I need to compare too.
If the ids of the 3 tags match the id of a tag inside of vm.tags I need to turn their borders on. There are 3 borders too: border1, border2, border3.
const tagsColorCheck = () => {
let name, selected, its_ticker;
let selectedTags = TagsFactory.retrieveTickerTags('onlyTags');
if (selectedTags.length > 0) {
for (let i=0; i<vm.tags.length; i++) {
for (let j=0; j<selectedTags.length; j++) {
if (selectedTags[j].term_id == vm.tags[i].term_id) {
name = 'border'+ ( j + 1 );
selected = 'selected';
its_ticker = 'its_ticker';
vm.tags[i][name] = true;
vm.tags[i][selected] = true;
vm.tags[i][its_ticker] = selectedTags[j].its_ticker;
}
}
}
}
};
So far here is what I have in process (_.each):
const tagsColorCheck = () => {
let name, selected, its_ticker, vmTerm, term_1, term_2, term_3, ticker_1, ticker_2, ticker_3;
let selectedTags = TagsFactory.retrieveTickerTags('onlyTags');
if (!_.isEmpty(selectedTags)) {
vmTerm = R.findIndex(R.propEq('term_id', selectedTags[0].term_id))(vm.tags);
}
if (selectedTags[0]) { term_1 = parseInt(selectedTags[0].term_id); ticker_1 = selectedTags[0].its_ticker; }
if (selectedTags[1]) { term_2 = parseInt(selectedTags[1].term_id); ticker_2 = selectedTags[1].its_ticker; }
if (selectedTags[2]) { term_3 = parseInt(selectedTags[2].term_id); ticker_3 = selectedTags[2].its_ticker; }
_.each(vm.tags, (tag) => {
if (tag.term_id === term_1) {
tag.selected = true;
tag.border1 = true;
tag.its_ticker = ticker_1;
}
if (tag.term_id === term_2) {
tag.selected = true;
tag.border2 = true;
tag.its_ticker = ticker_2;
}
if (tag.term_id === term_3) {
tag.selected = true;
tag.border3 = true;
tag.its_ticker = ticker_3;
}
})
};
And this (for of loop):
const tagsColorCheck = () => {
let name, selected, its_ticker, vmTerm, term_1, term_2, term_3, ticker_1, ticker_2, ticker_3;
let selectedTags = TagsFactory.retrieveTickerTags('onlyTags');
const borderRizeTag = (tag) => {
if (tag.term_id === term_1) {
tag.selected = true;
tag.border1 = true;
tag.its_ticker = ticker_1;
}
if (tag.term_id === term_2) {
tag.selected = true;
tag.border2 = true;
tag.its_ticker = ticker_2;
}
if (tag.term_id === term_3) {
tag.selected = true;
tag.border3 = true;
tag.its_ticker = ticker_3;
}
return tag;
}
if (!_.isEmpty(selectedTags)) {
vmTerm = R.findIndex(R.propEq('term_id', selectedTags[0].term_id))(vm.tags);
}
if (selectedTags[0]) { term_1 = parseInt(selectedTags[0].term_id); ticker_1 = selectedTags[0].its_ticker; }
if (selectedTags[1]) { term_2 = parseInt(selectedTags[1].term_id); ticker_2 = selectedTags[1].its_ticker; }
if (selectedTags[2]) { term_3 = parseInt(selectedTags[2].term_id); ticker_3 = selectedTags[2].its_ticker; }
for (let tag of vm.tags) {
console.log(tag);
tag = borderRizeTag(tag);
}
console.log('vmTerm',vmTerm);
};
ES6 fiddle to run: http://www.es6fiddle.net/is0prsq9/ (note, copy the entire text, and paste it inside a browser console or a node REPL, and then examine the value of tags to see the result)
It's not lodash, and you don't really need it with ES6 constructs. Relevant code:
const tagsColorCheck = () => {
let tags = TagsFactory.retrieveTickerTags('onlyTags')
sel.forEach( (s,i) =>
tags.filter(t => t.term_id === s.term_id).forEach( t => {
t['border' + (i+1)] = true
t.selected = true
t.its_ticker = s.its_ticker
})
)
return tags
}
If you were writing this in a functional language, you would have access to a list comprehension and it would be a bit cleaner. Essentially, this is a pretty clear case of (for every x in a and y in b) so a list comprehension is what you need, but you don't have it in javascript (mozilla has it, but not useful outside of that realm).
The result is a somewhat functional approach -- however, it can never really be functional in pure javascript. Possibly the most important benefit of the functional paradigm are immutable data structures where you would compose your new list. Instead, you just modify them in place here, which really is not very functional at all. Still, if you prefer the each approach to a literal incremental one, as you have done above and as I did in my post, then it's a (albeit slower but arguably cleaner) better approach.
Figured out an awesome solution! :D using both _lodash and ramda.
So below, immediately each is quicker to reason about, then using R.equals to compare if the term_ids match. Then setting the values of the keys on the correct tag object.
if (!_.isEmpty(selectedTags)) {
_.each(vm.tags, tag => {
_.each(selectedTags, (selectedTag, index) => {
let areTermIDsSame = R.equals;
if (areTermIDsSame(parseInt(selectedTag.term_id), parseInt(tag.term_id))) {
name = 'border'+ ( index + 1 );
selected = 'selected';
its_ticker = 'its_ticker';
tag[name] = true;
tag[selected] = true;
tag[its_ticker] = selectedTag.its_ticker;
}
});
})
}
The idea is simple - create an index of all tags by term_id. Iterate the selected tags. If a tag is found by id in the tags index, mutate it by assigning an object with the new properties.
btw - The only thing lodash is needed for is _.keyBy(), and you can easily do that using Array.prototype.reduce if you don't want to use lodash.
/** mocked vm **/
const vm = {
tags: [{ term_id: 1 }, { term_id: 2 }, { term_id: 3 }, { term_id: 4 }, { term_id: 5 }, { term_id: 6 }]
}
/** mocked TagsFactory **/
const TagsFactory = {
retrieveTickerTags: () => [{ term_id: 1, its_ticker: 'ticker 1' }, { term_id: 4, its_ticker: 'ticker 4' }, { term_id: 5, its_ticker: 'ticker 5' }]
};
const tagsColorCheck = () => {
const selectedTags = TagsFactory.retrieveTickerTags('onlyTags');
if (selectedTags.length === 0) { // if selectedTags is empty exit
return;
}
const vmTagsIndex = _.keyBy(vm.tags, (tag) => tag.term_id); // create an index of tags by term_id
selectedTags.forEach(({
term_id, its_ticker
}, index) => { // loop through selectd tags and retreive term_id and its_ticker from the current selected tag
const tag = vmTagsIndex[term_id]; // find the tag in the vmTagsIndex
if (!tag) { // if the id doesn't exist in vmTagsIndex exit
return;
}
Object.assign(tag, { // mutate the tag by assigining it an object with the available properties
selected: true,
[`border${index + 1}`]: true,
its_ticker
});
});
};
tagsColorCheck();
console.log(vm.tags);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

Categories

Resources