I am dipping my toe in JavaScript (and CSS). New to asking questions here; open to feedback. I'm posting in part to help others find an answer to a challenge I was facing. I couldn't find an example of what I was trying to do via Googling and head scratching.
The code does what I want it to. What are some approaches to optimize and refactor it?
Multiple button groups ...independently styled ...can each update respective parts of a concatenated string with one click.
https://jsfiddle.net/ncarlton/by8ragpc/1/
I am using HTML, CSS and JavaScript.
Objectives of the code included:
- Concatenate variables based on user selections (buttons in my case).
- Start with default choices.
- Style each button group independently. This is because the three vars will live in different areas of my final implementation's GUI ... they represent different features. The mockup has each button group styled differently.
- Any button click updates the concatenated string; no "Submit" button.
- The updates replace values in their respective positions of the concatenated string ... so each button click "swaps out" the previous value (don't re-arrange the order of first, middle, last).
JS:
//make default variables in UPPER to show that values should come from .js and not from .html
let _firstName = "MARTIN";
let _middleName = "LUTHER";
let _lastName = "KING";
//build the full Name
let fullName = _firstName + " " + _middleName + " " + _lastName;
//replace the <span>Need A. Change with the default values
//default values start as UPPERcase to show they came from variables and not innerHTML
document.getElementById("myName").innerHTML = fullName;
//swap out any of the name parts by a single button click: first, middle, last
//also style the buttons in each group to look different
function changeName() {
//First Name Selections and Style changes
const btnFirstSelect = function() {
this.parentNode.getElementsByClassName("btnSelFirst")[0].classList.remove("btnSelFirst");
this.classList.add("btnSelFirst");
_firstName = this.innerHTML;
fullName = _firstName + " " + _middleName + " " + _lastName;
document.getElementById("myName").innerHTML = fullName;
};
document.querySelectorAll(".btnsFirstName .btnFirst").forEach(btnFirst => btnFirst.addEventListener('click', btnFirstSelect));
//Middle Name Selections and Style changes
const btnMiddleSelect = function() {
this.parentNode.getElementsByClassName("btnSelMiddle")[0].classList.remove("btnSelMiddle");
this.classList.add("btnSelMiddle");
_middleName = this.innerHTML;
fullName = _firstName + " " + _middleName + " " + _lastName;
document.getElementById("myName").innerHTML = fullName;
};
document.querySelectorAll(".btnsMiddleName .btnMiddle").forEach(btnMiddle => btnMiddle.addEventListener('click', btnMiddleSelect));
//Last Name Selections and Syle changes
const btnLastSelect = function() {
this.parentNode.getElementsByClassName("btnSelLast")[0].classList.remove("btnSelLast");
this.classList.add("btnSelLast");
_lastName = this.innerHTML;
fullName = _firstName + " " + _middleName + " " + _lastName;
document.getElementById("myName").innerHTML = fullName;
};
document.querySelectorAll(".btnsLastName .btnLast").forEach(btnLast => btnLast.addEventListener('click', btnLastSelect));
}
window.onload = changeName;
//click a button and then reload the console with this
//confirm your selection changed the var by grabbing the innerHTML
//confirm the full name was also rebuilt
console.log(_firstName, _middleName, _lastName, fullName);
HMTL:
<body>
<h4>Name Builder from Button Choices</h4>
<div>My name is: <span id="myName">Need A. Change</span>
</div>
<hr />
<div class="btnsFirstName ">First name Choices:
<button class="btnFirst btnSelFirst">Martin</button>
<button class="btnFirst">Barack</button>
<button class="btnFirst">Jelly</button>
</div>
<div class="btnsMiddleName">Middle Name Choices:
<button class="btnMiddle btnSelMiddle">Luther</button>
<button class="btnMiddle">Hussein</button>
<button class="btnMiddle">Roll</button>
</div>
<div class="btnsLastName">Last Name Choices:
<button class="btnLast btnSelLast">King</button>
<button class="btnLast">Obama</button>
<button class="btnLast">Morton</button>
</div>
<p>(Each button click should build the full name by swapping out the value of the clicked button in the correct position. Ideally the button groups would change styles independently too.)</p>
</body>
CSS:
.btnFirst,
.btnMiddle,
.btnLast {
background-color: grey;
color: green;
}
.btnSelFirst {
background-color: black;
color: white;
outline: none;
}
.btnFirst:hover {
background-color: black;
color: white;
outline: none;
}
.btnSelMiddle {
background-color: white;
color: black;
outline: none;
}
.btnMiddle:hover {
background-color: white;
color: black;
outline: none;
}
.btnSelLast {
background-color: pink;
color: blue;
outline: none;
}
.btnLast:hover {
background-color: pink;
color: blue;
outline: none;
}
body {
font-family: Helvetica, Arial, Sans-Serif;
}
Using the following question, I sort of "tacked on" the additional redundant functional code to make the buttons "work" the way I wanted: How to apply javascript to multiple button groups
I've tried a couple things to reduce the code redundancy but I hope to learn various techniques.