Coding has been kicking my butt lately. We are building a calorie counter and jumping around the code so much that it needs to be clarified. The freecodecamp course needs to give you more time to practice when you are initially learning a topic. We do it once and move on. I find myself needing to catch up on some things. I want to move slower to improve my understanding of the topic. And lately, a few of the ‘problems’ I’m trying to figure out have been stated objectives rather than having instructions about the code. I’m starting to think the best teaching tools are Google and YouTube.
This last weekend was relaxing. I hung out with Tommy. And I played Final Fantasy XIV. Now that I’m caught up with the main quests, I have been grinding to get my relic tools for my gatherers and crafting jobs. I was also getting tomes for the Moogle event going on now.
Tommy, Kel, and I went to a Japanese restaurant on Friday. They make the food right in front of you. I like that place. Of course, they gave me so much food that I took it home. It has taken me a few days to finish what I had. Saturday, we went shopping for dinners and food for Super Bowl Sunday. Then I played Final Fantasy some more. Sunday, Tommy and I rode the bike. I did yoga, also. Then it was Super Bowl time. It was great, but I’m glad I wasn’t emotionally invested. The game had some nail-biting moments. The halftime show had a lot of choreography. It was alright. I’m still miffed about missing the New Kids on the Block during halftime when I was 14 because the station showed Desert Storm instead.
We had a snowstorm on Saturday as well. The Outback took the snow like a champ. She saw the snow as no challenge. Tommy and I saw an accident on the freeway as we were heading to the store. There was a big backup on the highway.
I spent most of my day studying while the other half tended to Merlin and Mimi. Tonight we’re having burgers. This maketh me joyous. Maybe we can have sweet potatoes with it. I’d better get back to studying. I still have a few hours left.
JavaScript notes…
———————————————
Calorie Counter:
Step 45
Give your label element a for attribute with the value X-#-name, where X is the value of the entryDropdown element and # is the value of entryNumber. Remember that HTML attributes should be wrapped in double quotes.
function addEntry() { const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`); const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length; const HTMLString = ` `; }
Step 46
After your label element, and on a new line in your template string, create an input element. Give it a type attribute set to text, a placeholder attribute set to Name, and an id attribute that matches the for attribute of your label element.
function addEntry() { const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`); const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length; const HTMLString = ` `; }
Step 47
Create another label element (on a new line) at the end of your HTMLString. This label should have the text Entry # Calories, using your template literal syntax to replace # with the value of entryNumber, and the for attribute set to X-#-calories, where X is the value of entryDropdown and # is the value of entryNumber.
function addEntry() { const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`); const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length; const HTMLString = ` `; }
Step 48
Finally, on a new line after your second label, create another input element. Give this one a type attribute set to number, a min attribute set to 0 (to ensure negative calories cannot be added), a placeholder attribute set to Calories, and an id attribute that matches the for attribute of your second label element.
function addEntry() { const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`); const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length; const HTMLString = ` `; }
Step 49
To see your new HTML content for the targetInputContainer, you will need to use the innerHTML property.
The innerHTML property sets or returns the HTML content inside an element.
Here is a form element with a label and input element nested inside.
If you want to add another label and input element inside the form, then you can use the innerHTML property as shown below:
const formElement = document.getElementById(“form”);
const formContent = `
`;
formElement.innerHTML += formContent;
Use the addition assignment operator += to append your HTMLString variable to targetInputContainer.innerHTML.
function addEntry() { const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`); const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length; const HTMLString = ` `; targetInputContainer.innerHTML += HTMLString; }
Step 50
In the Role Playing Game project, you learned how to set a button’s behavior by editing its onclick property. You can also edit an element’s behavior by adding an event listener.
The following example uses the addEventListener method to add a click event to a button. When the button is clicked, the printName function is called.
const button = document.querySelector(‘.btn’);
function printName() {
console.log(“Jessica”);
}
button.addEventListener(‘click’, printName);
The addEventListener method takes two arguments. The first is the event to listen to. (Ex. ‘click’) The second is the callback function, or the function that runs when the event is triggered.
Call the .addEventListener() method on the addEntryButton. Pass in the string click for the first argument and the addEntry function for the second argument.
Note that you should not call addEntry, but pass the variable (or function reference) directly.
addEntryButton.addEventListener('click', addEntry);
Step 51
Try adding a couple of entries to the Breakfast category, and you may notice some bugs! The first thing we need to fix is the entry counts – the first entry should have a count of 1, not 0.
This bug occurs because you are querying for input[type=”text”] elements before adding the new entry to the page. To fix this, update your entryNumber variable to be the value of the length of the query plus 1. Add this on your declaration line, not in your template strings.
function addEntry() { const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`); const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1; const HTMLString = ` `; targetInputContainer.innerHTML += HTMLString; }