// creating a named function, as a constant, since the function isn't
// expected to be modified by code; this function is defined using
// Arrow syntax, and passes in the Event Object - from the (later)
// use of EventTarget.addEventListener() - to the function body:
const getResults = (evt) => {
// here we retrieve the element to which the function was bound
// with EventTarget.addEventListener():
let button = evt.currentTarget,
// from the <button> element we navigate - with Element.closest()
// to the closest ancestor-element that matches the supplied CSS
// selector; note that if no such element is found then this
// will return null. So if you can't be sure the element will
// exist, sanity-check the variable before use:
ancestor = button.closest('li'),
// from the ancestor we retrieve the <textarea> element, using
// Element.querySelector(), which finds the first element
// inside of the ('ancestor', <li>) Element that matches the
// selector; again: if no such element is found, this will
// return null:
textarea = ancestor.querySelector('textarea'),
// this is my habitual practice, but effectively we try to
// retrieve the value property of the <textarea> element, if
// that doesn't have a value, or returns a falsey value,
// we retrieve the text-content instead:
entry = textarea.value || textarea.textContent,
// here we split the value/text-content on new-line characters,
// using String.protoype.split() and passing in a regular
// expression literal (/<regex sequence>/); which returns an
// Array. We then use Array.prototype.reduce() to return a new
// Array based on the passed-in Array:
result = entry.split(/\n/).reduce(
// here we pass in the accumulator ('acc', the Array we're working
// to produce on each iteration through this Array) and the
// Array-entry ('curr'):
(acc, curr) => {
// here we split the current ('curr') Array-value which is a String,
// again using String.prototype.split() and a regular expression-literal;
// this regular expression matches a comma followed by zero-or-more white-
// space characters (tabs, space, etc...); we expect this String to return
// a three part Array and we know the order; so we can use destructuring
// assignment to define person as equal to the first Array-element,
// posX to the second and posY to the third. If there are more
// Array elements returned those will be unallocated:
let [person, posX, posY] = curr.split(/,\s*/);
// I can't remember the term for this, but it's effectively a shorthand;
// but we use Array.prototype.push() to add an Object to the
// accumulator Array; this Object passes in the variables and those variables
// become both the name of the property (so the variable 'person' becomes both
// the property 'person' and sets the value of that property to the value of
// the variable):
acc.push({
person,
posX,
posY,
});
// we return the accumulator to continue working on it in the next iteration:
return acc;
// and here we pass in an empty Array-literal to act as the accumulator:
}, []);
// logging the result to the console:
console.log(result);
},
// here we find all <button> elements with a 'type' attribute equal to 'button', using
// document.querySelectorAll() to obtain a NodeList:
buttons = document.querySelectorAll('button[type=button]');
// here we use NodeList.prototype.forEach() to iterate over the <button> elements:
buttons.forEach(
// passing in a reference to the current Node of the NodeList over which we're iterating
// to the Arrow function-body, and using EventTarget.addEventListener() to bind the
// getResults() function as the event-handler for the 'click' event, this also passes
// the Event Object to the named function:
(btn) => btn.addEventListener('click', getResults)
);
*,
::before,
::after {
box-sizing: border-box;
font-family: sans-serif;
font-size: 16px;
font-weight: 400;
line-height: 1.5;
margin: 0;
padding: 0;
}
ul,
li {
list-style-type: none;
padding: 1em;
}
li {
display: flex;
flex-direction: column;
gap: 0.5em;
justify-content: space-between;
}
textarea {
min-height: 40vmin;
width: 100%;
}
<ul>
<li class="inputValue">
<textarea>1, 2300,450
2, 2200, 920
3, 3400, 440</textarea>
<button type="button">format</button>
</li>
</ul>