Hide/Show Element function is undefined? - javascript

Learning JS and was following a complex tutorial and keep getting errors for these specific functions. Stating that my "hide and show element" functions are undefined? Which i thought was odd since they are definitions kinda? Mostly confused because worked fine for the person in the video tutorial.
Any help understanding why is much appreciated!
'use strict';
hideElement = (element) => element.style.display = 'none';
showElement = (element) => element.style.display = 'block';
hideElement('connectWalletBtn');
showElement('userProfileBtn');
// define user button elements
const connectWalletBtn = document.getElementById('connectWalletBtn');
const userProfileBtn = document.getElementById('userProfileBtn');
<button id="connectWalletBtn">Connect Wallet</button>
<button id="userProfileBtn">Profile</button>

Firstly, you have never defined your variables for your functions. Do that:
const hideElement = (element) => element.style.display = 'none';
const showElement = (element) => element.style.display = 'block';
Second, your functions expect to get passed an element, but you are calling them with a string. Go with
hideElement(connectWalletBtn);
showElement(userProfileBtn);
instead.
The third problem is that you're using constant variables which you only declare after using them.
As an improvement, to toggle the display property of an element between none and initial, the DOM API has the hidden property/attribute (which sync). Use it.
Here's the corrected snippet:
'use strict';
const hideElement = element => element.hidden = true;
const showElement = element => element.hidden = false;
// make sure the DOM is fully parsed so elements
// are available for Javascript access
document.addEventListener('DOMContentLoaded', function() {
// find user button elements and store references in variables
const connectWalletBtn = document.getElementById('connectWalletBtn');
const userProfileBtn = document.getElementById('userProfileBtn');
hideElement(connectWalletBtn);
showElement(userProfileBtn);
})
<button id="connectWalletBtn">Connect Wallet</button>
<button id="userProfileBtn">Profile</button>

I think you forgot to grab the element from the dom.
hideElement = (element) => document.getElementById(element).style.display = 'none';
showElement = (element) => document.getElementById(element).style.display = 'block';

Related

Why is my function not reading to my EventListener?

