2
\$\begingroup\$

Problem Statement

Write JavaScript code hideOddRows.js that attaches to the button click event and hides the odd rows of the table when clicked.

Expected Output

enter image description here

When you click on "Hide Odd Rows":

enter image description here


Solution

/* hideOddRows.js */
document.querySelector('[name=HideRows]').onclick = hideRows;

function hideRows(){
    var elements = document.getElementsByClassName('hide');
    Array.prototype.forEach.call(elements, function(element){
        element.style.display = "none";
    });
    return true;
}
<!DOCTYPE html>
<html>
    <head>
        <title>Hide odd rows</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <div style="background-color:#8F9779;width:200px;height:30px;">
        </div>
        <hr style="width:200px" align="left">
        <table border="1" >
            <tr class="hide" >
                <td width="40" height="20">row 1</td>
            </tr>
            <tr>
                <td width="40" height="20">row 2</td>
            </tr>
            <tr class="hide">
                <td width="40" height="20">row 3</td>
            </tr>
            <tr>
                <td width="40" height="20">row 4</td>
            </tr>
            <tr class="hide">
                <td width="40" height="20">row 5</td>
            </tr>
        </table><br>
        <button type="button" name="HideRows">Hide Odd Rows</button>
        <script type="text/javascript" src="hideOddRows.js"></script>
    </body>
</html>

Questions

  1. I could not manage to place script tag in head due to DOM loading issue. How do I improve this solution to place script tag in head?

  2. Can I improve the HTML code?

Note: I've yet to learn jQuery.

\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

Your JavaScript is OK, but beware of writing code where you can get away without it. In this case, there is a CSS3 :nth-child() selector1 that lets you select odd rows without tagging them manually with class="hide".

You just have to trigger the CSS rule when the button is pressed. Note that if you want to select one specific element in a document, it's better to mark it using id="…" and select it using document.getElementById(…) — that's exactly what it is designed to do, and browsers will optimize ID lookups to be as fast as possible.

/* hideOddRows.js */
document.getElementById('HideRows').onclick = function hideRows() {
    document.getElementsByTagName('table').item(0).className = 'odd-rows-hidden';
}
table.odd-rows-hidden tr:nth-child(odd) {
    display: none;
}
<!DOCTYPE html>
<html>
    <head>
        <title>Hide odd rows</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <div style="background-color:#8F9779;width:200px;height:30px;">
        </div>
        <hr style="width:200px" align="left">
        <table border="1" >
            <tr>
                <td width="40" height="20">row 1</td>
            </tr>
            <tr>
                <td width="40" height="20">row 2</td>
            </tr>
            <tr>
                <td width="40" height="20">row 3</td>
            </tr>
            <tr>
                <td width="40" height="20">row 4</td>
            </tr>
            <tr>
                <td width="40" height="20">row 5</td>
            </tr>
        </table><br>
        <button type="button" id="HideRows">Hide Odd Rows</button>
        <script type="text/javascript" src="hideOddRows.js"></script>
    </body>
</html>


1 Caveat: requires Internet Explorer ≥ 9. If you need to support older versions of IE, you'll probably want jQuery.

\$\endgroup\$
0
0
\$\begingroup\$
  1. I could not manage to place script tag in head due to DOM loading issue. How do I improve this solution to place script tag in head?

Placing the script tag in the header is not a necessity of HTML, in fact, I often put my scripts at the bottom of my body tag.

  1. Can we improve html code?

Yeah, we can.

        <tr class="hide" >
            <td width="40" height="20">row 1</td>
        </tr>
        <tr>
            <td width="40" height="20">row 2</td>
        </tr>
        <tr class="hide">
            <td width="40" height="20">row 3</td>
        </tr>
        <tr>
            <td width="40" height="20">row 4</td>
        </tr>
        <tr class="hide">
            <td width="40" height="20">row 5</td>
        </tr>

Instead of using class="hide", you can iterate over the elements and count the index.


return true; is unnecessary because you don't do anything with the result.


Instead of Array.prototype.forEach.call(elements, you can evoke forEach directly on the nodelist, as long as you attach the additional call to Array.prototype.slice.call.

I would suggest to remember that for cases where you make frequent document retrieval calls, simplifying document calls comes in very handy:

For example, one of my simplifications for jQuery-like selection:

function $$(selector, el) {
    if (!el) { el = document; }
    return Array.prototype.slice.call(el.querySelectorAll(selector));
}

Which would let you make a call like:

$$('.postTitle')

and iterate over it like an array.


All together:

All together, it would look like:

document.querySelector('[name=HideRows]').onclick = function(){
    Array.prototype.slice.call(document.getElementsByTagName('td')).forEach(function(element, index){
        if (index % 2 !== 0){
            element.style.display = "none";
        }
    });
}

Additionally, you should call things like in .onclick = hideRows before it's defined, if the function was anonymous, that would cause a bug. It's a good habit to get into.

\$\endgroup\$
2
  • \$\begingroup\$ In your final code, you use the class hide which is given only to the odd rows, and then check for (index % 2 !== 0). That will only return every second odd row instead of every odd row. \$\endgroup\$
    – bIgBoY
    Dec 16, 2015 at 6:35
  • \$\begingroup\$ It is a JavaScript solution, a polyfill is when you replace an unwritten function with its implementation in a different solution/library, for example jQuery has a simpler document retrieval system, which I tend to replace with polyfills to discourage jQuery use \$\endgroup\$
    – Quill
    Dec 16, 2015 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.