user11879292
user11879292

Reputation:

Update a number based on style

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.

here

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

Answers (4)

Get Off My Lawn
Get Off My Lawn

Reputation: 36311

Filter

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>


Reduce

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

Naveen Kumar V
Naveen Kumar V

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

displacedtexan
displacedtexan

Reputation: 1008

Document.getElementsByClassName() returns an array-like object, not a number. Try setting count equal to the length.

Upvotes: 2

ExceptionLimeCat
ExceptionLimeCat

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

Related Questions