Today is a good ‘study day.’ I stayed focused and got a lot done. We’re learning regex and template strings right now, and it’s kicking me in the butt. But I’m enjoying it. Well, not so much of the kicking of the butt.
Somehow, the E drive on my computer has become corrupted. My computer says it isn’t the correct file system, and to use the drive, I must format it. I don’t want to format the drive. I have pictures on there. I would like to know if I took the drive out if I can get the information off of it. I want to know what happened. I haven’t done anything new to my computer. The E drive suddenly stopped working. /sigh
I don’t have any appointments today, so I have the house to myself while Kel and Karissa are out. Karissa has to go to her math class on campus once a week for an hour. She’s been doing well in her classes so far. Alexis has been doing well, also. Well, as she tells me. I’m always worried about the kids’ wellbeing.
I logged into my LiveJournal today and read some past posts. I was furious in some of my posts. I want to think that I’m doing better now. However, I was angry yesterday after therapy. Next week, we will review the traumas I experienced during my teens and twenties. I didn’t have much for trauma in my twenties, except for maybe dealing with my mom. I have had a lot of drama in my twenties, but not trauma. Well, one significant trauma was Kevin passing away. The therapist wants to talk more about that next week.
I have yet to eat lunch. I should do that. It’s easy for me to forget lunch, snack a little, and wait for dinner. Of course, if anyone else ate like I did, I’d have some words about good health and eating habits. Yet it’s hard to eat when I’m alone and sitting at my desk all day. My brain screams at me if I eat, and I feel like I’m overeating when, in fact, I haven’t eaten much at all. I count my calories. Even with lunch, I don’t meet my calorie requirement most days. I eat more when everyone is home. I hardly eat when I’m alone.
Well, I’m going to get some food. I am hungry and can’t have another cup of coffee to curb my hunger.
JavaScript notes…
—————————————–
Calorie Counter:
Step 29
In HTML, number inputs allow for exponential notation (such as 1e10). You need to filter those out.
Start by creating a function called isInvalidInput – it should take a single str parameter.
function isInvalidInput(str) { }
Step 30
Declare a regex variable, and assign it a regex that matches the character e.
function isInvalidInput(str) { const regex = /e/; }
Step 31
The e in a number input can also be an uppercase E. Regex has a flag for this, however – the i flag, which stands for “insensitive”. This flag makes your pattern case-insensitive. Add the i flag to your regex pattern.
function isInvalidInput(str) { const regex = /e/i; }
Step 32
Number inputs only allow the e to occur between two digits. To match any number, you can use the character class [0-9]. This will match any digit between 0 and 9.
Add this character class before and after e in your pattern.
function isInvalidInput(str) { const regex = /[0-9]e[0-9]/i; }
Step 33
The + modifier in a regex allows you to match a pattern that occurs one or more times. To match your digit pattern one or more times, add a plus after each of the digit character classes. For example: [0-9]+.
function isInvalidInput(str) { const regex = /[0-9]+e[0-9]+/i; }
Step 34
There is a shorthand character class to match any digit: \d. Replace your [0-9] character classes with this shorthand.
function isInvalidInput(str) { const regex = /\d+e\d+/i; }
Step 35
Strings have a .match() method, which takes a regex argument. .match() will return an array of match results – containing either the first match, or all matches if the global flag is used.
const str = ‘example string’;
const regex = /example/;
const result = str.match(regex); // Returns [‘example’]
Return the result of calling the .match() method on str and passing your regex variable as the argument. You’ll use this match result later on.
function isInvalidInput(str) { const regex = /\d+e\d+/i; return str.match(regex); }
Step 36
Your next step is to allow users to add entries to the calorie counter. Declare an empty function addEntry. This function should not take any parameters.
function addEntry() { }
Step 37
You’ll need to know which category the entry goes in. Thankfully, you added a dropdown for the user to select a category.
Remember that you queried that dropdown earlier in your JavaScript and assigned it to the entryDropdown button. You can use the value property to get the value of the selected option.
Use concatenation to add a # to the beginning of the value property of entryDropdown, and assign that result to a targetId variable.
function addEntry() { let targetId = "#" + entryDropdown.value; }
Step 38
Now you need to target the .input-container element within the element that has your targetId. Declare a new targetInputContainer variable, and assign it the value of document.querySelector(). Use concatenation to separate targetId and ‘.input-container’ with a space, and pass that string to querySelector().
function addEntry() { const targetId = '#' + entryDropdown.value; const targetInputContainer = document.querySelector(targetId + ' .input-container'); }
Step 39
JavaScript has a feature called template literals, which allow you to interpolate variables directly within a string. Template literals are denoted with backticks “, as opposed to single or double quotes. Variables can be passed in to a template literal by surrounding the variable with ${} – the value of the variable will be inserted into the string.
For example:
const name = “Naomi”;
const templateLiteral = `Hello, my name is ${name}~!`;
console.log(templateLiteral);
The console will show the string “Hello, my name is Naomi~!”.
Replace your concatenated string in the querySelector with a template literal – be sure to keep the space between your targetId variable and .input-container.
function addEntry() { const targetId = '#' + entryDropdown.value; const targetInputContainer = document.querySelector(`${targetId} .input-container`); }
Step 40
Thanks to template literals, you actually don’t need the targetId variable at all. Remove that variable, and update your template literal to replace targetId with entryDropdown.value – remember to add # before that, in the string.
function addEntry() { const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`); }
Step 41
You will want to number the entries a user adds. To get all of the number inputs, you can use the querySelectorAll() method.
The querySelectorAll() method returns a NodeList of all the elements that match the selector. A NodeList is an array-like object, so you can access the elements using bracket notation.
Declare an entryNumber variable and give it the value of targetInputContainer.querySelectorAll(). You do not need to pass an argument to the query selector yet.
function addEntry() { const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`); const entryNumber = targetInputContainer.querySelectorAll(); }
Step 42
Each entry will have a text input for the entry’s name, and a number input for the calories. To get a count of the number of entries, you can query by text inputs. Note that you cannot query by number inputs, as you have an extra number input for the user’s calorie budget.
Pass the string input[type=”text”] to the querySelectorAll() method. Remember that you will need to use single quotes for your string, so that you can use double quotes within.
This will return a NodeList of all the text inputs in the form. You can then access the length property of the NodeList to get the number of entries. Do this on the same line.
function addEntry() { const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`); const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length; }
Step 43
Now you need to build your dynamic HTML string to add to the webpage. Declare a new HTMLString variable, and assign it an empty template literal string.
function addEntry() { const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`); const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length; const HTMLString = ``; }
Step 44
Inside your template literal, create a label element and give it the text Entry # Name. Using your template literal syntax, replace # with the value of entryNumber.
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 = ` `; }