i'm trying to do something with an element when i click on it. I putted this eventListener so it changes the value of a variable when i click on that element.
But it doesn't work, and when i check with debugger the function is not even getting inside of the eventListener, it just completely ignores it and i don't get errors in the console, why does this happen??
my code:
markAsRead(articleid) {
debugger
//there is three different "X", and i needed to get the three of them
let mainNode = document.querySelectorAll('.markasread')[0];
let firstNode = document.querySelectorAll('.markasread')[1];
let secondNode = document.querySelectorAll('.markasread')[2];
firstNode.addEventListener('click', ()=>{
this.$parent.markingAsRead = false;
this.isLoading = false;
console.log('test 1')
});
secondNode.addEventListener('click', ()=>{
this.$parent.markingAsRead = false;
this.isLoading = false;
console.log('test 2')
});
this.isLoading = true;
this.$parent.markingAsRead = true;
this.$eventBus.$emit('articleRemove', (articleid));
this.titleAcross = '';
}, ```
I'm using Vue.js, btw
querySelector and querySelectorAll are usually not the way to go in VueJS, if you want to select something. Either bind with state or use a template reference.

How to test a ternary operator with Jasmine in javascript

I am trying to test a piece of my code using Jasmine, but I am stuck on which method to use and how to go about testing this particular function. Here is my code:
const foodInfoToggle1 = () => {
const foodInfo = document.querySelector('#first');
foodInfo.style.display === "none" ? foodInfo.style.display = "block" : foodInfo.style.display = "none";
}
This function encompasses toggle functionality and is assigned to a button. Once the button is clicked, the function runs to see if the paragraph is set to 'none'. If it is, then it switches to 'block' and vice versa. As you can see, my function is not accepting any parameters so I am finding it difficult to use test cases. How exactly would I go about testing this type of code using Jasmine.
describe('foodInfoToggle1', () => {
let element;
beforeEach(() => {
element = document.createElement('span');
spyOn(document, 'querySelector').and.callFake(selector => {
if (selector === '#first') return element;
});
});
it('Should change the display from none to block', () => {
element.style.display = 'none';
foodInfoToggle1();
expect(element.style.display).toEqual('block');
});
it('Should change the display from block to none', () => {
element.style.display = 'block';
foodInfoToggle1();
expect(element.style.display).toEqual('none');
});
});
I didn't find a quick way to include jasmine in the post, so hopefully all my syntax is correct.
The idea here being for each test, we create a dummy element and mockout the querySelector method. If it is called with the expected selector, return the dummy element.
Then for each of our tests, we put the style display in our expected initial value. We then call the method, and verify that the style display changed.

using $ instead of querySelector()

I want to implement something to make myself instead of writing something.querySelector() to write $, I've fixed the half of the problem which is when I want to make document.querySelector() instead, I can now use $
<div>
<button>hi</button>
</div>
let $ = (x) => {
return document.querySelector(x);
}
div = $("div");
But the thing that I want to do now is to select the button from inside the div, so now I can't do:
div.$("button");
I want to do it, I know a little bit about prototypes, but I don't know how to implement this thing, How?
[EDIT]: I've seen many people saying that It's a bad implementation, could you please tell why?
If you don't want to mess with prototypes, you can have $ accept a second argument, the parent to select from.
const $ = (x, parent = document) => {
return parent.querySelector(x);
}
const div = $("div");
const button = $('button', div);
console.log(button);
<div>
<button>hi</button>
</div>
Changing prototypes is bad practice, but it's doable:
const $ = (x, parent = document) => {
return parent.querySelector(x);
}
Element.prototype.$ = function(selector) {
return $(selector, this);
}
const div = $("div");
const button = div.$('button');
console.log(button);
<div>
<button>hi</button>
</div>
window.$ = HTMLElement.prototype.$ = function(selector) {
if (this === window) {
return document.querySelector(selector);
} else {
return this.querySelector(selector);
}
};
console.log($('div').$('button'));
<div>
<button>hi</button>
</div>
You can, I don't know if I would, put the method on the window and HTMLElement prototype to allow chaining like you asked about.
It's not recommended, but you can modify Element.prototype and Document.prototype.
Element.prototype.$ = Document.prototype.$ = function(x){
return this.querySelector(x);
}
Probably not the best approach but you could assign a property $ to the element that is a function that queries that element
let $ = (x) => {
let el = document.querySelector(x)
el.$ = (y) => el.querySelector(y)
return el;
}
div = $("div");
console.log(div.$('button'))
<div>
<button>hi</button>
</div>
It's very simple and you need only two lines of code to make it all work as expected.
Document.prototype.$ = Document.prototype.querySelector
Element.prototype.$ = Element.prototype.querySelector

Trying to have eventHandler in its own class access to another class's method

I am trying to understand how to use Classes to divide my functions by its purpose.
I am building a todo list app using classes. (I know this may not be ideal use case of class, but still wanted to get used to utilizing class)
I made a CreateTodoList class with constructor for todoList and todos to store data.
so addTodo basically takes text received from eventHandler to todos(array) and create a DOM element using addtoList(text).
Outside CreateTodoList class, I created another class called 'Events' where its going to handle all the events from the user inputs. all this will do is to call addTodo function passing the user input value.
I tried many ways to get this working, but it seems as though anything inside class can't recognize the variable outside nor I can reference another class methods by using CreateTodoList.eventListener.
Would you point out whats wrong with the code below, and possibly explain how it works?
Thanks in advance.
const add = document.querySelector('#btn_add');
let addInput = document.querySelector('#add');
const form = document.querySelector('#form');
class CreateTodoList {
constructor(list) {
this.todoList = list;
this.todos = [];
}
addtoList(text) {
let checkboxEl = document.createElement('span');
checkboxEl.classList.add('round');
let checkboxEl2 = document.createElement('input');
checkboxEl2.id = 'checkbox';
checkboxEl2.type = 'checkbox';
let checkboxEl3 = document.createElement('label');
checkboxEl3.htmlFor = 'checkbox';
checkboxEl.appendChild(checkboxEl2);
checkboxEl.appendChild(checkboxEl3);
let todoTextEl = document.createElement('input');
todoTextEl.value = text;
todoTextEl.disabled = true;
todoTextEl.classList.add('edit_input');
todoTextEl.id = 'edit_input';
todoTextEl.type = 'text';
todoTextEl.name = 'edit_input';
let todoTextEl2 = document.createElement('label');
todoTextEl2.htmlFor = 'edit_input';
let editEl = document.createElement('i');
editEl.classList.add('far');
editEl.classList.add('fa-edit');
let deleteEl = document.createElement('i');
deleteEl.classList.add('far');
deleteEl.classList.add('fa-trash-alt');
let dateEl = document.createElement('small');
dateEl.textContent = timeago.format(new Date());
let liEl = document.createElement('li');
liEl.appendChild(checkboxEl);
liEl.appendChild(todoTextEl);
liEl.appendChild(todoTextEl2);
liEl.appendChild(editEl);
liEl.appendChild(deleteEl);
liEl.appendChild(dateEl);
let list = document.querySelector('ul');
list.appendChild(li);
return liEl;
}
addTodo(text) {
this.todos.push(text);
this.todoList.appendChild(CreateTodoList.addtoList(text));
}
class Events{
add.eventHandler('click', (e) => {
e.preventDefault();
let userText = document.querySelector('#userInput').value;
CreateTodoList.addTodo(userText);
});
}
There are two ways to solve this problem. The first method is instantiating the CreateTodoList class. Classes are data mixed with functions that manipulate that data. Because classes are data, you need to create a variable for their data, otherwise they don't exist as far as the code's concerned. Doing this creates an instance of the class, hence the name instantiation:
class Events{
add_events(){
add.eventHandler('click', (e) => {
e.preventDefault();
let userText = document.querySelector('#userInput').value;
// Creating an instance
let todoList = CreateTodoList();
todoList.addTodo(userText);
});
}
}
If you want to use classes as a namespace to organize functions, like you're trying to do in your example code, then you need to use the second method, which is using the 'static' keyword.
class CreateTodoList{
// defining addTodo as static
static function addTodo(text){
// adding todo list
}
}
This tells the class that you're not trying to manipulate it's data. You can then call the function straight from the class name.
class Events{
add.eventHandler('click', (e) => {
e.preventDefault();
let userText = document.querySelector('#userInput').value;
// calling the static function from the class name
CreateTodoList.addTodo(userText);
});
}
See more about the static keyword here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static

How to use parameter of my function in code?

I got piece of code html and js,css too.I need to use this parameter accordionElem in my function so that on click it will work like accordion with animation, but if l add parameter my code stops.
html code
<h1>Accordian</h1>
How do I learn about activities and events in the CS department?
<p>...</p>
How do I become a section leader?
<p>Please see the CS198 Website for more information about the section leading program.</p>
How many CS classes should I take this quarter?
<p>Most students find that 2-3 classes is a manageable workload, but different students find different workloads comfortable. Most students find they are able to handle more CS classes per quarter as they advance in the major. For more details see the courseload recommendations webpage.</p>
<a href="#" class="accordian">How can I get a summer job or internship? How do I get a
full-time job?</a>
<p>...</p>
How do I file to graduate? Can I participate in the graduation ceremony even if I am not receiving a diploma?<p>...</p>
How does the Honor Code apply to CS?
<p>...</p>
js code
I want to use this accordianEllem in some way so that my code can work.
let createAccordian = function(accordianElem) {
let sadrzaj = accordianElem.nextElementSibling;
console.log(sadrzaj);
sadrzaj.style.transition = "max-height 0.5s ease-out";
if(sadrzaj.style.display === "block") {
/* sadrzaj.style.maxHeight = "0px";*/
window.setTimeout(function () {
sadrzaj.style.maxHeight = '0px';
}, 50);
window.setTimeout(function () {
sadrzaj.style.display= 'none';
}, 550);
}
else {
sadrzaj.style.display = "block";
sadrzaj.style.maxHeight = sadrzaj.scrollHeight + "px";
}
let getHeight = function () {
sadrzaj.style.display = 'block';
let height = sadrzaj.scrollHeight + 'px';
sadrzaj.style.display = '';
return height;
};
let height = getHeight();
sadrzaj.style.display='block';
sadrzaj.style.height = 'auto';
sadrzaj.style.height = height;
window.setTimeout(function () {
sadrzaj.style.height = '';
}, 350);
};
const akordi = document.querySelectorAll('.accordian');
const par = document.querySelectorAll('p');
let aks = document.getElementsByClassName('accordian');
console.log(aks);
for( let i of par){ i.style.display = 'none';i.style.maxHeight = "0px"; }
for( let i of akordi){
i.addEventListener('click',createAccordian(akordi)); }
Event listeners take a function as the second parameter, and in that function, you should be calling your function createAcrodian passing the parameters.
i.addEventListener('click', function() {
createAccordian(i);
})
Or with using ES arrow function
i.addEventListener('click', () => createAccordian(i));
I have noticed you are looping through an akordi array, but not passing the "i" value (or current loop item), but you are passing the whole array. If you are still learning, it's really rewarding to always console.log values or run debug in loops just to understand what is going on.
You can pass your function to these event listeners,
eg.
i.addEventListener('click',createAccordian);
...But since you are passing some parameters, you should be using one of the above examples
PS. I have noticed you are using some of your native tongue to define variables, I would strongly recommend you to use English for everything.

Categories

Resources