Reputation:
I am working on a job-listing website. I have a search page where the user is able to see all the job posting and filter jobs with the search bar.
On the top of the job dashboard, I am displaying the total number of jobs displayed on the page.
Let's say without filter there is 234 jobs available. If the user type "tech" that number drop to 34 and out the the 234 <li>
elements, 200 are displayed as none
and 34 keep their original value.
What I have static one
count = document.getElementsByClassName("job");
document.getElementById("number-jobs-total").innerHTML = count;
What I am working on
The issue is the count
is undefined, do you know what is wrong?
const updateTotalJobs = () => {
count = document.getElementsByClassName("job");
var arr = Array.from(count);
for(var i = 0 ; i < arr.length ; i++){
if(arr[i].style.display=="none"){
count--;
}
}
console.log(count);
};
search.addEventListener("keyup", e =>{
filterJobs(e.currentTarget.value.trim());
updateTotalJobs();
});
HTML
Span at line number 4
<div class="job-listing">
<div class="container">
<div class="job-number">
<h2>We Found <span id="number-jobs-total" class="text-secondary"></span> Offers For <span>You</span> </h2>
</div>
<ul class="job-board">
<li class="job job-1">
<div class="job-title">
<h2>Process Engineer</h2>
</div>
<div class="job-location">
<p>Location: Naypyitaw</p>
</div>
<div class="job-type">
<p>Type: Full-Time</p>
</div>
<div class="job-date">
<p>Published on 07/19/2019</p>
</div>
<div class="job-industry">
<p>Engineering</p>
</div>
<ul class="job-keywords">
<li>Engineering</li>
<li>Science</li>
</ul>
</li>
<li class="job job-2">
<div class="job-title">
<h2>Chief Financial Officier</h2>
</div>
<div class="job-location">
<p>Location: Naypyitaw</p>
</div>
<div class="job-type">
<p>Type: Full-Time</p>
</div>
<div class="job-date">
<p>Published on 07/18/2019</p>
</div>
</li>
<li class="job job-3">
<div class="job-title">
<h2>Assistant CEO</h2>
</div>
<div class="job-location">
<p>Location: Naypyitaw</p>
</div>
<div class="job-type">
<p>Type: Part-Time</p>
</div>
<div class="job-date">
<p>Published on 07/18/2019</p>
</div>
</li>
<li class="job job-4">
<div class="job-title">
<h2>Front-End Developer</h2>
</div>
<div class="job-location">
<p>Location: Naypyitaw</p>
</div>
<div class="job-type">
<p>Type: Part-Time</p>
</div>
<div class="job-date">
<p>Published on 07/18/2019</p>
</div>
</li>
</ul>
<nav class="pagination-container">
<ul class="pagination">
<li><a href="javascript:void(0)">Previous</a></li>
<li><a href="javascript:void(0)">Next</a></li>
</ul>
</nav>
</div>
</div>
</div>
</body>
Upvotes: 1
Views: 68
Reputation: 36311
You could simply get a count of items by using filter and getting the items that don't equal none
.
ES6 Solution:
let count = [...document.getElementsByClassName("job")]
.filter(i => i.style.display != 'none').length
ES5 Solution:
let count = Array.from(document.getElementsByClassName("job"))
.filter(i => i.style.display != 'none').length
In this example the first Item is hidden, and the console will display Job Count: 3
:
let count = [...document.getElementsByClassName("job")]
.filter(i => i.style.display != 'none').length
console.log('Job Count:', count)
<div class="job-listing">
<div class="container">
<div class="job-number">
<h2>We Found <span id="number-jobs-total" class="text-secondary"></span> Offers For <span>You</span> </h2>
</div>
<ul class="job-board">
<li class="job job-1" style="display:none">
<div class="job-title">
<h2>Process Engineer</h2>
</div>
<div class="job-location">
<p>Location: Naypyitaw</p>
</div>
<div class="job-type">
<p>Type: Full-Time</p>
</div>
<div class="job-date">
<p>Published on 07/19/2019</p>
</div>
<div class="job-industry">
<p>Engineering</p>
</div>
<ul class="job-keywords">
<li>Engineering</li>
<li>Science</li>
</ul>
</li>
<li class="job job-2">
<div class="job-title">
<h2>Chief Financial Officier</h2>
</div>
<div class="job-location">
<p>Location: Naypyitaw</p>
</div>
<div class="job-type">
<p>Type: Full-Time</p>
</div>
<div class="job-date">
<p>Published on 07/18/2019</p>
</div>
</li>
<li class="job job-3">
<div class="job-title">
<h2>Assistant CEO</h2>
</div>
<div class="job-location">
<p>Location: Naypyitaw</p>
</div>
<div class="job-type">
<p>Type: Part-Time</p>
</div>
<div class="job-date">
<p>Published on 07/18/2019</p>
</div>
</li>
<li class="job job-4">
<div class="job-title">
<h2>Front-End Developer</h2>
</div>
<div class="job-location">
<p>Location: Naypyitaw</p>
</div>
<div class="job-type">
<p>Type: Part-Time</p>
</div>
<div class="job-date">
<p>Published on 07/18/2019</p>
</div>
</li>
</ul>
<nav class="pagination-container">
<ul class="pagination">
<li><a href="javascript:void(0)">Previous</a></li>
<li><a href="javascript:void(0)">Next</a></li>
</ul>
</nav>
</div>
</div>
We could also use reduce, which will just do some basic addition. Instead of returning an array and getting the length, it will just return the number.
let count = [...document.getElementsByClassName("job")]
.reduce((val, i) => i.style.display != 'none' ? val + 1 : val, 0)
let count = [...document.getElementsByClassName("job")]
.reduce((val, i) => i.style.display != 'none' ? val + 1 : val, 0)
console.log('Job Count:', count)
<div class="job-listing">
<div class="container">
<div class="job-number">
<h2>We Found <span id="number-jobs-total" class="text-secondary"></span> Offers For <span>You</span> </h2>
</div>
<ul class="job-board">
<li class="job job-1" style="display:none">
<div class="job-title">
<h2>Process Engineer</h2>
</div>
<div class="job-location">
<p>Location: Naypyitaw</p>
</div>
<div class="job-type">
<p>Type: Full-Time</p>
</div>
<div class="job-date">
<p>Published on 07/19/2019</p>
</div>
<div class="job-industry">
<p>Engineering</p>
</div>
<ul class="job-keywords">
<li>Engineering</li>
<li>Science</li>
</ul>
</li>
<li class="job job-2">
<div class="job-title">
<h2>Chief Financial Officier</h2>
</div>
<div class="job-location">
<p>Location: Naypyitaw</p>
</div>
<div class="job-type">
<p>Type: Full-Time</p>
</div>
<div class="job-date">
<p>Published on 07/18/2019</p>
</div>
</li>
<li class="job job-3">
<div class="job-title">
<h2>Assistant CEO</h2>
</div>
<div class="job-location">
<p>Location: Naypyitaw</p>
</div>
<div class="job-type">
<p>Type: Part-Time</p>
</div>
<div class="job-date">
<p>Published on 07/18/2019</p>
</div>
</li>
<li class="job job-4">
<div class="job-title">
<h2>Front-End Developer</h2>
</div>
<div class="job-location">
<p>Location: Naypyitaw</p>
</div>
<div class="job-type">
<p>Type: Part-Time</p>
</div>
<div class="job-date">
<p>Published on 07/18/2019</p>
</div>
</li>
</ul>
<nav class="pagination-container">
<ul class="pagination">
<li><a href="javascript:void(0)">Previous</a></li>
<li><a href="javascript:void(0)">Next</a></li>
</ul>
</nav>
</div>
</div>
Upvotes: 4
Reputation: 2809
Solution:
You were decrementing the count which is actually an array. That was the only mistake I could see in your code. But still it can be optimized as suggested in others solutions.
const updateTotalJobs = () => {
arr = document.getElementsByClassName("job");
count = arr.length;
for(var i = 0 ; i < arr.length ; i++){
if(arr[i].style.display=="none"){
count--;
}
}
console.log(count);
}
Upvotes: 1
Reputation: 1008
Document.getElementsByClassName()
returns an array-like object, not a number. Try setting count equal to the length.
Upvotes: 2
Reputation: 6400
It would be easier to use a class for this calculation. You can simply query for the two classes and the difference of the result set counts will be the value you are looking for.
.hide-job{
display:none;
}
const updateTotalJobs = () => {
count = document.querySelectorAll('.job').length - document.querySelectorAll('.hide-job').length
console.log(count);
};
Upvotes: 1